ahmadsanafarooq commited on
Commit
af5a7d4
·
verified ·
1 Parent(s): 5e94278

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +338 -81
app.py CHANGED
@@ -646,51 +646,293 @@ def show_main_app():
646
  username = st.session_state.username
647
 
648
  st.set_page_config(page_title="DilBot - Emotional AI", page_icon="🧠")
649
- # --- PASTE YOUR CUSTOM CSS HERE FOR THE MAIN APP ---
650
  st.markdown("""
651
  <style>
652
- /* Example: Styling for the main app page */
653
  .stApp {
654
- background-color: #e6e9f0; /* Slightly different background */
 
 
655
  }
656
- /* Chat message styling (more complex, but an idea) */
657
- .user-message {
658
- background-color: #dcf8c6; /* Light green for user */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
659
  border-radius: 10px;
660
- padding: 10px;
661
- margin-bottom: 10px;
662
- align-self: flex-end; /* Align to right */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
663
  }
664
- .bot-message {
665
- background-color: #ffffff; /* White for bot */
 
666
  border-radius: 10px;
667
- padding: 10px;
668
- margin-bottom: 10px;
669
- align-self: flex-start; /* Align to left */
670
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
671
  }
672
- /* Style for expanders */
673
  .streamlit-expanderHeader {
674
- background-color: #f0f0f0;
675
- border-radius: 5px;
676
- padding: 10px;
677
- margin-bottom: 5px;
 
 
 
 
 
 
 
678
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
679
  </style>
680
  """, unsafe_allow_html=True)
681
  # --- END CUSTOM CSS ---
 
682
 
683
- # Header with logout
684
  col1, col2 = st.columns([4, 1])
685
  with col1:
686
  st.title(f"🧠 DilBot - Welcome back, {username}!")
687
- st.markdown("Your personal emotional AI companion")
688
  with col2:
689
  if st.button("Logout", key="logout_btn"):
690
  st.session_state.authenticated = False
691
  st.session_state.username = None
692
  st.rerun()
693
-
694
  # Quote categories
695
  quote_categories = {
696
  "Grief": ["Grief is the price we pay for love.", "Tears are the silent language of grief.", "What we have once enjoyed we can never lose; all that we love deeply becomes a part of us."],
@@ -698,15 +940,28 @@ def show_main_app():
698
  "Healing": ["Every wound has its own time to heal.", "It's okay to take your time to feel better.", "Healing is not linear, and that's perfectly okay."],
699
  "Relationships": ["The best relationships are built on trust.", "Love is not about possession but appreciation.", "Healthy relationships require both people to show up authentically."]
700
  }
701
-
702
  # UI for quote selection and file upload
703
- col1, col2 = st.columns(2)
704
- with col1:
705
- selected_category = st.selectbox("🎯 Choose a quote theme:", list(quote_categories.keys()))
706
- with col2:
707
- uploaded_quotes = st.file_uploader("📁 Upload your own quotes (.txt)", type=["txt"])
708
-
709
- uploaded_audio = st.file_uploader("🎤 Upload a voice message (.wav)", type=["wav"])
 
 
 
 
 
 
 
 
 
 
 
 
 
710
 
711
  # Handle vectorstore
712
  current_quotes = []
@@ -736,17 +991,18 @@ def show_main_app():
736
  st.success("✅ Voice transcribed successfully!")
737
 
738
  # Input area
 
739
  user_input = st.text_area(
740
- "💬 What's on your mind?",
741
  value=st.session_state.transcribed_text,
742
- height=100,
743
- placeholder="Share your thoughts, feelings, or experiences..."
744
  )
745
-
746
  final_input = user_input.strip() or st.session_state.transcribed_text.strip()
747
 
748
  # Main interaction button
749
- if st.button("🧠 Talk to DilBot", type="primary"):
750
  if not final_input:
751
  st.warning("⚠️ Please enter something to share or upload a voice message.")
752
  else:
@@ -779,32 +1035,31 @@ Respond as DilBot with warmth, empathy, and understanding. Keep it conversationa
779
  save_user_journal(username, final_input, emotion, score, response)
780
 
781
  # Display results
782
- col1, col2 = st.columns([2, 1])
783
- with col1:
 
 
784
  st.success(f"**Emotion Detected:** {emotion.capitalize()} ({round(score*100)}% confidence)")
785
- with col2:
786
  if is_crisis(final_input):
