Amrutha04 commited on
Commit
4abfe83
·
verified ·
1 Parent(s): 5a0c3c2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +97 -114
app.py CHANGED
@@ -2,144 +2,127 @@ import streamlit as st
2
  from prompt_builder import build_prompt
3
  from model_api import query_model
4
 
 
5
  st.set_page_config(page_title="FitPlan AI", layout="wide")
6
 
7
- # Optimized CSS for Unified Daily Cards
8
  st.markdown("""
9
  <style>
10
  .stApp { background: linear-gradient(135deg, #f6d365 0%, #fda085 100%); background-attachment: fixed; }
11
  section[data-testid="stSidebar"] { background-color: #000000 !important; }
12
- section[data-testid="stSidebar"] h1, section[data-testid="stSidebar"] p { color: #FFFFFF !important; }
13
 
14
- /* Assessment Card */
15
- .assessment-card {
16
- background-color: white !important; padding: 25px; border-radius: 15px;
17
- border-left: 10px solid #004d57; color: #000000 !important; margin-bottom: 30px;
18
- }
19
-
20
- /* Single Unified White Box Per Day */
21
  .day-container {
22
  background-color: white !important;
23
  padding: 30px;
24
  border-radius: 25px;
25
- margin-bottom: 40px;
26
- box-shadow: 0 10px 30px rgba(0,0,0,0.1);
 
27
  }
 
28
 
29
- .day-header {
30
- color: #004d57;
31
- font-size: 26px;
32
- font-weight: bold;
33
- margin-bottom: 20px;
34
- display: flex;
35
- align-items: center;
36
- border-bottom: 2px solid #f0f2f6;
37
- padding-bottom: 15px;
38
- }
39
-
40
- /* Clean Exercise Rows inside the Unified Box */
41
- .exercise-row {
42
- display: flex;
43
- align-items: center;
44
- justify-content: space-between;
45
- padding: 18px 0;
46
- border-bottom: 1px solid #f1f1f1;
47
- }
48
  .exercise-row:last-child { border-bottom: none; }
49
-
50
- .ex-name { flex: 2; font-weight: 600; color: #2d3436; font-size: 18px; display: flex; align-items: center; }
51
-
52
  .stat-group { display: flex; gap: 15px; flex: 1.5; justify-content: flex-end; }
53
-
54
- .stat-pill {
55
- text-align: center;
56
- min-width: 75px;
57
- background: #f8f9fa;
58
- padding: 6px;
59
- border-radius: 12px;
60
- }
61
-
62
  .stat-val { color: #004d57; font-weight: bold; font-size: 15px; display: block; }
63
- .stat-label { font-size: 10px; color: #636e72; text-transform: uppercase; display: block; margin-top: 2px; }
64
  </style>
65
  """, unsafe_allow_html=True)
66
 
 
 
 
67
  if 'page' not in st.session_state: st.session_state.page = 'input'
68
- if 'workout_plan' not in st.session_state: st.session_state.workout_plan = None
69
 
70
- # --- SIDEBAR ---
71
- with st.sidebar:
72
- st.markdown("# 👤 Personalised Fitness Plan")
73
- if st.session_state.page == 'result':
74
- if st.button("⬅️ Back to Profile"):
75
- st.session_state.page = 'input'
76
- st.rerun()
77
-
78
- # --- INPUT PAGE ---
79
- if st.session_state.page == 'input':
80
- st.title("🏋️ Fitness Profile")
81
- col1, col2, col3 = st.columns([2, 1, 1])
82
- with col1: name = st.text_input("Name")
83
- with col2: gender = st.selectbox("Gender", ["Male", "Female", "Other"])
84
- with col3: age = st.number_input("Age", min_value=1, value=19)
85
 
86
- h, w = st.columns(2)
87
- with h: height = st.number_input("Height (cm)", min_value=1.0)
88
- with w: weight = st.number_input("Weight (kg)", min_value=1.0)
89
-
90
- goal = st.selectbox("Goal", ["Build Muscle", "Weight Loss", "Strength", "Flexibility"])
91
- level = st.selectbox("Fitness Level", ["Beginner", "Intermediate", "Advanced"])
92
- equip = st.multiselect("Equipment", ["Dumbbells", "Kettlebells", "Pull-up Bar", "Resistance Bands", "Yoga Mat", "No Equipment"])
93
-
94
- if st.button("Generate Plan"):
95
- prompt, bmi, bmi_status, status_color = build_prompt(name, gender, age, height, weight, goal, level, equip)
96
- with st.spinner("Crafting your unified routine..."):
97
- raw_workout = query_model(prompt)
98
- st.session_state.workout_plan = raw_workout
99
- st.session_state.assessment_data = {"name": name, "bmi": bmi, "status": bmi_status, "color": status_color, "age": age, "gender": gender}
100
- st.session_state.page = 'result'
101
  st.rerun()
 
 
 
102
 
