Spaces:
Running
Running
Upload 19 files
Browse files- .env +2 -0
- __pycache__/config.cpython-313.pyc +0 -0
- config.py +64 -0
- images/malala.jpg +0 -0
- images/michelle.jpg +0 -0
- images/oprah.jpg +0 -0
- images/zendaya.jpg +0 -0
- init-file.txt +64 -0
- main.py +154 -0
- pages/__pycache__/she_fuels.cpython-313.pyc +0 -0
- pages/__pycache__/she_glows.cpython-313.pyc +0 -0
- pages/__pycache__/she_legends.cpython-313.pyc +0 -0
- pages/__pycache__/she_melted_mascara.cpython-313.pyc +0 -0
- pages/init-file.txt +1 -0
- pages/she_fuels.py +99 -0
- pages/she_glows.py +199 -0
- pages/she_legends.py +176 -0
- pages/she_melted_mascara.py +331 -0
- requirements-final.txt +7 -0
.env
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
GOOGLE_API_KEY='AIzaSyCZKVNKkew-c6j7Xl2ETP2DIudiKEDKILU'
|
2 |
+
ELEVEN_LABS_API_KEY= 'sk_5bfb3df818e08d23918effbb86dcd73d07170e6cdb1cdb62'
|
__pycache__/config.cpython-313.pyc
ADDED
Binary file (2.54 kB). View file
|
|
config.py
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from dotenv import load_dotenv
|
2 |
+
import os
|
3 |
+
|
4 |
+
# Load environment variables
|
5 |
+
load_dotenv()
|
6 |
+
|
7 |
+
# Mentor configurations
|
8 |
+
MENTORS = {
|
9 |
+
"Michelle Obama": {
|
10 |
+
"role": "The OG Girlboss π",
|
11 |
+
"description": "Hey queen! Ready to level up your life?",
|
12 |
+
"voice_id": os.getenv('MICHELLE_VOICE_ID', 'VwIOyTB23ovdJOtf6bDL'),
|
13 |
+
"image": "images/michelle.jpg",
|
14 |
+
"background": "#FFD1DC",
|
15 |
+
"quote": "When they go low, we go high... and straight to the top! π
",
|
16 |
+
"prompt": "You are Michelle Obama, speaking with warmth and empowerment. Use phrases like 'Let me tell you something, queen' and modern Gen Z language while maintaining wisdom and grace."
|
17 |
+
},
|
18 |
+
"Malala Yousafzai": {
|
19 |
+
"role": "Education Queen π",
|
20 |
+
"description": "Education is your superpower! Period! π«",
|
21 |
+
"voice_id": os.getenv('MALALA_VOICE_ID', 'slZSYMWKOktfmwDdSSlU'),
|
22 |
+
"image": "images/malala.jpg",
|
23 |
+
"background": "#E6E6FA",
|
24 |
+
"quote": "One voice can change the world, bestie! β¨",
|
25 |
+
"prompt": "You are Malala Yousafzai, speaking with passion about education and empowerment. Use Gen Z language while maintaining your message of courage and determination."
|
26 |
+
},
|
27 |
+
"Oprah": {
|
28 |
+
"role": "Inspiration Icon π«",
|
29 |
+
"description": "What I know for sure is that you're meant for greatness!",
|
30 |
+
"voice_id": os.getenv('OPRAH_VOICE_ID', 'XRcuD3dLgdnEN7pidadv'),
|
31 |
+
"image": "images/oprah.jpg",
|
32 |
+
"background": "#FFB6C1",
|
33 |
+
"quote": "Living your best life starts with being your authentic self! π
",
|
34 |
+
"prompt": "You are Oprah Winfrey, speaking with wisdom and inspiration. Use your signature phrase 'What I know for sure' and combine it with modern Gen Z language."
|
35 |
+
},
|
36 |
+
"Zendaya": {
|
37 |
+
"role": "Gen Z Queen π",
|
38 |
+
"description": "Let's keep it real and authentic!",
|
39 |
+
"voice_id": os.getenv('ZENDAYA_VOICE_ID', 'slZSYMWKOktfmwDdSSlU'),
|
40 |
+
"image": "images/zendaya.jpg",
|
41 |
+
"background": "#E0FFFF",
|
42 |
+
"quote": "Your mental health comes first, period! β¨",
|
43 |
+
"prompt": "You are Zendaya, speaking about self-expression and mental health. Use Gen Z language naturally while providing thoughtful advice."
|
44 |
+
}
|
45 |
+
}
|
46 |
+
|
47 |
+
# Learning paths
|
48 |
+
LEARNING_PATHS = {
|
49 |
+
"Money Moves": {
|
50 |
+
"emoji": "π°",
|
51 |
+
"color": "#98FB98",
|
52 |
+
"modules": ["Budget Like a Boss", "Investing 101", "Side Hustle Success"]
|
53 |
+
},
|
54 |
+
"Boss Babe": {
|
55 |
+
"emoji": "π",
|
56 |
+
"color": "#FFB6C1",
|
57 |
+
"modules": ["Main Character Energy", "Speak Your Truth", "Build Your Dream Team"]
|
58 |
+
},
|
59 |
+
"Entrepreneur Era": {
|
60 |
+
"emoji": "π
",
|
61 |
+
"color": "#DDA0DD",
|
62 |
+
"modules": ["Business Basics", "Social Media Slay", "Brand Building 101"]
|
63 |
+
}
|
64 |
+
}
|
images/malala.jpg
ADDED
![]() |
images/michelle.jpg
ADDED
![]() |
images/oprah.jpg
ADDED
![]() |
images/zendaya.jpg
ADDED
![]() |
init-file.txt
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from dotenv import load_dotenv
|
2 |
+
import os
|
3 |
+
|
4 |
+
# Load environment variables
|
5 |
+
load_dotenv()
|
6 |
+
|
7 |
+
# Mentor configurations
|
8 |
+
MENTORS = {
|
9 |
+
"Michelle Obama": {
|
10 |
+
"role": "The OG Girlboss π",
|
11 |
+
"description": "Hey queen! Ready to level up your life?",
|
12 |
+
"voice_id": os.getenv('MICHELLE_VOICE_ID'),
|
13 |
+
"image": "images/michelle.jpg",
|
14 |
+
"background": "#FFD1DC",
|
15 |
+
"quote": "When they go low, we go high... and straight to the top! π
",
|
16 |
+
"prompt": "You are Michelle Obama, speaking with warmth and empowerment. Use phrases like 'Let me tell you something, queen' and modern Gen Z language while maintaining wisdom and grace."
|
17 |
+
},
|
18 |
+
"Malala Yousafzai": {
|
19 |
+
"role": "Education Queen π",
|
20 |
+
"description": "Education is your superpower! Period! π«",
|
21 |
+
"voice_id": os.getenv('MALALA_VOICE_ID'),
|
22 |
+
"image": "images/malala.jpg",
|
23 |
+
"background": "#E6E6FA",
|
24 |
+
"quote": "One voice can change the world, bestie! β¨",
|
25 |
+
"prompt": "You are Malala Yousafzai, speaking with passion about education and empowerment. Use Gen Z language while maintaining your message of courage and determination."
|
26 |
+
},
|
27 |
+
"Oprah": {
|
28 |
+
"role": "Inspiration Icon π«",
|
29 |
+
"description": "What I know for sure is that you're meant for greatness!",
|
30 |
+
"voice_id": os.getenv('OPRAH_VOICE_ID'),
|
31 |
+
"image": "images/oprah.jpg",
|
32 |
+
"background": "#FFB6C1",
|
33 |
+
"quote": "Living your best life starts with being your authentic self! π
",
|
34 |
+
"prompt": "You are Oprah Winfrey, speaking with wisdom and inspiration. Use your signature phrase 'What I know for sure' and combine it with modern Gen Z language."
|
35 |
+
},
|
36 |
+
"Zendaya": {
|
37 |
+
"role": "Gen Z Queen π",
|
38 |
+
"description": "Let's keep it real and authentic!",
|
39 |
+
"voice_id": os.getenv('ZENDAYA_VOICE_ID'),
|
40 |
+
"image": "images/zendaya.jpg",
|
41 |
+
"background": "#E0FFFF",
|
42 |
+
"quote": "Your mental health comes first, period! β¨",
|
43 |
+
"prompt": "You are Zendaya, speaking about self-expression and mental health. Use Gen Z language naturally while providing thoughtful advice."
|
44 |
+
}
|
45 |
+
}
|
46 |
+
|
47 |
+
# Learning paths
|
48 |
+
LEARNING_PATHS = {
|
49 |
+
"Money Moves": {
|
50 |
+
"emoji": "π°",
|
51 |
+
"color": "#98FB98",
|
52 |
+
"modules": ["Budget Like a Boss", "Investing 101", "Side Hustle Success"]
|
53 |
+
},
|
54 |
+
"Boss Babe": {
|
55 |
+
"emoji": "π",
|
56 |
+
"color": "#FFB6C1",
|
57 |
+
"modules": ["Main Character Energy", "Speak Your Truth", "Build Your Dream Team"]
|
58 |
+
},
|
59 |
+
"Entrepreneur Era": {
|
60 |
+
"emoji": "π
",
|
61 |
+
"color": "#DDA0DD",
|
62 |
+
"modules": ["Business Basics", "Social Media Slay", "Brand Building 101"]
|
63 |
+
}
|
64 |
+
}
|
main.py
ADDED
@@ -0,0 +1,154 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
|
3 |
+
def switch_page(page_name):
|
4 |
+
st.session_state.current_page = page_name
|
5 |
+
st.rerun()
|
6 |
+
|
7 |
+
def show_main():
|
8 |
+
# Page config
|
9 |
+
st.set_page_config(
|
10 |
+
page_title="HerCorners",
|
11 |
+
page_icon="β¨",
|
12 |
+
layout="wide",
|
13 |
+
initial_sidebar_state="expanded"
|
14 |
+
)
|
15 |
+
|
16 |
+
# Hide streamlit default menu and footer
|
17 |
+
st.markdown("""
|
18 |
+
<style>
|
19 |
+
#MainMenu {visibility: hidden;}
|
20 |
+
footer {visibility: hidden;}
|
21 |
+
.stDeployButton {display:none;}
|
22 |
+
|
23 |
+
/* Style for sidebar buttons */
|
24 |
+
div.stButton > button {
|
25 |
+
width: 100%;
|
26 |
+
padding: 10px 10px;
|
27 |
+
border: none;
|
28 |
+
background-color: #FFE4E1;
|
29 |
+
color: black;
|
30 |
+
border-radius: 10px;
|
31 |
+
text-align: left;
|
32 |
+
margin: 5px 0;
|
33 |
+
}
|
34 |
+
|
35 |
+
div.stButton > button:hover {
|
36 |
+
background-color: #FFB6C1;
|
37 |
+
color: white;
|
38 |
+
}
|
39 |
+
|
40 |
+
/* Style for title box */
|
41 |
+
.title-box {
|
42 |
+
background: linear-gradient(45deg, #FF69B4, #FFB6C1);
|
43 |
+
padding: 20px;
|
44 |
+
border-radius: 10px;
|
45 |
+
margin-bottom: 20px;
|
46 |
+
text-align: center;
|
47 |
+
color: white;
|
48 |
+
cursor: pointer;
|
49 |
+
}
|
50 |
+
|
51 |
+
/* Style for home button */
|
52 |
+
.home-button {
|
53 |
+
background-color: #FFB6C1;
|
54 |
+
color: white;
|
55 |
+
padding: 10px;
|
56 |
+
border-radius: 10px;
|
57 |
+
text-align: center;
|
58 |
+
margin: 10px 0;
|
59 |
+
cursor: pointer;
|
60 |
+
}
|
61 |
+
</style>
|
62 |
+
""", unsafe_allow_html=True)
|
63 |
+
|
64 |
+
# Initialize session state
|
65 |
+
if 'current_page' not in st.session_state:
|
66 |
+
st.session_state.current_page = 'home'
|
67 |
+
|
68 |
+
# Sidebar navigation
|
69 |
+
with st.sidebar:
|
70 |
+
# Title box that works as home button
|
71 |
+
st.markdown("""
|
72 |
+
<div class="title-box" onclick="window.location.href='#'">
|
73 |
+
<h1>β¨ HerCorners β¨</h1>
|
74 |
+
<p>Your safe space to slay! π
</p>
|
75 |
+
</div>
|
76 |
+
""", unsafe_allow_html=True)
|
77 |
+
|
78 |
+
# Home button at the top of navigation
|
79 |
+
if st.button("π Home", use_container_width=True):
|
80 |
+
switch_page('home')
|
81 |
+
|
82 |
+
st.markdown("<hr>", unsafe_allow_html=True) # Divider
|
83 |
+
|
84 |
+
# Navigation buttons
|
85 |
+
if st.button("π She Legends", use_container_width=True):
|
86 |
+
switch_page('legends')
|
87 |
+
|
88 |
+
if st.button("π§ She Melted Mascara", use_container_width=True):
|
89 |
+
switch_page('mascara')
|
90 |
+
|
91 |
+
if st.button("β¨ She Glows", use_container_width=True):
|
92 |
+
switch_page('glows')
|
93 |
+
|
94 |
+
if st.button("π₯ She Fuels", use_container_width=True):
|
95 |
+
switch_page('fuels')
|
96 |
+
|
97 |
+
# Main content area
|
98 |
+
if st.session_state.current_page == 'home':
|
99 |
+
st.markdown("""
|
100 |
+
<div style='text-align: center; padding: 50px;'>
|
101 |
+
<h1>Welcome to HerCorners! β¨</h1>
|
102 |
+
<p style='font-size: 20px; margin: 20px 0;'>Choose from our spaces:</p>
|
103 |
+
</div>
|
104 |
+
""", unsafe_allow_html=True)
|
105 |
+
|
106 |
+
# Feature cards
|
107 |
+
col1, col2 = st.columns(2)
|
108 |
+
with col1:
|
109 |
+
st.markdown("""
|
110 |
+
<div style='background-color: #FFE4E1; padding: 20px; border-radius: 10px; margin: 10px 0;'>
|
111 |
+
<h3>π She Legends</h3>
|
112 |
+
<p>Chat with inspiring mentors for guidance and support!</p>
|
113 |
+
</div>
|
114 |
+
|
115 |
+
<div style='background-color: #E6E6FA; padding: 20px; border-radius: 10px; margin: 10px 0;'>
|
116 |
+
<h3>π§ She Melted Mascara</h3>
|
117 |
+
<p>Share your feelings in a safe, supportive space!</p>
|
118 |
+
</div>
|
119 |
+
""", unsafe_allow_html=True)
|
120 |
+
|
121 |
+
with col2:
|
122 |
+
st.markdown("""
|
123 |
+
<div style='background-color: #98FB98; padding: 20px; border-radius: 10px; margin: 10px 0;'>
|
124 |
+
<h3>β¨ She Glows</h3>
|
125 |
+
<p>Learn new skills and level up your life!</p>
|
126 |
+
</div>
|
127 |
+
|
128 |
+
<div style='background-color: #FFB6C1; padding: 20px; border-radius: 10px; margin: 10px 0;'>
|
129 |
+
<h3>π₯ She Fuels</h3>
|
130 |
+
<p>Share your wins and inspire others!</p>
|
131 |
+
</div>
|
132 |
+
""", unsafe_allow_html=True)
|
133 |
+
|
134 |
+
else:
|
135 |
+
# Add home button in main content area when not on home page
|
136 |
+
if st.button("π Back to Home", type="secondary"):
|
137 |
+
switch_page('home')
|
138 |
+
|
139 |
+
# Import and show the appropriate page
|
140 |
+
if st.session_state.current_page == 'legends':
|
141 |
+
from pages.she_legends import show_page
|
142 |
+
show_page()
|
143 |
+
elif st.session_state.current_page == 'mascara':
|
144 |
+
from pages.she_melted_mascara import show_page
|
145 |
+
show_page()
|
146 |
+
elif st.session_state.current_page == 'glows':
|
147 |
+
from pages.she_glows import show_page
|
148 |
+
show_page()
|
149 |
+
elif st.session_state.current_page == 'fuels':
|
150 |
+
from pages.she_fuels import show_page
|
151 |
+
show_page()
|
152 |
+
|
153 |
+
if __name__ == "__main__":
|
154 |
+
show_main()
|
pages/__pycache__/she_fuels.cpython-313.pyc
ADDED
Binary file (4.58 kB). View file
|
|
pages/__pycache__/she_glows.cpython-313.pyc
ADDED
Binary file (8.87 kB). View file
|
|
pages/__pycache__/she_legends.cpython-313.pyc
ADDED
Binary file (8.93 kB). View file
|
|
pages/__pycache__/she_melted_mascara.cpython-313.pyc
ADDED
Binary file (16.2 kB). View file
|
|
pages/init-file.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
# This file can be empty, it just marks the directory as a Python package
|
pages/she_fuels.py
ADDED
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import google.generativeai as genai
|
3 |
+
from datetime import datetime
|
4 |
+
import os
|
5 |
+
from dotenv import load_dotenv
|
6 |
+
|
7 |
+
def show_page():
|
8 |
+
# Configure Gemini
|
9 |
+
load_dotenv()
|
10 |
+
genai.configure(api_key=os.getenv('GOOGLE_API_KEY'))
|
11 |
+
|
12 |
+
# Page title
|
13 |
+
st.title("π₯ She Fuels")
|
14 |
+
st.write("Share your wins & get support! β¨")
|
15 |
+
|
16 |
+
# Initialize session state for posts
|
17 |
+
if 'posts' not in st.session_state:
|
18 |
+
st.session_state.posts = []
|
19 |
+
|
20 |
+
# Two columns layout
|
21 |
+
col1, col2 = st.columns([1, 2])
|
22 |
+
|
23 |
+
with col1:
|
24 |
+
# Simple share form
|
25 |
+
st.markdown("### Share Your Win β¨")
|
26 |
+
|
27 |
+
# Category selection
|
28 |
+
category = st.selectbox(
|
29 |
+
"Type of win:",
|
30 |
+
["β¨ Achievement", "πͺ Challenge Overcome", "π‘ Advice to Share"]
|
31 |
+
)
|
32 |
+
|
33 |
+
# Share story
|
34 |
+
story = st.text_area(
|
35 |
+
"What's your win?",
|
36 |
+
placeholder="Share something you're proud of..."
|
37 |
+
)
|
38 |
+
|
39 |
+
if st.button("Share β¨"):
|
40 |
+
if story:
|
41 |
+
try:
|
42 |
+
# Get AI support response
|
43 |
+
model = genai.GenerativeModel('gemini-pro')
|
44 |
+
prompt = f"""As a supportive friend, respond to this achievement using Gen Z language and emojis:
|
45 |
+
Category: {category}
|
46 |
+
Story: {story}
|
47 |
+
Keep it encouraging and specific to their achievement!"""
|
48 |
+
|
49 |
+
response = model.generate_content(prompt)
|
50 |
+
|
51 |
+
# Add post
|
52 |
+
new_post = {
|
53 |
+
'category': category,
|
54 |
+
'content': story,
|
55 |
+
'support': response.text,
|
56 |
+
'time': datetime.now().strftime("%I:%M %p"),
|
57 |
+
'likes': 0
|
58 |
+
}
|
59 |
+
st.session_state.posts.insert(0, new_post)
|
60 |
+
st.success("Posted! Thanks for sharing! β¨")
|
61 |
+
st.rerun()
|
62 |
+
|
63 |
+
except Exception as e:
|
64 |
+
st.error("Oops! Try sharing again! π")
|
65 |
+
|
66 |
+
with col2:
|
67 |
+
# Display posts
|
68 |
+
st.markdown("### Community Wins β¨")
|
69 |
+
|
70 |
+
for post in st.session_state.posts:
|
71 |
+
with st.container():
|
72 |
+
# Post content with styling
|
73 |
+
st.markdown(f"""
|
74 |
+
<div style='
|
75 |
+
background-color: #FFE4E1;
|
76 |
+
padding: 15px;
|
77 |
+
border-radius: 10px;
|
78 |
+
margin: 10px 0;'>
|
79 |
+
<p style='color: #666; font-size: 0.9em;'>
|
80 |
+
{post['category']} β’ {post['time']}
|
81 |
+
</p>
|
82 |
+
<p>{post['content']}</p>
|
83 |
+
</div>
|
84 |
+
""", unsafe_allow_html=True)
|
85 |
+
|
86 |
+
# AI support message
|
87 |
+
st.info(post['support'])
|
88 |
+
|
89 |
+
# Simple interaction
|
90 |
+
if st.button(f"β¨ Send Support ({post['likes']})", key=f"like_{post['time']}"):
|
91 |
+
post['likes'] += 1
|
92 |
+
st.balloons()
|
93 |
+
st.rerun()
|
94 |
+
|
95 |
+
if not st.session_state.posts:
|
96 |
+
st.markdown("""
|
97 |
+
### Share Your First Win! β¨
|
98 |
+
Be the first to inspire others! π«
|
99 |
+
""")
|
pages/she_glows.py
ADDED
@@ -0,0 +1,199 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import google.generativeai as genai
|
3 |
+
from datetime import datetime
|
4 |
+
import os
|
5 |
+
from dotenv import load_dotenv
|
6 |
+
|
7 |
+
# Initialize Gemini
|
8 |
+
load_dotenv()
|
9 |
+
genai.configure(api_key=os.getenv('GOOGLE_API_KEY'))
|
10 |
+
|
11 |
+
# Learning paths focused on modern skills
|
12 |
+
LEARNING_PATHS = {
|
13 |
+
"π° Money Queen": {
|
14 |
+
"emoji": "π°",
|
15 |
+
"color": "#98FB98",
|
16 |
+
"description": "Master your money! From budgeting to investing, get that bag! π
",
|
17 |
+
"modules": [
|
18 |
+
{
|
19 |
+
"title": "Budget Like a Boss",
|
20 |
+
"topics": ["Personal budgeting", "Saving strategies", "Money mindset"],
|
21 |
+
"prompt": "You're teaching teen girls about {topic}. Use Gen Z language, be encouraging, and give practical examples they can relate to."
|
22 |
+
},
|
23 |
+
{
|
24 |
+
"title": "Investing 101",
|
25 |
+
"topics": ["Stock market basics", "Investment apps", "Long-term planning"],
|
26 |
+
"prompt": "Explain {topic} to teen girls using Gen Z language. Make investing concepts fun and relatable."
|
27 |
+
},
|
28 |
+
{
|
29 |
+
"title": "Side Hustle Era",
|
30 |
+
"topics": ["Online business ideas", "Digital marketing", "Pricing strategies"],
|
31 |
+
"prompt": "Share practical advice about {topic} for teen entrepreneurs. Use trendy language and real examples."
|
32 |
+
}
|
33 |
+
]
|
34 |
+
},
|
35 |
+
"π€ AI & Tech Bestie": {
|
36 |
+
"emoji": "π€",
|
37 |
+
"color": "#FFB6C1",
|
38 |
+
"description": "Slay the AI game! Learn to use AI tools like a pro! β¨",
|
39 |
+
"modules": [
|
40 |
+
{
|
41 |
+
"title": "AI Tools Mastery",
|
42 |
+
"topics": ["Gemini basics", "ChatGPT tips", "Prompt writing"],
|
43 |
+
"prompt": "Teach teen girls how to use {topic}. Include practical examples and creative ways to use AI tools."
|
44 |
+
},
|
45 |
+
{
|
46 |
+
"title": "Content Creation",
|
47 |
+
"topics": ["AI writing tools", "Image generation", "Video editing AI"],
|
48 |
+
"prompt": "Explain how to use {topic} for content creation. Include trendy examples and creative ideas."
|
49 |
+
},
|
50 |
+
{
|
51 |
+
"title": "AI Business Ideas",
|
52 |
+
"topics": ["AI services", "Online tutoring", "Digital products"],
|
53 |
+
"prompt": "Share ideas for {topic} that teen girls can start. Make it practical and achievable."
|
54 |
+
}
|
55 |
+
]
|
56 |
+
},
|
57 |
+
"π Business Queen": {
|
58 |
+
"emoji": "π",
|
59 |
+
"color": "#DDA0DD",
|
60 |
+
"description": "Build your empire! Learn business & marketing secrets! π«",
|
61 |
+
"modules": [
|
62 |
+
{
|
63 |
+
"title": "Business Basics",
|
64 |
+
"topics": ["Business planning", "Market research", "Branding"],
|
65 |
+
"prompt": "Explain {topic} in Gen Z language. Use examples relevant to teen entrepreneurs."
|
66 |
+
},
|
67 |
+
{
|
68 |
+
"title": "Social Media Empire",
|
69 |
+
"topics": ["Content strategy", "Growth hacks", "Monetization"],
|
70 |
+
"prompt": "Share practical tips for {topic}. Include trending platforms and strategies."
|
71 |
+
},
|
72 |
+
{
|
73 |
+
"title": "Customer Queen",
|
74 |
+
"topics": ["Customer service", "Community building", "Brand loyalty"],
|
75 |
+
"prompt": "Teach about {topic} using relatable examples for teen business owners."
|
76 |
+
}
|
77 |
+
]
|
78 |
+
}
|
79 |
+
}
|
80 |
+
|
81 |
+
def get_ai_lesson(path, module, topic):
|
82 |
+
"""Get personalized lesson from Gemini"""
|
83 |
+
try:
|
84 |
+
prompt = f"{LEARNING_PATHS[path]['modules'][module]['prompt'].format(topic=topic)}\n\nProvide a fun, interactive lesson with:\n1. Key points\n2. Real examples\n3. Action steps\n4. Pro tips"
|
85 |
+
model = genai.GenerativeModel('gemini-pro')
|
86 |
+
response = model.generate_content(prompt)
|
87 |
+
return response.text
|
88 |
+
except Exception as e:
|
89 |
+
return "Oops! Let's try that lesson again bestie! π"
|
90 |
+
|
91 |
+
def create_practice_task(path, module, topic):
|
92 |
+
"""Generate practice task using Gemini"""
|
93 |
+
try:
|
94 |
+
prompt = f"""Create a practical task for teen girls learning about {topic}.
|
95 |
+
Make it:
|
96 |
+
1. Fun and engaging
|
97 |
+
2. Actually doable
|
98 |
+
3. Related to real life
|
99 |
+
4. Something they can complete in 15-30 minutes
|
100 |
+
Use Gen Z language and emojis!"""
|
101 |
+
|
102 |
+
model = genai.GenerativeModel('gemini-pro')
|
103 |
+
response = model.generate_content(prompt)
|
104 |
+
return response.text
|
105 |
+
except Exception as e:
|
106 |
+
return "Let's try another task bestie! π"
|
107 |
+
|
108 |
+
def show_page():
|
109 |
+
st.markdown("""
|
110 |
+
<h1 style='text-align: center;'>β¨ She Glows β¨</h1>
|
111 |
+
<p style='text-align: center;'>Level up your skills & secure that bag! π
</p>
|
112 |
+
""", unsafe_allow_html=True)
|
113 |
+
|
114 |
+
# Initialize session state
|
115 |
+
if 'current_path' not in st.session_state:
|
116 |
+
st.session_state.current_path = None
|
117 |
+
if 'progress' not in st.session_state:
|
118 |
+
st.session_state.progress = {}
|
119 |
+
if 'achievements' not in st.session_state:
|
120 |
+
st.session_state.achievements = []
|
121 |
+
|
122 |
+
# Create columns
|
123 |
+
col1, col2 = st.columns([1, 2])
|
124 |
+
|
125 |
+
with col1:
|
126 |
+
st.markdown("### Choose Your Glow Up β¨")
|
127 |
+
|
128 |
+
# Path selection buttons
|
129 |
+
for path, info in LEARNING_PATHS.items():
|
130 |
+
if st.button(
|
131 |
+
f"{info['emoji']} {path}",
|
132 |
+
key=f"path_{path}",
|
133 |
+
use_container_width=True
|
134 |
+
):
|
135 |
+
st.session_state.current_path = path
|
136 |
+
st.rerun()
|
137 |
+
|
138 |
+
# Show achievements
|
139 |
+
if st.session_state.achievements:
|
140 |
+
st.markdown("### Your Achievements π")
|
141 |
+
for achievement in st.session_state.achievements:
|
142 |
+
st.markdown(f"- {achievement['emoji']} {achievement['title']}")
|
143 |
+
|
144 |
+
with col2:
|
145 |
+
if st.session_state.current_path:
|
146 |
+
path = st.session_state.current_path
|
147 |
+
path_info = LEARNING_PATHS[path]
|
148 |
+
|
149 |
+
# Display path info
|
150 |
+
st.markdown(f"""
|
151 |
+
<div style='background-color: {path_info['color']}30;
|
152 |
+
padding: 20px; border-radius: 15px; margin-bottom: 20px;'>
|
153 |
+
<h3>{path_info['emoji']} {path}</h3>
|
154 |
+
<p>{path_info['description']}</p>
|
155 |
+
</div>
|
156 |
+
""", unsafe_allow_html=True)
|
157 |
+
|
158 |
+
# Show modules
|
159 |
+
st.markdown("### Your Modules π")
|
160 |
+
for i, module in enumerate(path_info['modules']):
|
161 |
+
with st.expander(f"{module['title']} β¨"):
|
162 |
+
# Topics in module
|
163 |
+
for topic in module['topics']:
|
164 |
+
st.markdown(f"#### {topic}")
|
165 |
+
|
166 |
+
# Get lesson
|
167 |
+
if st.button(f"Learn about {topic} π", key=f"learn_{topic}"):
|
168 |
+
lesson = get_ai_lesson(path, i, topic)
|
169 |
+
st.markdown(lesson)
|
170 |
+
|
171 |
+
# Practice task
|
172 |
+
st.markdown("### Practice Time! πͺ")
|
173 |
+
task = create_practice_task(path, i, topic)
|
174 |
+
st.info(task)
|
175 |
+
|
176 |
+
# Complete button
|
177 |
+
if st.button("I've completed this! β
", key=f"complete_{topic}"):
|
178 |
+
# Add achievement
|
179 |
+
achievement = {
|
180 |
+
'title': f"Mastered {topic}",
|
181 |
+
'emoji': "π",
|
182 |
+
'date': datetime.now().strftime("%B %d, %Y")
|
183 |
+
}
|
184 |
+
st.session_state.achievements.append(achievement)
|
185 |
+
st.balloons()
|
186 |
+
st.success("Yass queen! Keep slaying! π")
|
187 |
+
st.rerun()
|
188 |
+
|
189 |
+
else:
|
190 |
+
st.markdown("""
|
191 |
+
### Welcome to Your Glow Up Journey! β¨
|
192 |
+
|
193 |
+
Choose your path to start:
|
194 |
+
- π° Money Queen: Master your finances
|
195 |
+
- π€ AI & Tech Bestie: Learn AI tools
|
196 |
+
- π Business Queen: Start your empire
|
197 |
+
|
198 |
+
Let's level up together! π
|
199 |
+
""")
|
pages/she_legends.py
ADDED
@@ -0,0 +1,176 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from elevenlabs import generate, set_api_key, Voice
|
3 |
+
import google.generativeai as genai
|
4 |
+
from datetime import datetime
|
5 |
+
import os
|
6 |
+
from PIL import Image
|
7 |
+
from dotenv import load_dotenv
|
8 |
+
import sys
|
9 |
+
from pathlib import Path
|
10 |
+
|
11 |
+
# Add the root directory to Python path
|
12 |
+
root_dir = Path(__file__).parent.parent
|
13 |
+
sys.path.append(str(root_dir))
|
14 |
+
|
15 |
+
from config import MENTORS
|
16 |
+
|
17 |
+
# Load environment variables
|
18 |
+
load_dotenv()
|
19 |
+
|
20 |
+
# Configure APIs
|
21 |
+
set_api_key(os.getenv('ELEVEN_LABS_API_KEY'))
|
22 |
+
genai.configure(api_key=os.getenv('GOOGLE_API_KEY'))
|
23 |
+
|
24 |
+
def load_mentor_image(mentor_name):
|
25 |
+
"""Load mentor image from path"""
|
26 |
+
try:
|
27 |
+
image_path = os.path.join(root_dir, MENTORS[mentor_name]["image"])
|
28 |
+
return Image.open(image_path)
|
29 |
+
except Exception as e:
|
30 |
+
st.error(f"Error loading image: {str(e)}")
|
31 |
+
return None
|
32 |
+
|
33 |
+
def get_ai_response(mentor, message, conversation_history):
|
34 |
+
"""Get AI response using Gemini"""
|
35 |
+
try:
|
36 |
+
model = genai.GenerativeModel('gemini-pro')
|
37 |
+
prompt = f"{MENTORS[mentor]['prompt']}\n\nPrevious conversation:\n{conversation_history}\n\nUser: {message}\nYou:"
|
38 |
+
|
39 |
+
response = model.generate_content(prompt)
|
40 |
+
return response.text
|
41 |
+
except Exception as e:
|
42 |
+
st.error(f"Error generating response: {str(e)}")
|
43 |
+
return "Sorry bestie, I'm having a moment! Let's try again? β¨"
|
44 |
+
|
45 |
+
def get_voice_response(text, mentor):
|
46 |
+
"""Generate voice response using ElevenLabs"""
|
47 |
+
try:
|
48 |
+
# Debug print to check voice ID
|
49 |
+
print(f"Using voice ID for {mentor}: {MENTORS[mentor]['voice_id']}")
|
50 |
+
|
51 |
+
# Generate audio with direct voice ID
|
52 |
+
audio = generate(
|
53 |
+
text=text,
|
54 |
+
voice=MENTORS[mentor]["voice_id"], # Use voice ID directly
|
55 |
+
model="eleven_monolingual_v1" # Specify model explicitly
|
56 |
+
)
|
57 |
+
|
58 |
+
if audio:
|
59 |
+
print(f"Successfully generated voice for {mentor}")
|
60 |
+
return audio
|
61 |
+
else:
|
62 |
+
st.error(f"No audio generated for {mentor}")
|
63 |
+
return None
|
64 |
+
|
65 |
+
except Exception as e:
|
66 |
+
st.error(f"Error generating voice for {mentor}: {str(e)}")
|
67 |
+
print(f"Voice generation error details: {str(e)}")
|
68 |
+
return None
|
69 |
+
|
70 |
+
def show_page():
|
71 |
+
st.title("π She Legends")
|
72 |
+
st.write("Spill the tea with your fave mentors! They've been through it all and are here to share their wisdom!")
|
73 |
+
|
74 |
+
# Initialize session states
|
75 |
+
if 'messages' not in st.session_state:
|
76 |
+
st.session_state.messages = []
|
77 |
+
if 'current_mentor' not in st.session_state:
|
78 |
+
st.session_state.current_mentor = None
|
79 |
+
|
80 |
+
col1, col2 = st.columns([1, 2])
|
81 |
+
|
82 |
+
with col1:
|
83 |
+
st.markdown("### Choose Your Mentor β¨")
|
84 |
+
for mentor in MENTORS:
|
85 |
+
if st.button(
|
86 |
+
f"{mentor}\n{MENTORS[mentor]['role']}",
|
87 |
+
key=f"select_{mentor}",
|
88 |
+
use_container_width=True
|
89 |
+
):
|
90 |
+
st.session_state.current_mentor = mentor
|
91 |
+
st.session_state.messages = []
|
92 |
+
st.rerun()
|
93 |
+
|
94 |
+
with col2:
|
95 |
+
if st.session_state.current_mentor:
|
96 |
+
mentor = st.session_state.current_mentor
|
97 |
+
mentor_info = MENTORS[mentor]
|
98 |
+
|
99 |
+
# Display mentor card with image
|
100 |
+
col_img, col_info = st.columns([1, 2])
|
101 |
+
with col_img:
|
102 |
+
image = load_mentor_image(mentor)
|
103 |
+
if image:
|
104 |
+
st.image(image, use_container_width=True)
|
105 |
+
|
106 |
+
with col_info:
|
107 |
+
st.markdown(f"""
|
108 |
+
<div style='background-color: {mentor_info["background"]}; padding: 20px; border-radius: 15px;'>
|
109 |
+
<h2>{mentor}</h2>
|
110 |
+
<p><strong>{mentor_info['role']}</strong></p>
|
111 |
+
<p><em>"{mentor_info['quote']}"</em></p>
|
112 |
+
<p>{mentor_info['description']}</p>
|
113 |
+
</div>
|
114 |
+
""", unsafe_allow_html=True)
|
115 |
+
|
116 |
+
# Chat interface
|
117 |
+
st.markdown("### π Chat Space")
|
118 |
+
|
119 |
+
for message in st.session_state.messages:
|
120 |
+
with st.chat_message(message["role"]):
|
121 |
+
st.write(message["content"])
|
122 |
+
if message["role"] == "assistant" and "audio" in message:
|
123 |
+
st.audio(message["audio"])
|
124 |
+
|
125 |
+
# Chat input
|
126 |
+
user_message = st.chat_input(f"Ask {mentor} anything...")
|
127 |
+
if user_message:
|
128 |
+
# Add user message
|
129 |
+
st.session_state.messages.append({
|
130 |
+
"role": "user",
|
131 |
+
"content": user_message,
|
132 |
+
"timestamp": datetime.now().strftime("%I:%M %p")
|
133 |
+
})
|
134 |
+
|
135 |
+
# Get AI response
|
136 |
+
conversation_history = "\n".join([
|
137 |
+
f"{'User' if m['role']=='user' else 'You'}: {m['content']}"
|
138 |
+
for m in st.session_state.messages[-5:]
|
139 |
+
])
|
140 |
+
|
141 |
+
ai_response = get_ai_response(mentor, user_message, conversation_history)
|
142 |
+
audio = get_voice_response(ai_response, mentor)
|
143 |
+
|
144 |
+
# Add mentor response
|
145 |
+
st.session_state.messages.append({
|
146 |
+
"role": "assistant",
|
147 |
+
"content": ai_response,
|
148 |
+
"audio": audio,
|
149 |
+
"timestamp": datetime.now().strftime("%I:%M %p")
|
150 |
+
})
|
151 |
+
|
152 |
+
st.rerun()
|
153 |
+
|
154 |
+
else:
|
155 |
+
st.markdown("""
|
156 |
+
### Hey Bestie! π
|
157 |
+
Choose your fave mentor from the left to start chatting!
|
158 |
+
Each queen brings their own unique vibe and wisdom! β¨
|
159 |
+
""")
|
160 |
+
|
161 |
+
# Preview all mentors with images
|
162 |
+
for mentor, info in MENTORS.items():
|
163 |
+
col_img, col_info = st.columns([1, 3])
|
164 |
+
with col_img:
|
165 |
+
image = load_mentor_image(mentor)
|
166 |
+
if image:
|
167 |
+
st.image(image, use_container_width=True)
|
168 |
+
|
169 |
+
with col_info:
|
170 |
+
st.markdown(f"""
|
171 |
+
<div style='background-color: {info["background"]}40; padding: 20px; border-radius: 15px;'>
|
172 |
+
<h3>{mentor}</h3>
|
173 |
+
<p>{info['role']}</p>
|
174 |
+
<p><em>"{info['quote']}"</em></p>
|
175 |
+
</div>
|
176 |
+
""", unsafe_allow_html=True)
|
pages/she_melted_mascara.py
ADDED
@@ -0,0 +1,331 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from datetime import datetime
|
3 |
+
import os
|
4 |
+
import google.generativeai as genai
|
5 |
+
from dotenv import load_dotenv
|
6 |
+
from PIL import Image
|
7 |
+
import io
|
8 |
+
|
9 |
+
# Load environment variables
|
10 |
+
load_dotenv()
|
11 |
+
genai.configure(api_key=os.getenv('GOOGLE_API_KEY'))
|
12 |
+
|
13 |
+
# Define categories with their properties
|
14 |
+
CATEGORIES = {
|
15 |
+
"π Heartbreak Hotel": {
|
16 |
+
"color": "#FFB6C1",
|
17 |
+
"prompt": "You are an empathetic friend helping with heartbreak. Use gentle, supportive, Gen Z language.",
|
18 |
+
"description": "Share your heart feels & get support π"
|
19 |
+
},
|
20 |
+
"π Family Tea": {
|
21 |
+
"color": "#E6E6FA",
|
22 |
+
"prompt": "You are a wise friend helping with family issues. Use understanding, Gen Z language.",
|
23 |
+
"description": "Spill the family tea & get advice π«"
|
24 |
+
},
|
25 |
+
"π School Stress": {
|
26 |
+
"color": "#98FB98",
|
27 |
+
"prompt": "You are a supportive friend helping with school stress. Use encouraging, Gen Z language.",
|
28 |
+
"description": "Academic pressure? Let's talk it out π"
|
29 |
+
},
|
30 |
+
"π§ Mental Health": {
|
31 |
+
"color": "#DDA0DD",
|
32 |
+
"prompt": "You are a caring friend and art therapist helping with mental health. Use gentle, supportive Gen Z language.",
|
33 |
+
"description": "Safe space for mental health chat & art sharing π"
|
34 |
+
}
|
35 |
+
}
|
36 |
+
|
37 |
+
def get_ai_response(message, category, image=None):
|
38 |
+
"""Get supportive response from Gemini"""
|
39 |
+
try:
|
40 |
+
if image:
|
41 |
+
model = genai.GenerativeModel('gemini-pro-vision')
|
42 |
+
prompt = f"""As an empathetic art therapist for teens, analyze this drawing:
|
43 |
+
1. Describe the emotions expressed
|
44 |
+
2. Note any significant elements or symbols
|
45 |
+
3. Provide gentle, supportive feedback
|
46 |
+
4. Ask a caring question about their feelings
|
47 |
+
Use Gen Z friendly language and be very supportive."""
|
48 |
+
response = model.generate_content([prompt, image])
|
49 |
+
else:
|
50 |
+
model = genai.GenerativeModel('gemini-pro')
|
51 |
+
prompt = f"{CATEGORIES[category]['prompt']}\nUser: {message}\nRespond with empathy and support:"
|
52 |
+
response = model.generate_content(prompt)
|
53 |
+
return response.text
|
54 |
+
except Exception as e:
|
55 |
+
return "I'm here for you bestie! Let's try chatting again? π"
|
56 |
+
|
57 |
+
def show_page():
|
58 |
+
st.title("π§ She Melted Mascara")
|
59 |
+
st.write("Your safe space to let it all out! No filter needed here bestie π")
|
60 |
+
|
61 |
+
# Initialize session states
|
62 |
+
if 'current_category' not in st.session_state:
|
63 |
+
st.session_state.current_category = None
|
64 |
+
if 'chat_history' not in st.session_state:
|
65 |
+
st.session_state.chat_history = {}
|
66 |
+
for category in CATEGORIES:
|
67 |
+
st.session_state.chat_history[category] = []
|
68 |
+
if 'community_posts' not in st.session_state:
|
69 |
+
st.session_state.community_posts = []
|
70 |
+
if 'view' not in st.session_state:
|
71 |
+
st.session_state.view = 'categories'
|
72 |
+
|
73 |
+
# Layout
|
74 |
+
col1, col2 = st.columns([1, 2])
|
75 |
+
|
76 |
+
# Left Column Navigation
|
77 |
+
with col1:
|
78 |
+
st.markdown("### Choose Your Space π")
|
79 |
+
|
80 |
+
# Category buttons
|
81 |
+
for category in CATEGORIES:
|
82 |
+
if st.button(
|
83 |
+
f"{category}\n{CATEGORIES[category]['description']}",
|
84 |
+
key=f"cat_{category}",
|
85 |
+
use_container_width=True
|
86 |
+
):
|
87 |
+
st.session_state.current_category = category
|
88 |
+
st.session_state.view = 'chat'
|
89 |
+
st.rerun()
|
90 |
+
|
91 |
+
# Community button
|
92 |
+
if st.button("π Community Board\nSee shared stories & support others",
|
93 |
+
key="community", use_container_width=True):
|
94 |
+
st.session_state.view = 'community'
|
95 |
+
st.rerun()
|
96 |
+
|
97 |
+
# Right Column Content
|
98 |
+
with col2:
|
99 |
+
if st.session_state.view == 'chat' and st.session_state.current_category:
|
100 |
+
category = st.session_state.current_category
|
101 |
+
|
102 |
+
# Category Header
|
103 |
+
st.markdown(f"""
|
104 |
+
<div style='background-color: {CATEGORIES[category]["color"]}40;
|
105 |
+
padding: 15px; border-radius: 10px; margin-bottom: 20px;'>
|
106 |
+
<h3>{category}</h3>
|
107 |
+
<p>{CATEGORIES[category]["description"]}</p>
|
108 |
+
</div>
|
109 |
+
""", unsafe_allow_html=True)
|
110 |
+
|
111 |
+
# Chat mode selection
|
112 |
+
chat_mode = st.radio(
|
113 |
+
"Choose your chat mode:",
|
114 |
+
["π Private Chat", "β¨ Public Share"],
|
115 |
+
horizontal=True
|
116 |
+
)
|
117 |
+
|
118 |
+
if chat_mode == "π Private Chat":
|
119 |
+
# Mental Health category special features
|
120 |
+
if category == "π§ Mental Health":
|
121 |
+
tab1, tab2 = st.tabs(["π Chat", "π¨ Art Expression"])
|
122 |
+
|
123 |
+
with tab1:
|
124 |
+
# Display chat history
|
125 |
+
for message in st.session_state.chat_history[category]:
|
126 |
+
with st.chat_message(message["role"]):
|
127 |
+
st.write(message["content"])
|
128 |
+
if "image" in message:
|
129 |
+
st.image(message["image"])
|
130 |
+
|
131 |
+
# Chat input
|
132 |
+
if prompt := st.chat_input("Share your feelings..."):
|
133 |
+
# Add user message
|
134 |
+
st.session_state.chat_history[category].append({
|
135 |
+
"role": "user",
|
136 |
+
"content": prompt,
|
137 |
+
"timestamp": datetime.now().strftime("%I:%M %p")
|
138 |
+
})
|
139 |
+
|
140 |
+
# Get AI response
|
141 |
+
response = get_ai_response(prompt, category)
|
142 |
+
st.session_state.chat_history[category].append({
|
143 |
+
"role": "assistant",
|
144 |
+
"content": response,
|
145 |
+
"timestamp": datetime.now().strftime("%I:%M %p")
|
146 |
+
})
|
147 |
+
st.rerun()
|
148 |
+
|
149 |
+
with tab2:
|
150 |
+
st.write("Express yourself through art π¨")
|
151 |
+
uploaded_file = st.file_uploader(
|
152 |
+
"Upload your drawing",
|
153 |
+
type=['png', 'jpg', 'jpeg']
|
154 |
+
)
|
155 |
+
|
156 |
+
if uploaded_file:
|
157 |
+
image = Image.open(uploaded_file)
|
158 |
+
st.image(image, caption="Your artwork")
|
159 |
+
|
160 |
+
share_option = st.radio(
|
161 |
+
"Would you like to:",
|
162 |
+
["Keep private & get AI feedback", "Share with community"],
|
163 |
+
key="art_share_option"
|
164 |
+
)
|
165 |
+
|
166 |
+
if st.button("π« Process Artwork"):
|
167 |
+
if share_option == "Keep private & get AI feedback":
|
168 |
+
# Add to private chat
|
169 |
+
st.session_state.chat_history[category].append({
|
170 |
+
"role": "user",
|
171 |
+
"content": "I made this drawing to express my feelings...",
|
172 |
+
"image": image,
|
173 |
+
"timestamp": datetime.now().strftime("%I:%M %p")
|
174 |
+
})
|
175 |
+
|
176 |
+
# Get AI analysis
|
177 |
+
response = get_ai_response(None, category, image)
|
178 |
+
st.session_state.chat_history[category].append({
|
179 |
+
"role": "assistant",
|
180 |
+
"content": response,
|
181 |
+
"timestamp": datetime.now().strftime("%I:%M %p")
|
182 |
+
})
|
183 |
+
else:
|
184 |
+
# Share with community
|
185 |
+
st.session_state.community_posts.insert(0, {
|
186 |
+
"category": category,
|
187 |
+
"content": "Sharing my feelings through art...",
|
188 |
+
"image": image,
|
189 |
+
"timestamp": datetime.now().strftime("%I:%M %p"),
|
190 |
+
"hugs": 0,
|
191 |
+
"support": 0,
|
192 |
+
"comments": []
|
193 |
+
})
|
194 |
+
st.rerun()
|
195 |
+
|
196 |
+
else:
|
197 |
+
# Regular chat interface for other categories
|
198 |
+
for message in st.session_state.chat_history[category]:
|
199 |
+
with st.chat_message(message["role"]):
|
200 |
+
st.write(message["content"])
|
201 |
+
|
202 |
+
if prompt := st.chat_input("Tell me what's on your mind..."):
|
203 |
+
# Add user message
|
204 |
+
st.session_state.chat_history[category].append({
|
205 |
+
"role": "user",
|
206 |
+
"content": prompt,
|
207 |
+
"timestamp": datetime.now().strftime("%I:%M %p")
|
208 |
+
})
|
209 |
+
|
210 |
+
# Get AI response
|
211 |
+
response = get_ai_response(prompt, category)
|
212 |
+
st.session_state.chat_history[category].append({
|
213 |
+
"role": "assistant",
|
214 |
+
"content": response,
|
215 |
+
"timestamp": datetime.now().strftime("%I:%M %p")
|
216 |
+
})
|
217 |
+
st.rerun()
|
218 |
+
|
219 |
+
else: # Public Share mode
|
220 |
+
with st.form(key=f"public_share_{category}"):
|
221 |
+
st.write("Share with the community π")
|
222 |
+
share_text = st.text_area("Your story matters!")
|
223 |
+
|
224 |
+
col1, col2 = st.columns(2)
|
225 |
+
with col1:
|
226 |
+
anonymous = st.checkbox("Stay anonymous", value=True)
|
227 |
+
with col2:
|
228 |
+
allow_comments = st.checkbox("Allow comments", value=True)
|
229 |
+
|
230 |
+
if st.form_submit_button("Share π"):
|
231 |
+
if share_text:
|
232 |
+
# Get AI support message
|
233 |
+
support_msg = get_ai_response(share_text, category)
|
234 |
+
|
235 |
+
# Add to community posts
|
236 |
+
st.session_state.community_posts.insert(0, {
|
237 |
+
"category": category,
|
238 |
+
"content": share_text,
|
239 |
+
"support_message": support_msg,
|
240 |
+
"timestamp": datetime.now().strftime("%I:%M %p"),
|
241 |
+
"anonymous": anonymous,
|
242 |
+
"allow_comments": allow_comments,
|
243 |
+
"hugs": 0,
|
244 |
+
"support": 0,
|
245 |
+
"comments": []
|
246 |
+
})
|
247 |
+
st.success("Thanks for sharing, bestie! π")
|
248 |
+
st.rerun()
|
249 |
+
|
250 |
+
elif st.session_state.view == 'community':
|
251 |
+
st.markdown("### π Community Board")
|
252 |
+
|
253 |
+
# Filter options
|
254 |
+
col1, col2 = st.columns([2, 1])
|
255 |
+
with col1:
|
256 |
+
filter_cat = st.selectbox(
|
257 |
+
"Filter by category",
|
258 |
+
["All"] + list(CATEGORIES.keys())
|
259 |
+
)
|
260 |
+
with col2:
|
261 |
+
sort_by = st.selectbox(
|
262 |
+
"Sort by",
|
263 |
+
["Latest", "Most Support", "Most Hugs"]
|
264 |
+
)
|
265 |
+
|
266 |
+
# Sort posts
|
267 |
+
posts = st.session_state.community_posts.copy()
|
268 |
+
if sort_by == "Most Support":
|
269 |
+
posts.sort(key=lambda x: x.get('support', 0), reverse=True)
|
270 |
+
elif sort_by == "Most Hugs":
|
271 |
+
posts.sort(key=lambda x: x.get('hugs', 0), reverse=True)
|
272 |
+
|
273 |
+
# Display posts
|
274 |
+
for idx, post in enumerate(posts):
|
275 |
+
if filter_cat == "All" or filter_cat == post["category"]:
|
276 |
+
with st.container():
|
277 |
+
# Post content
|
278 |
+
st.markdown(f"""
|
279 |
+
<div style='background-color: {CATEGORIES[post["category"]]["color"]}40;
|
280 |
+
padding: 15px; border-radius: 10px; margin: 10px 0;'>
|
281 |
+
<p style='color: #666; font-size: 0.9em;'>
|
282 |
+
{post["category"]} β’ {"Anonymous" if post.get("anonymous", True) else "Someone"} β’ {post["timestamp"]}
|
283 |
+
</p>
|
284 |
+
<p>{post["content"]}</p>
|
285 |
+
</div>
|
286 |
+
""", unsafe_allow_html=True)
|
287 |
+
|
288 |
+
# Display image if present
|
289 |
+
if "image" in post:
|
290 |
+
st.image(post["image"])
|
291 |
+
|
292 |
+
# Support message if present
|
293 |
+
if "support_message" in post:
|
294 |
+
st.info(post["support_message"])
|
295 |
+
|
296 |
+
# Interaction buttons
|
297 |
+
col1, col2, col3 = st.columns([1,1,2])
|
298 |
+
with col1:
|
299 |
+
if st.button(f"π« Hug ({post.get('hugs', 0)})", key=f"hug_{idx}"):
|
300 |
+
post['hugs'] = post.get('hugs', 0) + 1
|
301 |
+
st.rerun()
|
302 |
+
with col2:
|
303 |
+
if st.button(f"π Support ({post.get('support', 0)})", key=f"support_{idx}"):
|
304 |
+
post['support'] = post.get('support', 0) + 1
|
305 |
+
st.rerun()
|
306 |
+
with col3:
|
307 |
+
if post.get('allow_comments', True):
|
308 |
+
with st.expander("π Comments"):
|
309 |
+
# Display existing comments
|
310 |
+
for comment in post.get('comments', []):
|
311 |
+
st.write(f"Anonymous: {comment}")
|
312 |
+
|
313 |
+
# Add new comment
|
314 |
+
new_comment = st.text_input("Add a supportive comment", key=f"comment_{idx}")
|
315 |
+
if st.button("Send π", key=f"send_{idx}"):
|
316 |
+
if new_comment:
|
317 |
+
if 'comments' not in post:
|
318 |
+
post['comments'] = []
|
319 |
+
post['comments'].append(new_comment)
|
320 |
+
st.rerun()
|
321 |
+
|
322 |
+
else:
|
323 |
+
st.markdown("""
|
324 |
+
### Welcome to Your Safe Space! π
|
325 |
+
Choose a category on the left to:
|
326 |
+
- Chat privately with AI support
|
327 |
+
- Share with the community
|
328 |
+
- Give and receive support
|
329 |
+
|
330 |
+
Remember: You're never alone here! π«
|
331 |
+
""")
|
requirements-final.txt
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
streamlit==1.24.0
|
2 |
+
google-generativeai==0.3.1
|
3 |
+
elevenlabs==0.2.24
|
4 |
+
python-dotenv==1.0.0
|
5 |
+
Pillow==9.5.0
|
6 |
+
requests==2.31.0
|
7 |
+
python-dateutil==2.8.2
|