IAMTFRMZA commited on
Commit
4e6e288
Β·
verified Β·
1 Parent(s): fd030cb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +160 -86
app.py CHANGED
@@ -1,95 +1,169 @@
1
- import gradio as gr
2
  import pandas as pd
3
  import gspread
 
4
  from oauth2client.service_account import ServiceAccountCredentials
5
  from datetime import datetime
6
 
7
- # -- Login credentials --
8
- USER_CREDENTIALS = {"[email protected]": "Pass.123"}
9
-
10
- # -- Load Google Sheets data --
11
- def get_sheet_data():
12
- scope = ["https://spreadsheets.google.com/feeds", "https://www.googleapis.com/auth/drive"]
13
- creds = ServiceAccountCredentials.from_json_keyfile_name("credentials.json", scope)
14
- client = gspread.authorize(creds)
15
-
16
- # βœ… Fixed sheet name here:
17
- sheet = client.open_by_title("userAccess").worksheet("Field Sales")
18
- data = pd.DataFrame(sheet.get_all_records())
19
- return data
20
-
21
- # -- Generate report based on selected period --
22
- def generate_report(data, period="Daily"):
23
- try:
24
- if "Date" not in data.columns:
25
- return "❌ Column 'Date' not found in the sheet."
26
-
27
- data["Date"] = pd.to_datetime(data["Date"], errors='coerce')
28
- data = data.dropna(subset=["Date"])
29
- now = pd.Timestamp.today()
30
-
31
- if period == "Weekly":
32
- data = data[data["Date"] >= now - pd.Timedelta(days=7)]
33
- elif period == "Monthly":
34
- data = data[data["Date"].dt.month == now.month]
35
- elif period == "Yearly":
36
- data = data[data["Date"].dt.year == now.year]
37
-
38
- total_visits = len(data)
39
- current = len(data[data["Current/Prospect Custor"] == "Current"])
40
- new = len(data[data["Current/Prospect Custor"] == "Prospect"])
41
- second_hand = len(data[data["Customer Type"].str.contains("Second", na=False)])
42
- telesales = len(data[data["Source"] == "TeleSales"])
43
- oem_visits = len(data[data["Source"] == "OEM Visit"])
44
- orders = len(data[data["Order Received"] == "Yes"])
45
- order_value = data["Order Value"].sum() if "Order Value" in data.columns else 0
46
-
47
- return (
48
- f"### {period} Report\n"
49
- f"- **Total Visits:** {total_visits}\n"
50
- f"- **Current Dealerships:** {current}\n"
51
- f"- **New Dealerships:** {new}\n"
52
- f"- **% Current:** {current / total_visits * 100:.1f}% | **% New:** {new / total_visits * 100:.1f}%\n"
53
- f"- **Second-hand Dealerships:** {second_hand}\n"
54
- f"- **TeleSales Calls:** {telesales}\n"
55
- f"- **OEM Visits:** {oem_visits}\n"
56
- f"- **Orders Received:** {orders}\n"
57
- f"- **Total Order Value:** ${order_value:,.2f}"
58
- )
59
- except Exception as e:
60
- return f"❌ Error during report generation: {str(e)}"
61
-
62
- # -- Login function --
63
- def login(email, password):
64
- if USER_CREDENTIALS.get(email) == password:
65
- return gr.update(visible=True), gr.update(visible=False), ""
66
- else:
67
- return gr.update(visible=False), gr.update(visible=True), "❌ Invalid email or password"
68
-
69
- # -- Report trigger --
70
- def report(period):
71
- try:
72
- data = get_sheet_data()
73
- if data.empty:
74
- return "⚠️ No data found in the sheet."
75
- return generate_report(data, period)
76
- except Exception as e:
77
- return f"❌ Failed to load sheet: {str(e)}"
78
-
79
- # -- Gradio UI --
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  with gr.Blocks() as app:
81
- with gr.Row(visible=True) as login_row:
82
- email = gr.Textbox(label="Email")
83
- password = gr.Textbox(label="Password", type="password")
84
- login_btn = gr.Button("Login")
85
- login_error = gr.Textbox(label="", visible=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
- with gr.Row(visible=False) as dashboard:
88
- period_dropdown = gr.Dropdown(["Daily", "Weekly", "Monthly", "Yearly"], value="Weekly", label="Select Report Period")
89
- report_btn = gr.Button("Generate Report")
90
- report_output = gr.Markdown()
 
91
 
92
- login_btn.click(fn=login, inputs=[email, password], outputs=[dashboard, login_error, login_error])
93
- report_btn.click(fn=report, inputs=[period_dropdown], outputs=report_output)
94
 
95
- app.launch()
 
 
1
  import pandas as pd
2
  import gspread
3
+ import gradio as gr
4
  from oauth2client.service_account import ServiceAccountCredentials
5
  from datetime import datetime
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("credentials.json", scope)
17
+ client = gspread.authorize(creds)
18
+ sheet_file = client.open("userAccess")
19
+
20
+ # ------------------ HELPERS ------------------
21
+ def load_tab(sheet_name):
22
+ return pd.DataFrame(sheet_file.worksheet(sheet_name).get_all_records())
23
+
24
+ # ------------------ FIELD SALES ------------------
25
+ def load_field_sales():
26
+ df = load_tab("Field Sales")
27
+ df['Date'] = pd.to_datetime(df.get("Date", datetime.today()), errors='coerce')
28
+ df = df.dropna(subset=["Date"])
29
+ df['DateStr'] = df['Date'].dt.date.astype(str)
30
+ df['Order Value'] = pd.to_numeric(df.get("Order Value", 0), errors='coerce').fillna(0)
31
+ return df
32
+
33
+ def generate_summary(date_str):
34
+ df = load_field_sales()
35
+ all_reps = sorted(df['Rep'].dropna().unique())
36
+ day_df = df[df['DateStr'] == date_str]
37
+
38
+ total_visits = day_df.groupby("Rep").size().reset_index(name="Total Visits")
39
+ current = day_df[day_df["Current/Prospect Custor"] == "Current"]
40
+ prospect = day_df[day_df["Current/Prospect Custor"] == "Prospect"]
41
+ breakdown = pd.DataFrame({
42
+ "Rep": all_reps,
43
+ "Current": [len(current[current["Rep"] == rep]) for rep in all_reps],
44
+ "Prospect": [len(prospect[prospect["Rep"] == rep]) for rep in all_reps]
45
+ })
46
+ active_list = total_visits['Rep'].tolist()
47
+ inactive_list = [rep for rep in all_reps if rep not in active_list]
48
+ inactive_df = pd.DataFrame({'Inactive Reps': inactive_list})
49
+ return total_visits, breakdown, inactive_df
50
+
51
+ def get_order_summary(date_str):
52
+ df = load_field_sales()
53
+ day_df = df[df['DateStr'] == date_str]
54
+ rep_group = day_df.groupby("Rep").agg({
55
+ "Order Received": lambda x: (x == "Yes").sum(),
56
+ "Order Value": "sum"
57
+ }).reset_index().rename(columns={
58
+ "Order Received": "Orders Received",
59
+ "Order Value": "Total Order Value"
60
+ })
61
+ return rep_group.sort_values(by="Total Order Value", ascending=False)
62
+
63
+ def get_escalations():
64
+ df = load_field_sales()
65
+ flagged = df[df["Customer Type"].str.contains("Second", na=False)]
66
+ return flagged if not flagged.empty else pd.DataFrame([["No second-hand dealerships flagged."]], columns=["Status"])
67
+
68
+ # ------------------ TELESALeS ------------------
69
+ def get_telesales_summary():
70
+ df = load_tab("TeleSales")
71
+ df["Date"] = pd.to_datetime(df.get("Date", datetime.today()), errors='coerce')
72
+ df["DateStr"] = df["Date"].dt.date.astype(str)
73
+ return df.groupby(["Rep Email", "DateStr"]).size().reset_index(name="Calls Made")
74
+
75
+ # ------------------ OEM VISITS ------------------
76
+ def get_oem_summary():
77
+ df = load_tab("OEM Visit")
78
+ df["Date"] = pd.to_datetime(df.get("Date", datetime.today()), errors='coerce')
79
+ df["DateStr"] = df["Date"].dt.date.astype(str)
80
+ return df.groupby(["Rep", "DateStr"]).size().reset_index(name="OEM Visits")
81
+
82
+ # ------------------ CUSTOMER REQUESTS ------------------
83
+ def get_requests():
84
+ return load_tab("Customer Requests")
85
+
86
+ # ------------------ CUSTOMER LISTINGS ------------------
87
+ def get_listings():
88
+ return load_tab("CustomerListings")
89
+
90
+ # ------------------ USERS ------------------
91
+ def get_users():
92
+ return load_tab("Users")
93
+
94
+ # ------------------ GRADIO APP ------------------
95
  with gr.Blocks() as app:
96
+ with gr.Row():
97
+ with gr.Column(visible=True) as login_ui:
98
+ gr.Markdown("## πŸ” Login Required")
99
+ email = gr.Textbox(label="Email")
100
+ password = gr.Textbox(label="Password", type="password")
101
+ login_btn = gr.Button("Login")
102
+ login_msg = gr.Markdown("")
103
+
104
+ with gr.Column(visible=False) as main_ui:
105
+ gr.Markdown("## πŸ—‚οΈ CarMat Dashboard")
106
+
107
+ # preload dates for field sales
108
+ df_initial = load_field_sales()
109
+ unique_dates = sorted(df_initial["DateStr"].unique(), reverse=True)
110
+
111
+ # --- Summary Tab ---
112
+ with gr.Tab("πŸ“Š Summary"):
113
+ date_summary = gr.Dropdown(label="Select Date", choices=unique_dates)
114
+ visits = gr.Dataframe(label="βœ… Total Visits")
115
+ breakdown = gr.Dataframe(label="🏷️ Current vs. Prospect")
116
+ inactive = gr.Dataframe(label="⚠️ Inactive Reps")
117
+ date_summary.change(fn=generate_summary, inputs=date_summary, outputs=[visits, breakdown, inactive])
118
+
119
+ # --- Orders Tab ---
120
+ with gr.Tab("πŸ“¦ Orders"):
121
+ order_date = gr.Dropdown(label="Select Date", choices=unique_dates)
122
+ order_table = gr.Dataframe(label="πŸ’° Orders Summary")
123
+ order_date.change(fn=get_order_summary, inputs=order_date, outputs=order_table)
124
+
125
+ # --- Escalations ---
126
+ with gr.Tab("🚨 Escalations"):
127
+ esc_table = gr.Dataframe(value=get_escalations, label="Second-hand Dealerships")
128
+ esc_btn = gr.Button("πŸ”„ Refresh")
129
+ esc_btn.click(fn=get_escalations, outputs=esc_table)
130
+
131
+ # --- TeleSales ---
132
+ with gr.Tab("πŸ“ž TeleSales"):
133
+ ts_table = gr.Dataframe(value=get_telesales_summary, label="TeleSales Summary")
134
+ ts_refresh = gr.Button("πŸ”„ Refresh TeleSales")
135
+ ts_refresh.click(fn=get_telesales_summary, outputs=ts_table)
136
+
137
+ # --- OEM Visits ---
138
+ with gr.Tab("🏭 OEM Visits"):
139
+ oem_table = gr.Dataframe(value=get_oem_summary, label="OEM Visit Summary")
140
+ oem_refresh = gr.Button("πŸ”„ Refresh OEM")
141
+ oem_refresh.click(fn=get_oem_summary, outputs=oem_table)
142
+
143
+ # --- Requests ---
144
+ with gr.Tab("πŸ“¬ Customer Requests"):
145
+ req_table = gr.Dataframe(value=get_requests, label="Customer Requests", interactive=False)
146
+ req_refresh = gr.Button("πŸ”„ Refresh Requests")
147
+ req_refresh.click(fn=get_requests, outputs=req_table)
148
+
149
+ # --- Dealerships ---
150
+ with gr.Tab("πŸ“‹ Dealership Directory"):
151
+ listings_table = gr.Dataframe(value=get_listings, label="Customer Listings")
152
+ listings_refresh = gr.Button("πŸ”„ Refresh Listings")
153
+ listings_refresh.click(fn=get_listings, outputs=listings_table)
154
+
155
+ # --- Users ---
156
+ with gr.Tab("πŸ‘€ Users"):
157
+ users_table = gr.Dataframe(value=get_users, label="Users")
158
+ users_refresh = gr.Button("πŸ”„ Refresh Users")
159
+ users_refresh.click(fn=get_users, outputs=users_table)
160
 
161
+ def do_login(user, pw):
162
+ if VALID_USERS.get(user) == pw:
163
+ return gr.update(visible=False), gr.update(visible=True), ""
164
+ else:
165
+ return gr.update(visible=True), gr.update(visible=False), "❌ Invalid login."
166
 
167
+ login_btn.click(fn=do_login, inputs=[email, password], outputs=[login_ui, main_ui, login_msg])
 
168
 
169
+ app.launch()