dimoZ commited on
Commit
b22e788
·
verified ·
1 Parent(s): 1caec78

Delete main.py

Browse files
Files changed (1) hide show
  1. main.py +0 -661
main.py DELETED
@@ -1,661 +0,0 @@
1
- import streamlit as st
2
- import pandas as pd
3
- import numpy as np
4
- import matplotlib.pyplot as plt
5
- import seaborn as sns
6
- from google import genai
7
- from google.genai import types
8
- import json
9
- import streamlit.components.v1 as components
10
- from datetime import datetime, date
11
- import io
12
- import base64
13
-
14
- # ------------------------------
15
- # Custom JSON Encoder for Timestamps
16
- # ------------------------------
17
- class CustomJSONEncoder(json.JSONEncoder):
18
- def default(self, obj):
19
- if isinstance(obj, (datetime, date, pd.Timestamp)):
20
- return obj.isoformat()
21
- if isinstance(obj, np.integer):
22
- return int(obj)
23
- if isinstance(obj, np.floating):
24
- return float(obj)
25
- if isinstance(obj, np.ndarray):
26
- return obj.tolist()
27
- if pd.isna(obj):
28
- return None
29
- return super().default(obj)
30
-
31
- # ------------------------------
32
- # Page Configuration
33
- # ------------------------------
34
- st.set_page_config(
35
- page_title="AI Excel BI Dashboard",
36
- page_icon="📊",
37
- layout="wide",
38
- initial_sidebar_state="expanded"
39
- )
40
-
41
- # Initialize session state
42
- if 'api_configured' not in st.session_state:
43
- st.session_state['api_configured'] = False
44
- if 'dark_mode' not in st.session_state:
45
- st.session_state['dark_mode'] = True # Default to dark mode
46
-
47
- # ------------------------------
48
- # Sidebar: API Key Setup
49
- # ------------------------------
50
- with st.sidebar:
51
- st.header("⚙️ Configuration")
52
- st.markdown("---")
53
-
54
- api_key = st.text_input(
55
- "🔑 Gemini API Key",
56
- type="password",
57
- help="Enter your Google Gemini API key"
58
- )
59
-
60
- if api_key:
61
- try:
62
- client = genai.Client(api_key=api_key)
63
- st.success("✅ API Key Configured")
64
- st.session_state['api_configured'] = True
65
- except Exception as e:
66
- st.error(f"❌ Invalid API Key: {e}")
67
- client = None
68
- st.session_state['api_configured'] = False
69
- else:
70
- client = None
71
-
72
- st.markdown("---")
73
-
74
- st.subheader("ℹ️ About")
75
- st.info("""
76
- This AI-powered dashboard:
77
- - Analyzes Excel/CSV data
78
- - Generates intelligent visualizations
79
- - Creates interactive HTML dashboards
80
- - Provides business insights
81
- - Detects company/brand data
82
- """)
83
-
84
- st.markdown("---")
85
- st.caption("Powered by Google Gemini AI")
86
-
87
- # Apply dark mode styling (always on by default)
88
- st.markdown("""
89
- <style>
90
- .stApp {
91
- background-color: #0e1117;
92
- color: #fafafa;
93
- }
94
- </style>
95
- """, unsafe_allow_html=True)
96
-
97
- # ------------------------------
98
- # Main Area: Dashboard
99
- # ------------------------------
100
- st.title("📊 AI-Powered Business Intelligence Dashboard")
101
- st.markdown("Upload your data file and let AI create professional insights!")
102
-
103
- # Check if API key is configured
104
- if not api_key or not client:
105
- st.warning("⚠️ Please enter your Gemini API Key in the sidebar to continue.")
106
- st.stop()
107
-
108
- # ------------------------------
109
- # File Upload Section
110
- # ------------------------------
111
- st.markdown("---")
112
- uploaded_file = st.file_uploader(
113
- "📂 Upload Your Data File",
114
- type=["csv", "xlsx"],
115
- help="Supports CSV and Excel files"
116
- )
117
-
118
- if uploaded_file:
119
- try:
120
- # Load dataset
121
- with st.spinner("Loading data..."):
122
- if uploaded_file.name.endswith(".csv"):
123
- df = pd.read_csv(uploaded_file)
124
- else:
125
- df = pd.read_excel(uploaded_file)
126
-
127
- st.success(f"✅ File '{uploaded_file.name}' uploaded successfully!")
128
-
129
- # ------------------------------
130
- # Enhanced Data Overview Section
131
- # ------------------------------
132
- st.markdown("---")
133
- st.subheader("📋 Comprehensive Data Overview")
134
-
135
- # Basic Metrics
136
- col1, col2, col3, col4, col5 = st.columns(5)
137
- with col1:
138
- st.metric("Total Rows", f"{df.shape[0]:,}")
139
- with col2:
140
- st.metric("Total Columns", df.shape[1])
141
- with col3:
142
- st.metric("Numeric Columns", len(df.select_dtypes(include=['number']).columns))
143
- with col4:
144
- st.metric("Categorical Columns", len(df.select_dtypes(include=['object']).columns))
145
- with col5:
146
- missing_pct = (df.isnull().sum().sum() / (df.shape[0] * df.shape[1]) * 100)
147
- st.metric("Missing Data", f"{missing_pct:.1f}%")
148
-
149
- # Detailed Data Analysis
150
- with st.expander("🔍 View Detailed Data Analysis", expanded=True):
151
- tab1, tab2, tab3 = st.tabs(["📊 Data Preview", "📈 Statistics", "⚠️ Data Quality"])
152
-
153
- with tab1:
154
- st.dataframe(df.head(15), use_container_width=True)
155
-
156
- with tab2:
157
- # Statistical Summary
158
- st.markdown("**Statistical Summary**")
159
- numeric_cols = df.select_dtypes(include=['number']).columns
160
- if len(numeric_cols) > 0:
161
- stats_df = df[numeric_cols].describe()
162
- st.dataframe(stats_df, use_container_width=True)
163
- else:
164
- st.info("No numeric columns found for statistical analysis")
165
-
166
- # Categorical Summary
167
- cat_cols = df.select_dtypes(include=['object']).columns
168
- if len(cat_cols) > 0:
169
- st.markdown("**Categorical Summary**")
170
- cat_summary = pd.DataFrame({
171
- 'Column': cat_cols,
172
- 'Unique Values': [df[col].nunique() for col in cat_cols],
173
- 'Most Frequent': [df[col].mode()[0] if len(df[col].mode()) > 0 else 'N/A' for col in cat_cols],
174
- 'Frequency': [df[col].value_counts().iloc[0] if len(df[col]) > 0 else 0 for col in cat_cols]
175
- })
176
- st.dataframe(cat_summary, use_container_width=True)
177
-
178
- with tab3:
179
- # Data Quality Metrics
180
- quality_data = []
181
- for col in df.columns:
182
- missing = df[col].isnull().sum()
183
- missing_pct = (missing / len(df)) * 100
184
-
185
- # Check for blank spaces in string columns
186
- blank_spaces = 0
187
- if df[col].dtype == 'object':
188
- blank_spaces = df[col].astype(str).str.strip().eq('').sum()
189
-
190
- # Standard deviation for numeric columns
191
- std_dev = df[col].std() if df[col].dtype in ['int64', 'float64'] else None
192
-
193
- quality_data.append({
194
- 'Column': col,
195
- 'Data Type': str(df[col].dtype),
196
- 'Missing Values': missing,
197
- 'Missing %': f"{missing_pct:.2f}%",
198
- 'Blank Spaces': blank_spaces,
199
- 'Std Deviation': f"{std_dev:.2f}" if std_dev is not None else 'N/A',
200
- 'Unique Values': df[col].nunique()
201
- })
202
-
203
- quality_df = pd.DataFrame(quality_data)
204
- st.dataframe(quality_df, use_container_width=True)
205
-
206
- # Highlight issues
207
- total_missing = df.isnull().sum().sum()
208
- if total_missing > 0:
209
- st.warning(f"⚠️ Found {total_missing:,} missing values across the dataset")
210
- else:
211
- st.success("✅ No missing values detected")
212
-
213
- # ------------------------------
214
- # AI Analysis Section
215
- # ------------------------------
216
- st.markdown("---")
217
- st.subheader("🤖 AI-Generated Dashboard")
218
-
219
- col_btn1, col_btn2 = st.columns(2)
220
-
221
- with col_btn1:
222
- generate_charts = st.button("📈 Generate Charts & Insights", type="primary", use_container_width=True)
223
-
224
- with col_btn2:
225
- generate_interactive = st.button("🎨 Generate Interactive HTML Dashboard", type="secondary", use_container_width=True)
226
-
227
- # Add Presentation Maker Button
228
- st.markdown("")
229
- generate_presentation = st.button("🎤 Generate AI Presentation (PPT)", use_container_width=True)
230
-
231
- # ------------------------------
232
- # Generate Charts and Insights (Collage View)
233
- # ------------------------------
234
- if generate_charts:
235
- with st.spinner("AI is analyzing your data..."):
236
- try:
237
- # Prepare schema with proper serialization
238
- sample_data = df.head(3).copy()
239
- for col in sample_data.columns:
240
- if sample_data[col].dtype == 'datetime64[ns]' or isinstance(sample_data[col].iloc[0], pd.Timestamp):
241
- sample_data[col] = sample_data[col].astype(str)
242
-
243
- schema = {
244
- "columns": {col: str(df[col].dtype) for col in df.columns},
245
- "sample": sample_data.to_dict(),
246
- "shape": {"rows": int(df.shape[0]), "columns": int(df.shape[1])},
247
- "numeric_columns": [col for col in df.select_dtypes(include=['number']).columns.tolist()],
248
- "categorical_columns": [col for col in df.select_dtypes(include=['object']).columns.tolist()]
249
- }
250
-
251
- prompt = f"""
252
- You are a business intelligence and data visualization expert.
253
-
254
- Dataset Information:
255
- {json.dumps(schema, indent=2, cls=CustomJSONEncoder)}
256
-
257
- Analyze this dataset and determine:
258
- 1. Is this company/business data? (sales, revenue, employees, products, etc.)
259
- 2. What industry or domain does it belong to? (retail, finance, healthcare, entertainment, etc.)
260
- 3. What are the key metrics and KPIs?
261
-
262
- Then respond with ONLY a valid JSON object (no markdown, no explanations) with this exact structure:
263
- {{
264
- "domain": "industry name (e.g., retail, finance, entertainment, generic)",
265
- "is_company_data": true/false,
266
- "charts": [
267
- {{"type": "bar", "x": "column_name", "y": "column_name", "title": "Descriptive Chart Title"}},
268
- {{"type": "line", "x": "column_name", "y": "column_name", "title": "Descriptive Chart Title"}},
269
- {{"type": "scatter", "x": "column_name", "y": "column_name", "title": "Descriptive Chart Title"}},
270
- {{"type": "pie", "column": "column_name", "title": "Descriptive Chart Title"}}
271
- ],
272
- "insights": [
273
- "First business insight about the data",
274
- "Second business insight about the data",
275
- "Third business insight about the data"
276
- ]
277
- }}
278
-
279
- Chart types available: bar, line, scatter, histogram, pie
280
- Generate 4-6 charts that would be most insightful for this data domain.
281
- """
282
-
283
- # Call Gemini API
284
- response = client.models.generate_content(
285
- model="gemini-2.0-flash-exp",
286
- contents=[prompt]
287
- )
288
-
289
- # Parse response
290
- response_text = response.text.strip()
291
- if response_text.startswith("```"):
292
- response_text = response_text.split("```")[1]
293
- if response_text.startswith("json"):
294
- response_text = response_text[4:]
295
-
296
- chart_plan = json.loads(response_text)
297
-
298
- # Store in session state
299
- st.session_state['chart_plan'] = chart_plan
300
- st.session_state['df'] = df
301
-
302
- except Exception as e:
303
- st.error(f"❌ Error generating dashboard: {e}")
304
- st.exception(e)
305
-
306
- # ------------------------------
307
- # Display Charts in Collage View
308
- # ------------------------------
309
- if 'chart_plan' in st.session_state:
310
- chart_plan = st.session_state['chart_plan']
311
- df = st.session_state['df']
312
-
313
- st.markdown("---")
314
- st.markdown("### 📈 Visualizations Collage")
315
- st.markdown(f"**Dashboard Title:** {uploaded_file.name.split('.')[0].replace('_', ' ').title()}")
316
- st.markdown("**Detailed Charts & Graphs** - Comprehensive visual analysis with proper labels and insights")
317
-
318
- charts = chart_plan.get("charts", [])
319
-
320
- # Create matplotlib figure with all charts
321
- num_charts = len(charts)
322
- cols_per_row = 3
323
- rows = (num_charts + cols_per_row - 1) // cols_per_row
324
-
325
- fig = plt.figure(figsize=(20, 5 * rows))
326
-
327
- for idx, chart in enumerate(charts, 1):
328
- try:
329
- chart_type = chart.get("type")
330
- title = chart.get("title", f"Chart {idx}")
331
-
332
- ax = fig.add_subplot(rows, cols_per_row, idx)
333
-
334
- if chart_type == "bar" and "x" in chart and "y" in chart:
335
- grouped_data = df.groupby(chart["x"])[chart["y"]].sum()
336
- # Limit to top 15 categories for readability
337
- if len(grouped_data) > 15:
338
- grouped_data = grouped_data.nlargest(15)
339
- sns.barplot(x=grouped_data.values, y=grouped_data.index, ax=ax, palette='Blues_d')
340
- ax.set_xlabel(chart["y"], fontsize=10)
341
- ax.set_ylabel(chart["x"], fontsize=10)
342
-
343
- elif chart_type == "line" and "x" in chart and "y" in chart:
344
- # Sample data if too many points
345
- plot_df = df.copy()
346
- if len(plot_df) > 100:
347
- plot_df = plot_df.sample(100).sort_values(by=chart["x"])
348
- sns.lineplot(data=plot_df, x=chart["x"], y=chart["y"], ax=ax, marker='o', color='green', linewidth=2)
349
- ax.set_xlabel(chart["x"], fontsize=10)
350
- ax.set_ylabel(chart["y"], fontsize=10)
351
- plt.setp(ax.xaxis.get_majorticklabels(), rotation=45, ha='right', fontsize=8)
352
-
353
- elif chart_type == "scatter" and "x" in chart and "y" in chart:
354
- sns.scatterplot(data=df, x=chart["x"], y=chart["y"], ax=ax, color='coral', s=50, alpha=0.6)
355
- ax.set_xlabel(chart["x"], fontsize=10)
356
- ax.set_ylabel(chart["y"], fontsize=10)
357
-
358
- elif chart_type == "histogram" and "x" in chart:
359
- sns.histplot(df[chart["x"]].dropna(), bins=20, kde=True, ax=ax, color='purple', alpha=0.7)
360
- ax.set_xlabel(chart["x"], fontsize=10)
361
- ax.set_ylabel("Frequency", fontsize=10)
362
-
363
- elif chart_type == "pie" and "column" in chart:
364
- data = df[chart["column"]].value_counts().head(5)
365
- colors = sns.color_palette("pastel")
366
- ax.pie(data.values, labels=data.index, autopct='%1.1f%%', startangle=90, colors=colors)
367
-
368
- ax.set_title(title, fontsize=11, fontweight='bold', pad=10)
369
-
370
- except Exception as chart_error:
371
- ax.text(0.5, 0.5, f'Error: {str(chart_error)}', ha='center', va='center')
372
- ax.set_title(title, fontsize=11)
373
-
374
- plt.tight_layout()
375
- st.pyplot(fig)
376
- plt.close()
377
-
378
- # Display Insights
379
- st.markdown("---")
380
- st.markdown("### 💡 Business Insights")
381
-
382
- insights = chart_plan.get("insights", [])
383
- for idx, insight in enumerate(insights, 1):
384
- st.markdown(f"**{idx}.** {insight}")
385
-
386
- # ------------------------------
387
- # Generate Interactive HTML Dashboard (Professional Power BI Style)
388
- # ------------------------------
389
- if generate_interactive:
390
- with st.spinner("Generating professional interactive dashboard..."):
391
- try:
392
- # Detect domain and company info
393
- domain = st.session_state.get('chart_plan', {}).get('domain', 'general')
394
- is_company = st.session_state.get('chart_plan', {}).get('is_company_data', False)
395
-
396
- # Get file name for dashboard title
397
- dashboard_title = uploaded_file.name.split('.')[0].replace('_', ' ').title()
398
-
399
- # Prepare data with proper serialization
400
- sample_data = df.head(20).copy()
401
- for col in sample_data.columns:
402
- if sample_data[col].dtype == 'datetime64[ns]' or isinstance(sample_data[col].iloc[0], pd.Timestamp):
403
- sample_data[col] = sample_data[col].astype(str)
404
-
405
- stats_dict = {}
406
- for col in df.select_dtypes(include=['number']).columns:
407
- stats_dict[col] = {
408
- 'mean': float(df[col].mean()),
409
- 'median': float(df[col].median()),
410
- 'std': float(df[col].std()),
411
- 'min': float(df[col].min()),
412
- 'max': float(df[col].max())
413
- }
414
-
415
- html_prompt = f"""
416
- Create a COMPLETE, self-contained, professional Power BI-style HTML dashboard.
417
-
418
- Dataset Context:
419
- - Dashboard Title: {dashboard_title}
420
- - Domain: {domain}
421
- - Is Company Data: {is_company}
422
- - Columns: {', '.join(df.columns.tolist())}
423
- - Rows: {df.shape[0]}
424
- - Sample Data: {json.dumps(sample_data.to_dict('records')[:10], cls=CustomJSONEncoder)}
425
- - Statistics: {json.dumps(stats_dict, cls=CustomJSONEncoder)}
426
-
427
- CRITICAL Requirements for Handling Large Data:
428
- 1. For bar charts with many categories (>15), show only TOP 15 values and add "...and X more" text
429
- 2. For time series/date data, aggregate by week or month, never show individual dates
430
- 3. Use responsive chart heights (max 300px per chart)
431
- 4. Implement proper overflow handling with max-height and scrolling only if necessary
432
- 5. For dates on x-axis: rotate labels 45deg, use abbreviated format (MMM-YY), show every Nth label
433
-
434
- Dashboard Design:
435
- 1. Use Chart.js from CDN: https://cdn.jsdelivr.net/npm/chart.js
436
- 2. Dynamic color scheme based on domain/data characteristics:
437
- - Finance: Blue (#1e3a8a) to Navy gradient with gold accents
438
- - Retail/Sales: Orange (#ea580c) to Green (#16a34a) gradient
439
- - Healthcare: Teal (#0d9488) to Blue (#0284c7) gradient
440
- - Entertainment/Movies: Purple (#7c3aed) to Magenta (#db2777) gradient
441
- - Technology: Cyan (#06b6d4) to Blue (#3b82f6) gradient
442
- - Generic: Professional Blue (#2563eb) to Gray (#64748b) gradient
443
- 3. Layout: Responsive grid with 2-3 columns, cards with shadows
444
- 4. Include:
445
- - Top banner with "{dashboard_title}" as main title
446
- - 4-6 KPI cards with key metrics (large numbers, trend indicators)
447
- - 6-8 charts in grid layout (bar, line, pie, doughnut, area charts)
448
- - Each chart in a card with title, proper spacing
449
- - All charts must be USEFUL for Business Intelligence and KPI tracking
450
- - Focus on metrics that show: trends, comparisons, distributions, performance
451
- 5. If company data, add company logo placeholder at top
452
- 6. Footer: "{datetime.now().strftime('%B %d, %Y')} | {dashboard_title} Analytics Dashboard"
453
- 7. Make charts interactive: hover tooltips, legend toggle
454
- 8. Use actual data values, aggregate large datasets intelligently
455
- 9. Add smooth animations (fade-in, scale effects)
456
- 10. Ensure dates are always visible, accurate & readable
457
-
458
- Chart Configuration Best Practices:
459
- - Bar charts: Horizontal for many categories.
460
- - Line charts: Aggregate time data, show trends not noise
461
- - Pie/Doughnut: Limit to top 10 categories, group "Others"
462
- - Use appropriate scales and formatting (K, M, B for large numbers)
463
-
464
- Return ONLY complete HTML code starting with <!DOCTYPE html>
465
- NO markdown, NO explanations, just pure HTML that looks like a professional BI tool.
466
- """
467
-
468
- response = client.models.generate_content(
469
- model="gemini-2.0-flash-exp",
470
- contents=[html_prompt]
471
- )
472
-
473
- html_code = response.text.strip()
474
-
475
- if html_code.startswith("```"):
476
- html_code = html_code.split("```")[1]
477
- if html_code.startswith("html"):
478
- html_code = html_code[4:]
479
- html_code = html_code.strip()
480
-
481
- st.session_state['html_dashboard'] = html_code
482
- st.success("✅ Professional dashboard generated!")
483
-
484
- except Exception as e:
485
- st.error(f"❌ Error generating HTML dashboard: {e}")
486
- st.exception(e)
487
-
488
- # ------------------------------
489
- # Display Interactive HTML Dashboard
490
- # ------------------------------
491
- if 'html_dashboard' in st.session_state:
492
- st.markdown("---")
493
- st.markdown("### 🎨 Professional Interactive Dashboard")
494
-
495
- html_code = st.session_state['html_dashboard']
496
-
497
- # Display the interactive HTML
498
- components.html(html_code, height=1000, scrolling=True)
499
-
500
- col1, col2 = st.columns(2)
501
- with col1:
502
- st.download_button(
503
- label="📥 Download HTML Dashboard",
504
- data=html_code,
505
- file_name=f"dashboard_{uploaded_file.name.split('.')[0]}.html",
506
- mime="text/html",
507
- use_container_width=True
508
- )
509
-
510
- with col2:
511
- with st.expander("💻 View HTML Source Code"):
512
- st.code(html_code, language="html")
513
-
514
- # ------------------------------
515
- # Generate AI Presentation (PPT-style HTML)
516
- # ------------------------------
517
- if generate_presentation:
518
- with st.spinner("Creating professional presentation..."):
519
- try:
520
- # Get insights and domain info
521
- chart_plan = st.session_state.get('chart_plan', {})
522
- domain = chart_plan.get('domain', 'general')
523
- insights = chart_plan.get('insights', [])
524
-
525
- dashboard_title = uploaded_file.name.split('.')[0].replace('_', ' ').title()
526
-
527
- # Prepare data summary
528
- key_metrics = []
529
- for col in df.select_dtypes(include=['number']).columns[:4]:
530
- key_metrics.append({
531
- 'metric': col,
532
- 'value': float(df[col].sum()),
533
- 'avg': float(df[col].mean()),
534
- 'trend': 'up' if df[col].mean() > df[col].median() else 'down'
535
- })
536
-
537
- presentation_prompt = f"""
538
- Create a professional HTML presentation (PowerPoint-style) with slide navigation.
539
-
540
- Presentation Context:
541
- - Title: {dashboard_title} - Business Intelligence Analysis
542
- - Domain: {domain}
543
- - Dataset: {df.shape[0]} rows, {df.shape[1]} columns
544
- - Key Insights: {json.dumps(insights, cls=CustomJSONEncoder)}
545
- - Key Metrics: {json.dumps(key_metrics, cls=CustomJSONEncoder)}
546
-
547
- Create EXACTLY 5 slides with this structure:
548
-
549
- SLIDE 1 - Title & Introduction:
550
- - Large title: "{dashboard_title}"
551
- - Subtitle: "Business Intelligence Dashboard Analysis"
552
- - Brief introduction about the data and purpose
553
- - Beautiful gradient background matching {domain} theme
554
- - Company logo placeholder if applicable
555
-
556
- SLIDE 2 - Key Objectives & Questions:
557
- - Title: "Business Objectives"
558
- - List 3-4 core business questions this analysis answers
559
- - Use bullet points with icons
560
- - Examples: "What drives revenue growth?", "Which segments perform best?", etc.
561
-
562
- SLIDE 3 - Data & Analysis:
563
- - Title: "Key Findings & Visualizations"
564
- - Include 2-3 mini chart visualizations using Chart.js
565
- - Show the most important metrics and trends
566
- - Use actual data from the metrics provided
567
- - Keep charts simple and clear
568
-
569
- SLIDE 4 - Insights & Recommendations:
570
- - Title: "Strategic Insights"
571
- - Present the top 3 insights from the data
572
- - Add actionable recommendations for each insight
573
- - Use cards/boxes for visual separation
574
- - Include trend indicators (↑↓→)
575
-
576
- SLIDE 5 - Conclusion & Next Steps:
577
- - Title: "Conclusion & Action Plan"
578
- - Recap key takeaways (3-4 points)
579
- - Suggest 2-3 concrete next steps
580
- - Add a "Questions?" section
581
- - Thank you message
582
-
583
- Technical Requirements:
584
- 1. Full-screen slides (100vh height, 100vw width)
585
- 2. Slide navigation: Previous/Next buttons + keyboard arrows
586
- 3. Slide counter: "Slide X of 5"
587
- 4. Smooth transitions between slides (slide/fade effect)
588
- 5. Professional design matching {domain} color scheme:
589
- - Finance: Navy blue with gold accents
590
- - Retail: Orange and green tones
591
- - Healthcare: Teal and blue
592
- - Entertainment: Purple and magenta
593
- - Technology: Cyan and blue
594
- - Generic: Professional blue-gray
595
- 6. Use Chart.js for any charts (CDN: https://cdn.jsdelivr.net/npm/chart.js)
596
- 7. Responsive typography and spacing
597
- 8. Each slide should be self-contained and visually appealing
598
- 9. Add subtle animations (fade-in effects for content)
599
- 10. Footer on each slide with page number and date
600
-
601
- Return ONLY complete HTML code starting with <!DOCTYPE html>
602
- NO markdown, NO explanations.
603
- The presentation should look like a professional PowerPoint/Keynote presentation.
604
- """
605
-
606
- response = client.models.generate_content(
607
- model="gemini-2.0-flash-exp",
608
- contents=[presentation_prompt]
609
- )
610
-
611
- ppt_html = response.text.strip()
612
-
613
- if ppt_html.startswith("```"):
614
- ppt_html = ppt_html.split("```")[1]
615
- if ppt_html.startswith("html"):
616
- ppt_html = ppt_html[4:]
617
- ppt_html = ppt_html.strip()
618
-
619
- st.session_state['presentation'] = ppt_html
620
- st.success("✅ Presentation generated!")
621
-
622
- except Exception as e:
623
- st.error(f"❌ Error generating presentation: {e}")
624
- st.exception(e)
625
-
626
- # ------------------------------
627
- # Display Presentation
628
- # ------------------------------
629
- if 'presentation' in st.session_state:
630
- st.markdown("---")
631
- st.markdown("### 🎤 AI-Generated Business Presentation")
632
- st.info("Use arrow keys or navigation buttons to move between slides")
633
-
634
- ppt_html = st.session_state['presentation']
635
-
636
- # Display the presentation
637
- components.html(ppt_html, height=700, scrolling=False)
638
-
639
- st.download_button(
640
- label="📥 Download Presentation (HTML)",
641
- data=ppt_html,
642
- file_name=f"presentation_{uploaded_file.name.split('.')[0]}.html",
643
- mime="text/html",
644
- use_container_width=True
645
- )
646
-
647
- except Exception as e:
648
- st.error(f"❌ Error loading file: {e}")
649
- st.exception(e)
650
-
651
- else:
652
- st.info("👆 Please upload a CSV or Excel file to get started.")
653
-
654
- # ------------------------------
655
- # Footer
656
- # ------------------------------
657
- st.markdown("---")
658
- st.markdown(
659
- f"<div style='text-align: center; color: gray;'>Built with Streamlit & Google Gemini AI</div>",
660
- unsafe_allow_html=True
661
- )