Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -14,10 +14,10 @@ from email.mime.text import MIMEText
|
|
14 |
import re
|
15 |
import json
|
16 |
|
17 |
-
# Configure Gemini API
|
18 |
genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
|
19 |
|
20 |
-
# Gmail API configuration
|
21 |
GMAIL_ADDRESS = os.getenv("GMAIL_ADDRESS")
|
22 |
GMAIL_TOKEN_JSON = os.getenv("GMAIL_TOKEN_JSON")
|
23 |
|
@@ -27,7 +27,7 @@ def get_gmail_service():
|
|
27 |
creds = Credentials.from_authorized_user_info(json.loads(GMAIL_TOKEN_JSON))
|
28 |
return build("gmail", "v1", credentials=creds)
|
29 |
except Exception as e:
|
30 |
-
|
31 |
|
32 |
# Coping Strategies Library
|
33 |
coping_strategies = {
|
@@ -106,12 +106,15 @@ def chatbot_function(message, mood, conversation_mode, region, state):
|
|
106 |
|
107 |
history = state["chat_history"]
|
108 |
|
|
|
|
|
|
|
109 |
try:
|
110 |
-
lang = detect(message)
|
111 |
except:
|
112 |
lang = "en"
|
113 |
|
114 |
-
if mood and mood != "Select mood
|
115 |
history.append([f"I'm feeling {mood.lower()}.", None])
|
116 |
|
117 |
history.append([message, None])
|
@@ -134,17 +137,17 @@ def chatbot_function(message, mood, conversation_mode, region, state):
|
|
134 |
try:
|
135 |
response = model.generate_content(prompt)
|
136 |
response_text = response.text
|
137 |
-
except Exception:
|
138 |
-
response_text = "I'm here for you
|
139 |
|
140 |
-
if mood and mood != "Select mood
|
141 |
mood_key = mood.lower()
|
142 |
if mood_key in coping_strategies:
|
143 |
strategy = random.choice(coping_strategies[mood_key])
|
144 |
response_text += f"\n\n**Coping Strategy**: {strategy}"
|
145 |
|
146 |
region_key = region if region in regional_resources else "Global"
|
147 |
-
resources = "\n\n**
|
148 |
response_text += resources
|
149 |
|
150 |
history[-1][1] = response_text
|
@@ -166,25 +169,25 @@ def clear_chat(state):
|
|
166 |
|
167 |
# Mood journal function
|
168 |
def log_mood(mood, state):
|
169 |
-
if mood and mood != "Select mood
|
170 |
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
171 |
state["mood_journal"].append({"timestamp": timestamp, "mood": mood.lower()})
|
172 |
-
return "Mood logged
|
173 |
-
return "Please select a mood
|
174 |
|
175 |
# Mood trend visualization
|
176 |
def show_mood_trends(state):
|
177 |
if not state["mood_journal"]:
|
178 |
return "No moods logged yet.", state
|
179 |
df = pd.DataFrame(state["mood_journal"])
|
180 |
-
fig = px.line(df, x="timestamp", y="mood", title="Mood Trends
|
181 |
return fig, state
|
182 |
|
183 |
# Feedback function
|
184 |
def submit_feedback(feedback_text, rating, state):
|
185 |
if feedback_text or rating:
|
186 |
state["feedback"].append({"text": feedback_text, "rating": rating, "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")})
|
187 |
-
return "
|
188 |
return "Please provide feedback or a rating.", state
|
189 |
|
190 |
# Emergency resources
|
@@ -199,8 +202,8 @@ def show_emergency_resources():
|
|
199 |
# Get available times for selected therapist
|
200 |
def get_available_times(therapist):
|
201 |
if therapist and therapist in therapists:
|
202 |
-
return f"Available times for {therapist} loaded.
|
203 |
-
return "Please select a therapist."
|
204 |
|
205 |
# Create MIME message for Gmail API
|
206 |
def create_message(to, subject, message_text):
|
@@ -246,10 +249,19 @@ Mental Health Chatbot
|
|
246 |
"""
|
247 |
user_message = create_message(user_email, "Appointment Confirmation", user_body)
|
248 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
249 |
try:
|
250 |
-
service =
|
251 |
-
|
252 |
-
user_result = service.users().messages().send(userId="me", body=user_message).execute()
|
253 |
return True, ""
|
254 |
except HttpError as e:
|
255 |
error_msg = f"Gmail API error: {str(e)}"
|
@@ -275,25 +287,25 @@ def schedule_appointment(therapist, time_slot, date, user_email, state):
|
|
275 |
if not therapist or therapist not in therapists:
|
276 |
return "Please select a therapist.", state
|
277 |
if not time_slot:
|
278 |
-
return "Please select a
|
279 |
if not date:
|
280 |
return "Please select a date.", state
|
281 |
if not user_email or not re.match(r"[^@]+@[^@]+\.[^@]+", user_email):
|
282 |
-
return "Please enter a valid email
|
283 |
|
284 |
try:
|
285 |
appointment_date = datetime.strptime(date, "%Y-%m-%d")
|
286 |
if appointment_date < datetime.now():
|
287 |
return "Please select a future date.", state
|
288 |
except ValueError:
|
289 |
-
return "Invalid date format
|
290 |
|
291 |
try:
|
292 |
appointment_time = datetime.strptime(time_slot, "%H:%M").strftime("%H:%M")
|
293 |
if appointment_time not in therapists[therapist]["times"]:
|
294 |
return f"Time {appointment_time} is not available for {therapist}.", state
|
295 |
except ValueError:
|
296 |
-
return "Invalid time format
|
297 |
|
298 |
appointment = {
|
299 |
"therapist": therapist,
|
@@ -307,127 +319,115 @@ def schedule_appointment(therapist, time_slot, date, user_email, state):
|
|
307 |
therapist_email = therapists[therapist]["email"]
|
308 |
success, error_msg = send_emails(therapist, appointment_time, date, user_email, therapist_email, state)
|
309 |
if success:
|
310 |
-
return f"Appointment booked with {therapist} on {date} at {appointment_time}. Emails sent
|
311 |
else:
|
312 |
return (f"Appointment booked with {therapist} on {date} at {appointment_time}. "
|
313 |
-
f"
|
314 |
-
f"Please email {therapist_email} with your details (date: {date}, time: {appointment_time}) "
|
315 |
-
f"and check {user_email} for confirmation (spam/junk)."), state
|
316 |
|
317 |
-
# Custom CSS for
|
318 |
custom_css = """
|
319 |
-
/* General Styling */
|
320 |
body {
|
321 |
-
font-family: '
|
322 |
-
background
|
|
|
323 |
}
|
324 |
|
325 |
-
/* Containers */
|
326 |
.gradio-container {
|
327 |
-
max-width:
|
328 |
-
margin:
|
329 |
-
padding:
|
330 |
-
background:
|
331 |
-
border-radius:
|
332 |
-
box-shadow: 0
|
333 |
}
|
334 |
|
335 |
-
/* Headings */
|
336 |
h1 {
|
337 |
-
|
338 |
-
|
339 |
text-align: center;
|
340 |
-
margin-bottom:
|
341 |
}
|
342 |
|
343 |
h2, h3 {
|
344 |
-
color: #
|
345 |
}
|
346 |
|
347 |
-
/* Inputs and Buttons */
|
348 |
input, select, textarea {
|
349 |
-
border
|
350 |
-
border:
|
351 |
-
padding:
|
352 |
-
|
|
|
|
|
353 |
}
|
354 |
|
355 |
input:focus, select:focus, textarea:focus {
|
356 |
-
border-color: #
|
357 |
outline: none;
|
|
|
358 |
}
|
359 |
|
360 |
button {
|
361 |
-
background:
|
362 |
-
color:
|
363 |
border: none !important;
|
364 |
-
border-radius:
|
365 |
-
padding:
|
366 |
-
font-
|
367 |
-
|
|
|
368 |
}
|
369 |
|
370 |
button:hover {
|
371 |
-
|
372 |
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2) !important;
|
373 |
}
|
374 |
|
375 |
-
/* Chatbox */
|
376 |
textarea[readonly] {
|
377 |
-
background: #
|
378 |
-
border-radius:
|
379 |
-
padding:
|
|
|
380 |
}
|
381 |
|
382 |
-
/* Appointment Section */
|
383 |
#appointment-section .gr-box {
|
384 |
-
background: #
|
385 |
-
border-radius:
|
386 |
-
padding:
|
387 |
}
|
388 |
|
389 |
-
|
390 |
-
#date-picker input, #time-picker input {
|
391 |
width: 100%;
|
392 |
-
padding: 10px;
|
393 |
-
border: 1px solid #d1d9e0;
|
394 |
-
border-radius: 8px;
|
395 |
-
font-size: 1em;
|
396 |
-
cursor: pointer;
|
397 |
-
}
|
398 |
-
|
399 |
-
#date-picker input::-webkit-calendar-picker-indicator,
|
400 |
-
#time-picker input::-webkit-calendar-picker-indicator {
|
401 |
-
cursor: pointer;
|
402 |
}
|
403 |
|
404 |
-
/* Responsive Design */
|
405 |
@media (max-width: 600px) {
|
406 |
.gradio-container {
|
407 |
-
padding:
|
|
|
408 |
}
|
409 |
button {
|
410 |
-
padding:
|
411 |
}
|
412 |
}
|
413 |
"""
|
414 |
|
415 |
-
# JavaScript
|
416 |
custom_js = """
|
417 |
document.addEventListener('DOMContentLoaded', function() {
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
|
|
|
|
431 |
}
|
432 |
});
|
433 |
"""
|
@@ -436,84 +436,85 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
436 |
with gr.Blocks(title="Mental Health Support Chatbot", css=custom_css, js=custom_js) as demo:
|
437 |
state = gr.State({"chat_history": [], "mood_journal": [], "feedback": [], "appointments": [], "failed_emails": []})
|
438 |
|
439 |
-
gr.Markdown("
|
440 |
-
gr.Markdown("A safe space to share
|
441 |
|
442 |
with gr.Row():
|
443 |
-
with gr.Column(scale=
|
444 |
mood = gr.Dropdown(
|
445 |
-
choices=["Select mood
|
446 |
-
label="
|
447 |
-
value="Select mood
|
448 |
)
|
449 |
conversation_mode = gr.Radio(
|
450 |
choices=["Neutral", "Calm", "Motivational"],
|
451 |
-
label="
|
452 |
value="Neutral"
|
453 |
)
|
454 |
region = gr.Dropdown(
|
455 |
choices=["USA", "India", "UK", "Global"],
|
456 |
-
label="
|
457 |
value="Global"
|
458 |
)
|
459 |
-
with gr.Column(scale=
|
460 |
chatbot = gr.Textbox(
|
461 |
-
label="
|
462 |
value="",
|
463 |
interactive=False,
|
464 |
-
lines=
|
465 |
show_copy_button=True
|
466 |
)
|
467 |
user_input = gr.Textbox(
|
468 |
-
placeholder="Type your message
|
469 |
-
label="
|
470 |
lines=2
|
471 |
)
|
472 |
with gr.Row():
|
473 |
submit_btn = gr.Button("Send")
|
474 |
-
clear_btn = gr.Button("Clear
|
475 |
|
476 |
-
emergency_btn = gr.Button("
|
477 |
emergency_output = gr.Markdown("")
|
478 |
|
479 |
with gr.Accordion("Mood Journal"):
|
480 |
log_mood_btn = gr.Button("Log Mood")
|
481 |
-
mood_log_output = gr.Textbox(label="
|
482 |
-
mood_trend_btn = gr.Button("
|
483 |
mood_trend_output = gr.Plot()
|
484 |
|
485 |
-
with gr.Accordion("
|
486 |
-
feedback_text = gr.Textbox(label="
|
487 |
-
feedback_rating = gr.Slider(minimum=1, maximum=5, step=1, label="
|
488 |
-
feedback_btn = gr.Button("Submit
|
489 |
-
feedback_output = gr.Textbox(label="
|
490 |
|
491 |
with gr.Accordion("Schedule Appointment", elem_id="appointment-section"):
|
492 |
therapist = gr.Dropdown(
|
493 |
choices=list(therapists.keys()),
|
494 |
-
label="
|
495 |
)
|
496 |
date = gr.Textbox(
|
497 |
-
label="
|
498 |
-
placeholder="
|
499 |
elem_id="date-picker"
|
500 |
)
|
501 |
-
time_slot = gr.
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
)
|
506 |
user_email = gr.Textbox(
|
507 |
-
label="
|
508 |
-
placeholder="
|
509 |
)
|
510 |
-
schedule_btn = gr.Button("Book
|
511 |
-
schedule_output = gr.Textbox(label="
|
512 |
|
513 |
submit_btn.click(
|
514 |
fn=chatbot_function,
|
515 |
inputs=[user_input, mood, conversation_mode, region, state],
|
516 |
-
outputs=[chatbot, state]
|
|
|
517 |
)
|
518 |
user_input.submit(
|
519 |
fn=chatbot_function,
|
@@ -548,7 +549,7 @@ with gr.Blocks(title="Mental Health Support Chatbot", css=custom_css, js=custom_
|
|
548 |
therapist.change(
|
549 |
fn=get_available_times,
|
550 |
inputs=therapist,
|
551 |
-
outputs=schedule_output
|
552 |
)
|
553 |
schedule_btn.click(
|
554 |
fn=schedule_appointment,
|
@@ -557,9 +558,8 @@ with gr.Blocks(title="Mental Health Support Chatbot", css=custom_css, js=custom_
|
|
557 |
)
|
558 |
|
559 |
gr.Markdown("""
|
560 |
-
|
561 |
-
|
562 |
-
- [National Suicide Prevention Lifeline](https://suicidepreventionlifeline.org/)
|
563 |
- [MentalHealth.gov](https://www.mentalhealth.gov/)
|
564 |
- [Crisis Text Line](https://www.crisistextline.org/)
|
565 |
""")
|
|
|
14 |
import re
|
15 |
import json
|
16 |
|
17 |
+
# Configure Gemini API
|
18 |
genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
|
19 |
|
20 |
+
# Gmail API configuration
|
21 |
GMAIL_ADDRESS = os.getenv("GMAIL_ADDRESS")
|
22 |
GMAIL_TOKEN_JSON = os.getenv("GMAIL_TOKEN_JSON")
|
23 |
|
|
|
27 |
creds = Credentials.from_authorized_user_info(json.loads(GMAIL_TOKEN_JSON))
|
28 |
return build("gmail", "v1", credentials=creds)
|
29 |
except Exception as e:
|
30 |
+
return None, f"Failed to initialize Gmail API: {str(e)}"
|
31 |
|
32 |
# Coping Strategies Library
|
33 |
coping_strategies = {
|
|
|
106 |
|
107 |
history = state["chat_history"]
|
108 |
|
109 |
+
if not message.strip():
|
110 |
+
return "Please enter a message.", state
|
111 |
+
|
112 |
try:
|
113 |
+
lang = detect(message)
|
114 |
except:
|
115 |
lang = "en"
|
116 |
|
117 |
+
if mood and mood != "Select mood":
|
118 |
history.append([f"I'm feeling {mood.lower()}.", None])
|
119 |
|
120 |
history.append([message, None])
|
|
|
137 |
try:
|
138 |
response = model.generate_content(prompt)
|
139 |
response_text = response.text
|
140 |
+
except Exception as e:
|
141 |
+
response_text = f"I'm here for you, but something went wrong: {str(e)}. Please try again."
|
142 |
|
143 |
+
if mood and mood != "Select mood":
|
144 |
mood_key = mood.lower()
|
145 |
if mood_key in coping_strategies:
|
146 |
strategy = random.choice(coping_strategies[mood_key])
|
147 |
response_text += f"\n\n**Coping Strategy**: {strategy}"
|
148 |
|
149 |
region_key = region if region in regional_resources else "Global"
|
150 |
+
resources = "\n\n**Resources**:\n" + "\n".join(regional_resources[region_key])
|
151 |
response_text += resources
|
152 |
|
153 |
history[-1][1] = response_text
|
|
|
169 |
|
170 |
# Mood journal function
|
171 |
def log_mood(mood, state):
|
172 |
+
if mood and mood != "Select mood":
|
173 |
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
174 |
state["mood_journal"].append({"timestamp": timestamp, "mood": mood.lower()})
|
175 |
+
return "Mood logged!", state
|
176 |
+
return "Please select a mood.", state
|
177 |
|
178 |
# Mood trend visualization
|
179 |
def show_mood_trends(state):
|
180 |
if not state["mood_journal"]:
|
181 |
return "No moods logged yet.", state
|
182 |
df = pd.DataFrame(state["mood_journal"])
|
183 |
+
fig = px.line(df, x="timestamp", y="mood", title="Mood Trends", markers=True)
|
184 |
return fig, state
|
185 |
|
186 |
# Feedback function
|
187 |
def submit_feedback(feedback_text, rating, state):
|
188 |
if feedback_text or rating:
|
189 |
state["feedback"].append({"text": feedback_text, "rating": rating, "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")})
|
190 |
+
return "Feedback submitted!", state
|
191 |
return "Please provide feedback or a rating.", state
|
192 |
|
193 |
# Emergency resources
|
|
|
202 |
# Get available times for selected therapist
|
203 |
def get_available_times(therapist):
|
204 |
if therapist and therapist in therapists:
|
205 |
+
return therapists[therapist]["times"], f"Available times for {therapist} loaded."
|
206 |
+
return [], "Please select a therapist."
|
207 |
|
208 |
# Create MIME message for Gmail API
|
209 |
def create_message(to, subject, message_text):
|
|
|
249 |
"""
|
250 |
user_message = create_message(user_email, "Appointment Confirmation", user_body)
|
251 |
|
252 |
+
service, error = get_gmail_service()
|
253 |
+
if not service:
|
254 |
+
state["failed_emails"].append({
|
255 |
+
"therapist_email": {"to": therapist_email, "subject": "New Appointment", "body": therapist_body},
|
256 |
+
"user_email": {"to": user_email, "subject": "Appointment Confirmation", "body": user_body},
|
257 |
+
"error": error,
|
258 |
+
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
259 |
+
})
|
260 |
+
return False, error
|
261 |
+
|
262 |
try:
|
263 |
+
service.users().messages().send(userId="me", body=therapist_message).execute()
|
264 |
+
service.users().messages().send(userId="me", body=user_message).execute()
|
|
|
265 |
return True, ""
|
266 |
except HttpError as e:
|
267 |
error_msg = f"Gmail API error: {str(e)}"
|
|
|
287 |
if not therapist or therapist not in therapists:
|
288 |
return "Please select a therapist.", state
|
289 |
if not time_slot:
|
290 |
+
return "Please select a time slot.", state
|
291 |
if not date:
|
292 |
return "Please select a date.", state
|
293 |
if not user_email or not re.match(r"[^@]+@[^@]+\.[^@]+", user_email):
|
294 |
+
return "Please enter a valid email.", state
|
295 |
|
296 |
try:
|
297 |
appointment_date = datetime.strptime(date, "%Y-%m-%d")
|
298 |
if appointment_date < datetime.now():
|
299 |
return "Please select a future date.", state
|
300 |
except ValueError:
|
301 |
+
return "Invalid date format (use YYYY-MM-DD).", state
|
302 |
|
303 |
try:
|
304 |
appointment_time = datetime.strptime(time_slot, "%H:%M").strftime("%H:%M")
|
305 |
if appointment_time not in therapists[therapist]["times"]:
|
306 |
return f"Time {appointment_time} is not available for {therapist}.", state
|
307 |
except ValueError:
|
308 |
+
return "Invalid time format (use HH:MM).", state
|
309 |
|
310 |
appointment = {
|
311 |
"therapist": therapist,
|
|
|
319 |
therapist_email = therapists[therapist]["email"]
|
320 |
success, error_msg = send_emails(therapist, appointment_time, date, user_email, therapist_email, state)
|
321 |
if success:
|
322 |
+
return f"Appointment booked with {therapist} on {date} at {appointment_time}. Emails sent!", state
|
323 |
else:
|
324 |
return (f"Appointment booked with {therapist} on {date} at {appointment_time}. "
|
325 |
+
f"Email sending failed: {error_msg}. Please contact {therapist_email}."), state
|
|
|
|
|
326 |
|
327 |
+
# Custom CSS for clean UI
|
328 |
custom_css = """
|
|
|
329 |
body {
|
330 |
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
|
331 |
+
background: #f5f7fa;
|
332 |
+
color: #1a202c;
|
333 |
}
|
334 |
|
|
|
335 |
.gradio-container {
|
336 |
+
max-width: 800px;
|
337 |
+
margin: 20px auto;
|
338 |
+
padding: 24px;
|
339 |
+
background: #ffffff;
|
340 |
+
border-radius: 12px;
|
341 |
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
342 |
}
|
343 |
|
|
|
344 |
h1 {
|
345 |
+
font-size: 1.8em;
|
346 |
+
color: #2d3748;
|
347 |
text-align: center;
|
348 |
+
margin-bottom: 16px;
|
349 |
}
|
350 |
|
351 |
h2, h3 {
|
352 |
+
color: #4a5568;
|
353 |
}
|
354 |
|
|
|
355 |
input, select, textarea {
|
356 |
+
border: 1px solid #e2e8f0 !important;
|
357 |
+
border-radius: 6px !important;
|
358 |
+
padding: 8px !important;
|
359 |
+
font-size: 1em !important;
|
360 |
+
width: 100% !important;
|
361 |
+
box-sizing: border-box;
|
362 |
}
|
363 |
|
364 |
input:focus, select:focus, textarea:focus {
|
365 |
+
border-color: #3182ce !important;
|
366 |
outline: none;
|
367 |
+
box-shadow: 0 0 0 2px rgba(49, 130, 206, 0.2);
|
368 |
}
|
369 |
|
370 |
button {
|
371 |
+
background: #3182ce !important;
|
372 |
+
color: #ffffff !important;
|
373 |
border: none !important;
|
374 |
+
border-radius: 6px !important;
|
375 |
+
padding: 10px 20px !important;
|
376 |
+
font-size: 1em !important;
|
377 |
+
cursor: pointer;
|
378 |
+
transition: background 0.2s;
|
379 |
}
|
380 |
|
381 |
button:hover {
|
382 |
+
background: #2b6cb0 !important;
|
|
|
383 |
}
|
384 |
|
|
|
385 |
textarea[readonly] {
|
386 |
+
background: #edf2f7 !important;
|
387 |
+
border-radius: 6px !important;
|
388 |
+
padding: 12px !important;
|
389 |
+
font-size: 1em;
|
390 |
}
|
391 |
|
|
|
392 |
#appointment-section .gr-box {
|
393 |
+
background: #f7fafc !important;
|
394 |
+
border-radius: 8px !important;
|
395 |
+
padding: 16px !important;
|
396 |
}
|
397 |
|
398 |
+
#date-picker, #time-picker {
|
|
|
399 |
width: 100%;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
400 |
}
|
401 |
|
|
|
402 |
@media (max-width: 600px) {
|
403 |
.gradio-container {
|
404 |
+
padding: 16px;
|
405 |
+
margin: 10px;
|
406 |
}
|
407 |
button {
|
408 |
+
padding: 8px 16px !important;
|
409 |
}
|
410 |
}
|
411 |
"""
|
412 |
|
413 |
+
# JavaScript for date/time pickers
|
414 |
custom_js = """
|
415 |
document.addEventListener('DOMContentLoaded', function() {
|
416 |
+
try {
|
417 |
+
const dateInput = document.querySelector('#date-picker input');
|
418 |
+
if (dateInput) {
|
419 |
+
dateInput.type = 'date';
|
420 |
+
dateInput.placeholder = 'YYYY-MM-DD';
|
421 |
+
}
|
422 |
+
|
423 |
+
const timeInput = document.querySelector('#time-picker input');
|
424 |
+
if (timeInput) {
|
425 |
+
timeInput.type = 'time';
|
426 |
+
timeInput.step = '1800';
|
427 |
+
timeInput.placeholder = 'HH:MM';
|
428 |
+
}
|
429 |
+
} catch (e) {
|
430 |
+
console.error('Picker initialization failed:', e);
|
431 |
}
|
432 |
});
|
433 |
"""
|
|
|
436 |
with gr.Blocks(title="Mental Health Support Chatbot", css=custom_css, js=custom_js) as demo:
|
437 |
state = gr.State({"chat_history": [], "mood_journal": [], "feedback": [], "appointments": [], "failed_emails": []})
|
438 |
|
439 |
+
gr.Markdown("## Mental Health Support Chatbot")
|
440 |
+
gr.Markdown("A safe space to share your feelings and access support.")
|
441 |
|
442 |
with gr.Row():
|
443 |
+
with gr.Column(scale=1):
|
444 |
mood = gr.Dropdown(
|
445 |
+
choices=["Select mood", "Happy", "Sad", "Anxious", "Stressed", "Other"],
|
446 |
+
label="Mood",
|
447 |
+
value="Select mood"
|
448 |
)
|
449 |
conversation_mode = gr.Radio(
|
450 |
choices=["Neutral", "Calm", "Motivational"],
|
451 |
+
label="Style",
|
452 |
value="Neutral"
|
453 |
)
|
454 |
region = gr.Dropdown(
|
455 |
choices=["USA", "India", "UK", "Global"],
|
456 |
+
label="Region",
|
457 |
value="Global"
|
458 |
)
|
459 |
+
with gr.Column(scale=2):
|
460 |
chatbot = gr.Textbox(
|
461 |
+
label="Chat",
|
462 |
value="",
|
463 |
interactive=False,
|
464 |
+
lines=10,
|
465 |
show_copy_button=True
|
466 |
)
|
467 |
user_input = gr.Textbox(
|
468 |
+
placeholder="Type your message...",
|
469 |
+
label="Message",
|
470 |
lines=2
|
471 |
)
|
472 |
with gr.Row():
|
473 |
submit_btn = gr.Button("Send")
|
474 |
+
clear_btn = gr.Button("Clear")
|
475 |
|
476 |
+
emergency_btn = gr.Button("Crisis Support")
|
477 |
emergency_output = gr.Markdown("")
|
478 |
|
479 |
with gr.Accordion("Mood Journal"):
|
480 |
log_mood_btn = gr.Button("Log Mood")
|
481 |
+
mood_log_output = gr.Textbox(label="Status", interactive=False)
|
482 |
+
mood_trend_btn = gr.Button("View Trends")
|
483 |
mood_trend_output = gr.Plot()
|
484 |
|
485 |
+
with gr.Accordion("Feedback"):
|
486 |
+
feedback_text = gr.Textbox(label="Feedback", placeholder="Your thoughts...")
|
487 |
+
feedback_rating = gr.Slider(minimum=1, maximum=5, step=1, label="Rating")
|
488 |
+
feedback_btn = gr.Button("Submit")
|
489 |
+
feedback_output = gr.Textbox(label="Status", interactive=False)
|
490 |
|
491 |
with gr.Accordion("Schedule Appointment", elem_id="appointment-section"):
|
492 |
therapist = gr.Dropdown(
|
493 |
choices=list(therapists.keys()),
|
494 |
+
label="Therapist"
|
495 |
)
|
496 |
date = gr.Textbox(
|
497 |
+
label="Date",
|
498 |
+
placeholder="YYYY-MM-DD",
|
499 |
elem_id="date-picker"
|
500 |
)
|
501 |
+
time_slot = gr.Dropdown(
|
502 |
+
choices=[],
|
503 |
+
label="Time",
|
504 |
+
interactive=True
|
505 |
)
|
506 |
user_email = gr.Textbox(
|
507 |
+
label="Email",
|
508 |
+
placeholder="[email protected]"
|
509 |
)
|
510 |
+
schedule_btn = gr.Button("Book")
|
511 |
+
schedule_output = gr.Textbox(label="Status", interactive=False)
|
512 |
|
513 |
submit_btn.click(
|
514 |
fn=chatbot_function,
|
515 |
inputs=[user_input, mood, conversation_mode, region, state],
|
516 |
+
outputs=[chatbot, state],
|
517 |
+
_js="() => { return true; }"
|
518 |
)
|
519 |
user_input.submit(
|
520 |
fn=chatbot_function,
|
|
|
549 |
therapist.change(
|
550 |
fn=get_available_times,
|
551 |
inputs=therapist,
|
552 |
+
outputs=[time_slot, schedule_output]
|
553 |
)
|
554 |
schedule_btn.click(
|
555 |
fn=schedule_appointment,
|
|
|
558 |
)
|
559 |
|
560 |
gr.Markdown("""
|
561 |
+
**Resources:**
|
562 |
+
- [Suicide Prevention Lifeline](https://suicidepreventionlifeline.org/)
|
|
|
563 |
- [MentalHealth.gov](https://www.mentalhealth.gov/)
|
564 |
- [Crisis Text Line](https://www.crisistextline.org/)
|
565 |
""")
|