787
- st.error("🚨 Crisis detected! Please reach out to a mental health professional immediately.")
788
-
789
- # Show relevant quote
790
- if current_quotes:
791
- model = SentenceTransformer("all-MiniLM-L6-v2")
792
- quote_embeddings = model.encode(current_quotes, convert_to_tensor=True)
793
- user_embedding = model.encode(final_input, convert_to_tensor=True)
794
- sims = util.pytorch_cos_sim(user_embedding, quote_embeddings)[0]
795
- best_match = sims.argmax().item()
796
- selected_quote = current_quotes[best_match]
797
- st.info(f"💭 **Quote for you:** *{selected_quote}*")
798
-
799
- # Show response
800
- st.markdown("### 🤖 DilBot's Response:")
801
- st.markdown(f"> {response}")
802
-
803
- # Audio response
804
- speak(response, username)
805
-
806
- # Clear transcribed text after successful interaction
807
- st.session_state.transcribed_text = ""
808
 
809
  # User's personal dashboard
810
  st.markdown("---")
@@ -816,6 +1071,7 @@ Respond as DilBot with warmth, empathy, and understanding. Keep it conversationa
816
  if journal_data:
817
  # Mood tracker
818
  st.subheader("📈 Your Daily Mood Tracker")
 
819
 
820
  # Prepare data for chart
821
  df_data = []
@@ -827,47 +1083,48 @@ Respond as DilBot with warmth, empathy, and understanding. Keep it conversationa
827
  })
828
 
829
  if df_data:
830
- chart = alt.Chart(alt.Data(values=df_data)).mark_bar().encode(
831
- x=alt.X('date:N', title='Date'),
832
- y=alt.Y('count():Q', title='Frequency'),
833
- color=alt.Color('emotion:N', title='Emotion'),
834
- tooltip=['date:N', 'emotion:N', 'count():Q']
835
- ).properties(
836
- width=600,
837
- height=300,
838
- title="Your Emotional Journey Over Time"
839
- )
840
- st.altair_chart(chart, use_container_width=True)
841
 
842
  # Recent conversations
843
  st.subheader("💬 Recent Conversations")
844
  recent_entries = journal_data[-5:] if len(journal_data) >= 5 else journal_data
845
-
846
- for i, entry in enumerate(reversed(recent_entries)):
847
- with st.expander(f"📅 {entry['date']} - {entry['emotion'].capitalize()} ({entry['confidence']}%)"):
848
- st.markdown(f"**You said:** {entry['user_input']}")
849
- st.markdown(f"**DilBot replied:** {entry['response']}")
 
 
 
 
850
 
851
  # Statistics
852
  st.subheader("📊 Your Emotional Statistics")
853
  col1, col2, col3 = st.columns(3)
854
-
855
  with col1:
856
  st.metric("Total Conversations", len(journal_data))
857
-
858
  with col2:
859
  emotions = [entry['emotion'] for entry in journal_data]
860
  most_common = max(set(emotions), key=emotions.count) if emotions else "None"
861
  st.metric("Most Common Emotion", most_common.capitalize())
862
-
863
  with col3:
864
  if journal_data:
865
  avg_confidence = sum(entry['confidence'] for entry in journal_data) / len(journal_data)
866
  st.metric("Avg. Confidence", f"{avg_confidence:.1f}%")
867
-
868
  else:
869
  st.info("🌟 Start your first conversation with DilBot to see your personal dashboard!")
870
-
871
  st.markdown("---")
872
  st.caption("Built by Members of CSG Hackathon Team | Your data is stored privately and securely")
873
 
 
646
  username = st.session_state.username
647
 
648
  st.set_page_config(page_title="DilBot - Emotional AI", page_icon="🧠")
