Spaces:
Sleeping
Sleeping
File size: 8,788 Bytes
70dfae8 ac6ac0c 074e3cc 0ce92f8 3bf9177 0ce92f8 3bf9177 9f8a8e0 3bf9177 dbf471f 669337b cdaba65 0ce92f8 fa8dbc3 0ce92f8 9f8a8e0 0ce92f8 9f8a8e0 fa8dbc3 dbf471f 9f8a8e0 3bf9177 9f8a8e0 dbf471f 0ce92f8 ed87a59 9f8a8e0 716d8ef dbf471f 9f8a8e0 0ce92f8 716d8ef 9f8a8e0 716d8ef ac6ac0c 716d8ef 9f8a8e0 669337b 9f8a8e0 716d8ef 9f8a8e0 cdaba65 716d8ef 9f8a8e0 669337b 9f8a8e0 dbf471f 9f8a8e0 716d8ef 9f8a8e0 716d8ef 9f8a8e0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | import streamlit as st
from prompt_builder import build_prompt
from model_api import query_model
from diet_builder import build_diet_prompt
st.set_page_config(page_title="FitPlan AI", layout="wide")
# --- UI STYLING (Preserving your exact original look) ---
st.markdown("""
<style>
header {visibility: hidden;}
.stApp { background: linear-gradient(135deg, #f6d365 0%, #fda085 100%); background-attachment: fixed; }
section[data-testid="stSidebar"] { background-color: #000000 !important; }
section[data-testid="stSidebar"] h1, section[data-testid="stSidebar"] p { color: #FFFFFF !important; }
.assessment-card {
background-color: white !important; padding: 25px; border-radius: 15px;
border-left: 10px solid #004d57; color: #000000 !important; margin-bottom: 30px;
}
.stat-card { background: white; padding: 20px; border-radius: 15px; text-align: center; border-top: 5px solid #004d57; box-shadow: 0 4px 15px rgba(0,0,0,0.05); }
.day-container { background-color: white !important; padding: 30px; border-radius: 25px; margin-bottom: 40px; box-shadow: 0 10px 30px rgba(0,0,0,0.1); }
.day-header { color: #004d57; font-size: 26px; font-weight: bold; margin-bottom: 20px; border-bottom: 2px solid #f0f2f6; padding-bottom: 15px; }
.item-row { display: flex; align-items: center; justify-content: space-between; padding: 18px 0; border-bottom: 1px solid #f1f1f1; }
.item-row:last-child { border-bottom: none; }
.ex-name { flex: 2; font-weight: 600; color: #2d3436; font-size: 18px; }
.stat-group { display: flex; gap: 15px; flex: 1.5; justify-content: flex-end; }
.stat-pill { text-align: center; min-width: 75px; background: #f8f9fa; padding: 6px; border-radius: 12px; }
.stat-val { color: #004d57; font-weight: bold; font-size: 15px; display: block; }
.stat-label { font-size: 10px; color: #636e72; text-transform: uppercase; display: block; }
</style>
""", unsafe_allow_html=True)
# --- NAVIGATION STATE ---
if 'page' not in st.session_state: st.session_state.page = 'dashboard'
if 'user_data' not in st.session_state: st.session_state.user_data = None
if 'workout_plan' not in st.session_state: st.session_state.workout_plan = None
if 'diet_plan' not in st.session_state: st.session_state.diet_plan = None
# --- SIDEBAR ---
with st.sidebar:
st.markdown("# π€ FitPlan AI")
if st.button("π Dashboard", use_container_width=True):
st.session_state.page = 'dashboard'
st.rerun()
if st.button("ποΈ Workout Plan", use_container_width=True):
# If a plan exists, show the result, otherwise show input
if st.session_state.workout_plan:
st.session_state.page = 'result'
else:
st.session_state.page = 'input'
st.rerun()
if st.button("π₯ Dietary Plan", use_container_width=True):
st.session_state.page = 'diet'
st.rerun()
if st.session_state.workout_plan:
st.write("---")
if st.button("π Create New Profile"):
st.session_state.workout_plan = None
st.session_state.diet_plan = None
st.session_state.user_data = None
st.session_state.page = 'input'
st.rerun()
# --- 1. DASHBOARD PAGE ---
if st.session_state.page == 'dashboard':
st.title("π Your Dashboard")
if st.session_state.user_data:
d = st.session_state.user_data
col1, col2, col3 = st.columns(3)
with col1: st.markdown(f'<div class="stat-card"><div style="font-size:24px; font-weight:bold;">{d["name"]}</div><div style="color:#636e72;">USER</div></div>', unsafe_allow_html=True)
with col2: st.markdown(f'<div class="stat-card"><div style="font-size:24px; font-weight:bold;">{d["bmi"]:.1f}</div><div style="color:#636e72;">BMI</div></div>', unsafe_allow_html=True)
with col3: st.markdown(f'<div class="stat-card"><div style="font-size:24px; font-weight:bold; color:{d["color"]}">{d["status"]}</div><div style="color:#636e72;">HEALTH STATUS</div></div>', unsafe_allow_html=True)
st.write("---")
st.success(f"Current Goal: **{d['goal']}**")
else:
st.warning("Go to 'Workout Plan' to generate your profile.")
# --- 2. INPUT PAGE ---
elif st.session_state.page == 'input':
st.title("ποΈ Fitness Profile")
c1, c2, c3 = st.columns([2, 1, 1])
with c1: name = st.text_input("Name")
with c2: gender = st.selectbox("Gender", ["Male", "Female", "Other"])
with c3: age = st.number_input("Age", min_value=1, value=19)
h, w = st.columns(2)
with h: height = st.number_input("Height (cm)", min_value=1.0)
with w: weight = st.number_input("Weight (kg)", min_value=1.0)
goal = st.selectbox("Goal", ["Build Muscle", "Weight Loss", "Strength", "Flexibility"])
level = st.selectbox("Fitness Level", ["Beginner", "Intermediate", "Advanced"])
equip = st.multiselect("Equipment", ["Dumbbells", "Kettlebells", "Pull-up Bar", "Resistance Bands", "Yoga Mat", "No Equipment"])
if st.button("Generate Complete Plan"):
prompt, bmi, status, color = build_prompt(name, gender, age, height, weight, goal, level, equip)
with st.spinner("AI is crafting your routine..."):
st.session_state.workout_plan = query_model(prompt)
st.session_state.user_data = {"name": name, "bmi": bmi, "status": status, "color": color, "age": age, "gender": gender, "goal": goal, "height": height, "weight": weight, "level": level}
st.session_state.diet_plan = None
st.session_state.page = 'result'
st.rerun()
# --- 3. WORKOUT RESULT (Stored Memory) ---
elif st.session_state.page == 'result':
d = st.session_state.user_data
st.markdown(f'<div class="assessment-card"><h2>Hello {d["name"]}</h2><p>BMI: <strong>{d["bmi"]:.2f}</strong> | <span style="color:{d["color"]}">{d["status"]}</span></p></div>', unsafe_allow_html=True)
raw = st.session_state.workout_plan
days = ["Day 1:", "Day 2:", "Day 3:", "Day 4:", "Day 5:"]
for i in range(len(days)):
start = raw.find(days[i])
if start != -1:
end = raw.find(days[i+1]) if i+1 < len(days) else len(raw)
day_text = raw[start:end].strip()
st.markdown(f'<div class="day-container"><div class="day-header">π· {days[i][:-1]}</div>', unsafe_allow_html=True)
for line in day_text.split("\n"):
if "|" in line:
parts = [p.strip() for p in line.replace("- ", "").split("|")]
if len(parts) == 4:
n, s, r, rs = parts
st.markdown(f'<div class="item-row"><div class="ex-name">π₯ {n}</div><div class="stat-group"><div class="stat-pill"><span class="stat-val">{s}</span><span class="stat-label">Sets</span></div><div class="stat-pill"><span class="stat-val">{r}</span><span class="stat-label">Reps</span></div><div class="stat-pill" style="background:#fff3e0;"><span class="stat-val" style="color:#e65100;">{rs}</span><span class="stat-label">Rest</span></div></div></div>', unsafe_allow_html=True)
st.markdown('</div>', unsafe_allow_html=True)
st.download_button("π₯ Download Plan", data=raw, file_name=f"{d['name']}_Plan.txt")
# --- 4. DIETARY PAGE (Stored Memory) ---
elif st.session_state.page == 'diet':
st.title("π₯ Dietary Plan")
if st.session_state.user_data:
d = st.session_state.user_data
# Only query the model if the diet doesn't exist yet
if not st.session_state.diet_plan:
d_prompt = build_diet_prompt(d['name'], d['gender'], d['age'], d['height'], d['weight'], d['goal'])
with st.spinner("Generating unique meal plan..."):
st.session_state.diet_plan = query_model(d_prompt)
raw_diet = st.session_state.diet_plan
st.markdown('<div class="day-container"><div class="day-header">π Daily Nutrition</div>', unsafe_allow_html=True)
for line in raw_diet.split("\n"):
if "|" in line:
parts = [p.strip() for p in line.replace("- ", "").split("|")]
if len(parts) == 4:
m_n, m_t, m_i, m_c = parts
st.markdown(f'<div class="item-row"><div class="ex-name">π΄ {m_n}<br><small>{m_i}</small></div><div class="stat-group"><div class="stat-pill"><span class="stat-val">{m_t}</span><span class="stat-label">Time</span></div><div class="stat-pill" style="background:#e8f5e9;"><span class="stat-val" style="color:#2e7d32;">{m_c}</span><span class="stat-label">Energy</span></div></div></div>', unsafe_allow_html=True)
st.markdown('</div>', unsafe_allow_html=True)
else:
st.warning("Generate a profile in 'Workout Plan' first.") |