IAMTFRMZA commited on
Commit
106b612
Β·
verified Β·
1 Parent(s): d685333

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +15 -18
app.py CHANGED
@@ -1,17 +1,17 @@
1
- import gradio as gr
2
  import pandas as pd
3
  import gspread
4
- from oauth2client.service_account import ServiceAccountCredentials
5
  import plotly.express as px
 
6
 
7
- # ------------------ Authentication ------------------
8
  VALID_USERS = {
9
  "[email protected]": "Pass.123",
10
  "[email protected]": "Pass.123",
11
  "[email protected]": "Pass.123"
12
  }
13
 
14
- # ------------------ Data Setup ------------------
15
  scope = ["https://spreadsheets.google.com/feeds", "https://www.googleapis.com/auth/drive"]
16
  creds = ServiceAccountCredentials.from_json_keyfile_name("tough-star.json", scope)
17
  client = gspread.authorize(creds)
@@ -20,10 +20,10 @@ sheet = client.open_by_url(sheet_url).worksheet("Calls")
20
  data = sheet.get_all_records()
21
  df = pd.DataFrame(data)
22
 
 
23
  df['Timestamp'] = pd.to_datetime(df['Timestamp'], dayfirst=True, errors='coerce')
24
  df['Date'] = df['Timestamp'].dt.date.astype(str)
25
  df['Time'] = df['Timestamp'].dt.time
26
-
27
  location_split = df['Location'].str.split(',', expand=True)
28
  df['Latitude'] = pd.to_numeric(location_split[0], errors='coerce')
29
  df['Longitude'] = pd.to_numeric(location_split[1], errors='coerce')
@@ -32,10 +32,9 @@ df = df[(df['Latitude'] != 0) & (df['Longitude'] != 0)]
32
  df = df.sort_values(by=['Rep Name', 'Timestamp'])
33
  df['Time Diff (min)'] = df.groupby(['Rep Name', 'Date'])['Timestamp'].diff().dt.total_seconds().div(60).fillna(0)
34
  df['Visit Order'] = df.groupby(['Rep Name', 'Date']).cumcount() + 1
35
-
36
  ALL_REPS = sorted(df['Rep Name'].dropna().unique())
37
 
38
- # ------------------ App Logic ------------------
39
  def generate_summary(date_str):
40
  day_df = df[df['Date'] == date_str]
41
  active = day_df.groupby('Rep Name').size().reset_index(name='Total Visits')
@@ -90,8 +89,8 @@ def show_map(date_str, rep):
90
 
91
  fig.update_layout(mapbox_style="open-street-map", title=f"πŸ“ {rep}'s Route on {date_str}")
92
 