649
+ # --- CUSTOM CSS FOR MAIN APP ---
650
  st.markdown("""
651
  <style>
652
+ /* Global Styles & Background */
653
  .stApp {
654
+ background-color: #f0f2f6; /* Light, calming background */
655
+ color: #333333; /* Darker default text color for better readability */
656
+ font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; /* Modern, clean font */
657
  }
658
+
659
+ /* Header & Titles */
660
+ h1, h2, h3, h4, h5, h6 {
661
+ color: #4A4A4A; /* Slightly darker grey for headings */
662
+ margin-top: 1.5rem;
663
+ margin-bottom: 0.8rem;
664
+ }
665
+ h1 {
666
+ font-size: 2.5em;
667
+ font-weight: 700;
668
+ color: #7289da; /* DilBot's primary color */
669
+ }
670
+ h2 {
671
+ font-size: 1.8em;
672
+ font-weight: 600;
673
+ border-bottom: 1px solid #e0e0e0; /* Subtle line under subheaders */
674
+ padding-bottom: 0.5rem;
675
+ margin-bottom: 1.5rem;
676
+ }
677
+ h3 {
678
+ font-size: 1.5em;
679
+ font-weight: 600;
680
+ color: #555555;
681
+ }
682
+
683
+ /* Metrics (Total Conversations, Most Common Emotion, Avg. Confidence) */
684
+ [data-testid="stMetric"] {
685
+ background-color: #ffffff;
686
+ border: 1px solid #e0e0e0;
687
  border-radius: 10px;
688
+ padding: 15px;
689
+ box-shadow: 0 4px 8px rgba(0,0,0,0.05);
690
+ text-align: center;
691
+ margin-bottom: 1rem;
692
+ }
693
+ [data-testid="stMetricLabel"] {
694
+ font-size: 0.9em;
695
+ color: #666666;
696
+ margin-bottom: 5px;
697
+ }
698
+ [data-testid="stMetricValue"] {
699
+ font-size: 2.2em;
700
+ font-weight: 700;
701
+ color: #7289da; /* Match DilBot's primary color */
702
+ }
703
+
704
+ /* Buttons */
705
+ .stButton>button {
706
+ background-color: #7289da; /* DilBot's primary blue/purple */
707
+ color: white;
708
+ border: none;
709
+ border-radius: 8px;
710
+ padding: 10px 20px;
711
+ font-size: 1em;
712
+ font-weight: bold;
713
+ transition: background-color 0.3s ease, transform 0.2s ease;
714
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
715
+ cursor: pointer;
716
+ }
717
+ .stButton>button:hover {
718
+ background-color: #5b6fb8; /* Darker shade on hover */
719
+ transform: translateY(-2px); /* Slight lift effect */
720
+ }
721
+ .stButton>button:active {
722
+ background-color: #4a5a90;
723
+ transform: translateY(0);
724
+ }
725
+ /* Style for the logout button specifically if different */
726
+ [data-testid="stSidebarNav"] + div > .stButton > button { /* Adjust selector if needed for top-right logout */
727
+ background-color: #dc3545; /* Red for logout */
728
+ }
729
+ [data-testid="stSidebarNav"] + div > .stButton > button:hover {
730
+ background-color: #c82333;
731
+ }
732
+
733
+
734
+ /* Text Inputs and Text Areas */
735
+ .stTextInput>div>div>input, .stTextArea>div>div>textarea {
736
+ border-radius: 8px;
737
+ border: 1px solid #ced4da; /* Light grey border */
738
+ padding: 12px 15px;
739
+ font-size: 1em;
740
+ color: #333333;
741
+ box-shadow: inset 0 1px 3px rgba(0,0,0,0.05);
742
+ transition: border-color 0.3s ease, box-shadow 0.3s ease;
743
+ }
744
+ .stTextInput>div>div>input:focus, .stTextArea>div>div>textarea:focus {
745
+ border-color: #7289da; /* Highlight on focus */
746
+ box-shadow: 0 0 0 0.2rem rgba(114, 137, 218, 0.25);
747
+ outline: none;
748
+ }
749
+ .stTextInput>label, .stTextArea>label {
750
+ font-weight: 600;
751
+ color: #555555;
752
+ margin-bottom: 5px; /* Add some space below label */
753
+ }
754
+
755
+ /* Selectbox (Dropdown) */
756
+ .stSelectbox>div>div>div {
757
+ border-radius: 8px;
758
+ border: 1px solid #ced4da;
759
+ padding: 8px 12px;
760
+ font-size: 1em;
761
+ color: #333333;
762
+ box-shadow: inset 0 1px 3px rgba(0,0,0,0.05);
763
+ }
764
+ .stSelectbox>label {
765
+ font-weight: 600;
766
+ color: #555555;
767
  }
768
+
769
+ /* File Uploader */
770
+ [data-testid="stFileUploaderDropzone"] {
771
  border-radius: 10px;
772
+ border: 2px dashed #a0a8b4; /* Dashed border */
773
+ background-color: #ffffff;
774
+ padding: 20px;
775
+ transition: border-color 0.3s ease, background-color 0.3s ease;
776
+ margin-bottom: 1rem; /* Space below uploader */
777
+ }
778
+ [data-testid="stFileUploaderDropzone"]:hover {
779
+ border-color: #7289da; /* Highlight on hover */
780
+ background-color: #f7f7f7;
781
+ }
782
+ /* Hide the redundant 'Drag and drop file here' text */
783
+ [data-testid="stFileUploaderDropzone"] p:first-child {
784
+ display: none;
785
+ }
786
+ [data-testid="stFileUploaderFileName"] {
787
+ font-size: 0.9em;
788
+ color: #555;
789
+ margin-top: 5px;
790
+ }
791
+
792
+
793
+ /* Information, Success, Error, Warning Boxes */
794
+ [data-testid="stAlert"] {
795
+ border-radius: 8px;
796
+ padding: 15px 20px;
797
+ margin-bottom: 1rem;
798
+ font-size: 1em;
799
+ line-height: 1.5;
800
+ }
801
+ [data-testid="stAlert"] .css-1aumx4k { /* Inner div for icon/text */
802
+ align-items: center;
803
+ }
804
+ /* Specific styles for each type */
805
+ [data-testid="stAlert"] .streamlit-warning {
806
+ background-color: #fff3cd; /* Light yellow */
807
+ color: #664d03;
808
+ border-left: 5px solid #ffc107; /* Yellow border */
809
+ }
810
+ [data-testid="stAlert"] .streamlit-success {
811
+ background-color: #d1e7dd; /* Light green */
812
+ color: #0f5132;
813
+ border-left: 5px solid #198754; /* Green border */
814
+ }
815
+ [data-testid="stAlert"] .streamlit-error {
816
+ background-color: #f8d7da; /* Light red */
817
+ color: #842029;
818
+ border-left: 5px solid #dc3545; /* Red border */
819
+ }
820
+ [data-testid="stAlert"] .streamlit-info {
821
+ background-color: #cfe2ff; /* Light blue */
822
+ color: #055160;
823
+ border-left: 5px solid #0dcaf0; /* Cyan border */
824
+ }
825
+
826
+
827
+ /* Markdown for Quote and Response */
828
+ .stMarkdown h3 { /* For "DilBot's Response" title */
829
+ font-size: 1.6em;
830
+ color: #7289da;
831
+ margin-top: 2rem;
832
+ margin-bottom: 1rem;
833
+ }
834
+ /* Styling for the blockquote (DilBot's response) */
835
+ .stMarkdown blockquote {
836
+ background-color: #ffffff;
837
+ border-left: 6px solid #7289da; /* Accent border */
838
+ padding: 15px 20px;
839
+ margin: 1.5rem 0;
840
+ border-radius: 10px;
841
+ font-style: italic;
842
+ color: #4a4a4a;
843
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1);
844
+ line-height: 1.6;
845
+ }
846
+ .stMarkdown blockquote p { /* Ensure text inside blockquote is styled */
847
+ margin-bottom: 0;
848
+ }
849
+
850
+ /* Quote for you (st.info) */
851
+ .stInfo { /* Target the st.info for quotes specifically if needed */
852
+ background-color: #e6f7ff; /* Lighter blue for quote box */
853
+ border-left: 6px solid #4893c5; /* Accent border */
854
+ color: #004085;
855
+ border-radius: 8px;
856
+ padding: 15px 20px;
857
+ margin-top: 1.5rem;
858
+ font-style: italic;
859
+ }
860
+ .stInfo span[data-baseweb="tag"] { /* Targeting the '💭 Quote for you:' part */
861
+ font-weight: bold;
862
+ color: #004085;
863
+ }
864
+
865
+
866
+ /* Audio Player */
867
+ .stAudio {
868
+ margin-top: 1.5rem;
869
+ margin-bottom: 2rem;
870
+ }
871
+
872
+ /* Expander styling (for conversations) */
873
+ .streamlit-expanderContent {
874
+ background-color: #f8f9fa; /* Light background for content */
875
+ border-left: 3px solid #ced4da;
876
+ padding: 10px 15px;
877
+ border-bottom-left-radius: 8px;
878
+ border-bottom-right-radius: 8px;
879
+ margin-top: -10px; /* Adjust to sit right under header */
880
  }
 
881
  .streamlit-expanderHeader {
882
+ background-color: #ffffff;
883
+ border: 1px solid #e0e0e0;
884
+ border-radius: 8px;
885
+ padding: 10px 15px;
886
+ margin-bottom: 0.5rem;
887
+ cursor: pointer;
888
+ transition: background-color 0.2s ease;
889
+ box-shadow: 0 2px 4px rgba(0,0,0,0.05);
890
+ }
891
+ .streamlit-expanderHeader:hover {
892
+ background-color: #f5f5f5;
893
  }
894
+ .streamlit-expanderHeader > div > div > p { /* Target expander title text */
895
+ font-weight: 500;
896
+ color: #333333;
897
+ }
898
+ .stExpander.css-1r0f5rs.e1gf0vsg1 { /* specific class for closed expander */
899
+ /* You might need to inspect to get the exact class for closed/open state */
900
+ /* border-radius: 8px; */
901
+ }
902
+
903
+
904
+ /* Horizontal rule */
905
+ hr {
906
+ border-top: 1px solid #e0e0e0;
907
+ margin-top: 2rem;
908
+ margin-bottom: 2rem;
909
+ }
910
+
911
+ /* Caption (footer) */
912
+ .stMarkdown small {
913
+ color: #888888;
914
+ font-size: 0.85em;
915
+ margin-top: 2rem;
916
+ display: block; /* Make sure it takes its own line */
917
+ text-align: center;
918
+ }
919
+
920
  </style>
921
  """, unsafe_allow_html=True)
