# utils/ui_components.py import streamlit as st import plotly.graph_objects as go from config.settings import BADGES from config.themes import THEMES def apply_custom_theme(theme_name: str): """Applies a custom theme using CSS variables.""" theme = THEMES.get(theme_name, THEMES["default"]) css = f""" """ st.markdown(css, unsafe_allow_html=True) def display_user_stats(stats: dict): """Displays user statistics in a dashboard format.""" cols = st.columns(4) with cols[0]: st.metric("Total Score", f"{stats.get('total_score', 0):,}") with cols[1]: st.metric("Quizzes Played", stats.get("quizzes_completed", 0)) with cols[2]: st.metric("Current Streak", f"🔥 {stats.get('current_streak', 0)}") with cols[3]: st.metric("Best Streak", f"⭐ {stats.get('best_streak', 0)}") def display_badges(earned_badges: list): """Displays earned badges.""" if not earned_badges: return st.markdown("### 🏆 Your Badges") cols = st.columns(len(BADGES)) for i, badge_id in enumerate(earned_badges): badge = BADGES.get(badge_id) if badge: with cols[i]: st.markdown( f"
", unsafe_allow_html=True, ) st.markdown( f"{badge['icon']}", unsafe_allow_html=True, ) st.markdown(f"**{badge['name']}**") st.markdown(f"
", unsafe_allow_html=True) def create_progress_chart(stats: dict) -> go.Figure: """Creates a progress chart for the user.""" history = stats.get("quiz_history", []) if not history: return go.Figure() dates = [item["timestamp"] for item in history] scores = [item["percentage"] for item in history] fig = go.Figure() fig.add_trace(go.Scatter(x=dates, y=scores, mode="lines+markers", name="Score %")) fig.update_layout( title="Quiz Performance Over Time", xaxis_title="Date", yaxis_title="Score (%)", yaxis_range=[0, 100], ) return fig def animated_success(message: str): """Displays an animated success message.""" st.success(message) def create_quiz_card(question: str, options: list): """Creates a card for a multiple-choice question.""" st.subheader(question) answer = st.radio( "Select your answer:", options, index=None, label_visibility="collapsed" ) return answer def render_flashcard(front_content: str, back_content: str, is_flipped: bool): """Renders a flippable flashcard.""" card_style = """ width: 100%; height: 300px; perspective: 1000px; """ flipper_style = f""" position: relative; width: 100%; height: 100%; transition: transform 0.6s; transform-style: preserve-3d; transform: {"rotateY(180deg)" if is_flipped else "none"}; """ face_style = """ position: absolute; width: 100%; height: 100%; -webkit-backface-visibility: hidden; backface-visibility: hidden; display: flex; justify-content: center; align-items: center; padding: 20px; border-radius: 10px; box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2); """ front_style = ( f"{{face_style}} background-color: var(--primary-color); color: white;" ) back_style = f"{{face_style}} background-color: var(--secondary-background-color); color: var(--text-color); transform: rotateY(180deg);" st.markdown( f"
\
{front_content}
\
{back_content}
\
", unsafe_allow_html=True, )