IAMTFRMZA commited on
Commit
6903ce6
·
verified ·
1 Parent(s): bc61590

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +75 -20
app.py CHANGED
@@ -11,10 +11,15 @@ client = gspread.authorize(creds)
11
  sheet_url = "https://docs.google.com/spreadsheets/d/1if4KoVQvw5ZbhknfdZbzMkcTiPfsD6bz9V3a1th-bwQ"
12
 
13
  # -------------------- UTILS --------------------
 
 
 
 
14
  def load_sheet(sheet_name):
15
  try:
16
  sheet = client.open_by_url(sheet_url).worksheet(sheet_name)
17
  df = pd.DataFrame(sheet.get_all_records())
 
18
  return df
19
  except Exception as e:
20
  return pd.DataFrame([{"Error": str(e)}])
@@ -29,22 +34,22 @@ def filter_week(df, date_column, rep_column=None, rep=None):
29
  df[date_column] = pd.to_datetime(df[date_column], errors='coerce').dt.date
30
  start, end = get_current_week_range()
31
  filtered = df[(df[date_column] >= start) & (df[date_column] <= end)]
32
- if rep and rep.strip():
33
  filtered = filtered[filtered[rep_column] == rep]
34
  return filtered
35
 
36
  def filter_date(df, date_column, rep_column, y, m, d, rep):
37
  try:
38
- date_str = str(datetime(int(y), int(m), int(d)).date())
39
  except:
40
  return pd.DataFrame([{"Error": "Invalid date input"}])
41
- df[date_column] = pd.to_datetime(df[date_column], errors='coerce').dt.date.astype(str)
42
- filtered = df[df[date_column] == date_str]
43
- if rep and rep.strip():
44
- filtered = filtered[df[rep_column] == rep]
45
  return filtered
46
 
47
- # -------------------- FUNCTIONS --------------------
48
  def get_calls(rep=None):
49
  df = load_sheet("Calls")
50
  if "Call Date" not in df.columns:
@@ -69,11 +74,38 @@ def search_appointments_by_date(y, m, d, rep):
69
  return pd.DataFrame([{"Error": "Missing 'Appointment Date' column"}])
70
  return filter_date(df, "Appointment Date", "Rep", y, m, d, rep)
71
 
72
- def get_leads():
73
  df = load_sheet("AllocatedLeads")
74
- if "Assigned Rep " not in df.columns or "Company Name" not in df.columns:
 
 
75
  return pd.DataFrame([{"Error": "Missing 'Assigned Rep' or 'Company Name' column"}])
76
- return df.groupby("Assigned Rep ")["Company Name"].apply(list).reset_index()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
  # -------------------- DROPDOWN OPTIONS --------------------
79
  def rep_options(sheet_name, rep_col):
@@ -82,7 +114,7 @@ def rep_options(sheet_name, rep_col):
82
  return sorted(df[rep_col].dropna().unique().tolist())
83
  return []
84
 
85
- # -------------------- UI --------------------
86
  with gr.Blocks(title="Graffiti Admin Dashboard") as app:
87
  gr.Markdown("# 📆 Graffiti Admin Dashboard")
88
 
@@ -102,19 +134,42 @@ with gr.Blocks(title="Graffiti Admin Dashboard") as app:
102
  with gr.Tab("Appointments Report"):
103
  rep_appt = gr.Dropdown(label="Optional Rep Filter", choices=rep_options("Appointments", "Rep"), allow_custom_value=True)
104
  appt_btn = gr.Button("Load Current Week Appointments")
105
- appt_table = gr.Dataframe()
106
- appt_btn.click(fn=get_appointments, inputs=rep_appt, outputs=appt_table)
 
 
 
 
 
 
107
 
108
  gr.Markdown("### 🔍 Search Appointments by Specific Date")
109
  y2, m2, d2 = gr.Textbox(label="Year"), gr.Textbox(label="Month"), gr.Textbox(label="Day")
110
  rep2 = gr.Dropdown(label="Optional Rep Filter", choices=rep_options("Appointments", "Rep"), allow_custom_value=True)
111
  appt_date_btn = gr.Button("Search Appointments by Date")
112
- appt_date_table = gr.Dataframe()
113
- appt_date_btn.click(fn=search_appointments_by_date, inputs=[y2, m2, d2, rep2], outputs=appt_date_table)
 
 
 
 
 
 
 
 
114
 
115
  with gr.Tab("Appointed Leads"):
116
- leads_btn = gr.Button("View Appointed Leads")
117
- leads_table = gr.Dataframe()
118
- leads_btn.click(fn=get_leads, outputs=leads_table)
119
-
120
- app.launch()
 
 
 
 
 
 
 
 
 
 
11
  sheet_url = "https://docs.google.com/spreadsheets/d/1if4KoVQvw5ZbhknfdZbzMkcTiPfsD6bz9V3a1th-bwQ"
12
 
13
  # -------------------- UTILS --------------------
14
+ def normalize_columns(df):
15
+ df.columns = df.columns.str.strip().str.title() # e.g. “appointment date ” → “Appointment Date”
16
+ return df
17
+
18
  def load_sheet(sheet_name):
19
  try:
20
  sheet = client.open_by_url(sheet_url).worksheet(sheet_name)
21
  df = pd.DataFrame(sheet.get_all_records())
22
+ df = normalize_columns(df)
23
  return df
24
  except Exception as e:
25
  return pd.DataFrame([{"Error": str(e)}])
 
34
  df[date_column] = pd.to_datetime(df[date_column], errors='coerce').dt.date
35
  start, end = get_current_week_range()
36
  filtered = df[(df[date_column] >= start) & (df[date_column] <= end)]
