import gradio as gr import pandas as pd from backend import get_columns, load_file, apply_filters, sales_insights, save_feedback import os # π¨ PROFESSIONAL CSS 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(): # ================= ANALYSIS TAB ================= with gr.Tab("π Analysis"): with gr.Row(): # π½ LEFT SIDEBAR 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") # π RIGHT MAIN PANEL 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") # ================= FEEDBACK TAB ================= with gr.Tab("π¬ Feedback"): with gr.Row(): # LEFT FORM 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") # RIGHT DISPLAY with gr.Column(scale=1, elem_classes="main"): show_btn = gr.Button("π Show Feedback") feedback_display = gr.HTML() # ================= FUNCTIONS ================= 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 "
No feedback yet
" def save_fb(name, comment, stars): msg = save_feedback(name, comment, stars) return msg # ================= EVENTS ================= 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)