103
- # --- RESULT PAGE ---
104
- elif st.session_state.page == 'result':
105
- d = st.session_state.assessment_data
106
- st.markdown(f'<div class="assessment-card"><h2>Hello {d["name"]}</h2><p>{d["gender"]} | {d["age"]} Years Old</p><p>BMI: <strong>{d["bmi"]:.2f}</strong> | <span style="color:{d["color"]}">{d["status"]}</span></p></div>', unsafe_allow_html=True)
 
 
 
 
 
 
107
 
108
- raw_content = st.session_state.workout_plan
109
- days = ["Day 1:", "Day 2:", "Day 3:", "Day 4:", "Day 5:"]
110
-
111
- for i in range(len(days)):
112
- start = raw_content.find(days[i])
113
- if start != -1:
114
- end = raw_content.find(days[i+1]) if i+1 < len(days) else len(raw_content)
115
- day_text = raw_content[start:end].strip()
116
-
117
- # Open Single White Day Container
118
- st.markdown(f'<div class="day-container"><div class="day-header">🔷 {days[i][:-1]}</div>', unsafe_allow_html=True)
119
-
120
- lines = day_text.split("\n")
121
- for line in lines:
122
- if "|" in line:
123
- parts = [p.strip() for p in line.replace("- ", "").split("|")]
124
- if len(parts) == 4:
125
- ex_name, sets, reps, rest = parts
126
- st.markdown(f"""
127
- <div class="exercise-row">
128
- <div class="ex-name">🔥 {ex_name}</div>
129
- <div class="stat-group">
130
- <div class="stat-pill"><span class="stat-val">{sets}</span><span class="stat-label">Sets</span></div>
131
- <div class="stat-pill"><span class="stat-val">{reps}</span><span class="stat-label">Reps</span></div>
132
- <div class="stat-pill" style="background:#fff3e0;"><span class="stat-val" style="color:#e65100;">{rest}</span><span class="stat-label">Rest</span></div>
133
- </div>
134
- </div>
135
- """, unsafe_allow_html=True)
136
-
137
- if "Rest" in day_text or "Recovery" in day_text:
138
- st.markdown('<p style="color:#636e72; font-style:italic; padding-top:10px;">🧘 Recovery Day: Focused on flexibility and rest.</p>', unsafe_allow_html=True)
139
-
140
- st.markdown('</div>', unsafe_allow_html=True) # Close Day Container
141
 
142
- st.download_button("📥 Download Full Plan", data=raw_content, file_name=f"{d['name']}_Workout.txt")
 
 
 
 
 
 
 
143
 
144
-
145
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  from prompt_builder import build_prompt
3
  from model_api import query_model
4
 
5
+ # 1. Page Configuration
6
  st.set_page_config(page_title="FitPlan AI", layout="wide")
7
 
8
+ # 2. UI Styling (Login & Unified Day Cards)
9
  st.markdown("""
10
  <style>
11
  .stApp { background: linear-gradient(135deg, #f6d365 0%, #fda085 100%); background-attachment: fixed; }
12
  section[data-testid="stSidebar"] { background-color: #000000 !important; }
 
13
 
14
+ /* Login Container */
15
+ .login-box { background: white; padding: 40px; border-radius: 20px; box-shadow: 0 10px 25px rgba(0,0,0,0.1); max-width: 450px; margin: 80px auto; text-align: center; }
16
+
17
+ /* Unified White Box Per Day */
 
 
 
18
  .day-container {
19
  background-color: white !important;
20
  padding: 30px;
21
  border-radius: 25px;
22
+ margin-bottom: 35px;
23
+ box-shadow: 0 10px 30px rgba(0,0,0,0.08);
24
+ border-left: 12px solid #004d57;
25
  }
26
+ .day-header { color: #004d57; font-size: 26px; font-weight: bold; border-bottom: 2px solid #f0f2f6; padding-bottom: 15px; margin-bottom: 20px; }
27
 
28
+ /* Exercise Row Alignment */
29
+ .exercise-row { display: flex; justify-content: space-between; align-items: center; padding: 15px 0; border-bottom: 1px solid #f1f1f1; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  .exercise-row:last-child { border-bottom: none; }
31
+ .ex-name { flex: 2; font-weight: 600; color: #2d3436; font-size: 18px; }
 
 
32
  .stat-group { display: flex; gap: 15px; flex: 1.5; justify-content: flex-end; }
33
+ .stat-pill { background: #f8f9fa; padding: 6px 12px; border-radius: 12px; text-align: center; min-width: 75px; }
 
 
 
 
 
 
 
 
34
  .stat-val { color: #004d57; font-weight: bold; font-size: 15px; display: block; }
35
+ .stat-label { font-size: 10px; color: #636e72; text-transform: uppercase; }
36
  </style>
37
  """, unsafe_allow_html=True)
38
 
