IAMTFRMZA commited on
Commit
70a3386
·
verified ·
1 Parent(s): 268cc18

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +88 -86
app.py CHANGED
@@ -18,116 +18,118 @@ creds = ServiceAccountCredentials.from_json_keyfile_name("deep-mile-461309-t8-0e
18
  client = gspread.authorize(creds)
19
  sheet_url = "https://docs.google.com/spreadsheets/d/1if4KoVQvw5ZbhknfdZbzMkcTiPfsD6bz9V3a1th-bwQ"
20
 
21
- # ------------------ SHEET REFRESH ------------------
22
  def load_sheet(sheet_name):
23
  sheet = client.open_by_url(sheet_url).worksheet(sheet_name)
24
- df = pd.DataFrame(sheet.get_all_records())
25
- return df
26
-
27
- # ------------------ REPORT HELPERS ------------------
28
- def week_range(date):
29
- start = date - timedelta(days=date.weekday())
 
 
 
 
 
 
30
  end = start + timedelta(days=6)
31
  return start, end
32
 
33
- def month_range(date):
34
- start = date.replace(day=1)
35
- if start.month == 12:
36
- end = start.replace(year=start.year+1, month=1, day=1) - timedelta(days=1)
37
- else:
38
- end = start.replace(month=start.month+1, day=1) - timedelta(days=1)
39
- return start, end
40
 
41
- # ------------------ REPORT FILTERS ------------------
42
- def filter_calls(date, period="Daily"):
43
  df = load_sheet("Calls")
44
- df['Date'] = pd.to_datetime(df['Date'], errors='coerce')
45
- if period == "Weekly":
46
- start, end = week_range(date)
47
- df = df[(df['Date'] >= start) & (df['Date'] <= end)]
48
- elif period == "Monthly":
49
- start, end = month_range(date)
50
- df = df[(df['Date'] >= start) & (df['Date'] <= end)]
51
- else:
52
- df = df[df['Date'] == date]
53
- return df
54
-
55
- def filter_appointments(date, period="Daily"):
56
  df = load_sheet("Appointments")
57
- df['Date'] = pd.to_datetime(df['Date'], errors='coerce')
58
- if period == "Weekly":
59
- start, end = week_range(date)
60
- df = df[(df['Date'] >= start) & (df['Date'] <= end)]
61
- elif period == "Monthly":
62
- start, end = month_range(date)
63
- df = df[(df['Date'] >= start) & (df['Date'] <= end)]
64
- else:
65
- df = df[df['Date'] == date]
66
- return df
67
-
68
- # ------------------ USERS & METRICS ------------------
69
- def get_rep_metrics(date, period="Weekly"):
70
- calls = filter_calls(date, period)
71
- appts = filter_appointments(date, period)
72
- users = load_sheet("Users")
73
-
74
- call_counts = calls['Rep'].value_counts().to_dict()
75
- appt_counts = appts['Rep'].value_counts().to_dict()
76
-
77
- results = []
78
- for _, row in users.iterrows():
79
- rep = row['Rep']
80
- calls_done = call_counts.get(rep, 0)
81
- appts_done = appt_counts.get(rep, 0)
82
- results.append({
83
- "Rep": rep,
84
- "Weekly Target": row.get('Weekly Target', 0),
85
- "Calls Made": calls_done,
86
- "Appointments Booked": appts_done,
87
- "Gap to Target": max(0, row.get('Weekly Target', 0) - calls_done)
88
- })
89
- return pd.DataFrame(results)
90
 
91
  # ------------------ UI ------------------
92
  with gr.Blocks() as app:
93
  with gr.Row():
94
  with gr.Column(visible=True) as login_ui:
95
- gr.Markdown("## 🔐 Login Required")
96
  email = gr.Textbox(label="Email")
97
  password = gr.Textbox(label="Password", type="password")
98
  login_btn = gr.Button("Login")
99
  login_msg = gr.Markdown("")
100
 
101
  with gr.Column(visible=False) as main_ui:
102
- gr.Markdown("## 📊 Graffiti Admin Dashboard")
103
-
104
- with gr.Tab("📞 Calls Report"):
105
- calls_period = gr.Radio(choices=["Daily", "Weekly", "Monthly"], value="Daily", label="Report Period")
106
- calls_date = gr.Date(label="Select Date")
107
- calls_output = gr.Dataframe()
108
- calls_date.change(fn=filter_calls, inputs=[calls_date, calls_period], outputs=calls_output)
109
- calls_period.change(fn=filter_calls, inputs=[calls_date, calls_period], outputs=calls_output)
110
-
111
- with gr.Tab("📅 Appointments Report"):
112
- appt_period = gr.Radio(choices=["Daily", "Weekly", "Monthly"], value="Daily", label="Report Period")
113
- appt_date = gr.Date(label="Select Date")
114
- appt_output = gr.Dataframe()
115
- appt_date.change(fn=filter_appointments, inputs=[appt_date, appt_period], outputs=appt_output)
116
- appt_period.change(fn=filter_appointments, inputs=[appt_date, appt_period], outputs=appt_output)
117
-
118
- with gr.Tab("🎯 Rep Metrics vs Targets"):
119
- metric_date = gr.Date(label="Select Any Date in the Week/Month")
120
- metric_period = gr.Radio(choices=["Weekly", "Monthly"], value="Weekly", label="Metric Period")
121
- metric_table = gr.Dataframe()
122
- metric_date.change(fn=get_rep_metrics, inputs=[metric_date, metric_period], outputs=metric_table)
123
- metric_period.change(fn=get_rep_metrics, inputs=[metric_date, metric_period], outputs=metric_table)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
 
125
  def do_login(user, pw):
126
  if VALID_USERS.get(user) == pw:
127
  return gr.update(visible=False), gr.update(visible=True), ""
128
  else:
129
- return gr.update(visible=True), gr.update(visible=False), " Invalid email or password."
130
 
131
  login_btn.click(fn=do_login, inputs=[email, password], outputs=[login_ui, main_ui, login_msg])
132
 
133
- app.launch()
 
18
  client = gspread.authorize(creds)
19
  sheet_url = "https://docs.google.com/spreadsheets/d/1if4KoVQvw5ZbhknfdZbzMkcTiPfsD6bz9V3a1th-bwQ"
20
 
21
+ # ------------------ SHEET ACCESS UTILS ------------------
22
  def load_sheet(sheet_name):
23
  sheet = client.open_by_url(sheet_url).worksheet(sheet_name)
24
+ data = sheet.get_all_records()
25
+ return pd.DataFrame(data)
26
+
27
+ # ------------------ REPORT UTILS ------------------
28
+ def parse_date(date_str):
29
+ try:
30
+ return pd.to_datetime(date_str, errors='coerce').date()
31
+ except:
32
+ return None
33
+
34
+ def get_week_range(start_date):
35
+ start = start_date - timedelta(days=start_date.weekday())
36
  end = start + timedelta(days=6)
37
  return start, end
38
 
39
+ def get_month_range(date_obj):
40
+ start = date_obj.replace(day=1)
41
+ next_month = start + pd.DateOffset(months=1)
42
+ end = (next_month - timedelta(days=1)).date()
43
+ return start.date(), end
 
 
44
 
45
+ # ------------------ CALLS ------------------
46
+ def filter_calls_by_date_range(start, end):
47
  df = load_sheet("Calls")
48
+ df['Date'] = pd.to_datetime(df['Date'], errors='coerce').dt.date
49
+ return df[(df['Date'] >= start) & (df['Date'] <= end)]
50
+
51
+ # ------------------ APPOINTMENTS ------------------
52
+ def filter_appointments_by_date_range(start, end):
 
 
 
 
 
 
 
53
  df = load_sheet("Appointments")
54
+ df['Date'] = pd.to_datetime(df['Date'], errors='coerce').dt.date
55
+ return df[(df['Date'] >= start) & (df['Date'] <= end)]
56
+
57
+ # ------------------ APPOINTED LEADS ------------------
58
+ def appointed_leads_table():
59
+ df = load_sheet("Appointed Leads")
60
+ return df.groupby('Rep')['Customer Name'].apply(list).reset_index()
61
+
62
+ # ------------------ INTERACTIVE QUERY ------------------
63
+ def search_table(sheet_name, field, keyword):
64
+ df = load_sheet(sheet_name)
65
+ if field not in df.columns:
66
+ return pd.DataFrame(), "Field not found."
67
+ results = df[df[field].astype(str).str.contains(keyword, case=False, na=False)]
68
+ return results, f"Found {len(results)} results."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
  # ------------------ UI ------------------
71
  with gr.Blocks() as app:
72
  with gr.Row():
73
  with gr.Column(visible=True) as login_ui:
74
+ gr.Markdown("## \ud83d\udd10 Login Required")
75
  email = gr.Textbox(label="Email")
76
  password = gr.Textbox(label="Password", type="password")
77
  login_btn = gr.Button("Login")
78
  login_msg = gr.Markdown("")
79
 
80
  with gr.Column(visible=False) as main_ui:
81
+ gr.Markdown("## \ud83d\udcc2 Graffiti Admin Dashboard")
82
+
83
+ with gr.Tab("\ud83d\udcc5 Calls Report"):
84
+ report_type_call = gr.Radio(["Weekly", "Monthly"], label="Report Type")
85
+ date_input_call = gr.Textbox(label="Enter Start Date (YYYY-MM-DD)")
86
+ calls_table = gr.Dataframe()
87
+
88
+ def generate_call_report(rt, date_str):
89
+ date = parse_date(date_str)
90
+ if not date:
91
+ return pd.DataFrame()
92
+ start, end = get_week_range(date) if rt == "Weekly" else get_month_range(date)
93
+ return filter_calls_by_date_range(start, end)
94
+
95
+ report_type_call.change(generate_call_report, inputs=[report_type_call, date_input_call], outputs=calls_table)
96
+ date_input_call.change(generate_call_report, inputs=[report_type_call, date_input_call], outputs=calls_table)
97
+
98
+ with gr.Tab("\ud83d\udcc5 Appointments Report"):
99
+ report_type_appt = gr.Radio(["Weekly", "Monthly"], label="Report Type")
100
+ date_input_appt = gr.Textbox(label="Enter Start Date (YYYY-MM-DD)")
101
+ appt_table = gr.Dataframe()
102
+
103
+ def generate_appt_report(rt, date_str):
104
+ date = parse_date(date_str)
105
+ if not date:
106
+ return pd.DataFrame()
107
+ start, end = get_week_range(date) if rt == "Weekly" else get_month_range(date)
108
+ return filter_appointments_by_date_range(start, end)
109
+
110
+ report_type_appt.change(generate_appt_report, inputs=[report_type_appt, date_input_appt], outputs=appt_table)
111
+ date_input_appt.change(generate_appt_report, inputs=[report_type_appt, date_input_appt], outputs=appt_table)
112
+
113
+ with gr.Tab("\ud83e\uddcd Appointed Leads"):
114
+ leads_btn = gr.Button("View Appointed Leads")
115
+ leads_output = gr.Dataframe()
116
+ leads_btn.click(fn=appointed_leads_table, outputs=leads_output)
117
+
118
+ with gr.Tab("\ud83d\udd0d Query Live Sheets"):
119
+ sheet_choice = gr.Dropdown(choices=["LiveQuotes", "LiveCustomer", "LiveJobBags"], label="Select Sheet")
120
+ field_input = gr.Textbox(label="Field (column name)")
121
+ keyword_input = gr.Textbox(label="Keyword to search")
122
+ query_btn = gr.Button("Search")
123
+ query_table = gr.Dataframe()
124
+ query_info = gr.Markdown()
125
+ query_btn.click(fn=search_table, inputs=[sheet_choice, field_input, keyword_input], outputs=[query_table, query_info])
126
 
127
  def do_login(user, pw):
128
  if VALID_USERS.get(user) == pw:
129
  return gr.update(visible=False), gr.update(visible=True), ""
130
  else:
131
+ return gr.update(visible=True), gr.update(visible=False), "\u274c Invalid email or password."
132
 
133
  login_btn.click(fn=do_login, inputs=[email, password], outputs=[login_ui, main_ui, login_msg])
134
 
135
+ app.launch()