922
  # --- END CUSTOM CSS ---
923
+
924
 
925
+ # Header with logout
926
  col1, col2 = st.columns([4, 1])
927
  with col1:
928
  st.title(f"🧠 DilBot - Welcome back, {username}!")
929
+ st.markdown("<p style='font-size: 1.1em; color: #666666;'>Your personal emotional AI companion</p>", unsafe_allow_html=True) # Styled tagline
930
  with col2:
931
  if st.button("Logout", key="logout_btn"):
932
  st.session_state.authenticated = False
933
  st.session_state.username = None
934
  st.rerun()
935
+
936
  # Quote categories
937
  quote_categories = {
938
  "Grief": ["Grief is the price we pay for love.", "Tears are the silent language of grief.", "What we have once enjoyed we can never lose; all that we love deeply becomes a part of us."],
 
940
  "Healing": ["Every wound has its own time to heal.", "It's okay to take your time to feel better.", "Healing is not linear, and that's perfectly okay."],
941
  "Relationships": ["The best relationships are built on trust.", "Love is not about possession but appreciation.", "Healthy relationships require both people to show up authentically."]
942
  }
943
+
944
  # UI for quote selection and file upload
945
+ # Use st.container for better visual grouping
946
+ st.markdown("### 📝 Input Your Thoughts") # New subheader for input section
947
+ with st.container(border=True): # New feature in Streamlit for container with border
948
+ col1, col2 = st.columns(2)
949
+ with col1:
950
+ selected_category = st.selectbox("🎯 Choose a quote theme:", list(quote_categories.keys()))
951
+ with col2:
952
+ st.markdown("##### 📁 Custom Quotes & Voice Input") # Smaller header
953
+ uploaded_quotes = st.file_uploader("Upload your own quotes (.txt)", type=["txt"], key="quote_uploader")
954
+ uploaded_audio = st.file_uploader("Upload a voice message (.wav)", type=["wav"], key="audio_uploader")
955
+
956
+ # Voice transcription button moved for better flow
957
+ if uploaded_audio and st.button("🎙️ Transcribe Voice Message", key="transcribe_btn"): # Updated button text
958
+ with st.spinner("Transcribing your voice..."):
959
+ transcribed = transcribe_audio_file(uploaded_audio)
960
+ if transcribed.startswith("Error:"):
961
+ st.error(transcribed)
962
+ else:
963
+ st.session_state.transcribed_text = transcribed
964
+ st.success("✅ Voice transcribed successfully!")
965
 
