Update app.py
Browse files
app.py
CHANGED
|
@@ -201,18 +201,13 @@ class B2BCustomerAnalytics:
|
|
| 201 |
|
| 202 |
# Create modern horizontal dashboard
|
| 203 |
summary_html = f"""
|
| 204 |
-
|
| 205 |
-
<div style="display: flex; flex-wrap: wrap; gap: 0.75rem; margin-bottom: 3rem;">
|
| 206 |
|
| 207 |
<!-- Card 1: Total Customers -->
|
| 208 |
-
<div style="flex:
|
| 209 |
-
<!-- Left Icon -->
|
| 210 |
<div style="flex-shrink: 0; padding: 0.5rem; background: #dbeafe; border-radius: 0.5rem;">
|
| 211 |
-
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="#1d4ed8" style="width:24px; height:24px;">
|
| 212 |
-
<path stroke-linecap="round" stroke-linejoin="round" d="M18 18.72a9.094 9.094 0 003.741-.479 3 3 0 00-4.682-2.72m-7.5-2.962a3.75 3.75 0 015.962 0zM16.5 9.75a4.5 4.5 0 11-9 0 4.5 4.5 0 019 0zM18.75 10.5h.008v.008h-.008V10.5zM12 15.75h.008v.008H12v-.008z" />
|
| 213 |
-
</svg>
|
| 214 |
</div>
|
| 215 |
-
<!-- Right Text Content -->
|
| 216 |
<div>
|
| 217 |
<span style="font-size: 1.5rem; font-weight: 700; color: #1f2937; display: block; line-height: 1.2;">{total_customers:,}</span>
|
| 218 |
<h3 style="color: #374151; font-weight: 600; margin: 0; font-size: 0.875rem;">Total Customers</h3>
|
|
@@ -220,14 +215,10 @@ class B2BCustomerAnalytics:
|
|
| 220 |
</div>
|
| 221 |
|
| 222 |
<!-- Card 2: Total Revenue -->
|
| 223 |
-
<div style="flex:
|
| 224 |
-
<!-- Left Icon -->
|
| 225 |
<div style="flex-shrink: 0; padding: 0.5rem; background: #d1fae5; border-radius: 0.5rem;">
|
| 226 |
-
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="#047857" style="width:24px; height:24px;">
|
| 227 |
-
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 18.75a60.07 60.07 0 0115.797 2.101c.727.198 1.453-.342 1.453-1.096V18.75M3.75 4.5v.75A.75.75 0 013 6h-.75m0 0v-.75A.75.75 0 013 4.5h.75m0 0a.75.75 0 01.75.75v.75m0 0h.75a.75.75 0 010 1.5h-.75m0 0a.75.75 0 01-.75.75v.75m0 0h.75a.75.75 0 010 1.5h-.75m0 0a.75.75 0 01-.75.75v.75m0 0h.75a.75.75 0 010 1.5h-.75m0 0a.75.75 0 01-.75.75V18a2.25 2.25 0 012.25-2.25h13.5A2.25 2.25 0 0121 18v.75m-18 0v-.75a2.25 2.25 0 012.25-2.25h13.5A2.25 2.25 0 0121 18v.75" />
|
| 228 |
-
</svg>
|
| 229 |
</div>
|
| 230 |
-
<!-- Right Text Content -->
|
| 231 |
<div>
|
| 232 |
<span style="font-size: 1.5rem; font-weight: 700; color: #1f2937; display: block; line-height: 1.2;">${(total_revenue/1000000):.1f}M</span>
|
| 233 |
<h3 style="color: #374151; font-weight: 600; margin: 0; font-size: 0.875rem;">Total Revenue</h3>
|
|
@@ -235,14 +226,10 @@ class B2BCustomerAnalytics:
|
|
| 235 |
</div>
|
| 236 |
|
| 237 |
<!-- Card 3: Avg Order Value -->
|
| 238 |
-
<div style="flex:
|
| 239 |
-
<!-- Left Icon -->
|
| 240 |
<div style="flex-shrink: 0; padding: 0.5rem; background: #ede9fe; border-radius: 0.5rem;">
|
| 241 |
-
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="#7c3aed" style="width:24px; height:24px;">
|
| 242 |
-
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 18L9 11.25l4.306 4.307a11.95 11.95 0 015.814-5.519l2.74-1.22m0 0l-5.94-2.28m5.94 2.28l-2.28 5.941" />
|
| 243 |
-
</svg>
|
| 244 |
</div>
|
| 245 |
-
<!-- Right Text Content -->
|
| 246 |
<div>
|
| 247 |
<span style="font-size: 1.5rem; font-weight: 700; color: #1f2937; display: block; line-height: 1.2;">${avg_order_value:.0f}</span>
|
| 248 |
<h3 style="color: #374151; font-weight: 600; margin: 0; font-size: 0.875rem;">Avg Order Value</h3>
|
|
@@ -250,14 +237,10 @@ class B2BCustomerAnalytics:
|
|
| 250 |
</div>
|
| 251 |
|
| 252 |
<!-- Card 4: High Risk Clients -->
|
| 253 |
-
<div style="flex:
|
| 254 |
-
<!-- Left Icon -->
|
| 255 |
<div style="flex-shrink: 0; padding: 0.5rem; background: #fee2e2; border-radius: 0.5rem;">
|
| 256 |
-
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="#dc2626" style="width:24px; height:24px;">
|
| 257 |
-
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" />
|
| 258 |
-
</svg>
|
| 259 |
</div>
|
| 260 |
-
<!-- Right Text Content -->
|
| 261 |
<div>
|
| 262 |
<span style="font-size: 1.5rem; font-weight: 700; color: #1f2937; display: block; line-height: 1.2;">{risk_dist.get('High', 0)}</span>
|
| 263 |
<h3 style="color: #374151; font-weight: 600; margin: 0; font-size: 0.875rem;">High Risk Clients</h3>
|
|
@@ -265,14 +248,10 @@ class B2BCustomerAnalytics:
|
|
| 265 |
</div>
|
| 266 |
|
| 267 |
<!-- Card 5: Champion Customers -->
|
| 268 |
-
<div style="flex:
|
| 269 |
-
<!-- Left Icon -->
|
| 270 |
<div style="flex-shrink: 0; padding: 0.5rem; background: #fef3c7; border-radius: 0.5rem;">
|
| 271 |
-
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="#d97706" style="width:24px; height:24px;">
|
| 272 |
-
<path stroke-linecap="round" stroke-linejoin="round" d="M16.5 18.75h-9a9.06 9.06 0 00-4.914.932l-.006.004c-.317.184-.644.362-.978.536a.75.75 0 01-1.114-.658l.012-.023c.125-.23.26-.456.402-.676l.01-.017a9.02 9.02 0 013.91-4.013l.006-.004a9.02 9.02 0 014.013-3.91l.017-.01c.22-.142.446-.277.676-.402l.023-.012a.75.75 0 01.658 1.114c-.174.334-.352.66-.536.978l-.004.006a9.06 9.06 0 00-.932 4.914zM16.5 18.75h-9m9 0a12.015 12.015 0 01-9 0" />
|
| 273 |
-
</svg>
|
| 274 |
</div>
|
| 275 |
-
<!-- Right Text Content -->
|
| 276 |
<div>
|
| 277 |
<span style="font-size: 1.5rem; font-weight: 700; color: #1f2937; display: block; line-height: 1.2;">{segment_dist.get('Champions', 0)}</span>
|
| 278 |
<h3 style="color: #374151; font-weight: 600; margin: 0; font-size: 0.875rem;">Champion Customers</h3>
|
|
@@ -280,14 +259,10 @@ class B2BCustomerAnalytics:
|
|
| 280 |
</div>
|
| 281 |
|
| 282 |
<!-- Card 6: Healthy Customers -->
|
| 283 |
-
<div style="flex:
|
| 284 |
-
<!-- Left Icon -->
|
| 285 |
<div style="flex-shrink: 0; padding: 0.5rem; background: #cffafe; border-radius: 0.5rem;">
|
| 286 |
-
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="#0891b2" style="width:24px; height:24px;">
|
| 287 |
-
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
| 288 |
-
</svg>
|
| 289 |
</div>
|
| 290 |
-
<!-- Right Text Content -->
|
| 291 |
<div>
|
| 292 |
<span style="font-size: 1.5rem; font-weight: 700; color: #1f2937; display: block; line-height: 1.2;">{risk_dist.get('Low', 0)}</span>
|
| 293 |
<h3 style="color: #374151; font-weight: 600; margin: 0; font-size: 0.875rem;">Healthy Customers</h3>
|
|
@@ -950,7 +925,7 @@ def create_gradio_interface():
|
|
| 950 |
|
| 951 |
with gr.Tabs(elem_classes="tab-nav"):
|
| 952 |
|
| 953 |
-
with gr.Tab("
|
| 954 |
with gr.Row():
|
| 955 |
with gr.Column(scale=1):
|
| 956 |
file_input = gr.File(
|
|
@@ -972,7 +947,7 @@ def create_gradio_interface():
|
|
| 972 |
elem_classes="block"
|
| 973 |
)
|
| 974 |
|
| 975 |
-
with gr.Tab("
|
| 976 |
with gr.Row():
|
| 977 |
with gr.Column():
|
| 978 |
segment_chart = gr.Plot(label="Customer Segments Distribution")
|
|
@@ -984,7 +959,7 @@ def create_gradio_interface():
|
|
| 984 |
elem_classes="block"
|
| 985 |
)
|
| 986 |
|
| 987 |
-
with gr.Tab("
|
| 988 |
with gr.Column():
|
| 989 |
train_btn = gr.Button(
|
| 990 |
"Train Churn Prediction Model",
|
|
@@ -1001,13 +976,13 @@ def create_gradio_interface():
|
|
| 1001 |
with gr.Column():
|
| 1002 |
churn_chart = gr.Plot(label="Churn Risk Distribution")
|
| 1003 |
|
| 1004 |
-
with gr.Tab("
|
| 1005 |
revenue_chart = gr.Plot(
|
| 1006 |
label="Monthly Revenue Trends",
|
| 1007 |
elem_classes="block"
|
| 1008 |
)
|
| 1009 |
|
| 1010 |
-
with gr.Tab("
|
| 1011 |
with gr.Row():
|
| 1012 |
with gr.Column(scale=3):
|
| 1013 |
customer_id_input = gr.Textbox(
|
|
@@ -1024,7 +999,7 @@ def create_gradio_interface():
|
|
| 1024 |
|
| 1025 |
customer_insights = gr.HTML()
|
| 1026 |
|
| 1027 |
-
with gr.Tab("
|
| 1028 |
with gr.Column():
|
| 1029 |
gr.HTML("""
|
| 1030 |
<div style="background: linear-gradient(135deg, #f0f9ff, #e0f2fe); padding: 2rem; border-radius: 1rem; margin-bottom: 2rem; border-left: 4px solid #3b82f6;">
|
|
|
|
| 201 |
|
| 202 |
# Create modern horizontal dashboard
|
| 203 |
summary_html = f"""
|
| 204 |
+
<div style="display: flex; flex-wrap: wrap; gap: 0.75rem; margin-bottom: 3rem;">
|
|
|
|
| 205 |
|
| 206 |
<!-- Card 1: Total Customers -->
|
| 207 |
+
<div style="flex-grow: 0; flex-basis: 220px; background: white; padding: 1rem; border-radius: 0.75rem; box-shadow: 0 2px 4px rgba(0,0,0,0.05); border-left: 4px solid #3b82f6; display: flex; align-items: center; gap: 0.75rem;">
|
|
|
|
| 208 |
<div style="flex-shrink: 0; padding: 0.5rem; background: #dbeafe; border-radius: 0.5rem;">
|
| 209 |
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="#1d4ed8" style="width:24px; height:24px;"><path stroke-linecap="round" stroke-linejoin="round" d="M18 18.72a9.094 9.094 0 003.741-.479 3 3 0 00-4.682-2.72m-7.5-2.962a3.75 3.75 0 015.962 0zM16.5 9.75a4.5 4.5 0 11-9 0 4.5 4.5 0 019 0zM18.75 10.5h.008v.008h-.008V10.5zM12 15.75h.008v.008H12v-.008z" /></svg>
|
|
|
|
|
|
|
| 210 |
</div>
|
|
|
|
| 211 |
<div>
|
| 212 |
<span style="font-size: 1.5rem; font-weight: 700; color: #1f2937; display: block; line-height: 1.2;">{total_customers:,}</span>
|
| 213 |
<h3 style="color: #374151; font-weight: 600; margin: 0; font-size: 0.875rem;">Total Customers</h3>
|
|
|
|
| 215 |
</div>
|
| 216 |
|
| 217 |
<!-- Card 2: Total Revenue -->
|
| 218 |
+
<div style="flex-grow: 0; flex-basis: 220px; background: white; padding: 1rem; border-radius: 0.75rem; box-shadow: 0 2px 4px rgba(0,0,0,0.05); border-left: 4px solid #10b981; display: flex; align-items: center; gap: 0.75rem;">
|
|
|
|
| 219 |
<div style="flex-shrink: 0; padding: 0.5rem; background: #d1fae5; border-radius: 0.5rem;">
|
| 220 |
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="#047857" style="width:24px; height:24px;"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 18.75a60.07 60.07 0 0115.797 2.101c.727.198 1.453-.342 1.453-1.096V18.75M3.75 4.5v.75A.75.75 0 013 6h-.75m0 0v-.75A.75.75 0 013 4.5h.75m0 0a.75.75 0 01.75.75v.75m0 0h.75a.75.75 0 010 1.5h-.75m0 0a.75.75 0 01-.75.75v.75m0 0h.75a.75.75 0 010 1.5h-.75m0 0a.75.75 0 01-.75.75v.75m0 0h.75a.75.75 0 010 1.5h-.75m0 0a.75.75 0 01-.75.75V18a2.25 2.25 0 012.25-2.25h13.5A2.25 2.25 0 0121 18v.75m-18 0v-.75a2.25 2.25 0 012.25-2.25h13.5A2.25 2.25 0 0121 18v.75" /></svg>
|
|
|
|
|
|
|
| 221 |
</div>
|
|
|
|
| 222 |
<div>
|
| 223 |
<span style="font-size: 1.5rem; font-weight: 700; color: #1f2937; display: block; line-height: 1.2;">${(total_revenue/1000000):.1f}M</span>
|
| 224 |
<h3 style="color: #374151; font-weight: 600; margin: 0; font-size: 0.875rem;">Total Revenue</h3>
|
|
|
|
| 226 |
</div>
|
| 227 |
|
| 228 |
<!-- Card 3: Avg Order Value -->
|
| 229 |
+
<div style="flex-grow: 0; flex-basis: 220px; background: white; padding: 1rem; border-radius: 0.75rem; box-shadow: 0 2px 4px rgba(0,0,0,0.05); border-left: 4px solid #8b5cf6; display: flex; align-items: center; gap: 0.75rem;">
|
|
|
|
| 230 |
<div style="flex-shrink: 0; padding: 0.5rem; background: #ede9fe; border-radius: 0.5rem;">
|
| 231 |
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="#7c3aed" style="width:24px; height:24px;"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 18L9 11.25l4.306 4.307a11.95 11.95 0 015.814-5.519l2.74-1.22m0 0l-5.94-2.28m5.94 2.28l-2.28 5.941" /></svg>
|
|
|
|
|
|
|
| 232 |
</div>
|
|
|
|
| 233 |
<div>
|
| 234 |
<span style="font-size: 1.5rem; font-weight: 700; color: #1f2937; display: block; line-height: 1.2;">${avg_order_value:.0f}</span>
|
| 235 |
<h3 style="color: #374151; font-weight: 600; margin: 0; font-size: 0.875rem;">Avg Order Value</h3>
|
|
|
|
| 237 |
</div>
|
| 238 |
|
| 239 |
<!-- Card 4: High Risk Clients -->
|
| 240 |
+
<div style="flex-grow: 0; flex-basis: 220px; background: white; padding: 1rem; border-radius: 0.75rem; box-shadow: 0 2px 4px rgba(0,0,0,0.05); border-left: 4px solid #ef4444; display: flex; align-items: center; gap: 0.75rem;">
|
|
|
|
| 241 |
<div style="flex-shrink: 0; padding: 0.5rem; background: #fee2e2; border-radius: 0.5rem;">
|
| 242 |
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="#dc2626" style="width:24px; height:24px;"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" /></svg>
|
|
|
|
|
|
|
| 243 |
</div>
|
|
|
|
| 244 |
<div>
|
| 245 |
<span style="font-size: 1.5rem; font-weight: 700; color: #1f2937; display: block; line-height: 1.2;">{risk_dist.get('High', 0)}</span>
|
| 246 |
<h3 style="color: #374151; font-weight: 600; margin: 0; font-size: 0.875rem;">High Risk Clients</h3>
|
|
|
|
| 248 |
</div>
|
| 249 |
|
| 250 |
<!-- Card 5: Champion Customers -->
|
| 251 |
+
<div style="flex-grow: 0; flex-basis: 220px; background: white; padding: 1rem; border-radius: 0.75rem; box-shadow: 0 2px 4px rgba(0,0,0,0.05); border-left: 4px solid #f59e0b; display: flex; align-items: center; gap: 0.75rem;">
|
|
|
|
| 252 |
<div style="flex-shrink: 0; padding: 0.5rem; background: #fef3c7; border-radius: 0.5rem;">
|
| 253 |
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="#d97706" style="width:24px; height:24px;"><path stroke-linecap="round" stroke-linejoin="round" d="M16.5 18.75h-9a9.06 9.06 0 00-4.914.932l-.006.004c-.317.184-.644.362-.978.536a.75.75 0 01-1.114-.658l.012-.023c.125-.23.26-.456.402-.676l.01-.017a9.02 9.02 0 013.91-4.013l.006-.004a9.02 9.02 0 014.013-3.91l.017-.01c.22-.142.446-.277.676-.402l.023-.012a.75.75 0 01.658 1.114c-.174.334-.352.66-.536.978l-.004.006a9.06 9.06 0 00-.932 4.914zM16.5 18.75h-9m9 0a12.015 12.015 0 01-9 0" /></svg>
|
|
|
|
|
|
|
| 254 |
</div>
|
|
|
|
| 255 |
<div>
|
| 256 |
<span style="font-size: 1.5rem; font-weight: 700; color: #1f2937; display: block; line-height: 1.2;">{segment_dist.get('Champions', 0)}</span>
|
| 257 |
<h3 style="color: #374151; font-weight: 600; margin: 0; font-size: 0.875rem;">Champion Customers</h3>
|
|
|
|
| 259 |
</div>
|
| 260 |
|
| 261 |
<!-- Card 6: Healthy Customers -->
|
| 262 |
+
<div style="flex-grow: 0; flex-basis: 220px; background: white; padding: 1rem; border-radius: 0.75rem; box-shadow: 0 2px 4px rgba(0,0,0,0.05); border-left: 4px solid #06b6d4; display: flex; align-items: center; gap: 0.75rem;">
|
|
|
|
| 263 |
<div style="flex-shrink: 0; padding: 0.5rem; background: #cffafe; border-radius: 0.5rem;">
|
| 264 |
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="#0891b2" style="width:24px; height:24px;"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
|
|
|
|
|
|
|
| 265 |
</div>
|
|
|
|
| 266 |
<div>
|
| 267 |
<span style="font-size: 1.5rem; font-weight: 700; color: #1f2937; display: block; line-height: 1.2;">{risk_dist.get('Low', 0)}</span>
|
| 268 |
<h3 style="color: #374151; font-weight: 600; margin: 0; font-size: 0.875rem;">Healthy Customers</h3>
|
|
|
|
| 925 |
|
| 926 |
with gr.Tabs(elem_classes="tab-nav"):
|
| 927 |
|
| 928 |
+
with gr.Tab("Data Upload & Dashboard", elem_id="data-tab"):
|
| 929 |
with gr.Row():
|
| 930 |
with gr.Column(scale=1):
|
| 931 |
file_input = gr.File(
|
|
|
|
| 947 |
elem_classes="block"
|
| 948 |
)
|
| 949 |
|
| 950 |
+
with gr.Tab("Customer Segmentation Analysis", elem_id="segmentation-tab"):
|
| 951 |
with gr.Row():
|
| 952 |
with gr.Column():
|
| 953 |
segment_chart = gr.Plot(label="Customer Segments Distribution")
|
|
|
|
| 959 |
elem_classes="block"
|
| 960 |
)
|
| 961 |
|
| 962 |
+
with gr.Tab("AI-Powered Churn Prediction", elem_id="churn-tab"):
|
| 963 |
with gr.Column():
|
| 964 |
train_btn = gr.Button(
|
| 965 |
"Train Churn Prediction Model",
|
|
|
|
| 976 |
with gr.Column():
|
| 977 |
churn_chart = gr.Plot(label="Churn Risk Distribution")
|
| 978 |
|
| 979 |
+
with gr.Tab("Revenue Analytics", elem_id="revenue-tab"):
|
| 980 |
revenue_chart = gr.Plot(
|
| 981 |
label="Monthly Revenue Trends",
|
| 982 |
elem_classes="block"
|
| 983 |
)
|
| 984 |
|
| 985 |
+
with gr.Tab("Customer Intelligence", elem_id="insights-tab"):
|
| 986 |
with gr.Row():
|
| 987 |
with gr.Column(scale=3):
|
| 988 |
customer_id_input = gr.Textbox(
|
|
|
|
| 999 |
|
| 1000 |
customer_insights = gr.HTML()
|
| 1001 |
|
| 1002 |
+
with gr.Tab("Executive Reports", elem_id="reports-tab"):
|
| 1003 |
with gr.Column():
|
| 1004 |
gr.HTML("""
|
| 1005 |
<div style="background: linear-gradient(135deg, #f0f9ff, #e0f2fe); padding: 2rem; border-radius: 1rem; margin-bottom: 2rem; border-left: 4px solid #3b82f6;">
|