37
+ if rep:
38
  filtered = filtered[filtered[rep_column] == rep]
39
  return filtered
40
 
41
  def filter_date(df, date_column, rep_column, y, m, d, rep):
42
  try:
43
+ target = datetime(int(y), int(m), int(d)).date()
44
  except:
45
  return pd.DataFrame([{"Error": "Invalid date input"}])
46
+ df[date_column] = pd.to_datetime(df[date_column], errors='coerce').dt.date
47
+ filtered = df[df[date_column] == target]
48
+ if rep:
49
+ filtered = filtered[filtered[rep_column] == rep]
50
  return filtered
51
 
52
+ # -------------------- REPORT FUNCTIONS --------------------
53
  def get_calls(rep=None):
54
  df = load_sheet("Calls")
55
  if "Call Date" not in df.columns:
 
74
  return pd.DataFrame([{"Error": "Missing 'Appointment Date' column"}])
75
  return filter_date(df, "Appointment Date", "Rep", y, m, d, rep)
76
 
77
+ def get_leads_detail():
78
  df = load_sheet("AllocatedLeads")
79
+ # normalize expected names if necessary:
80
+ df = df.rename(columns={"Assigned Rep": "Assigned Rep", "Company Name": "Company Name"})
81
+ if "Assigned Rep" not in df.columns or "Company Name" not in df.columns:
82
  return pd.DataFrame([{"Error": "Missing 'Assigned Rep' or 'Company Name' column"}])
83
+ return df
84
+
85
+ def get_leads_summary():
86
+ df = get_leads_detail()
87
+ if "Error" in df.columns:
88
+ return df
89
+ # count number of leads per rep
90
+ summary = df.groupby("Assigned Rep").size().reset_index(name="Leads Count")
91
+ return summary
92
+
93
+ # -------------------- INSIGHTS (Top Performers) --------------------
94
+ def compute_insights():
95
+ calls = get_calls()
96
+ appts = get_appointments()
97
+ leads = get_leads_detail()
98
+
99
+ top_calls = calls.groupby("Rep").size().idxmax() if not calls.empty else "N/A"
100
+ top_appts = appts.groupby("Rep").size().idxmax() if not appts.empty else "N/A"
101
+ top_leads = leads.groupby("Assigned Rep").size().idxmax() if "Assigned Rep" in leads.columns else "N/A"
102
+
103
+ insights = pd.DataFrame([
104
+ {"Metric": "Most Calls This Week", "Rep": top_calls},
105
+ {"Metric": "Most Appointments This Week", "Rep": top_appts},
106
+ {"Metric": "Most Leads Allocated", "Rep": top_leads},
107
+ ])
108
+ return insights
109
 
110
  # -------------------- DROPDOWN OPTIONS --------------------
111
  def rep_options(sheet_name, rep_col):
 
114
  return sorted(df[rep_col].dropna().unique().tolist())
115
  return []
116
 
117
+ # -------------------- UI LAYOUT --------------------
118
  with gr.Blocks(title="Graffiti Admin Dashboard") as app:
119
  gr.Markdown("# 📆 Graffiti Admin Dashboard")
120
 
 
134
  with gr.Tab("Appointments Report"):
135
  rep_appt = gr.Dropdown(label="Optional Rep Filter", choices=rep_options("Appointments", "Rep"), allow_custom_value=True)
136
  appt_btn = gr.Button("Load Current Week Appointments")
137
+ appt_summary = gr.Dataframe(label="📊 Weekly Appointments Summary by Rep")
138
+ appt_table = gr.Dataframe()
139
+ appt_btn.click(
140
+ fn=lambda rep: (get_appointments(rep).groupby("Rep").size().reset_index(name="Count"),
141
+ get_appointments(rep)),
142
+ inputs=rep_appt,
143
+ outputs=[appt_summary, appt_table]
144
+ )
145
 
146
  gr.Markdown("### 🔍 Search Appointments by Specific Date")
147
  y2, m2, d2 = gr.Textbox(label="Year"), gr.Textbox(label="Month"), gr.Textbox(label="Day")
148
  rep2 = gr.Dropdown(label="Optional Rep Filter", choices=rep_options("Appointments", "Rep"), allow_custom_value=True)
149
  appt_date_btn = gr.Button("Search Appointments by Date")
150
+ appt_date_summary = gr.Dataframe(label="📊 Appointments Summary for Date by Rep")
151
+ appt_date_table = gr.Dataframe()
152
+ appt_date_btn.click(
153
+ fn=lambda y,m,d,rep: (
154
+ search_appointments_by_date(y,m,d,rep).groupby("Rep").size().reset_index(name="Count"),
155
+ search_appointments_by_date(y,m,d,rep)
156
+ ),
157
+ inputs=[y2, m2, d2, rep2],
158
+ outputs=[appt_date_summary, appt_date_table]
159
+ )
160
 
161
  with gr.Tab("Appointed Leads"):
162
+ leads_btn = gr.Button("View Appointed Leads")
163
+ leads_summary= gr.Dataframe(label="📊 Leads Count by Rep")
164
+ leads_detail = gr.Dataframe(label="🔎 Detailed Leads")
165
+ leads_btn.click(
166
+ fn=lambda: (get_leads_summary(), get_leads_detail()),
167
+ outputs=[leads_summary, leads_detail]
168
+ )
169
+
170
+ with gr.Tab("Insights"):
171
+ insights_btn = gr.Button("Generate Insights")
172
+ insights_tbl = gr.Dataframe()
173
+ insights_btn.click(fn=compute_insights, outputs=insights_tbl)
174
+
175
+ app.launch()