| import gradio as gr |
| import pandas as pd |
| from backend import get_columns, load_file, apply_filters, sales_insights, save_feedback |
| import os |
|
|
| |
| custom_css = """ |
| body { |
| background-color: #f8f9fb; |
| font-family: 'Segoe UI', sans-serif; |
| } |
| |
| .gradio-container { |
| max-width: 1300px; |
| margin: auto; |
| } |
| |
| /* Sidebar */ |
| .sidebar { |
| background: #ffffff; |
| padding: 20px; |
| border-radius: 12px; |
| box-shadow: 0px 2px 8px rgba(0,0,0,0.05); |
| } |
| |
| /* Main panel */ |
| .main { |
| background: #ffffff; |
| padding: 20px; |
| border-radius: 12px; |
| box-shadow: 0px 2px 8px rgba(0,0,0,0.05); |
| } |
| |
| /* Header */ |
| h1 { |
| text-align: center; |
| color: #222; |
| margin-bottom: 20px; |
| } |
| |
| /* Buttons */ |
| button { |
| border-radius: 8px !important; |
| font-weight: 500; |
| } |
| |
| /* Mobile fix */ |
| @media (max-width: 768px) { |
| .gradio-container { |
| padding: 10px; |
| } |
| } |
| """ |
|
|
| with gr.Blocks(css=custom_css, title="Smart Dashboard") as demo: |
|
|
| gr.Markdown("# π Smart Data Dashboard By NadiΨ΄") |
|
|
| with gr.Tabs(): |
|
|
| |
| with gr.Tab("π Analysis"): |
|
|
| with gr.Row(): |
|
|
| |
| with gr.Column(scale=1, elem_classes="sidebar"): |
|
|
| file_input = gr.File(type="filepath", label="Upload File") |
|
|
| chart_type = gr.Dropdown( |
| ["Bar Chart", "Line Chart", "Pie Chart", "Box Plot"], |
| label="Chart Type" |
| ) |
|
|
| x_axis = gr.Dropdown(label="X-axis (Category)") |
| y_axis = gr.Dropdown(multiselect=True, label="Y-axis (Numeric)") |
|
|
| gr.Markdown("### π Filters") |
|
|
| filter_col = gr.Dropdown(label="Column") |
| filter_type = gr.Dropdown( |
| ["equals", "contains", "range"], |
| label="Type" |
| ) |
| filter_val = gr.Textbox(label="Value") |
|
|
| add_filter_btn = gr.Button("β Add Filter") |
|
|
| filters_state = gr.State([]) |
| filter_display = gr.JSON(label="Active Filters") |
|
|
| run_btn = gr.Button("π Run Analysis", variant="primary") |
|
|
| |
| with gr.Column(scale=2, elem_classes="main"): |
|
|
| output_chart = gr.Plot(label="Visualization") |
|
|
| with gr.Row(): |
| download_png = gr.File(label="Download Chart") |
| download_excel = gr.File(label="Download Data") |
|
|
| |
| with gr.Tab("π¬ Feedback"): |
|
|
| with gr.Row(): |
|
|
| |
| with gr.Column(scale=1, elem_classes="sidebar"): |
|
|
| name = gr.Textbox(label="Name") |
| comment = gr.Textbox(label="Comment", lines=4) |
| stars = gr.Slider(1, 5, value=5, step=1, label="Rating β") |
|
|
| fb_btn = gr.Button("Submit Feedback", variant="primary") |
| fb_status = gr.Textbox(label="Status") |
|
|
| |
| with gr.Column(scale=1, elem_classes="main"): |
|
|
| show_btn = gr.Button("π Show Feedback") |
| feedback_display = gr.HTML() |
|
|
| |
|
|
| def load_cols(file): |
| cols = get_columns(file) |
| return ( |
| gr.update(choices=cols), |
| gr.update(choices=cols), |
| gr.update(choices=cols) |
| ) |
|
|
| def add_filter(col, ftype, val, state): |
| if not col or not ftype or not val: |
| return state, state |
|
|
| state = [f for f in state if f["column"] != col] |
|
|
| if ftype == "range": |
| try: |
| vals = list(map(float, val.split(","))) |
| except: |
| return state, state |
| else: |
| vals = [v.strip() for v in val.split(",")] |
|
|
| state.append({"column": col, "type": ftype, "value": vals}) |
| return state, state |
|
|
| def run_analysis(file, chart, x, y, filters): |
| if not file: |
| raise gr.Error("Upload file first") |
|
|
| df = load_file(file) |
|
|
| if filters: |
| df = apply_filters(df, filters) |
|
|
| return sales_insights(df, chart, x, y) |
|
|
| def load_feedback(): |
| if os.path.exists("feedback.xlsx"): |
| df = pd.read_excel("feedback.xlsx") |
| return df.to_html(index=False) |
| return "<p>No feedback yet</p>" |
|
|
| def save_fb(name, comment, stars): |
| msg = save_feedback(name, comment, stars) |
| return msg |
|
|
| |
|
|
| file_input.change(load_cols, file_input, [x_axis, y_axis, filter_col]) |
|
|
| add_filter_btn.click( |
| add_filter, |
| [filter_col, filter_type, filter_val, filters_state], |
| [filters_state, filter_display] |
| ) |
|
|
| run_btn.click( |
| run_analysis, |
| [file_input, chart_type, x_axis, y_axis, filters_state], |
| [output_chart, download_png, download_excel] |
| ) |
|
|
| fb_btn.click( |
| save_fb, |
| [name, comment, stars], |
| fb_status |
| ) |
|
|
| show_btn.click( |
| load_feedback, |
| None, |
| feedback_display |
| ) |
|
|
| if __name__ == "__main__": |
| demo.launch(server_name="0.0.0.0", server_port=7860) |