"""Search — the landing page.""" from __future__ import annotations import streamlit as st from components import cards from nutriweb.data import catalog from views import state st.markdown( """

Find a product, get a healthier swap

Search by name or scan a barcode. Every result is checked against your allergens, your diet and your health profile before it is recommended.

""", unsafe_allow_html=True, ) @st.cache_data(show_spinner=False, ttl=600) def _search(query: str, limit: int) -> list[dict]: return catalog.search(query, limit=limit) @st.cache_data(show_spinner=False) def _stats() -> dict: return catalog.stats() def _use_example(example: str) -> None: """Fill the search box from an example chip.""" st.session_state.search_box = example query = st.text_input( "Search", placeholder="e.g. peanut butter, greek yogurt, or a barcode like 0049000028911", label_visibility="collapsed", key="search_box", ) if not query: stats = _stats() st.caption( f"{stats['products']:,} US products · {stats['scored']:,} with a health score · " f"{stats['graded_by_nutriweb']:,} graded by NutriWeb where Open Food Facts had no grade" ) st.markdown("##### Try one of these") examples = ["greek yogurt", "peanut butter", "granola bar", "tortilla chips", "sparkling water"] columns = st.columns(len(examples)) for column, example in zip(columns, examples): # Seeding must happen in an on_click callback, not in the button's # if-branch: Streamlit refuses assignment to a widget's key once that # widget has been instantiated this run, and search_box is created # above. Callbacks run before the rerun, so the assignment is legal. column.button( example, width="stretch", key=f"eg_{example}", on_click=_use_example, args=(example,), ) st.stop() with st.spinner("Searching..."): results = _search(query, 24) if not results: st.warning( f"Nothing matched **{query}**. Try a brand name, a simpler term, or a full barcode." ) st.stop() st.caption(f"{len(results)} results for **{query}**") for start in range(0, len(results), 4): row = results[start : start + 4] for column, product in zip(st.columns(4), row): with column: cards.product_card( product, key=f"open_{product['code']}", on_open=state.open_product, )