Shrey0405 commited on
Commit
ee19551
ยท
verified ยท
1 Parent(s): 7a02ad3

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +226 -95
src/streamlit_app.py CHANGED
@@ -1,106 +1,237 @@
1
  import streamlit as st
 
2
 
3
- st.set_page_config(page_title="FitPlan AI", page_icon="๐Ÿ’ช", layout="wide")
4
-
5
- # ---------- Custom Professional Colorful CSS ----------
6
  st.markdown("""
7
  <style>
8
- /* App Background Gradient */
9
- .stApp {
10
- background: linear-gradient(135deg, #1f3c88, #39a2db, #a1c4fd);
11
- background-attachment: fixed;
12
- }
13
-
14
- /* Main Card */
15
- .main-card {
16
- background: rgba(255, 255, 255, 0.95);
17
- padding: 40px;
18
- border-radius: 20px;
19
- box-shadow: 0px 10px 30px rgba(0,0,0,0.15);
20
- }
21
-
22
- /* Title */
23
- .title-text {
24
- font-size: 32px;
25
- font-weight: 700;
26
- color: #1f3c88;
27
- }
28
-
29
- /* Subtitle */
30
- .subtitle-text {
31
- color: #555;
32
- margin-bottom: 20px;
33
- }
34
-
35
- /* Button Styling */
36
- .stButton>button {
37
- background: linear-gradient(90deg, #1f3c88, #39a2db);
38
- color: white;
39
- font-size: 16px;
40
- font-weight: 600;
41
- border-radius: 10px;
42
- padding: 10px 20px;
43
- border: none;
44
- }
45
-
46
- .stButton>button:hover {
47
- background: linear-gradient(90deg, #162a5c, #2b7fb3);
48
- color: white;
49
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  </style>
51
  """, unsafe_allow_html=True)
52
 
53
- # ---------- Card Container ----------
54
- st.markdown("<div class='main-card'>", unsafe_allow_html=True)
55
-
56
- st.markdown("<div class='title-text'>๐Ÿ‹๏ธ FitPlan AI</div>", unsafe_allow_html=True)
57
- st.markdown("<div class='subtitle-text'>Create your personalized fitness journey.</div>", unsafe_allow_html=True)
58
-
59
- st.divider()
60
-
61
- # ---------- Layout ----------
62
- col1, col2 = st.columns(2)
63
-
 
 
 
 
 
 
 
 
 
64
  with col1:
65
- goal = st.selectbox(
66
- "๐ŸŽฏ Select Your Fitness Goal",
67
- ["Build Muscle", "Lose Weight", "Improve Endurance"]
68
- )
69
-
70
- level = st.radio(
71
- "๐Ÿ“Š Fitness Level",
72
- ["Beginner", "Intermediate", "Advanced"],
73
- horizontal=True
74
- )
75
-
76
  with col2:
77
- equipment = st.multiselect(
78
- "๐Ÿ‹๏ธ Available Equipment",
79
- ["Dumbbells", "Resistance Bands", "Barbell", "No Equipment"]
80
- )
81
-
82
- age = st.number_input("๐ŸŽ‚ Age", min_value=15, max_value=70)
83
-
84
- st.divider()
85
-
86
- # ---------- Button ----------
87
- if st.button("๐Ÿš€ Generate Personalized Plan", use_container_width=True):
88
-
89
- st.success("Your fitness plan is ready!")
90
-
91
- st.markdown("### ๐Ÿ“‹ Profile Summary")
92
- st.write(f"**Goal:** {goal}")
93
- st.write(f"**Fitness Level:** {level}")
94
- st.write(f"**Equipment:** {', '.join(equipment) if equipment else 'None'}")
95
- st.write(f"**Age:** {age}")
96
-
97
- st.markdown("### ๐Ÿ† Recommended Plan")
98
-
99
- if goal == "Lose Weight":
100
- st.info("โ€ข 30 min Cardio\nโ€ข 3 Days HIIT\nโ€ข Calorie Deficit Diet")
101
- elif goal == "Build Muscle":
102
- st.info("โ€ข 5 Day Strength Split\nโ€ข Progressive Overload\nโ€ข High Protein Diet")
 
 
 
 
 
 
 
 
103
  else:
104
- st.info("โ€ข Mixed Cardio + Functional Training\nโ€ข Mobility Work\nโ€ข Balanced Diet")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
- st.markdown("</div>", unsafe_allow_html=True)
 
1
  import streamlit as st
2
+ import math
3
 
