gameforrhw / templates /dashboard.html
pranit144's picture
Upload 7 files
05dff9f verified
Raw
History Blame
15.8 kB
{% 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 %}