File size: 12,823 Bytes
3c8615e
 
f24d56c
3c8615e
 
25784c4
8b43d60
 
 
0381fad
3c8615e
fec880a
52402fd
fec880a
 
 
 
 
 
 
2df62ed
5af845c
52402fd
 
fec880a
97336a8
 
 
 
fec880a
97336a8
2df62ed
 
 
 
a3c17fa
 
 
 
 
2df62ed
 
5b940aa
92fe3f1
 
13af3e0
156466a
13af3e0
8468201
8b43d60
e6c7b55
8468201
156466a
 
 
ab43899
156466a
8468201
c2241c4
8b43d60
8468201
 
 
 
 
 
 
 
 
 
3934b8b
8468201
3934b8b
8468201
 
 
 
 
 
 
 
 
 
3934b8b
8468201
 
 
 
 
 
 
 
3934b8b
8468201
 
 
 
 
 
1737776
ab43899
 
1737776
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c2241c4
 
 
 
1737776
 
8b43d60
 
ffcdcc7
8b43d60
 
 
 
 
ffcdcc7
eef2ede
8b43d60
8468201
0ca0958
 
 
 
e6c7b55
 
 
0ca0958
c2241c4
 
 
0ca0958
 
0381fad
c2241c4
0381fad
 
c2241c4
 
0381fad
eef2ede
c2241c4
 
 
 
0ca0958
 
 
 
 
09c7128
 
 
 
0ca0958
 
 
8468201
 
 
 
 
 
 
 
 
8b43d60
1737776
156466a
 
e6c7b55
 
0ca0958
e6c7b55
 
 
156466a
 
eef2ede
c2241c4
09c7128
 
 
eef2ede
c2241c4
 
eef2ede
c2241c4
 
eef2ede
0381fad
 
eef2ede
 
0381fad
 
 
 
 
 
 
 
 
 
 
c2241c4
0381fad
09c7128
 
eef2ede
 
 
09c7128
eef2ede
 
0381fad
09c7128
 
13af3e0
8468201
a903ab2
b284c02
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# app.py

import gradio as gr
from components.auth import register, login, logout
from components.predict import predict
from components.report_generator import create_report
from components.diabetes_factors import render_factors_info
from components.food_suggestions import render_food_guide
from components.doctor_info import render_doctor_list
from components.how_to_use import render_how_to_use_guide

# --- Style and Theme with FINAL Mobile-Responsive CSS ---
css = """
/* --- CRITICAL FIX FOR SCROLLING ON MOBILE --- */
/* This forces the entire page to allow vertical scrolling and grow with its content */
html, body {
  overflow-y: auto !important; /* Allow vertical scrolling! */
  height: auto !important;     /* Let the body grow beyond the screen height */
}

/* General container style for all screens */
.gradio-container { max-width: 1000px !important; margin: auto !important; }
.centered-text { text-align: center; }

/* Fix for invisible button text in dark mode */
.gradio-button.primary, .gradio-button.secondary {
  color: white !important;
}

/* Responsive rules for stacking content WITHIN the app */
@media (max-width: 768px) {
  .gradio-row {
    flex-direction: column !important;
    gap: 1rem !important;
  }
  .gradio-row > * {
    width: 100% !important;
    min-width: unset !important;
    margin: 0 !important;
  }
}
"""


