"""Example: Streamlit page patterns - from actual pages/ files.""" import streamlit as st # ============================================================================= # Example 1: Home page (Home.py) # ============================================================================= def render_home_page(): """Simplified version of Home.py.""" st.set_page_config( page_title="Motief: de stematlas", page_icon="🗺️", layout="centered", initial_sidebar_state="expanded", ) st.title("🗺️ Motief: de stematlas") st.markdown( "**Motief** brengt de Nederlandse Tweede Kamer in kaart op basis van " "echte stemmingen over moties. Gebruik de Stemwijzer om te ontdekken welke " "partij het beste bij jouw standpunten past, of verken de politieke ruimte " "zelf in de Explorer." ) st.divider() col1, col2 = st.columns(2) with col1: st.subheader("🗳️ Stemwijzer") st.markdown( "Stem op echte Tweede Kamer moties en zie welke partij het " "dichtst bij jouw keuzes staat." ) st.page_link("pages/1_Stemwijzer.py", label="Open Stemwijzer", icon="🗳️") with col2: st.subheader("🔭 Politiek Explorer") st.markdown( "Verken het politieke kompas, partijtrajecten door de tijd, " "en zoek vergelijkbare moties op in het archief." ) st.page_link("pages/2_Explorer.py", label="Open Explorer", icon="🔭") st.divider() st.caption("Data: Tweede Kamer API · Embeddings: QWEN (via OpenRouter)") # ============================================================================= # Example 2: Thin page wrapper (pages/1_Stemwijzer.py) # ============================================================================= def render_stemwijzer_page(): """Pattern: thin page that delegates to module function.""" st.set_page_config( page_title="Stemwijzer", page_icon="🗳️", layout="centered", ) # Delegate to main module from explorer import build_mp_quiz_tab build_mp_quiz_tab("data/motions.db") # ============================================================================= # Example 3: Session state initialization # ============================================================================= def init_session_state(): """Pattern: Initialize all session state at start.""" defaults = { "session_id": None, "current_motion_index": 0, "motions": [], "show_results": False, "user_votes": {}, } for key, default in defaults.items(): if key not in st.session_state: st.session_state[key] = default # ============================================================================= # Example 4: Sidebar configuration # ============================================================================= def render_sidebar(): """Pattern: Sidebar for configuration.""" with st.sidebar: st.header("Instellingen") motion_count = st.slider( "Aantal moties", min_value=5, max_value=25, value=10, help="Hoeveel moties wilt u beantwoorden?", ) policy_area = st.selectbox( "Beleidsgebied", [ "Alle", "Economie", "Klimaat", "Immigratie", "Zorg", "Onderwijs", "Defensie", "Sociale Zaken", "Algemeen", ], ) margin_range = st.slider( "Controversiële moties (%)", min_value=0, max_value=100, value=(0, 100), help="Filter op hoe omstreden de moties zijn", ) st.divider() if st.button("Start Nieuwe Sessie", type="primary"): return { "motion_count": motion_count, "policy_area": policy_area, "margin_range": margin_range, } return None # ============================================================================= # Example 5: Motion voting interface # ============================================================================= def render_motion_vote(motion: dict, index: int, total: int): """Pattern: Display motion and voting buttons.""" st.subheader(f"Motie {index + 1} van {total}") # Motion content st.markdown(f"### {motion['title']}") col1, col2 = st.columns([3, 1]) with col1: if motion.get("layman_explanation"): st.info(motion["layman_explanation"]) with st.expander("Meer details"): st.markdown(f"**Datum:** {motion.get('date', 'Onbekend')}") st.markdown(f"**Beleidsgebied:** {motion.get('policy_area', 'Onbekend')}") if motion.get("description"): st.markdown(f"**Beschrijving:** {motion['description']}") with col2: st.metric( label="Winstmarge", value=f"{motion.get('winning_margin', 0):.0%}", delta="Omstreden" if motion.get("controversy_score", 0) > 0.5 else "Helder", ) st.divider() # Voting buttons col1, col2, col3 = st.columns(3) with col1: st.button( "👍 **Voor**", on_click=on_vote, args=(motion["id"], "Voor"), use_container_width=True, ) with col2: st.button( "👎 **Tegen**", on_click=on_vote, args=(motion["id"], "Tegen"), use_container_width=True, ) with col3: st.button( "🤔 **Onthouden**", on_click=on_vote, args=(motion["id"], "Onthouden"), use_container_width=True, ) def on_vote(motion_id: int, vote: str): """Callback when user votes.""" # Record vote from database import db db.record_vote( session_id=st.session_state.session_id, motion_id=motion_id, vote=vote ) # Update session state st.session_state.user_votes[motion_id] = vote # Move to next or show results if st.session_state.current_motion_index < len(st.session_state.motions) - 1: st.session_state.current_motion_index += 1 else: st.session_state.show_results = True st.rerun() # ============================================================================= # Example 6: Results display # ============================================================================= def render_results(): """Pattern: Display voting results.""" from database import db st.header("📊 Uw Resultaten") # Get party results results = db.get_party_results(st.session_state.session_id) if not results: st.warning("Geen resultaten beschikbaar") return # Sort by agreement sorted_results = sorted( results.items(), key=lambda x: x[1].get("agreement_percentage", 0), reverse=True ) # Display top match if sorted_results: top_party, top_data = sorted_results[0] st.success( f"**Uw beste match:** {top_party} ({top_data.get('agreement_percentage', 0):.0%} overeenstemming)" ) st.divider() # Show all parties for party, data in sorted_results: agreement = data.get("agreement_percentage", 0) col1, col2 = st.columns([3, 1]) with col1: st.markdown(f"**{party}**") st.progress(agreement, text=f"{agreement:.0%}") with col2: st.metric("Overeenstemming", f"{agreement:.0%}") # Detailed breakdown with st.expander("Details per motie"): for motion in st.session_state.motions: user_vote = st.session_state.user_votes.get(motion["id"], "?") st.markdown(f"- **{motion['title']}**: U={user_vote}") # ============================================================================= # Example 7: Tabs layout # ============================================================================= def render_tabs_example(): """Pattern: Use tabs for organizing content.""" tab1, tab2, tab3 = st.tabs(["Compass", "Trajectories", "Zoeken"]) with tab1: st.subheader("Politiek Kompas") st.write("Visualiseer partijposities in 2D ruimte") # Add compass chart... with tab2: st.subheader("Partij Trajectories") st.write("Bekijk hoe partijen door de tijd bewegen") # Add trajectory chart... with tab3: st.subheader("Zoek Moties") query = st.text_input("Zoekterm") if query: # Search functionality... st.write(f"Zoeken naar: {query}") if __name__ == "__main__": # Demo rendering init_session_state() st.write("Streamlit page structure example")