Spaces:
Sleeping
Sleeping
| {% extends "base.html" %} | |
| {% block title %}Quiz Levels - Rainwater Quest{% endblock %} | |
| {% block content %} | |
| <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@600;700&family=Open+Sans:wght@400;600&display=swap" rel="stylesheet"> | |
| <style> | |
| /* Professional Quiz Levels Component Styles */ | |
| :root { | |
| --primary-blue: #007bff; /* Main interactive color (Water/Sky) */ | |
| --secondary-green: #28a745; /* Completion/Growth color (Earth/Green) */ | |
| --accent-teal: #17a2b8; /* Active/Highlight color (Teal-ish for water flow) */ | |
| --light-grey: #f8f9fa; /* Background for cards */ | |
| --medium-grey: #e9ecef; /* Border/separator */ | |
| --dark-text: #343a40; /* Primary text color */ | |
| --light-text: #ffffff; /* White text for contrast */ | |
| --locked-dim: #6c757d; /* Dimmed color for locked elements */ | |
| --card-border-radius: 12px; | |
| --soft-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); | |
| --hover-shadow: 0 8px 20px rgba(0, 0, 0, 0.15); | |
| --transition-speed: 0.3s ease; | |
| } | |
| /* Basic body styling to support the component if it's the only thing on the page */ | |
| body { | |
| margin: 0; | |
| padding: 0; | |
| background: linear-gradient(135deg, #e0f2f7 0%, #b3e5fc 100%); /* Overall soft background */ | |
| min-height: 100vh; | |
| display: flex; | |
| justify-content: center; | |
| align-items: flex-start; /* Align to top, allow scrolling if needed */ | |
| font-family: 'Open Sans', sans-serif; | |
| color: var(--dark-text); | |
| box-sizing: border-box; /* Ensures padding and border are included in element's total width and height */ | |
| } | |
| /* Overall container for the Quiz Levels component */ | |
| .quiz-levels-section { | |
| background-color: #fff; /* White background for the main section content */ | |
| padding: 30px; | |
| border-radius: var(--card-border-radius); | |
| box-shadow: var(--soft-shadow); | |
| margin: 40px auto; /* Center the component with some vertical spacing */ | |
| max-width: 1200px; /* Max width for larger screens */ | |
| width: 95%; /* Responsive width */ | |
| color: var(--dark-text); | |
| text-align: center; | |
| box-sizing: border-box; | |
| } | |
| .quiz-levels-section h2 { | |
| font-family: 'Montserrat', sans-serif; | |
| font-size: 2.5em; /* Slightly larger for emphasis */ | |
| color: var(--primary-blue); | |
| margin-bottom: 30px; /* More spacing */ | |
| text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1); /* Subtle text shadow */ | |
| } | |
| /* Grid for quiz level cards */ | |
| .quiz-levels-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); /* Responsive grid */ | |
| gap: 25px; | |
| justify-content: center; | |
| } | |
| /* Individual Quiz Level Card */ | |
| .quiz-level-card { | |
| background-color: var(--light-grey); | |
| border-radius: var(--card-border-radius); | |
| box-shadow: var(--soft-shadow); | |
| padding: 20px; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| text-align: center; | |
| transition: transform var(--transition-speed), box-shadow var(--transition-speed); | |
| border: 1px solid var(--medium-grey); | |
| position: relative; | |
| overflow: hidden; /* For pseudo-element effects if any were added */ | |
| min-height: 220px; /* Ensure cards have a minimum consistent height */ | |
| box-sizing: border-box; | |
| } | |
| .quiz-level-card:hover:not(.locked) { | |
| transform: translateY(-5px); | |
| box-shadow: var(--hover-shadow); | |
| } | |
| .level-icon { | |
| font-size: 3.2em; /* Slightly larger icon */ | |
| margin-bottom: 12px; | |
| line-height: 1; | |
| color: var(--primary-blue); | |
| } | |
| .level-number { | |
| font-family: 'Montserrat', sans-serif; | |
| font-size: 1.9em; /* Slightly larger number */ | |
| font-weight: 700; | |
| color: var(--dark-text); | |
| margin-bottom: 8px; | |
| } | |
| .level-title { | |
| font-family: 'Open Sans', sans-serif; | |
| font-size: 1em; /* Adjusted size */ | |
| font-weight: 600; | |
| color: var(--dark-text); | |
| min-height: 45px; /* Ensure consistent card height for title */ | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| margin-bottom: 20px; /* More spacing */ | |
| line-height: 1.3; | |
| } | |
| .level-actions { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 10px; | |
| width: 100%; | |
| margin-top: auto; /* Push actions to the bottom */ | |
| } | |
| .level-actions a, .level-actions button { | |
| display: block; | |
| width: 100%; | |
| padding: 12px 15px; /* More padding for buttons */ | |
| border-radius: 8px; | |
| text-decoration: none; | |
| font-family: 'Open Sans', sans-serif; | |
| font-weight: 600; | |
| font-size: 0.95em; /* Slightly larger font */ | |
| cursor: pointer; | |
| transition: background-color var(--transition-speed), transform 0.1s ease; | |
| box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); | |
| border: none; | |
| color: var(--light-text); | |
| } | |
| /* Action button styles based on context */ | |
| .level-actions .btn-start-level { | |
| background-color: var(--primary-blue); | |
| width: 150px; | |
| } | |
| .level-actions .btn-start-level:hover { | |
| background-color: #0056b3; | |
| transform: translateY(-1px); | |
| } | |
| .level-actions .btn-take-quiz { | |
| background-color: var(--secondary-green); | |
| width: 150px; | |
| } | |
| .level-actions .btn-take-quiz:hover { | |
| background-color: #218838; | |
| transform: translateY(-1px); | |
| } | |
| .level-actions .btn-score { | |
| background-color: var(--locked-dim); | |
| cursor: default; | |
| font-style: italic; | |
| box-shadow: inset 0 1px 3px rgba(0,0,0,0.1); | |
| } | |
| .level-actions .btn-score:hover { | |
| background-color: var(--locked-dim); | |
| transform: none; | |
| } | |
| /* Card Status Styles */ | |
| .quiz-level-card.locked { | |
| opacity: 0.6; /* More subtle dimming */ | |
| cursor: not-allowed; | |
| background-color: var(--medium-grey); | |
| border-color: #ced4da; | |
| } | |
| .quiz-level-card.locked:hover { | |
| transform: none; /* No hover effect for locked cards */ | |
| box-shadow: var(--soft-shadow); | |
| } | |
| .quiz-level-card.locked .level-icon, | |
| .quiz-level-card.locked .level-number, | |
| .quiz-level-card.locked .level-title { | |
| color: var(--locked-dim); | |
| } | |
| .quiz-level-card.locked .level-actions button, | |
| .quiz-level-card.locked .level-actions a { | |
| background-color: #adb5bd; | |
| cursor: not-allowed; | |
| box-shadow: none; | |
| } | |
| .quiz-level-card.locked .level-actions button:hover, | |
| .quiz-level-card.locked .level-actions a:hover { | |
| background-color: #adb5bd; | |
| transform: none; | |
| } | |
| .quiz-level-card.active { | |
| border-color: var(--accent-teal); | |
| box-shadow: 0 0 18px rgba(23, 162, 184, 0.4); /* Stronger shadow for active */ | |
| animation: pulse-active 1.5s infinite alternate ease-in-out; | |
| background: linear-gradient(135deg, #e8f7f9, #c5e6ed); /* Light gradient for active */ | |
| } | |
| .quiz-level-card.active .level-icon { | |
| color: var(--accent-teal); | |
| } | |
| .quiz-level-card.completed { | |
| border-color: var(--secondary-green); | |
| background: linear-gradient(135deg, #e9f7eb, #d4edda); /* Light gradient for completed */ | |
| } | |
| .quiz-level-card.completed .level-icon { | |
| color: var(--secondary-green); | |
| } | |
| /* No btn-watch specific style as it's replaced by start-level */ | |
| /* Animations */ | |
| @keyframes pulse-active { | |
| 0% { transform: scale(1); box-shadow: 0 0 18px rgba(23, 162, 184, 0.4); } | |
| 100% { transform: scale(1.02); box-shadow: 0 0 25px rgba(23, 162, 184, 0.6); } | |
| } | |
| /* Responsive Adjustments */ | |
| @media (max-width: 992px) { | |
| .quiz-levels-grid { | |
| grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); /* Slightly smaller cards */ | |
| gap: 20px; | |
| } | |
| .quiz-level-card { | |
| min-height: 200px; | |
| } | |
| } | |
| @media (max-width: 768px) { | |
| .quiz-levels-section { | |
| padding: 25px; | |
| margin: 20px auto; | |
| } | |
| .quiz-levels-section h2 { | |
| font-size: 2em; | |
| margin-bottom: 25px; | |
| } | |
| .quiz-levels-grid { | |
| grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); /* Even smaller cards */ | |
| gap: 15px; | |
| } | |
| .quiz-level-card { | |
| padding: 18px; | |
| min-height: 180px; | |
| } | |
| .level-icon { | |
| font-size: 2.8em; | |
| } | |
| .level-number { | |
| font-size: 1.6em; | |
| } | |
| .level-title { | |
| font-size: 0.9em; | |
| min-height: 40px; | |
| margin-bottom: 15px; | |
| } | |
| .level-actions a, .level-actions button { | |
| padding: 10px 12px; | |
| font-size: 0.88em; | |
| } | |
| } | |
| @media (max-width: 576px) { | |
| .quiz-levels-section { | |
| padding: 15px; | |
| margin: 10px; | |
| width: auto; /* Allow content to dictate width, with padding */ | |
| } | |
| .quiz-levels-section h2 { | |
| font-size: 1.7em; | |
| margin-bottom: 20px; | |
| } | |
| .quiz-levels-grid { | |
| grid-template-columns: 1fr; /* Stack vertically on very small screens */ | |
| gap: 12px; | |
| } | |
| .quiz-level-card { | |
| min-height: unset; /* Allow height to adjust to content */ | |
| } | |
| .level-title { | |
| min-height: unset; | |
| } | |
| } | |
| /* Styles for the new sections */ | |
| .user-info-section, .certificate-section { | |
| background-color: var(--light-grey); | |
| padding: 20px; | |
| border-radius: var(--card-border-radius); | |
| box-shadow: var(--soft-shadow); | |
| margin-top: 30px; | |
| text-align: left; | |
| border: 1px solid var(--medium-grey); | |
| } | |
| .user-info-section h3, .certificate-section h3 { | |
| font-family: 'Montserrat', sans-serif; | |
| color: var(--primary-blue); | |
| margin-bottom: 15px; | |
| } | |
| .user-info-section form { | |
| display: flex; | |
| gap: 10px; | |
| align-items: center; | |
| } | |
| .user-info-section input[type="text"] { | |
| flex-grow: 1; | |
| padding: 10px; | |
| border: 1px solid var(--medium-grey); | |
| border-radius: 6px; | |
| font-size: 1em; | |
| } | |
| .user-info-section button { | |
| background-color: var(--accent-teal); | |
| color: var(--light-text); | |
| padding: 10px 15px; | |
| border: none; | |
| border-radius: 6px; | |
| cursor: pointer; | |
| font-weight: 600; | |
| transition: background-color var(--transition-speed); | |
| } | |
| .user-info-section button:hover { | |
| background-color: #138496; | |
| } | |
| .certificate-section .btn-certificate { | |
| background-color: #f0ad4e; /* Warning-like color for certificate */ | |
| color: var(--light-text); | |
| padding: 12px 20px; | |
| border: none; | |
| border-radius: 8px; | |
| text-decoration: none; | |
| font-family: 'Open Sans', sans-serif; | |
| font-weight: 700; | |
| font-size: 1.1em; | |
| display: inline-block; | |
| margin-top: 20px; | |
| transition: background-color var(--transition-speed); | |
| } | |
| .certificate-section .btn-certificate:hover { | |
| background-color: #ec971f; | |
| } | |
| </style> | |
| <section class="quiz-levels-section"> | |
| <h2>Rainwater Harvesting Learning Path</h2> | |
| <div class="user-info-section"> | |
| <h3>Hello, {% if username %}{{ username }}{% else %}Guest{% endif %}!</h3> | |
| <p>Current Points: <strong>{{ user_progress.points }}</strong></p> | |
| <form action="{{ url_for('set_username') }}" method="POST"> | |
| <label for="username">Set Your Name for Certificate:</label> | |
| <input type="text" id="username" name="username" placeholder="Enter your name" value="{{ username }}" required> | |
| <button type="submit">Save Name</button> | |
| </form> | |
| </div> | |
| {% if all_videos_and_quizzes_completed %} | |
| <div class="certificate-section"> | |
| <h3>Congratulations, you've completed the course!</h3> | |
| <p>You've earned the "Ultimate HydroHero" badge!</p> | |
| <a href="{{ url_for('certificate') }}" class="btn-certificate">View & Print Your Certificate</a> | |
| </div> | |
| {% endif %} | |
| <h3>Your Learning Progress</h3> | |
| <div class="quiz-levels-grid"> | |
| {# Loop through actual video data from your backend #} | |
| {% for video in videos %} | |
| {% set video_id = video.id %} | |
| {% set is_completed = video_id in user_progress.completed_videos %} | |
| {% set quiz_taken = video_id in user_progress.video_quiz_scores %} | |
| {# Determine if the node is active: first node, or previous node completed #} | |
| {% set is_active = not is_completed and (loop.index0 == 0 or videos[loop.index0 - 1].id in user_progress.completed_videos) %} | |
| {% set is_locked = not is_completed and not is_active %} | |
| <div class="quiz-level-card {% if is_completed %}completed{% elif is_active %}active{% elif is_locked %}locked{% endif %}"> | |
| <div class="level-icon"> | |
| {% if is_completed %}โ {% elif is_active %}โถ๏ธ{% else %}๐{% endif %} {# Thematic icons based on status #} | |
| </div> | |
| <div class="level-number">Level {{ loop.index }}</div> | |
| <div class="level-title">{{ video.title }}</div> | |
| <div class="level-actions"> | |
| {% if is_locked %} | |
| <button disabled>Locked</button> | |
| {% elif is_active %} | |
| <a href="{{ url_for('start_level', video_id=video.id) }}" class="btn-start-level">Start Level</a> | |
| {% elif is_completed and not quiz_taken %} | |
| <a href="{{ url_for('quiz', video_id=video.id) }}" class="btn-take-quiz">Take Quiz</a> | |
| {% elif quiz_taken %} | |
| <button class="btn-score">Score: {{ user_progress.video_quiz_scores[video_id] }} Pts</button> | |
| {% endif %} | |
| </div> | |
| </div> | |
| {% endfor %} | |
| {# Placeholder for remaining levels if 'videos' list is less than 10 #} | |
| {% if videos|length < 10 %} | |
| {% for i in range(videos|length + 1, 11) %} {# Start from the next level number up to 10 #} | |
| <div class="quiz-level-card locked"> | |
| <div class="level-icon">๐</div> | |
| <div class="level-number">Level {{ i }}</div> | |
| <div class="level-title">Upcoming Topic</div> | |
| <div class="level-actions"> | |
| <button disabled>Locked</button> | |
| </div> | |
| </div> | |
| {% endfor %} | |
| {% endif %} | |
| </div> | |
| <div class="badges-container"> | |
| <h3>Your Badges:</h3> | |
| {% if user_progress.unlocked_badges %} | |
| <ul> | |
| {% for badge in user_progress.unlocked_badges %} | |
| <li>{{ badge.name }}: {{ badge.description }}</li> | |
| {% endfor %} | |
| </ul> | |
| {% else %} | |
| <p>No badges unlocked yet. Keep learning!</p> | |
| {% endif %} | |
| </div> | |
| </section> | |
| {% endblock %} |