93
- table = subset[[
94
- 'Visit Order', 'Dealership Name', 'Time', 'Time Diff (min)',
95
  'Type of call', 'Sales or service'
96
  ]].rename(columns={
97
  'Dealership Name': '🧭 Dealer',
@@ -113,13 +112,11 @@ def show_map(date_str, rep):
113
  table = pd.concat([table, summary_row], ignore_index=True)
114
  return table, fig
115
 
116
- # ------------------ Login + Protected UI ------------------
117
  with gr.Blocks() as app:
118
- state = gr.State(False)
119
-
120
  with gr.Row():
121
- with gr.Column(scale=1):
122
- login_title = gr.Markdown("## πŸ” Login Required")
123
  email = gr.Textbox(label="Email")
124
  password = gr.Textbox(label="Password", type="password")
125
  login_btn = gr.Button("Login")
@@ -146,12 +143,12 @@ with gr.Blocks() as app:
146
  date_picker.change(fn=get_reps, inputs=date_picker, outputs=rep_picker)
147
  btn.click(fn=show_map, inputs=[date_picker, rep_picker], outputs=[table, map_plot])
148
 
149
- def check_login(u, p):
150
- if VALID_USERS.get(u) == p:
151
  return gr.update(visible=False), gr.update(visible=True), ""
152
  else:
153
- return gr.update(), gr.update(), "❌ Incorrect email or password."
154
 
155
- login_btn.click(fn=check_login, inputs=[email, password], outputs=[login_title, main_ui, login_msg])
156
 
157
  app.launch()
 
 
1
  import pandas as pd
2
  import gspread
3
+ import gradio as gr
4
  import plotly.express as px
5
+ from oauth2client.service_account import ServiceAccountCredentials
6
 
7
+ # ------------------ AUTH ------------------
8
  VALID_USERS = {
9
  "[email protected]": "Pass.123",
10
  "[email protected]": "Pass.123",
11
  "[email protected]": "Pass.123"
12
  }
13
 
14
+ # ------------------ GOOGLE SHEET SETUP ------------------
15
  scope = ["https://spreadsheets.google.com/feeds", "https://www.googleapis.com/auth/drive"]
16
  creds = ServiceAccountCredentials.from_json_keyfile_name("tough-star.json", scope)
17
  client = gspread.authorize(creds)
 
20
  data = sheet.get_all_records()
21
  df = pd.DataFrame(data)
22
 
23
+ # ------------------ DATA CLEANING ------------------
24
  df['Timestamp'] = pd.to_datetime(df['Timestamp'], dayfirst=True, errors='coerce')
25
  df['Date'] = df['Timestamp'].dt.date.astype(str)
26
  df['Time'] = df['Timestamp'].dt.time
 
27
  location_split = df['Location'].str.split(',', expand=True)
28
  df['Latitude'] = pd.to_numeric(location_split[0], errors='coerce')
29
  df['Longitude'] = pd.to_numeric(location_split[1], errors='coerce')
 
32
  df = df.sort_values(by=['Rep Name', 'Timestamp'])
33
  df['Time Diff (min)'] = df.groupby(['Rep Name', 'Date'])['Timestamp'].diff().dt.total_seconds().div(60).fillna(0)
34
  df['Visit Order'] = df.groupby(['Rep Name', 'Date']).cumcount() + 1
 
35
  ALL_REPS = sorted(df['Rep Name'].dropna().unique())
36
 
37
+ # ------------------ DASHBOARD FUNCTIONS ------------------
38
  def generate_summary(date_str):
39
  day_df = df[df['Date'] == date_str]
40
  active = day_df.groupby('Rep Name').size().reset_index(name='Total Visits')
 
89
 
90
  fig.update_layout(mapbox_style="open-street-map", title=f"πŸ“ {rep}'s Route on {date_str}")
91
 
92
+ table = subset[[
93
+ 'Visit Order', 'Dealership Name', 'Time', 'Time Diff (min)',
94
  'Type of call', 'Sales or service'
95
  ]].rename(columns={
96
  'Dealership Name': '🧭 Dealer',
 
112
  table = pd.concat([table, summary_row], ignore_index=True)
113
  return table, fig
114
 
115
+ # ------------------ GRADIO APP ------------------
116
  with gr.Blocks() as app:
 
 
117
  with gr.Row():
118
+ with gr.Column(visible=True) as login_ui:
119
+ gr.Markdown("## πŸ” Login Required")
120
  email = gr.Textbox(label="Email")
121
  password = gr.Textbox(label="Password", type="password")
122
  login_btn = gr.Button("Login")
 
143
  date_picker.change(fn=get_reps, inputs=date_picker, outputs=rep_picker)
144
  btn.click(fn=show_map, inputs=[date_picker, rep_picker], outputs=[table, map_plot])
145
 
146
+ def do_login(user, pw):
147
+ if VALID_USERS.get(user) == pw:
148
  return gr.update(visible=False), gr.update(visible=True), ""
149
  else:
150
+ return gr.update(visible=True), gr.update(visible=False), "❌ Invalid email or password."
151
 
152
+ login_btn.click(fn=do_login, inputs=[email, password], outputs=[login_ui, main_ui, login_msg])
153
 
154
  app.launch()