Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -18,59 +18,58 @@ 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 |
def load_sheet(sheet_name):
|
22 |
sheet = client.open_by_url(sheet_url).worksheet(sheet_name)
|
23 |
-
|
24 |
-
return
|
25 |
|
26 |
-
# ------------------
|
27 |
-
def
|
28 |
-
|
29 |
-
start = today - timedelta(days=today.weekday())
|
30 |
end = start + timedelta(days=6)
|
31 |
-
return start
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
df
|
37 |
-
|
|
|
38 |
|
39 |
-
|
40 |
-
def appointed_leads_table():
|
41 |
df = load_sheet("AllocatedLeads")
|
42 |
-
grouped = df.groupby(
|
43 |
return grouped
|
44 |
|
45 |
-
|
46 |
-
|
47 |
-
df = load_sheet(sheet_name)
|
48 |
if field not in df.columns:
|
49 |
-
return pd.DataFrame(), "Field not found
|
50 |
results = df[df[field].astype(str).str.contains(keyword, case=False, na=False)]
|
51 |
-
return results, f"Found {len(results)}
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
start, end = get_current_week_range()
|
63 |
-
week_calls = calls_df[(calls_df['Date'] >= start) & (calls_df['Date'] <= end)]
|
64 |
-
week_appt = appt_df[(appt_df['Date'] >= start) & (appt_df['Date'] <= end)]
|
65 |
-
|
66 |
-
call_count = week_calls.groupby("Rep Name").size().reset_index(name="Calls This Week")
|
67 |
-
appt_count = week_appt.groupby("Rep Name").size().reset_index(name="Appointments This Week")
|
68 |
-
|
69 |
-
merged = users_df.merge(call_count, how='left', left_on='Name', right_on='Rep Name')
|
70 |
-
merged = merged.merge(appt_count, how='left', left_on='Name', right_on='Rep Name')
|
71 |
-
merged = merged.fillna(0)
|
72 |
-
|
73 |
-
return merged[['Name', 'Weekly Target', 'Calls This Week', 'Appointments This Week']]
|
74 |
|
75 |
# ------------------ GRADIO UI ------------------
|
76 |
with gr.Blocks() as app:
|
@@ -80,47 +79,46 @@ with gr.Blocks() as app:
|
|
80 |
email = gr.Textbox(label="Email")
|
81 |
password = gr.Textbox(label="Password", type="password")
|
82 |
login_btn = gr.Button("Login")
|
83 |
-
login_msg = gr.Markdown()
|
84 |
|
85 |
with gr.Column(visible=False) as main_ui:
|
86 |
gr.Markdown("## Graffiti Admin Dashboard")
|
87 |
|
88 |
with gr.Tab("Calls Report"):
|
89 |
-
|
90 |
calls_table = gr.Dataframe()
|
91 |
-
|
92 |
-
week_btn.click(lambda: filter_by_date_range("Calls", week_start, week_end), outputs=calls_table)
|
93 |
|
94 |
with gr.Tab("Appointments Report"):
|
|
|
95 |
appt_table = gr.Dataframe()
|
96 |
-
appt_btn
|
97 |
-
appt_btn.click(lambda: filter_by_date_range("Appointments", week_start, week_end), outputs=appt_table)
|
98 |
|
99 |
with gr.Tab("Appointed Leads"):
|
100 |
-
leads_output = gr.Dataframe()
|
101 |
leads_btn = gr.Button("View Appointed Leads")
|
102 |
-
|
|
|
103 |
|
104 |
with gr.Tab("Query Live Sheets"):
|
105 |
sheet_choice = gr.Dropdown(choices=["LiveQuotes", "LiveCustomer", "LiveJobBags"], label="Select Sheet")
|
106 |
field_input = gr.Textbox(label="Field (column name)")
|
107 |
keyword_input = gr.Textbox(label="Keyword to search")
|
108 |
query_btn = gr.Button("Search")
|
109 |
-
|
110 |
-
|
111 |
-
query_btn.click(fn=
|
112 |
|
113 |
-
with gr.Tab("Rep
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
|
118 |
def do_login(user, pw):
|
119 |
if VALID_USERS.get(user) == pw:
|
120 |
return gr.update(visible=False), gr.update(visible=True), ""
|
121 |
else:
|
122 |
-
return gr.update(visible=True), gr.update(visible=False), "
|
123 |
|
124 |
login_btn.click(fn=do_login, inputs=[email, password], outputs=[login_ui, main_ui, login_msg])
|
125 |
|
126 |
-
app.launch(
|
|
|
18 |
client = gspread.authorize(creds)
|
19 |
sheet_url = "https://docs.google.com/spreadsheets/d/1if4KoVQvw5ZbhknfdZbzMkcTiPfsD6bz9V3a1th-bwQ"
|
20 |
|
21 |
+
# ------------------ SHEET LOADING ------------------
|
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 FILTERS ------------------
|
28 |
+
def get_week_dates(ref_date):
|
29 |
+
start = ref_date - timedelta(days=ref_date.weekday())
|
|
|
30 |
end = start + timedelta(days=6)
|
31 |
+
return start, end
|
32 |
+
|
33 |
+
def filter_by_date_range(df, date_col, start, end):
|
34 |
+
df[date_col] = pd.to_datetime(df[date_col], errors='coerce')
|
35 |
+
return df[(df[date_col] >= start) & (df[date_col] <= end)]
|
36 |
+
|
37 |
+
# ------------------ REPORT TABS ------------------
|
38 |
+
def calls_week_summary():
|
39 |
+
today = datetime.today()
|
40 |
+
start, end = get_week_dates(today)
|
41 |
+
df = load_sheet("Calls")
|
42 |
+
filtered = filter_by_date_range(df, "Date", start, end)
|
43 |
+
return filtered
|
44 |
|
45 |
+
def appointments_week_summary():
|
46 |
+
today = datetime.today()
|
47 |
+
start, end = get_week_dates(today)
|
48 |
+
df = load_sheet("Appointments")
|
49 |
+
filtered = filter_by_date_range(df, "Date", start, end)
|
50 |
+
return filtered
|
51 |
|
52 |
+
def view_appointed_leads():
|
|
|
53 |
df = load_sheet("AllocatedLeads")
|
54 |
+
grouped = df.groupby("Rep")['Customer Name'].apply(list).reset_index()
|
55 |
return grouped
|
56 |
|
57 |
+
def search_live_sheet(sheet, field, keyword):
|
58 |
+
df = load_sheet(sheet)
|
|
|
59 |
if field not in df.columns:
|
60 |
+
return pd.DataFrame(), "Field not found"
|
61 |
results = df[df[field].astype(str).str.contains(keyword, case=False, na=False)]
|
62 |
+
return results, f"Found {len(results)} result(s)."
|
63 |
+
|
64 |
+
def weekly_target_report():
|
65 |
+
calls = calls_week_summary()
|
66 |
+
users = load_sheet("Users")
|
67 |
+
calls_by_rep = calls.groupby("Rep Name").size().reset_index(name="Calls This Week")
|
68 |
+
merged = users.merge(calls_by_rep, left_on="Name", right_on="Rep Name", how="left")
|
69 |
+
merged["Calls This Week"] = merged["Calls This Week"].fillna(0)
|
70 |
+
merged["Calls This Week"] = merged["Calls This Week"].astype(int)
|
71 |
+
merged["Target Met"] = merged["Calls This Week"] >= merged["Weekly Target"]
|
72 |
+
return merged[["Name", "Weekly Target", "Calls This Week", "Target Met"]]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
|
74 |
# ------------------ GRADIO UI ------------------
|
75 |
with gr.Blocks() as app:
|
|
|
79 |
email = gr.Textbox(label="Email")
|
80 |
password = gr.Textbox(label="Password", type="password")
|
81 |
login_btn = gr.Button("Login")
|
82 |
+
login_msg = gr.Markdown("")
|
83 |
|
84 |
with gr.Column(visible=False) as main_ui:
|
85 |
gr.Markdown("## Graffiti Admin Dashboard")
|
86 |
|
87 |
with gr.Tab("Calls Report"):
|
88 |
+
calls_btn = gr.Button("Load Current Week Calls")
|
89 |
calls_table = gr.Dataframe()
|
90 |
+
calls_btn.click(fn=calls_week_summary, outputs=calls_table)
|
|
|
91 |
|
92 |
with gr.Tab("Appointments Report"):
|
93 |
+
appt_btn = gr.Button("Load Current Week Appointments")
|
94 |
appt_table = gr.Dataframe()
|
95 |
+
appt_btn.click(fn=appointments_week_summary, outputs=appt_table)
|
|
|
96 |
|
97 |
with gr.Tab("Appointed Leads"):
|
|
|
98 |
leads_btn = gr.Button("View Appointed Leads")
|
99 |
+
leads_table = gr.Dataframe()
|
100 |
+
leads_btn.click(fn=view_appointed_leads, outputs=leads_table)
|
101 |
|
102 |
with gr.Tab("Query Live Sheets"):
|
103 |
sheet_choice = gr.Dropdown(choices=["LiveQuotes", "LiveCustomer", "LiveJobBags"], label="Select Sheet")
|
104 |
field_input = gr.Textbox(label="Field (column name)")
|
105 |
keyword_input = gr.Textbox(label="Keyword to search")
|
106 |
query_btn = gr.Button("Search")
|
107 |
+
result_table = gr.Dataframe()
|
108 |
+
result_info = gr.Markdown()
|
109 |
+
query_btn.click(fn=search_live_sheet, inputs=[sheet_choice, field_input, keyword_input], outputs=[result_table, result_info])
|
110 |
|
111 |
+
with gr.Tab("Weekly Rep Performance"):
|
112 |
+
target_btn = gr.Button("Compare Rep Activity vs Target")
|
113 |
+
target_table = gr.Dataframe()
|
114 |
+
target_btn.click(fn=weekly_target_report, outputs=target_table)
|
115 |
|
116 |
def do_login(user, pw):
|
117 |
if VALID_USERS.get(user) == pw:
|
118 |
return gr.update(visible=False), gr.update(visible=True), ""
|
119 |
else:
|
120 |
+
return gr.update(visible=True), gr.update(visible=False), "Invalid login."
|
121 |
|
122 |
login_btn.click(fn=do_login, inputs=[email, password], outputs=[login_ui, main_ui, login_msg])
|
123 |
|
124 |
+
app.launch()
|