966
  # Handle vectorstore
967
  current_quotes = []
 
991
  st.success("✅ Voice transcribed successfully!")
992
 
993
  # Input area
994
+ st.markdown("##### 💬 What's on your mind?")
995
  user_input = st.text_area(
996
+ "Share your thoughts, feelings, or experiences...", # Removed redundant label
997
  value=st.session_state.transcribed_text,
998
+ height=150, # Slightly increased height
999
+ placeholder="Type here or use your transcribed voice message..."
1000
  )
1001
+
1002
  final_input = user_input.strip() or st.session_state.transcribed_text.strip()
1003
 
1004
  # Main interaction button
1005
+ if st.button("🧠 Talk to DilBot", type="primary", use_container_width=True):
1006
  if not final_input:
1007
  st.warning("⚠️ Please enter something to share or upload a voice message.")
1008
  else:
 
1035
  save_user_journal(username, final_input, emotion, score, response)
1036
 
1037
  # Display results
1038
+ st.markdown("### 🤖 DilBot's Conversation:") # New title for conversation output
1039
+ with st.container(border=True): # Container for the conversation output
1040
+ # User's input presented in a div
1041
+ st.markdown(f"<div class='user-message'>**You:** {final_input}</div>", unsafe_allow_html=True)
1042
  st.success(f"**Emotion Detected:** {emotion.capitalize()} ({round(score*100)}% confidence)")
