File size: 4,840 Bytes
e78b10d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# 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,
    )