with gr.Blocks(title="DiaSpark: Your Health Management Platform", css=css) as demo:

    user_state = gr.State({"email": None, "id": None, "logged_in": False, "gender": None, "username": None})

    # --- Static Header (Always Visible) ---
    gr.Markdown("# 🩺 Welcome to DiaSpark: Your Health Management Platform")

    # --- Personalized Header (Visible only when logged in) ---
    with gr.Row(visible=False) as logged_in_header:
        welcome_message = gr.Markdown()

    # --- Main Tabs ---
    with gr.Tabs() as main_tabs:

        # --- Tab 1: Homepage ---
        with gr.TabItem("Home 🏠", id="home_tab"):
            gr.Markdown(
                "<h2 class='centered-text'>A Smart First Step in Understanding Your Health</h2>",
                elem_classes="centered-text"
            )
            gr.Markdown(
                """
                DiaSpark is a confidential tool that uses machine learning to provide an educational analysis of your diabetes risk factors.
                Our goal is to promote health awareness, not to provide a medical diagnosis.
                """
            )
            gr.Markdown("---")
            
            with gr.Accordion("🎯 Our Mission: The 'Why'", open=True):
                gr.Markdown(
                    """
                    We believe that awareness is the first and most powerful step towards a healthier life. 
                    This tool was built to help you:
                    *   **Gain Insight:** Understand how key health metrics can contribute to your overall risk profile.
                    *   **Encourage Proactive Care:** Use this information as a starting point for meaningful conversations with your doctor.
                    *   **Do It All Privately:** Your health data is sensitive. Our secure login ensures your prediction history is for your eyes only.
                    """
                )
            
            with gr.Accordion("πŸš€ Getting Started: The 'How'", open=False):
                gr.Markdown(
                    """
                    1.  **Create Your Secure Account:** Navigate to the **'Login / Signup'** tab. The process is quick and requires a username, email, password, and gender.
                    2.  **Enter Your Health Metrics:** Once logged in, go to the **'Prediction'** tab. Fill in the fields with your most recent health information.
                    3.  **Receive Your Instant Analysis:** Click the 'Predict My Risk' button. Our AI model will provide an immediate, educational assessment based on your data.
                    """
                )
            
            with gr.Accordion("⚠️ Important Disclaimer", open=False):
                gr.Markdown(
                    """
                    **This tool is NOT a substitute for professional medical advice, diagnosis, or treatment.**
                    The results from DiaSpark are for informational purposes only. Always seek the advice of your physician or another qualified health provider with any questions you may have regarding a medical condition. Never disregard professional medical advice or delay in seeking it because of something you have read or seen on this application.
                    """
                )

        # --- Tab 2: Authentication ---
        with gr.TabItem("Login / Signup πŸ”‘", id="auth_tab") as auth_tab_item:
            auth_message = gr.Markdown()
            
            with gr.Column(visible=True) as login_col:
                gr.Markdown("### Login to Your Account")
                email_login = gr.Textbox(label="Email", placeholder="Enter your email")
                pwd_login = gr.Textbox(label="Password", type="password", placeholder="Enter your password")
                login_btn = gr.Button("Login", variant="primary")
                show_signup_btn = gr.Button("New user? Sign up here.", variant="secondary")

            with gr.Column(visible=False) as signup_col:
                gr.Markdown("### Create a New Account")
                username_signup = gr.Textbox(label="Username", placeholder="Choose a unique username")
                email_signup = gr.Textbox(label="Email", placeholder="Enter your email")
                pwd_signup = gr.Textbox(
                    label="Password",
                    type="password",
                    placeholder="Create a password",
                    info="Must be at least 6 characters long."
                )
                gender_signup = gr.Radio(["Female", "Male"], label="Gender", info="This determines if the 'Pregnancies' field is shown.")
                signup_btn = gr.Button("Sign Up", variant="primary")
                show_login_btn = gr.Button("Already have an account? Login.", variant="secondary")
        
        # --- NEW "How to Use" Tab ---
        with gr.TabItem("How to Use πŸ’‘"):
            render_how_to_use_guide()

        # --- The rest of the informational and tool tabs ---
        with gr.TabItem("Learn About Diabetes πŸ“š"):
            render_factors_info()
            
        with gr.TabItem("Healthy Eating Guide πŸ₯—"):
            render_food_guide()
            
        with gr.TabItem("Find a Specialist πŸ§‘β€βš•οΈ"):
            render_doctor_list()

        # --- Prediction Tab ---
        with gr.TabItem("Prediction Tool πŸ”¬", id="prediction_tab"):
            
            with gr.Column(visible=False) as prediction_view:
                gr.Markdown("### Enter Your Health Metrics for Prediction")
                gr.Markdown("---")
                
                with gr.Row(visible=False) as pregnancies_row:
                    preg = gr.Number(label="Pregnancies", info="Number of times pregnant")

                with gr.Row():
                    with gr.Column(scale=2):
                        glucose = gr.Number(label="Glucose", info="Plasma glucose concentration (mg/dL)")
                        bp = gr.Number(label="Blood Pressure", info="Diastolic (bottom number, mm Hg)")
                        insulin = gr.Number(label="Insulin", info="2-Hour serum insulin (mu U/ml)")
                        age = gr.Number(label="Age", info="Age in years")
                    
                    with gr.Column(scale=1):
                        bmi = gr.Number(label="BMI", info="Your Body Mass Index. We can calculate this for you.")
                        
                        bmi_choice = gr.Radio(
                            ["I know my BMI", "Calculate from Weight/Height"],
                            label="Provide BMI",
                            value="I know my BMI"
                        )
                        with gr.Column(visible=False) as bmi_calc_view:
                            weight = gr.Number(label="Your Weight (kg)")
                            height = gr.Number(label="Your Height (cm)")
                
                with gr.Row():
                    predict_btn = gr.Button("Predict My Risk", variant="primary")
                
                result_output = gr.Textbox(label="Prediction Result", interactive=False)
                
                generate_report_btn = gr.Button("Download Report as PDF", variant="secondary", visible=False)
                report_file_output = gr.File(label="Your Report", visible=False)
                
                logout_btn = gr.Button("Logout", variant="stop")

            with gr.Column(visible=True) as logged_out_view:
                gr.Markdown(
                    """
                    <div style="text-align:center; padding: 50px;">
                        <h2>πŸ”’ Please log in to access the prediction tool.</h2>
                        <p>You can create an account or log in via the 'Login / Signup' tab.</p>
                    </div>
                    """
                )

    # --- Component Logic (Event Handlers) ---
    
    def switch_to_signup(): return gr.update(visible=False), gr.update(visible=True)
    def switch_to_login(): return gr.update(visible=True), gr.update(visible=False)
    show_signup_btn.click(fn=switch_to_signup, outputs=[login_col, signup_col])
    show_login_btn.click(fn=switch_to_login, outputs=[login_col, signup_col])
    
    def handle_user_state_change(user_data):
        is_logged_in = user_data.get("logged_in", False)
        is_female = user_data.get("gender") == "Female"
        username = user_data.get("username", "User")
        welcome_text = f"### πŸ‘‹ Welcome, {username}!"
        return (gr.update(visible=is_logged_in), gr.update(visible=not is_logged_in), gr.update(visible=is_female), gr.update(value=welcome_text), gr.update(visible=is_logged_in), gr.update(visible=not is_logged_in))
    user_state.change(fn=handle_user_state_change, inputs=user_state, outputs=[prediction_view, logged_out_view, pregnancies_row, welcome_message, logged_in_header, auth_tab_item])

    signup_btn.click(fn=register, inputs=[email_signup, pwd_signup, gender_signup, username_signup], outputs=[auth_message, email_signup, pwd_signup, gender_signup, username_signup])
    login_btn.click(fn=login, inputs=[email_login, pwd_login, user_state], outputs=[auth_message, user_state, main_tabs])
    # The logout handler must now also clear the weight and height fields.
    logout_btn.click(fn=logout, inputs=[user_state], outputs=[auth_message, user_state, main_tabs, email_login, pwd_login, preg, glucose, bp, insulin, bmi, age, result_output, pregnancies_row, weight, height, bmi_choice])

    # --- CORRECTED BMI LOGIC ---
    def toggle_bmi_inputs(choice):
        if choice == "I know my BMI":
            # Return 4 values: one for each output component
            return gr.update(interactive=True, value=None), None, None, gr.update(visible=False)
        else: # Calculate from Weight/Height
            # Also return 4 values here to match the outputs list
            return gr.update(interactive=False, value=None), gr.update(), gr.update(), gr.update(visible=True)
    bmi_choice.change(fn=toggle_bmi_inputs, inputs=bmi_choice, outputs=[bmi, weight, height, bmi_calc_view])

    def calculate_bmi(w, h):
        if w and h and w > 0 and h > 0:
            bmi_val = round(w / ((h / 100) ** 2), 2)
            return bmi_val
        return None
    weight.change(fn=calculate_bmi, inputs=[weight, height], outputs=bmi)
    height.change(fn=calculate_bmi, inputs=[weight, height], outputs=bmi)

    predict_btn.click(fn=predict, inputs=[preg, glucose, bp, insulin, bmi, age, user_state], outputs=[result_output])
    
    def handle_create_report(user, p, g, b, i, bmi_val, age_val, result):
        if not result:
            return gr.update(visible=False)
        # Recalculate is no longer needed, just use the value from the bmi box
        final_bmi_report = bmi_val if bmi_val is not None else 0
        input_data = {"Pregnancies": p if p is not None else 0, "Glucose": g, "Blood Pressure": b, "Insulin": i, "BMI": final_bmi_report, "Age": age_val}
        file_path = create_report(user, input_data, result)
        # CORRECTED TYPO: It should be 'file_path', not 'file_file'
        return gr.update(value=file_path, visible=True)
    generate_report_btn.click(fn=handle_create_report, inputs=[user_state, preg, glucose, bp, insulin, bmi, age, result_output], outputs=[report_file_output])
    
    result_output.change(fn=lambda x: gr.update(visible=bool(x)), inputs=result_output, outputs=generate_report_btn)

# --- Launch the App ---
if __name__ == "__main__":
    demo.launch()