1043
+
1044
  if is_crisis(final_input):
1045
+ st.error("🚨 Crisis detected! Please reach out to a mental health professional immediately. "
1046
+ "You are not alone. Consider contacting a helpline like the National Suicide Prevention Lifeline (988 in the US) or a local emergency service.") # Enhanced crisis message
1047
+
1048
+ if current_quotes:
1049
+ model = SentenceTransformer("all-MiniLM-L6-v2")
1050
+ quote_embeddings = model.encode(current_quotes, convert_to_tensor=True)
1051
+ user_embedding = model.encode(final_input, convert_to_tensor=True)
1052
+ sims = util.pytorch_cos_sim(user_embedding, quote_embeddings)[0]
1053
+ best_match = sims.argmax().item()
1054
+ selected_quote = current_quotes[best_match]
1055
+ st.info(f"💭 **Quote for you:** *{selected_quote}*")
1056
+
1057
+ # DilBot's response presented in a blockquote with custom styling
1058
+ st.markdown("### 🤖 DilBot's Response:")
1059
+ st.markdown(f"> {response}") # Using your existing markdown blockquote
1060
+
1061
+ speak(response, username)
1062
+ st.session_state.transcribed_text = ""
 
 
 
1063
 
1064
  # User's personal dashboard
1065
  st.markdown("---")
 
1071
  if journal_data:
1072
  # Mood tracker
1073
  st.subheader("📈 Your Daily Mood Tracker")
1074
+ with st.container(border=True):
1075
 
1076
  # Prepare data for chart
1077
  df_data = []
 
1083
  })
1084
 
1085
  if df_data:
1086
+ chart = alt.Chart(alt.Data(values=df_data)).mark_bar().encode(
1087
+ x=alt.X('date:N', title='Date'),
1088
+ y=alt.Y('count():Q', title='Frequency'),
1089
+ color=alt.Color('emotion:N', title='Emotion'),
1090
+ tooltip=['date:N', 'emotion:N', 'count():Q']
1091
+ ).properties(
1092
+ width=600,
1093
+ height=300,
1094
+ title="Your Emotional Journey Over Time"
1095
+ ).interactive() # Make chart interactive for zoom/pan
1096
+ st.altair_chart(chart, use_container_width=True)
1097
 
1098
  # Recent conversations
1099
  st.subheader("💬 Recent Conversations")
1100
  recent_entries = journal_data[-5:] if len(journal_data) >= 5 else journal_data
1101
+
1102
+ with st.container(border=True): # Wrap recent conversations in a container
1103
+ if recent_entries:
1104
+ for i, entry in enumerate(reversed(recent_entries)):
1105
+ with st.expander(f"📅 {entry['date']} - {entry['emotion'].capitalize()} ({entry['confidence']}%)"):
1106
+ st.markdown(f"**You said:** {entry['user_input']}")
1107
+ st.markdown(f"**DilBot replied:** {entry['response']}")
1108
+ else:
1109
+ st.info("No recent conversations yet. Start talking to DilBot!")
1110
 
1111
  # Statistics
1112
  st.subheader("📊 Your Emotional Statistics")
1113
  col1, col2, col3 = st.columns(3)
1114
+
1115
  with col1:
1116
  st.metric("Total Conversations", len(journal_data))
 
1117
  with col2:
1118
  emotions = [entry['emotion'] for entry in journal_data]
1119
  most_common = max(set(emotions), key=emotions.count) if emotions else "None"
1120
  st.metric("Most Common Emotion", most_common.capitalize())
 
1121
  with col3:
1122
  if journal_data:
1123
  avg_confidence = sum(entry['confidence'] for entry in journal_data) / len(journal_data)
1124
  st.metric("Avg. Confidence", f"{avg_confidence:.1f}%")
 
1125
  else:
1126
  st.info("🌟 Start your first conversation with DilBot to see your personal dashboard!")
1127
+
1128
  st.markdown("---")
1129
  st.caption("Built by Members of CSG Hackathon Team | Your data is stored privately and securely")
1130