39
+ # 3. Session State for Authentication
40
+ if 'logged_in' not in st.session_state: st.session_state.logged_in = False
41
+ if 'user_email' not in st.session_state: st.session_state.user_email = ""
42
  if 'page' not in st.session_state: st.session_state.page = 'input'
 
43
 
44
+ # --- LOGIN PAGE ---
45
+ if not st.session_state.logged_in:
46
+ st.markdown('<div class="login-box">', unsafe_allow_html=True)
47
+ st.title("🏋️ FitPlan AI Login")
48
+ st.write("Enter your email to access the generator")
49
+ email_input = st.text_input("Email Address", placeholder="example@email.com")
 
 
 
 
 
 
 
 
 
50
 
51
+ if st.button("Login"):
52
+ if "@" in email_input and "." in email_input:
53
+ st.session_state.logged_in = True
54
+ st.session_state.user_email = email_input
 
 
 
 
 
 
 
 
 
 
 
55
  st.rerun()
56
+ else:
57
+ st.error("Please enter a valid email address.")
58
+ st.markdown('</div>', unsafe_allow_html=True)
59
 
60
+ # --- PROTECTED GENERATOR CONTENT ---
61
+ else:
62
+ with st.sidebar:
63
+ st.markdown(f"👤 **{st.session_state.user_email}**")
64
+ if st.button("New Profile"):
65
+ st.session_state.page = 'input'
66
+ st.rerun()
67
+ if st.button("Logout"):
68
+ st.session_state.logged_in = False
69
+ st.rerun()
70
 
71
+ if st.session_state.page == 'input':
72
+ st.title("🚀 Fitness Plan Generator")
73
+ c1, c2, c3 = st.columns([2, 1, 1])
74
+ with c1: name = st.text_input("Name")
75
+ with c2: gender = st.selectbox("Gender", ["Male", "Female", "Other"])
76
+ with c3: age = st.number_input("Age", min_value=1, value=19)
77
+
78
+ h, w = st.columns(2)
79
+ with h: height = st.number_input("Height (cm)", min_value=1.0)
80
+ with w: weight = st.number_input("Weight (kg)", min_value=1.0)
81
+
82
+ goal = st.selectbox("Goal", ["Build Muscle", "Weight Loss", "Strength", "Flexibility"])
83
+ level = st.selectbox("Fitness Level", ["Beginner", "Intermediate", "Advanced"])
84
+ equip = st.multiselect("Equipment", ["Dumbbells", "Kettlebells", "Pull-up Bar", "Resistance Bands", "Yoga Mat", "No Equipment"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
+ if st.button("Generate My Routine"):
87
+ prompt, bmi, bmi_status, status_color = build_prompt(name, gender, age, height, weight, goal, level, equip)
88
+ with st.spinner("AI is building your unified plan..."):
89
+ raw_workout = query_model(prompt)
90
+ st.session_state.workout_plan = raw_workout
91
+ st.session_state.assessment_data = {"name": name, "bmi": bmi, "status": bmi_status, "color": status_color, "age": age, "gender": gender}
92
+ st.session_state.page = 'result'
93
+ st.rerun()
94
 
95
+ elif st.session_state.page == 'result':
96
+ d = st.session_state.assessment_data
97
+ st.title("📋 Your Personalized Routine")
98
+
99
+ raw_content = st.session_state.workout_plan
100
+ days = ["Day 1:", "Day 2:", "Day 3:", "Day 4:", "Day 5:"]
101
+
102
+ for i in range(len(days)):
103
+ start = raw_content.find(days[i])
104
+ if start != -1:
105
+ end = raw_content.find(days[i+1]) if i+1 < len(days) else len(raw_content)
106
+ day_text = raw_content[start:end].strip()
107
+
108
+ # Unified Day Card
109
+ st.markdown(f'<div class="day-container"><div class="day-header">🔹 {days[i][:-1]}</div>', unsafe_allow_html=True)
110
+
111
+ for line in day_text.split("\n"):
112
+ if "|" in line:
113
+ parts = [p.strip() for p in line.replace("- ", "").split("|")]
114
+ if len(parts) == 4:
115
+ ex_name, sets, reps, rest = parts
116
+ st.markdown(f"""
117
+ <div class="exercise-row">
118
+ <div class="ex-name">🔥 {ex_name}</div>
119
+ <div class="stat-group">
120
+ <div class="stat-pill"><span class="stat-val">{sets}</span><span class="stat-label">Sets</span></div>
121
+ <div class="stat-pill"><span class="stat-val">{reps}</span><span class="stat-label">Reps</span></div>
122
+ <div class="stat-pill" style="background:#fff3e0;"><span class="stat-val" style="color:#e65100;">{rest}</span><span class="stat-label">Rest</span></div>
123
+ </div>
124
+ </div>
125
+ """, unsafe_allow_html=True)
126
+ st.markdown('</div>', unsafe_allow_html=True)
127
+
128
+ st.download_button("📥 Download Plan", data=raw_content, file_name=f"{d['name']}_Workout.txt")