"""Profile — sign in, and set the preferences that drive every filter.""" from __future__ import annotations import streamlit as st from nutriweb.profile import auth from nutriweb.profile.model import ALLERGEN_CHOICES, DIET_CHOICES, UserProfile from views import state st.markdown( """

My profile

Everything here is used as a hard filter: allergens and diet exclude products outright rather than merely ranking them lower.

""", unsafe_allow_html=True, ) profile: UserProfile = state.profile() if auth.demo_mode(): st.caption( "No account database is configured, so profiles last for this session only. " "Set `MONGODB_URI` as a Space secret to persist them." ) def _preferences_form(current: UserProfile, key_prefix: str) -> UserProfile: """The shared preference widgets. Returns a profile built from the inputs.""" label_for_tag = {v: k for k, v in ALLERGEN_CHOICES.items()} selected_labels = st.multiselect( "Allergens to avoid", list(ALLERGEN_CHOICES), default=[label_for_tag[t] for t in current.allergens if t in label_for_tag], key=f"{key_prefix}_allergens", help="Matched against Open Food Facts' curated allergen and traces tags.", ) diets = st.multiselect( "Dietary preferences", DIET_CHOICES, default=current.diets, key=f"{key_prefix}_diets", ) col1, col2 = st.columns(2) with col1: age = st.number_input("Age", 1, 120, current.age, key=f"{key_prefix}_age") high_bp = st.checkbox( "High blood pressure", current.high_blood_pressure, key=f"{key_prefix}_bp", help="Flags and filters products above 1.15 g salt per 100 g.", ) with col2: gender = st.selectbox( "Gender", ["Prefer not to say", "Female", "Male", "Other"], index=["Prefer not to say", "Female", "Male", "Other"].index(current.gender) if current.gender in ["Prefer not to say", "Female", "Male", "Other"] else 0, key=f"{key_prefix}_gender", ) high_chol = st.checkbox( "High cholesterol", current.high_cholesterol, key=f"{key_prefix}_chol", help="Flags and filters products above 4 g saturated fat per 100 g.", ) avoid_additives = st.checkbox( "Exclude products with additives EFSA flags as high-risk", current.avoid_flagged_additives, key=f"{key_prefix}_additives", ) return UserProfile( user_id=current.user_id, age=int(age), gender=gender, allergens=[ALLERGEN_CHOICES[label] for label in selected_labels], diets=diets, high_blood_pressure=high_bp, high_cholesterol=high_chol, avoid_flagged_additives=avoid_additives, ) if profile.user_id: st.success(f"Signed in as **{profile.user_id}**") with st.form("prefs"): updated = _preferences_form(profile, "signed") if st.form_submit_button("Save preferences", type="primary"): updated.user_id = profile.user_id st.session_state.profile = updated auth.save_profile(updated) st.toast("Preferences saved.") st.divider() st.markdown("### Recently viewed") history = auth.recent_views(profile.user_id) if not history: st.caption("Nothing viewed yet.") else: for entry in history[:15]: st.markdown( f"- **{entry.get('product_name') or 'Unnamed'}** " f"{entry.get('brands') or ''} · " f"{entry.get('verdict') or ''}", unsafe_allow_html=True, ) st.stop() tab_guest, tab_login, tab_register = st.tabs( ["Use without an account", "Sign in", "Create account"] ) with tab_guest: st.caption( "Set preferences for this session only. Nothing is stored and no account is needed." ) with st.form("guest"): guest_profile = _preferences_form(profile, "guest") if st.form_submit_button("Apply", type="primary"): st.session_state.profile = guest_profile st.toast("Preferences applied for this session.") st.rerun() with tab_login: with st.form("login"): user_id = st.text_input("Username") password = st.text_input("Password", type="password") if st.form_submit_button("Sign in", type="primary"): result = auth.login(user_id, password) if result.ok: st.session_state.profile = result.profile st.rerun() else: st.error(result.message) with tab_register: with st.form("register"): new_id = st.text_input("Choose a username") new_pw = st.text_input("Choose a password", type="password", help="At least 8 characters.") new_profile = _preferences_form(UserProfile(), "reg") if st.form_submit_button("Create account", type="primary"): result = auth.register(new_id, new_pw, new_profile) if result.ok: st.session_state.profile = result.profile st.success(result.message) st.rerun() else: st.error(result.message)