4
+ # Custom CSS for professional, innovative look
 
 
5
  st.markdown("""
6
  <style>
7
+ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
8
+
9
+ .main {
10
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
11
+ padding: 2rem;
12
+ font-family: 'Poppins', sans-serif;
13
+ }
14
+
15
+ .stApp {
16
+ background-color: transparent;
17
+ }
18
+
19
+ h1 {
20
+ color: white !important;
21
+ font-weight: 700;
22
+ text-align: center;
23
+ text-shadow: 0 4px 8px rgba(0,0,0,0.3);
24
+ margin-bottom: 2rem;
25
+ }
26
+
27
+ .fitness-card {
28
+ background: rgba(255, 255, 255, 0.95);
29
+ padding: 2rem;
30
+ border-radius: 20px;
31
+ box-shadow: 0 20px 40px rgba(0,0,0,0.1);
32
+ backdrop-filter: blur(10px);
33
+ border: 1px solid rgba(255,255,255,0.2);
34
+ margin-bottom: 1.5rem;
35
+ }
36
+
37
+ .stTextInput > div > div > input {
38
+ border-radius: 12px;
39
+ border: 2px solid #e1e5e9;
40
+ padding: 12px 16px;
41
+ font-size: 16px;
42
+ transition: all 0.3s ease;
43
+ }
44
+
45
+ .stTextInput > div > div > input:focus {
46
+ border-color: #667eea;
47
+ box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
48
+ }
49
+
50
+ .stSelectbox > div > div > select {
51
+ border-radius: 12px;
52
+ border: 2px solid #e1e5e9;
53
+ padding: 12px 16px;
54
+ font-size: 16px;
55
+ transition: all 0.3s ease;
56
+ }
57
+
58
+ .stSelectbox > div > div > select:focus {
59
+ border-color: #667eea;
60
+ box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
61
+ }
62
+
63
+ .stMultiSelect > div > div {
64
+ border-radius: 12px;
65
+ border: 2px solid #e1e5e9;
66
+ }
67
+
68
+ .stButton > button {
69
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
70
+ color: white;
71
+ border: none;
72
+ border-radius: 12px;
73
+ padding: 14px 32px;
74
+ font-weight: 600;
75
+ font-size: 16px;
76
+ transition: all 0.3s ease;
77
+ box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
78
+ width: 100%;
79
+ }
80
+
81
+ .stButton > button:hover {
82
+ transform: translateY(-2px);
83
+ box-shadow: 0 12px 35px rgba(102, 126, 234, 0.6);
84
+ }
85
+
86
+ .bmi-result {
87
+ background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);
88
+ color: white;
89
+ padding: 1.5rem;
90
+ border-radius: 20px;
91
+ text-align: center;
92
+ box-shadow: 0 15px 35px rgba(17, 153, 142, 0.4);
93
+ font-size: 1.2rem;
94
+ font-weight: 600;
95
+ }
96
+
97
+ .bmi-underweight { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); box-shadow: 0 15px 35px rgba(240, 147, 251, 0.4); }
98
+ .bmi-normal { background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); box-shadow: 0 15px 35px rgba(79, 172, 254, 0.4); }
99
+ .bmi-overweight { background: linear-gradient(135deg, #fa709a 0%, #fee140 100%); box-shadow: 0 15px 35px rgba(250, 112, 154, 0.4); }
100
+ .bmi-obese { background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%); box-shadow: 0 15px 35px rgba(255, 154, 158, 0.4); }
101
+
102
+ .metric-card {
103
+ background: rgba(255, 255, 255, 0.9);
104
+ padding: 1.5rem;
105
+ border-radius: 16px;
106
+ text-align: center;
107
+ box-shadow: 0 10px 30px rgba(0,0,0,0.1);
108
+ margin: 1rem 0;
109
+ }
110
+
111
+ .error-message {
112
+ background: #fee;
113
+ color: #c33;
114
+ padding: 1rem;
115
+ border-radius: 12px;
116
+ border-left: 4px solid #c33;
117
+ }
118
  </style>
119
  """, unsafe_allow_html=True)
120
 
121
+ st.title("๐Ÿ’ช Fitness Profile Builder")
122
+
123
+ # Sidebar for instructions
124
+ with st.sidebar:
125
+ st.markdown("## ๐Ÿ“‹ How to Use")
126
+ st.markdown("- Fill in your details")
127
+ st.markdown("- Select your fitness preferences")
128
+ st.markdown("- Click **Calculate BMI**")
129
+ st.markdown("- Get your personalized fitness profile!")
130
+ st.markdown("---")
131
+ st.markdown("*Ready to transform your fitness journey? ๐Ÿš€*")
132
+
133
+ # Initialize session state
134
+ if 'show_result' not in st.session_state:
135
+ st.session_state.show_result = False
136
+
137
+ # Personal Information
138
+ st.markdown('<div class="fitness-card">', unsafe_allow_html=True)
139
+ st.subheader("๐Ÿ‘ค Personal Information")
140
+ col1, col2, col3 = st.columns(3)
141
  with col1:
142
+ name = st.text_input("Full Name", key="name", help="Enter your full name")
 
 
 
 
 
 
 
 
 
 
143
  with col2:
144
+ height_cm = st.number_input("Height (cm)", min_value=0.1, value=170.0, step=0.1, key="height", help="Enter height in centimeters")
145
+ with col3:
146
+ weight_kg = st.number_input("Weight (kg)", min_value=0.1, value=70.0, step=0.1, key="weight", help="Enter weight in kilograms")
147
+
148
+ st.markdown('</div>', unsafe_allow_html=True)
149
+
150
+ # Fitness Details
151
+ st.markdown('<div class="fitness-card">', unsafe_allow_html=True)
152
+ st.subheader("๐ŸŽฏ Fitness Details")
153
+
154
+ col4, col5, col6 = st.columns([1,1,1])
155
+ with col4:
156
+ goal = st.selectbox("Fitness Goal", ["Build Muscle", "Weight Loss", "Strength Gain", "Abs Building", "Flexible"], key="goal")
157
+ with col5:
158
+ fitness_level = st.selectbox("Fitness Level", ["Beginner", "Intermediate", "Advanced"], key="level")
159
+ with col6:
160
+ equipment = st.multiselect("Available Equipment",
161
+ ["Dumbbells", "Resistance Band", "Yoga Mat", "No Equipment", "Barbell", "Pull-up Bar", "Treadmill"],
162
+ default=["No Equipment"], key="equip")
163
+
164
+ st.markdown('</div>', unsafe_allow_html=True)
165
+
166
+ # Calculate button
167
+ if st.button("๐Ÿงฎ Calculate BMI & Generate Profile", key="calc", help="Click to compute your BMI and view profile"):
168
+ # Validation
169
+ if not name.strip():
170
+ st.error("โŒ Please enter your name.")
171
+ st.session_state.show_result = False
172
+ elif height_cm <= 0:
173
+ st.error("โŒ Height must be greater than 0.")
174
+ st.session_state.show_result = False
175
+ elif weight_kg <= 0:
176
+ st.error("โŒ Weight must be greater than 0.")
177
+ st.session_state.show_result = False
178
  else:
179
+ # BMI Calculation
180
+ height_m = height_cm / 100
181
+ bmi = round(weight_kg / (height_m ** 2), 2)
182
+
183
+ # BMI Category
184
+ if bmi < 18.5:
185
+ category = "Underweight"
186
+ category_class = "bmi-underweight"
187
+ elif 18.5 <= bmi < 25:
188
+ category = "Normal"
189
+ category_class = "bmi-normal"
190
+ elif 25 <= bmi < 30:
191
+ category = "Overweight"
192
+ category_class = "bmi-overweight"
193
+ else:
194
+ category = "Obese"
195
+ category_class = "bmi-obese"
196
+
197
+ st.session_state.bmi = bmi
198
+ st.session_state.category = category
199
+ st.session_state.category_class = category_class
200
+ st.session_state.show_result = True
201
+
202
+ # Display Results
203
+ if st.session_state.show_result:
204
+ st.markdown('<div class="fitness-card">', unsafe_allow_html=True)
205
+ st.subheader(f"โœ… Profile for {name.title()}")
206
+
207
+ # BMI Result Card
208
+ bmi_html = f'''
209
+ <div class="bmi-result {st.session_state.category_class}">
210
+ <h2 style="margin: 0;">BMI: {st.session_state.bmi}</h2>
211
+ <h3 style="margin: 0 0 1rem 0;">{st.session_state.category}</h3>
212
+ <p>Height: {height_cm} cm | Weight: {weight_kg} kg</p>
213
+ </div>
214
+ '''
215
+ st.markdown(bmi_html, unsafe_allow_html=True)
216
+
217
+ # Summary Cards
218
+ col_a, col_b, col_c = st.columns(3)
219
+ with col_a:
220
+ st.markdown('<div class="metric-card">', unsafe_allow_html=True)
221
+ st.metric("Goal", goal)
222
+ st.markdown('</div>', unsafe_allow_html=True)
223
+ with col_b:
224
+ st.markdown('<div class="metric-card">', unsafe_allow_html=True)
225
+ st.metric("Level", fitness_level)
226
+ st.markdown('</div>', unsafe_allow_html=True)
227
+ with col_c:
228
+ st.markdown('<div class="metric-card">', unsafe_allow_html=True)
229
+ st.metric("Equipment", ", ".join(equipment))
230
+ st.markdown('</div>', unsafe_allow_html=True)
231
+
232
+ st.markdown('</div>', unsafe_allow_html=True)
233
+
234
+ # Footer
235
+ st.markdown("---")
236
+ st.markdown("<p style='text-align: center; color: rgba(255,255,255,0.8); font-size: 0.9rem;'>Deployed on Hugging Face Spaces | Built with โค๏ธ using Streamlit</p>", unsafe_allow_html=True)
237