Trivia1 / utils /ui_components.py
Bharath370's picture
Upload 9 files
e78b10d verified
# 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"""
<style>
:root {{
--primary-color: {theme["primary_color"]};
--background-color: {theme["background_color"]};
--secondary-background-color: {theme["secondary_background_color"]};
--text-color: {theme["text_color"]};
--font: {theme["font"]};
}}
/* Apply background color to the main Streamlit elements */
.stApp {{
background-color: var(--background-color);
color: var(--text-color);
}}
.stSidebar {{
background-color: var(--secondary-background-color);
}}
</style>
"""
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"<div style='text-align: center; padding: 10px; border-radius: 10px; background-color: var(--secondary-background-color);'>",
unsafe_allow_html=True,
)
st.markdown(
f"<span style='font-size: 50px;'>{badge['icon']}</span>",
unsafe_allow_html=True,
)
st.markdown(f"**{badge['name']}**")
st.markdown(f"</div>", 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"<div style='{{card_style}}'><div style='{{flipper_style}}'> \
<div style='{{front_style}}'><div>{front_content}</div></div> \
<div style='{{back_style}}'><div>{back_content}</div></div> \
</div></div>",
unsafe_allow_html=True,
)