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.")