Spaces:
Sleeping
Sleeping
File size: 65,258 Bytes
3f0c152 e7afd1c |
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 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 |
# ==================== STREAMLIT CONFIG (MUST BE FIRST) ====================
import streamlit as st
st.set_page_config(
page_title="MindSync AI ⭐",
page_icon="🌈",
layout="wide"
)
# ==================== IMPORTS ====================
import json, os, faiss, bcrypt, datetime
import numpy as np
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import cv2
import pyttsx3
import threading
import tempfile
import time
from PIL import Image
import speech_recognition as sr
from deepface import DeepFace
# Local imports
import phase2_enhancements as phase2
import phase3_intervention as phase3
from _virtual_chat import virtual_chat_mode, save_session_to_mongo
from enhanced_rag_system import EnhancedRAGSystem, get_enhanced_response
from db import get_db
from hf_llm import generate_with_hf
# ==================== Database ====================
db = get_db()
# ==================== MENTAL HEALTH CONDITIONS ====================
MENTAL_HEALTH_CONDITIONS = {
"anxiety": {
"name": "Anxiety Disorders",
"icon": "😰",
"color": "#FF6B6B",
"description": "Excessive worry, fear, or nervousness that interferes with daily activities.",
"symptoms": [
"Persistent worrying or anxiety",
"Restlessness or feeling on edge",
"Difficulty concentrating",
"Muscle tension",
"Sleep disturbances",
"Rapid heartbeat or sweating",
"Avoiding situations that trigger anxiety"
],
"types": [
"Generalized Anxiety Disorder (GAD)",
"Social Anxiety Disorder",
"Panic Disorder",
"Specific Phobias",
"Separation Anxiety"
],
"non_medical_interventions": {
"breathing_techniques": {
"title": "Breathing & Relaxation",
"exercises": [
{
"name": "4-7-8 Breathing",
"description": "Inhale for 4 seconds, hold for 7, exhale for 8",
"duration": "5-10 minutes",
"best_for": "Quick calm during panic"
},
{
"name": "Box Breathing",
"description": "Inhale 4s → Hold 4s → Exhale 4s → Hold 4s",
"duration": "5 minutes",
"best_for": "Pre-stressful situations"
}
]
}
},
"when_to_seek_help": [
"Anxiety interferes with work, school, or relationships",
"You avoid many situations due to anxiety",
"Physical symptoms are severe (chest pain, dizziness)"
],
"success_stories": [
"Sarah, 28: 'I used the exposure hierarchy to overcome my social anxiety. Started with ordering coffee, now I give presentations at work!'"
]
},
"depression": {
"name": "Depression",
"icon": "😔",
"color": "#4A90E2",
"description": "Persistent feelings of sadness, hopelessness, and loss of interest in activities.",
"symptoms": [
"Persistent sad, empty, or hopeless mood",
"Loss of interest in activities once enjoyed",
"Changes in appetite or weight",
"Sleep problems (too much or too little)",
"Fatigue or loss of energy"
],
"types": [
"Major Depressive Disorder",
"Persistent Depressive Disorder (Dysthymia)",
"Seasonal Affective Disorder (SAD)"
],
"non_medical_interventions": {
"behavioral_activation": {
"title": "Behavioral Activation",
"exercises": [
{
"name": "Activity Scheduling",
"description": "Plan pleasurable and meaningful activities daily"
}
]
}
},
"when_to_seek_help": [
"Thoughts of suicide or self-harm",
"Unable to function in daily life"
],
"success_stories": [
"Priya, 31: 'Behavioral activation saved me. I forced myself to do one thing daily.'"
]
},
"stress": {
"name": "Chronic Stress",
"icon": "😫",
"color": "#F39C12",
"description": "Prolonged physical and emotional strain that can lead to burnout.",
"symptoms": [
"Feeling overwhelmed or unable to cope",
"Irritability or mood swings",
"Difficulty relaxing or 'switching off'"
],
"types": [
"Work-Related Stress",
"Academic Stress",
"Financial Stress"
],
"non_medical_interventions": {
"stress_management": {
"title": "Immediate Stress Relief",
"techniques": [
{
"name": "STOP Technique",
"steps": [
"S - Stop what you're doing",
"T - Take a breath (3 deep breaths)",
"O - Observe your thoughts, feelings",
"P - Proceed mindfully"
]
}
]
}
},
"when_to_seek_help": [
"Physical health declining",
"Burnout symptoms"
],
"success_stories": [
"David, 38: 'Implementing time blocking reduced my stress by 70%.'"
]
}
}
# ==================== ASSESSMENT QUESTIONS (15 each) ====================
ASSESSMENT_QUESTIONS = {
"anxiety": [
{"question": "Over the last 2 weeks, how often have you felt nervous, anxious, or on edge?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you been unable to stop or control worrying?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you been worrying too much about different things?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you had trouble relaxing?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you been so restless that it's hard to sit still?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you become easily annoyed or irritable?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you felt afraid as if something awful might happen?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you experienced heart racing or pounding?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you had trouble concentrating on things?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you experienced muscle tension or soreness?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you avoided situations because they make you anxious?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you had difficulty sleeping due to worry?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you felt like you're losing control?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you experienced sweating or trembling?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you had intrusive worrying thoughts?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]}
],
"depression": [
{"question": "Over the last 2 weeks, how often have you had little interest or pleasure in doing things?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you felt down, depressed, or hopeless?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you had trouble falling or staying asleep?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you felt tired or had little energy?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you had poor appetite or been overeating?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you felt bad about yourself or that you're a failure?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you had trouble concentrating on things?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you moved or spoken so slowly that others noticed?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you thought you would be better off dead?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you felt isolated or withdrawn from others?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you experienced unexplained crying spells?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you felt worthless or excessively guilty?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you lost interest in activities you used to enjoy?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you had difficulty making decisions?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]},
{"question": "How often have you felt like life isn't worth living?", "options": ["Not at all", "Several days", "More than half the days", "Nearly every day"], "scores": [0, 1, 2, 3]}
],
"stress": [
{"question": "In the last month, how often have you felt unable to control important things in your life?", "options": ["Never", "Almost never", "Sometimes", "Fairly often", "Very often"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you felt difficulties were piling up so high you could not overcome them?", "options": ["Never", "Almost never", "Sometimes", "Fairly often", "Very often"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you been upset because of something unexpected?", "options": ["Never", "Almost never", "Sometimes", "Fairly often", "Very often"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you felt nervous and stressed?", "options": ["Never", "Almost never", "Sometimes", "Fairly often", "Very often"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you felt confident about handling personal problems?", "options": ["Very often", "Fairly often", "Sometimes", "Almost never", "Never"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you felt things were going your way?", "options": ["Very often", "Fairly often", "Sometimes", "Almost never", "Never"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you found yourself unable to cope with all the things you had to do?", "options": ["Never", "Almost never", "Sometimes", "Fairly often", "Very often"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you been able to control irritations in your life?", "options": ["Very often", "Fairly often", "Sometimes", "Almost never", "Never"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you felt on top of things?", "options": ["Very often", "Fairly often", "Sometimes", "Almost never", "Never"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you been angered by things outside your control?", "options": ["Never", "Almost never", "Sometimes", "Fairly often", "Very often"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you felt overwhelmed by your responsibilities?", "options": ["Never", "Almost never", "Sometimes", "Fairly often", "Very often"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you had trouble relaxing?", "options": ["Never", "Almost never", "Sometimes", "Fairly often", "Very often"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you experienced physical symptoms of stress (headaches, stomach issues)?", "options": ["Never", "Almost never", "Sometimes", "Fairly often", "Very often"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you felt like you're constantly racing against time?", "options": ["Never", "Almost never", "Sometimes", "Fairly often", "Very often"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you had difficulty sleeping due to stress?", "options": ["Never", "Almost never", "Sometimes", "Fairly often", "Very often"], "scores": [0, 1, 2, 3, 4]}
],
"ptsd": [
{"question": "How often have you had unwanted upsetting memories of the traumatic event?", "options": ["Not at all", "A little bit", "Moderately", "Quite a bit", "Extremely"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you had nightmares about the traumatic event?", "options": ["Not at all", "A little bit", "Moderately", "Quite a bit", "Extremely"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you felt as if the traumatic event was happening again?", "options": ["Not at all", "A little bit", "Moderately", "Quite a bit", "Extremely"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you felt very upset when reminded of the traumatic event?", "options": ["Not at all", "A little bit", "Moderately", "Quite a bit", "Extremely"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you had strong physical reactions when reminded of the event?", "options": ["Not at all", "A little bit", "Moderately", "Quite a bit", "Extremely"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you avoided memories, thoughts, or feelings about the event?", "options": ["Not at all", "A little bit", "Moderately", "Quite a bit", "Extremely"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you avoided external reminders of the traumatic event?", "options": ["Not at all", "A little bit", "Moderately", "Quite a bit", "Extremely"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you had trouble remembering important parts of the event?", "options": ["Not at all", "A little bit", "Moderately", "Quite a bit", "Extremely"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you had strong negative beliefs about yourself or the world?", "options": ["Not at all", "A little bit", "Moderately", "Quite a bit", "Extremely"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you blamed yourself for the traumatic event?", "options": ["Not at all", "A little bit", "Moderately", "Quite a bit", "Extremely"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you had strong negative feelings (fear, horror, anger, guilt, shame)?", "options": ["Not at all", "A little bit", "Moderately", "Quite a bit", "Extremely"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you lost interest in activities you used to enjoy?", "options": ["Not at all", "A little bit", "Moderately", "Quite a bit", "Extremely"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you felt distant or cut off from other people?", "options": ["Not at all", "A little bit", "Moderately", "Quite a bit", "Extremely"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you been irritable or aggressive?", "options": ["Not at all", "A little bit", "Moderately", "Quite a bit", "Extremely"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often have you been overly alert or on guard?", "options": ["Not at all", "A little bit", "Moderately", "Quite a bit", "Extremely"], "scores": [0, 1, 2, 3, 4]}
],
"insomnia": [
{"question": "How often do you have difficulty falling asleep?", "options": ["Never", "Rarely", "Sometimes", "Often", "Always"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often do you wake up during the night?", "options": ["Never", "Rarely", "Sometimes", "Often", "Always"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often do you wake up too early and can't go back to sleep?", "options": ["Never", "Rarely", "Sometimes", "Often", "Always"], "scores": [0, 1, 2, 3, 4]},
{"question": "How satisfied are you with your current sleep pattern?", "options": ["Very satisfied", "Satisfied", "Neutral", "Dissatisfied", "Very dissatisfied"], "scores": [0, 1, 2, 3, 4]},
{"question": "How noticeable is your sleep problem to others?", "options": ["Not noticeable", "Barely noticeable", "Somewhat noticeable", "Very noticeable", "Extremely noticeable"], "scores": [0, 1, 2, 3, 4]},
{"question": "How worried are you about your sleep problem?", "options": ["Not worried", "A little worried", "Somewhat worried", "Very worried", "Extremely worried"], "scores": [0, 1, 2, 3, 4]},
{"question": "How much does your sleep problem interfere with daily functioning?", "options": ["Not at all", "A little", "Somewhat", "Much", "Very much"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often do you feel tired during the day?", "options": ["Never", "Rarely", "Sometimes", "Often", "Always"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often do you use sleep medication or aids?", "options": ["Never", "Rarely", "Sometimes", "Often", "Always"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often do you have difficulty concentrating due to lack of sleep?", "options": ["Never", "Rarely", "Sometimes", "Often", "Always"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often do you feel irritable due to poor sleep?", "options": ["Never", "Rarely", "Sometimes", "Often", "Always"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often does lack of sleep affect your mood?", "options": ["Never", "Rarely", "Sometimes", "Often", "Always"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often do you worry about not being able to sleep?", "options": ["Never", "Rarely", "Sometimes", "Often", "Always"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often do you feel unrefreshed after sleep?", "options": ["Never", "Rarely", "Sometimes", "Often", "Always"], "scores": [0, 1, 2, 3, 4]},
{"question": "How often does poor sleep affect your work or social life?", "options": ["Never", "Rarely", "Sometimes", "Often", "Always"], "scores": [0, 1, 2, 3, 4]}
]
}
# ==================== DeepFace Check ====================
try:
from deepface import DeepFace
DEEPFACE_AVAILABLE = True
except ImportError:
DEEPFACE_AVAILABLE = False
# ==================== Database / RAG ====================
# @st.cache_resource
# def load_emotion_model():
# return pipeline("text-classification", model="j-hartmann/emotion-english-distilroberta-base", return_all_scores=True)
@st.cache_resource
def init_enhanced_rag():
return EnhancedRAGSystem(rag_directory="rag_knowledges")
#embedder, index, rag_inputs, rag_outputs = load_rag()
# emotion_classifier = load_emotion_model()
enhanced_rag= init_enhanced_rag()
#users_col, sessions_col, assessments_col = db["users"], db["sessions"], db["assessments"]
users_col, sessions_col, assessments_col = db["users"], db["sessions"], db["assessments"]
reminders_col = db["reminders"]
CRISIS_KEYWORDS = ["suicide", "kill myself", "end my life", "i want to die", "self harm","i don't want to live","i can't go on"]
# Initialize RAG
enhanced_rag = init_enhanced_rag()
# ==================== TTS Engine ====================
class TTSEngine:
def __init__(self):
try:
self.engine = pyttsx3.init()
self.engine.setProperty('rate', 150)
self.engine.setProperty('volume', 0.9)
self.available = True
except:
self.available = False
def speak(self, text):
if not self.available:
return
threading.Thread(target=lambda: self.engine.say(text) or self.engine.runAndWait(), daemon=True).start()
tts_engine = TTSEngine()
# ==================== Helpers ====================
def create_user(u, p,gender=None):
if users_col.find_one({"username": u}):
return False
hashed = bcrypt.hashpw(p.encode(), bcrypt.gensalt())
users_col.insert_one({"username": u, "password": hashed,"gender": gender, "created_at": datetime.datetime.utcnow()})
return True
def verify_user(u, p):
user = users_col.find_one({"username": u})
return bcrypt.checkpw(p.encode(), user["password"]) if user else False
def detect_text_emotion(text: str):
text = text.lower()
if any(w in text for w in ["happy", "joy", "excited", "amazing", "great"]):
return "joy", 0.9
elif any(w in text for w in ["sad", "down", "cry", "tired"]):
return "sadness", 0.9
elif any(w in text for w in ["angry", "frustrated", "mad"]):
return "anger", 0.9
elif any(w in text for w in ["fear", "panic", "afraid"]):
return "fear", 0.9
else:
return "neutral", 0.5
if confidence > 0.8:
return emotion, confidence
# Fallback to transformer model for uncertain cases
try:
res = emotion_classifier(text)[0]
best_emotion = max(res, key=lambda x: x["score"])
return best_emotion["label"], best_emotion["score"]
except:
return emotion, confidence
# def retrieve_answer(query, emotion=None):
# """Enhanced RAG retrieval with emotion-aware responses and motivational content"""
# # First try RAG knowledge base
# if rag_inputs and index is not None:
# try:
# q_emb = embedder.encode([query], convert_to_numpy=True)
# distances, indices = index.search(q_emb, 3) # Get top 3 matches
# # Get the best match
# best_match_idx = indices[0][0]
# best_distance = distances[0][0]
# # If distance is reasonable (similar enough), use RAG response
# if best_distance < 1.5: # Threshold for similarity
# base_response = rag_outputs[best_match_idx]
# # Enhance with emotion-specific motivation
# enhanced_response = enhance_response_with_motivation(base_response, emotion, query)
# return enhanced_response
# except:
# pass
# # Fallback: Generate contextual response based on emotion and keywords
# return generate_contextual_response(query, emotion)
def retrieve_answer(user_input, emotion):
rag_result = enhanced_rag.retrieve_response(user_input, emotion, top_k=3)
if rag_result and rag_result["confidence"] > 0.65:
return rag_result["combined"]
prompt = f"""
You are an empathetic mental health support assistant.
User emotion: {emotion}
User says: {user_input}
Respond calmly, safely, and supportively.
Do NOT provide medical diagnosis.
"""
return generate_with_hf(prompt)
def get_severity_level(condition, score, max_score):
"""Determine severity level based on score"""
percentage = (score / max_score) * 100
if percentage <= 33:
return "Minimal"
elif percentage <= 66:
return "Moderate"
else:
return "Severe"
EMOJI_MAP = {"joy":"😊","sadness":"😢","anger":"😠","fear":"😰","surprise":"😲","neutral":"😐"}
# ==================== Session State ====================
if 'authenticated' not in st.session_state:
st.session_state.authenticated = False
#if 'username' not in st.session_state:
#st.session_state.username = None
if "username" not in st.session_state:
st.session_state.username = "guest"
if 'chat_history' not in st.session_state:
st.session_state.chat_history = []
if 'virtual_chat_history' not in st.session_state:
st.session_state.virtual_chat_history = []
if "gender" not in st.session_state:
st.session_state.gender = None # Will be set after login
# ==================== Authentication Page ====================
def auth_page():
st.title("🧠 Welcome to MindSync AI")
st.subheader("Login / Register")
tab1, tab2 = st.tabs(["Login", "Register"])
with tab1:
u = st.text_input("Username", key="auth_user")
p = st.text_input("Password", type="password", key="auth_pass")
if st.button("Login"):
if verify_user(u, p):
st.session_state.authenticated = True
st.session_state.username = u
user_data = users_col.find_one({"username": u})
st.session_state.gender = user_data.get("gender", "👤") # Default if not stored
st.success(f"Welcome back! {st.session_state.gender} {st.session_state.username}")
if st.session_state.gender is None:
st.session_state.gender = st.radio("Select your gender:", ["👨 Male", "👩 Female"])
st.rerun()
else:
st.error("Invalid credentials")
with tab2:
ru = st.text_input("New Username", key="reg_user")
rp = st.text_input("New Password", type="password", key="reg_pass")
rpp = st.text_input("Confirm Password", type="password", key="reg_pass2")
gender = st.radio("Select your gender:", ["👨 Male", "👩 Female"])
if st.button("Register"):
if rp != rpp:
st.error("Passwords don't match")
elif create_user(ru, rp):
st.success("Registered! Please login now.")
else:
st.error("Username already exists")
# ==================== Reminder System ====================
# Initialize reminder tracking in session state
if 'last_reminder_check' not in st.session_state:
st.session_state.last_reminder_check = datetime.datetime.now() - datetime.timedelta(minutes=10)
if 'shown_reminders' not in st.session_state:
st.session_state.shown_reminders = set()
if 'reminder_dismiss' not in st.session_state:
st.session_state.reminder_dismiss = {}
def show_pending_reminders(username):
"""Show pending reminders as sidebar notifications"""
now = datetime.datetime.now()
# Only check every 5 minutes
time_since_check = (now - st.session_state.last_reminder_check).seconds
if time_since_check < 300:
return
st.session_state.last_reminder_check = now
try:
active_reminders = list(reminders_col.find({"username": username, "enabled": True}))
except:
return
if not active_reminders:
return
current_hour = now.hour
current_minute = now.minute
current_time_str = f"{current_hour}:{current_minute:02d}"
reminders_shown = []
for reminder in active_reminders:
reminder_type = reminder.get('type')
reminder_id = f"{reminder_type}_{current_time_str}"
if reminder_id in st.session_state.shown_reminders:
continue
dismiss_until = st.session_state.reminder_dismiss.get(reminder_id)
if dismiss_until and now < dismiss_until:
continue
if reminder_type == "checkin":
reminder_time = reminder.get('time', '20:00')
r_hour, r_minute = map(int, reminder_time.split(':'))
if r_hour == current_hour and abs(r_minute - current_minute) <= 5:
reminders_shown.append({
'id': reminder_id,
'title': '🔔 Mood Check-in Reminder',
'message': 'Time to log your mood! Head to Mood Journal.',
'color': 'warning'
})
elif reminder_type == "breathing":
frequency = reminder.get('frequency', 'Every 4 hours')
should_show = False
if frequency == "Every 2 hours":
should_show = current_hour % 2 == 0 and current_minute < 5
elif frequency == "Every 4 hours":
should_show = current_hour % 4 == 0 and current_minute < 5
elif frequency == "Twice daily":
should_show = current_hour in [9, 18] and current_minute < 5
if should_show:
reminders_shown.append({
'id': reminder_id,
'title': '🌬️ Breathing Exercise Reminder',
'message': 'Take 2 minutes for a breathing break!',
'color': 'info'
})
elif reminder_type == "goal":
frequency = reminder.get('frequency', 'Daily')
should_show = False
if frequency == "Daily":
should_show = current_hour == 9 and current_minute < 5
elif frequency == "Every 3 days":
day_of_year = now.timetuple().tm_yday
should_show = day_of_year % 3 == 0 and current_hour == 9 and current_minute < 5
elif frequency == "Weekly":
should_show = now.weekday() == 0 and current_hour == 9 and current_minute < 5
if should_show:
reminders_shown.append({
'id': reminder_id,
'title': '🎯 Goal Progress Check',
'message': 'Review your wellness goals today!',
'color': 'success'
})
if reminders_shown:
st.sidebar.markdown("---")
st.sidebar.markdown("### 🔔 Reminders")
for reminder in reminders_shown:
st.session_state.shown_reminders.add(reminder['id'])
if reminder['color'] == 'warning':
st.sidebar.warning(f"**{reminder['title']}**")
elif reminder['color'] == 'info':
st.sidebar.info(f"**{reminder['title']}**")
elif reminder['color'] == 'success':
st.sidebar.success(f"**{reminder['title']}**")
st.sidebar.caption(reminder['message'])
col1, col2 = st.sidebar.columns(2)
with col1:
if st.sidebar.button("✓ Got it", key=f"dismiss_{reminder['id']}", use_container_width=True):
st.rerun()
with col2:
if st.sidebar.button("⏰ Snooze", key=f"snooze_{reminder['id']}", use_container_width=True):
st.session_state.reminder_dismiss[reminder['id']] = now + datetime.timedelta(minutes=30)
st.rerun()
st.sidebar.markdown("---")
def clear_old_reminders():
"""Clear reminder tracking daily"""
now = datetime.datetime.now()
if 'last_reminder_reset' not in st.session_state:
st.session_state.last_reminder_reset = now.date()
if st.session_state.last_reminder_reset < now.date():
st.session_state.shown_reminders = set()
st.session_state.reminder_dismiss = {}
st.session_state.last_reminder_reset = now.date()
# def detect_text_emotion(text: str):
# text = text.lower()
# if any(w in text for w in ["happy", "joy", "excited", "amazing", "great"]):
# return "joy", 0.9
# elif any(w in text for w in ["sad", "down", "cry", "tired"]):
# return "sadness", 0.9
# elif any(w in text for w in ["angry", "frustrated", "mad"]):
# return "anger", 0.9
# elif any(w in text for w in ["fear", "panic", "afraid"]):
# return "fear", 0.9
# else:
# return "neutral", 0.5
# ==================== NOW UPDATE YOUR chat_page() FUNCTION ====================
def chat_page():
if st.session_state.authenticated:
clear_old_reminders()
show_pending_reminders(st.session_state.username)
# Sidebar
with st.sidebar:
#st.title(f"👤 {st.session_state.username}")
user_emoji = st.session_state.get("gender", "👤")
st.title(f"{st.session_state.gender} {st.session_state.username}")
st.markdown("---")
# Radio selection
selected_page = st.radio("📍 Navigate", [
"💬 Chat",
"🎥 Virtual Chat",
"📊 Analytics",
"ℹ️ Resources",
# Phase 2
"🗓️ Mood Journal",
"🎯 Goals",
"📚 Exercises",
"🏆 Achievements",
"🔔 Reminders",
# Phase 3
"🎯 Coping Plans",
"📚 Resource Library",
"🎮 Interactive Tools"
])
# Update session_state when selection changes
st.session_state.page = selected_page
if st.button("Logout"):
st.session_state.authenticated = False
st.session_state.username = None
st.session_state.chat_history = []
st.session_state.gender = None
st.session_state.virtual_chat_history = []
st.rerun()
# ------------------ Page Routing ------------------
page = st.session_state.page # always get latest selection
# Phase 3
if page in ["🎯 Coping Plans", "📚 Resource Library", "🎮 Interactive Tools"]:
phase3.phase3_main(st.session_state.username, page)
# Phase 2
elif page in ["🗓️ Mood Journal", "🎯 Goals", "📚 Exercises",
"🏆 Achievements", "🔔 Reminders"]:
phase2.phase2_main(st.session_state.username, page)
# Other pages
elif page == "💬 Chat":
chat_interface()
elif page == "🎥 Virtual Chat":
#virtual_chat_mode(st.session_state.username,detect_text_emotion_func=detect_text_emotion)
virtual_chat_mode(
username=st.session_state.username,
detect_text_emotion_func=detect_text_emotion,
retrieve_answer_func=retrieve_answer # Added this line
)
elif page == "📊 Analytics":
analytics_page()
elif page == "ℹ️ Resources":
resources_page()
# ==================== Text Chat ====================
def chat_interface():
st.title("💬 Text Chat")
for m in st.session_state.chat_history:
with st.chat_message(m['role']):
st.markdown(m['content'])
if 'emotion' in m and m['role'] == 'assistant':
st.caption(f"Detected emotion: {EMOJI_MAP.get(m['emotion'], '😐')} {m['emotion']}")
user_input = st.chat_input("Type your message here...")
if user_input:
text_emotion, _ = detect_text_emotion(user_input)
is_crisis = any(k in user_input.lower() for k in CRISIS_KEYWORDS)
if is_crisis:
bot_reply = """⚠️ I'm deeply concerned about what you're sharing. Your life matters.
🆘 **Please reach out immediately**:
- AASRA: 91-22-27546669 (24/7)
- Vandrevala Foundation: 1860-2662-345 (24/7)
- iCall: 022-25521111
You don't have to face this alone. These helplines have trained counselors ready to listen and support you right now.
Please also tell someone you trust - a family member, friend, or colleague. You matter more than you know. 💙"""
else:
# Use enhanced retrieval with emotion awareness
bot_reply = retrieve_answer(user_input, text_emotion)
sessions_col.insert_one({
"username": st.session_state.username,
"user_text": user_input,
"bot_text": bot_reply,
"emotion": text_emotion,
"timestamp": datetime.datetime.utcnow()
})
st.session_state.chat_history.append({'role': 'user', 'content': user_input})
st.session_state.chat_history.append({'role': 'assistant', 'content': bot_reply, 'emotion': text_emotion})
st.rerun()
# ==================== Virtual Chat with Face Emotion ====================
# ==================== Analytics Page ====================
def analytics_page():
st.title("📊 Analytics Dashboard")
username = st.session_state.username
# Tabs for different analytics
tab1, tab2, tab3 = st.tabs(["💬 Chat Analytics", "📝 Assessment Reports", "📈 Combined Insights"])
# ==================== TAB 1: CHAT ANALYTICS ====================
with tab1:
cutoff = datetime.datetime.utcnow() - datetime.timedelta(days=30)
sessions = list(sessions_col.find({"username": username, "timestamp": {"$gte": cutoff}}))
if not sessions:
st.info("💡 Start chatting to see your analytics!")
return
df = pd.DataFrame(sessions)
df['timestamp'] = pd.to_datetime(df['timestamp'])
df['date'] = df['timestamp'].dt.date
df['hour'] = df['timestamp'].dt.hour
df['emotion'] = df.apply(lambda x: x.get('final_emotion') or x.get('emotion', 'neutral'), axis=1)
# Key Metrics
st.subheader("📈 Chat Metrics")
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric("Total Messages", len(sessions))
with col2:
st.metric("Most Common Emotion", df['emotion'].mode()[0].title() if len(df['emotion'].mode()) > 0 else "N/A")
with col3:
st.metric("Days Active", df['date'].nunique())
with col4:
avg_conf = df['face_confidence'].mean() if 'face_confidence' in df.columns else 0
st.metric("Avg Face Confidence", f"{avg_conf:.1%}")
# Emotion trends over time
st.subheader("📈 Emotion Trends Over Time")
emotion_over_time = df.groupby(['date', 'emotion']).size().reset_index(name='count')
fig = px.line(
emotion_over_time,
x='date',
y='count',
color='emotion',
title="Daily Emotion Patterns",
markers=True
)
st.plotly_chart(fig, use_container_width=True)
# Emotion distribution pie chart
st.subheader("🥧 Emotion Distribution")
col1, col2 = st.columns(2)
with col1:
fig2 = go.Figure(data=[go.Pie(
labels=df['emotion'].value_counts().index,
values=df['emotion'].value_counts().values,
hole=0.3,
marker=dict(colors=px.colors.qualitative.Set3)
)])
fig2.update_layout(title="Overall Emotion Distribution")
st.plotly_chart(fig2, use_container_width=True)
with col2:
# Hourly activity heatmap
hourly_data = df.groupby('hour').size().reset_index(name='count')
fig3 = px.bar(
hourly_data,
x='hour',
y='count',
title="Activity by Hour of Day",
labels={'hour': 'Hour', 'count': 'Number of Messages'}
)
st.plotly_chart(fig3, use_container_width=True)
# Scatter Plot - Face Confidence vs Text Emotion
st.subheader("📊 Face Confidence vs Emotion Analysis")
if 'face_confidence' in df.columns and 'face_emotion' in df.columns:
# Create scatter plot
fig4 = px.scatter(
df,
x='timestamp',
y='face_confidence',
color='face_emotion',
size=[10]*len(df),
hover_data=['user_text', 'emotion'],
title="Face Emotion Confidence Over Time",
labels={'face_confidence': 'Confidence Level', 'timestamp': 'Time'}
)
fig4.update_traces(marker=dict(size=12, line=dict(width=1, color='DarkSlateGrey')))
fig4.update_layout(height=400)
st.plotly_chart(fig4, use_container_width=True)
# Additional scatter: Emotion correlation
st.subheader("🔄 Text vs Face Emotion Match")
df['emotion_match'] = df.apply(
lambda x: 'Match' if x.get('face_emotion') == x.get('emotion') else 'Mismatch',
axis=1
)
fig5 = px.scatter(
df,
x='face_confidence',
y=df.index,
color='emotion_match',
hover_data=['face_emotion', 'emotion', 'user_text'],
title="Face vs Text Emotion Correlation",
labels={'face_confidence': 'Face Confidence', 'y': 'Session Index'},
color_discrete_map={'Match': '#00CC96', 'Mismatch': '#EF553B'}
)
st.plotly_chart(fig5, use_container_width=True)
# Stats
match_rate = (df['emotion_match'] == 'Match').sum() / len(df) * 100
st.info(f"📊 Face-Text Emotion Match Rate: **{match_rate:.1f}%**")
else:
st.info("💡 Use Virtual Chat with face detection to see face confidence analytics!")
# Weekly emotion summary
st.subheader("📅 Weekly Emotion Summary")
df['week'] = df['timestamp'].dt.to_period('W').astype(str)
weekly_emotions = df.groupby(['week', 'emotion']).size().reset_index(name='count')
fig6 = px.bar(
weekly_emotions,
x='week',
y='count',
color='emotion',
title="Weekly Emotion Breakdown",
barmode='stack'
)
st.plotly_chart(fig6, use_container_width=True)
# ==================== TAB 2: ASSESSMENT REPORTS ====================
with tab2:
st.subheader("📝 Mental Health Assessment History")
# Fetch all assessments for user
assessments = list(assessments_col.find({"username": username}).sort("timestamp", -1))
if not assessments:
st.info("💡 Take assessments in the Resources section to see reports here!")
return
# Convert to DataFrame
df_assess = pd.DataFrame(assessments)
df_assess['timestamp'] = pd.to_datetime(df_assess['timestamp'])
df_assess['date'] = df_assess['timestamp'].dt.date
# Summary metrics
st.subheader("📊 Assessment Summary")
col1, col2, col3 = st.columns(3)
with col1:
st.metric("Total Assessments", len(assessments))
with col2:
conditions_tested = df_assess['condition'].nunique()
st.metric("Conditions Tested", conditions_tested)
with col3:
most_recent = df_assess.iloc[0]['timestamp'].strftime("%Y-%m-%d")
st.metric("Last Assessment", most_recent)
# Assessment scores over time
st.subheader("📈 Assessment Scores Over Time")
fig_scores = px.line(
df_assess,
x='date',
y='percentage',
color='condition',
markers=True,
title="Assessment Score Trends (Percentage)",
labels={'percentage': 'Score (%)', 'date': 'Date', 'condition': 'Condition'}
)
st.plotly_chart(fig_scores, use_container_width=True)
# Condition-wise breakdown
st.subheader("🧩 Condition-wise Assessment Scores")
for condition in df_assess['condition'].unique():
with st.expander(f"📊 {MENTAL_HEALTH_CONDITIONS[condition]['icon']} {MENTAL_HEALTH_CONDITIONS[condition]['name']}"):
condition_data = df_assess[df_assess['condition'] == condition].sort_values('timestamp')
if len(condition_data) > 0:
# Line chart for this condition
fig_cond = go.Figure()
fig_cond.add_trace(go.Scatter(
x=condition_data['date'],
y=condition_data['score'],
mode='lines+markers',
name='Score',
line=dict(color=MENTAL_HEALTH_CONDITIONS[condition]['color'], width=3),
marker=dict(size=10)
))
fig_cond.update_layout(
title=f"{MENTAL_HEALTH_CONDITIONS[condition]['name']} Progress",
xaxis_title="Date",
yaxis_title="Score",
height=300
)
st.plotly_chart(fig_cond, use_container_width=True)
# Latest assessment details
latest = condition_data.iloc[-1]
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric("Latest Score", f"{latest['score']}/{latest['max_score']}")
with col2:
st.metric("Percentage", f"{latest['percentage']:.1f}%")
with col3:
severity = get_severity_level(condition, latest['score'], latest['max_score'])
st.metric("Severity", severity)
with col4:
# Progress indicator
if len(condition_data) > 1:
prev_score = condition_data.iloc[-2]['percentage']
current_score = latest['percentage']
delta = current_score - prev_score
st.metric("Change", f"{delta:+.1f}%", delta=f"{delta:+.1f}%")
else:
st.metric("Assessments", "1")
# Historical table
st.markdown("##### Assessment History")
history_table = condition_data[['date', 'score', 'max_score', 'percentage']].copy()
history_table['percentage'] = history_table['percentage'].round(1).astype(str) + '%'
history_table.columns = ['Date', 'Score', 'Max Score', 'Percentage']
st.dataframe(history_table, use_container_width=True, hide_index=True)
# Overall severity heatmap
st.subheader("🌡️ Severity Heatmap")
severity_data = df_assess.pivot_table(
values='percentage',
index='condition',
columns='date',
aggfunc='mean'
)
fig_heatmap = px.imshow(
severity_data,
labels=dict(x="Date", y="Condition", color="Severity %"),
color_continuous_scale="RdYlGn_r",
title="Assessment Severity Over Time"
)
st.plotly_chart(fig_heatmap, use_container_width=True)
# ==================== TAB 3: COMBINED INSIGHTS ====================
with tab3:
st.subheader("📈 Combined Mental Health Insights")
# Check if we have both chat and assessment data
if not sessions:
st.info("💡 No chat data available yet!")
return
if not assessments:
st.info("💡 No assessment data available yet!")
return
st.markdown("""
This section combines your chat emotions with assessment scores to provide comprehensive insights.
""")
# Emotion vs Assessment correlation
st.subheader("🔗 Emotion Patterns vs Assessment Scores")
# Get dominant emotions per day
df_emotions_daily = df.groupby(['date', 'emotion']).size().reset_index(name='count')
dominant_emotion_per_day = df_emotions_daily.loc[df_emotions_daily.groupby('date')['count'].idxmax()]
# Merge with assessments
df_merged = pd.merge(
df_assess[['date', 'condition', 'percentage']],
dominant_emotion_per_day[['date', 'emotion']],
on='date',
how='left'
)
# **FIX: Remove rows with NaN values in percentage or emotion**
df_merged = df_merged.dropna(subset=['percentage', 'emotion'])
if not df_merged.empty:
fig_combined = px.scatter(
df_merged,
x='date',
y='percentage',
color='emotion',
size=[10]*len(df_merged),
hover_data=['condition'],
title="Assessment Scores vs Daily Dominant Emotion",
labels={'percentage': 'Assessment Score (%)', 'date': 'Date'}
)
st.plotly_chart(fig_combined, use_container_width=True)
else:
st.info("💡 No overlapping data between chat emotions and assessments on the same days yet!")
# Wellness Score
st.subheader("💯 Overall Wellness Score")
# Calculate wellness score (inverted assessment scores + positive emotion ratio)
avg_assessment_score = df_assess['percentage'].mean()
positive_emotions = ['joy', 'surprise']
positive_ratio = (df['emotion'].isin(positive_emotions).sum() / len(df)) * 100
wellness_score = ((100 - avg_assessment_score) + positive_ratio) / 2
col1, col2, col3 = st.columns(3)
with col1:
st.metric("Wellness Score", f"{wellness_score:.1f}/100")
with col2:
st.metric("Positive Emotion %", f"{positive_ratio:.1f}%")
with col3:
st.metric("Avg Assessment Score", f"{avg_assessment_score:.1f}%")
# Gauge chart for wellness score
fig_gauge = go.Figure(go.Indicator(
mode="gauge+number+delta",
value=wellness_score,
domain={'x': [0, 1], 'y': [0, 1]},
title={'text': "Overall Wellness Score"},
gauge={
'axis': {'range': [None, 100]},
'bar': {'color': "darkblue"},
'steps': [
{'range': [0, 33], 'color': "lightcoral"},
{'range': [33, 66], 'color': "lightyellow"},
{'range': [66, 100], 'color': "lightgreen"}
],
'threshold': {
'line': {'color': "red", 'width': 4},
'thickness': 0.75,
'value': 90
}
}
))
st.plotly_chart(fig_gauge, use_container_width=True)
# Recommendations
st.subheader("💡 Personalized Recommendations")
if wellness_score >= 70:
st.success("""
🌟 **Great job!** Your mental health metrics are positive!
- Keep up your healthy routines
- Continue social connections
- Maintain work-life balance
""")
elif wellness_score >= 40:
st.warning("""
⚠️ **Room for improvement**
- Increase physical activity (30 min daily)
- Practice daily mindfulness or meditation
- Strengthen social connections
- Consider self-help resources in the app
""")
else:
st.error("""
🆘 **Attention needed**
- Your metrics suggest you may be struggling
- Strongly consider professional mental health support
- Use crisis helplines if in distress
- Implement daily self-care routines
- Reach out to trusted friends/family
""")
# Download report button
if st.button("📥 Download Full Report (CSV)"):
# Combine data for download
report_data = {
'Chat Sessions': len(sessions),
'Assessments Taken': len(assessments),
'Wellness Score': wellness_score,
'Positive Emotion %': positive_ratio,
'Average Assessment Score': avg_assessment_score
}
st.download_button(
label="Download Report",
data=str(report_data),
file_name=f"mental_health_report_{username}_{datetime.datetime.now().strftime('%Y%m%d')}.txt",
mime="text/plain"
)
# ==================== Resources Page with Quizzes ====================
def resources_page():
st.title("ℹ️ Mental Health Resources")
tab1, tab2, tab3 = st.tabs(["🆘 Crisis Helplines", "📝 Self-Assessments", "💡 Self-Help"])
with tab1:
st.subheader("🆘 Crisis Helplines (India)")
helplines = {
"AASRA": "91-22-27546669",
"Vandrevala Foundation": "1860-2662-345",
"iCall": "022-25521111",
"Snehi": "91-22-27546669"
}
for org, contact in helplines.items():
st.info(f"**{org}**: {contact}")
with tab2:
st.subheader("📝 Mental Health Self-Assessments")
condition = st.selectbox(
"Select a condition to assess:",
list(MENTAL_HEALTH_CONDITIONS.keys()),
format_func=lambda x: MENTAL_HEALTH_CONDITIONS[x]["name"]
)
data = MENTAL_HEALTH_CONDITIONS[condition]
st.markdown(f"## {data['icon']} {data['name']}")
st.markdown(data["description"])
with st.expander("📋 View Symptoms & Types"):
col1, col2 = st.columns(2)
with col1:
st.markdown("### Symptoms")
for s in data["symptoms"]:
st.write(f"• {s}")
with col2:
st.markdown("### Types")
for t in data["types"]:
st.write(f"• {t}")
# Assessment Quiz
if condition in ASSESSMENT_QUESTIONS:
st.markdown("---")
st.subheader(f"📝 {data['name']} Assessment Quiz (15 Questions)")
st.info("💡 This comprehensive assessment helps identify symptoms. Answer honestly for accurate results.")
questions = ASSESSMENT_QUESTIONS[condition]
total_score = 0
max_score = sum([max(q["scores"]) for q in questions])
# Use form for better UX
with st.form(key=f"quiz_form_{condition}"):
for idx, q in enumerate(questions):
st.markdown(f"**Question {idx + 1}/15:**")
choice = st.radio(
q["question"],
q["options"],
key=f"{condition}_q{idx}"
)
score_index = q["options"].index(choice)
total_score += q["scores"][score_index]
submitted = st.form_submit_button("📊 Submit & View Results")
if submitted:
# Calculate percentage
percentage = (total_score / max_score) * 100
# Save to database
assessment_record = {
"username": st.session_state.username,
"condition": condition,
"score": total_score,
"max_score": max_score,
"percentage": percentage,
"timestamp": datetime.datetime.utcnow()
}
assessments_col.insert_one(assessment_record)
st.markdown("---")
st.markdown(f"### 📊 Your Assessment Results")
# Score display
col1, col2, col3 = st.columns(3)
with col1:
st.metric("Total Score", f"{total_score}/{max_score}")
with col2:
st.metric("Percentage", f"{percentage:.1f}%")
with col3:
severity = get_severity_level(condition, total_score, max_score)
st.metric("Severity", severity)
# Progress bar
st.progress(total_score / max_score)
# Interpretation based on condition
st.markdown("### 🔍 Interpretation")
if condition == "anxiety":
if total_score <= 15:
st.success("🟢 **Minimal Anxiety** - You're experiencing low levels of anxiety.")
recommendation = "Continue healthy habits like exercise, good sleep, and stress management."
elif total_score <= 30:
st.warning("🟡 **Mild to Moderate Anxiety** - You're experiencing noticeable anxiety symptoms.")
recommendation = "Consider self-help strategies, breathing exercises, and lifestyle changes. Monitor your symptoms."
else:
st.error("🔴 **Moderate to Severe Anxiety** - You're experiencing significant anxiety that may be interfering with daily life.")
recommendation = "Strongly consider consulting a mental health professional. Self-help strategies can supplement professional treatment."
elif condition == "depression":
if total_score <= 15:
st.success("🟢 **Minimal Depression** - You're experiencing few depressive symptoms.")
recommendation = "Maintain healthy routines, social connections, and activities you enjoy."
elif total_score <= 30:
st.warning("🟡 **Mild to Moderate Depression** - You're experiencing noticeable depressive symptoms.")
recommendation = "Try behavioral activation, regular exercise, and social engagement. Consider therapy if symptoms persist."
else:
st.error("🔴 **Moderate to Severe Depression** - You're experiencing significant depression.")
recommendation = "Professional help is strongly recommended. Depression is treatable - please reach out to a mental health provider."
elif condition == "stress":
if total_score <= 20:
st.success("🟢 **Low Stress** - You're managing stress well.")
recommendation = "Continue your current coping strategies and maintain work-life balance."
elif total_score <= 40:
st.warning("🟡 **Moderate Stress** - You're experiencing considerable stress.")
recommendation = "Implement stress management techniques: time management, relaxation practices, and setting boundaries."
else:
st.error("🔴 **High Stress** - You're experiencing very high stress levels.")
recommendation = "Urgent lifestyle changes needed. Consider reducing commitments, seeking support, and possibly professional counseling."
elif condition == "ptsd":
if total_score <= 20:
st.success("🟢 **Minimal PTSD Symptoms** - You're experiencing few trauma-related symptoms.")
recommendation = "Continue self-care and processing strategies. Reach out for support if symptoms increase."
elif total_score <= 40:
st.warning("🟡 **Mild to Moderate PTSD** - You're experiencing noticeable trauma symptoms.")
recommendation = "Grounding techniques and support groups may help. Consider trauma-focused therapy like EMDR or CPT."
else:
st.error("🔴 **Moderate to Severe PTSD** - You're experiencing significant trauma symptoms.")
recommendation = "Professional trauma therapy is strongly recommended. PTSD is highly treatable with specialized approaches."
elif condition == "insomnia":
if total_score <= 20:
st.success("🟢 **Minimal Sleep Issues** - Your sleep is relatively good.")
recommendation = "Maintain good sleep hygiene and consistent sleep schedule."
elif total_score <= 40:
st.warning("🟡 **Moderate Insomnia** - You're experiencing noticeable sleep difficulties.")
recommendation = "Try CBT-I techniques: sleep restriction, stimulus control, and sleep hygiene improvements."
else:
st.error("🔴 **Severe Insomnia** - You're experiencing significant sleep problems.")
recommendation = "Consider consulting a sleep specialist. CBT-I (cognitive behavioral therapy for insomnia) is highly effective."
st.info(f"💡 **Recommendation**: {recommendation}")
st.warning("⚠️ **Important**: This is a screening tool, NOT a medical diagnosis. Please consult a qualified mental health professional for accurate assessment and treatment.")
# Action buttons
col1, col2 = st.columns(2)
with col1:
if st.button("📈 View My Assessment History"):
st.session_state.view_assessment_history = True
with col2:
if st.button("📞 Find Professional Help"):
st.info("Check the Crisis Helplines tab for professional resources.")
# Interventions
st.markdown("---")
st.subheader("🛠️ Non-Medical Interventions")
for section_key, section in data["non_medical_interventions"].items():
with st.expander(section["title"]):
for key, value in section.items():
if isinstance(value, list):
for item in value:
if isinstance(item, dict):
st.markdown(f"**{item.get('name', '')}**")
st.write(item.get('description', ''))
else:
st.write(f"• {item}")
# Success Stories
with st.expander("🌟 Success Stories"):
for story in data["success_stories"]:
st.success(story)
# When to Seek Help
with st.expander("🆘 When to Seek Professional Help"):
for item in data["when_to_seek_help"]:
st.warning(item)
with tab3:
st.subheader("💡 Quick Self-Help Tips")
st.markdown("""
### Breathing Exercises
- **4-7-8 Breathing**: Inhale 4s, hold 7s, exhale 8s
- **Box Breathing**: Inhale 4s, hold 4s, exhale 4s, hold 4s
### Daily Wellness
- 🌅 Morning sunlight (15-30 min)
- 🏃 Exercise (30 min daily)
- 😴 Sleep consistency (7-9 hours)
- 📝 Journaling
- 🧘 Meditation (5-10 min)
""")
# ==================== Main Entry Point ====================
def main():
if not st.session_state.authenticated:
auth_page()
else:
chat_page()
if __name__ == "__main__":
main() |