initial commit
This commit is contained in:
318
templates/base.html
Normal file
318
templates/base.html
Normal file
@@ -0,0 +1,318 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}Balotario Licencia Clase A - Categoría I{% endblock %}</title>
|
||||
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/svg+xml" href="{{ url_for('static', filename='favicon.svg') }}">
|
||||
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.svg') }}">
|
||||
<link rel="manifest" href="{{ url_for('static', filename='site.webmanifest') }}">
|
||||
<meta name="theme-color" content="#3498db">
|
||||
|
||||
<link href="{{ url_for('static', filename='css/bootstrap/bootstrap.min.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/fontawesome-local.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/custom.css') }}" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #2c3e50;
|
||||
--secondary-color: #3498db;
|
||||
--success-color: #27ae60;
|
||||
--danger-color: #e74c3c;
|
||||
--warning-color: #f39c12;
|
||||
--light-bg: #ecf0f1;
|
||||
}
|
||||
|
||||
body {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background: rgba(44, 62, 80, 0.95) !important;
|
||||
backdrop-filter: blur(10px);
|
||||
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-weight: bold;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
color: rgba(255, 255, 255, 0.8) !important;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.nav-link:hover {
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.container-main {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
|
||||
backdrop-filter: blur(10px);
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 2rem;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: none;
|
||||
border-radius: 15px;
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: linear-gradient(45deg, var(--secondary-color), #5dade2);
|
||||
border: none;
|
||||
border-radius: 25px;
|
||||
padding: 12px 30px;
|
||||
font-weight: 600;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: linear-gradient(45deg, #2980b9, var(--secondary-color));
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 20px rgba(52, 152, 219, 0.3);
|
||||
}
|
||||
|
||||
.btn-success {
|
||||
background: linear-gradient(45deg, var(--success-color), #58d68d);
|
||||
border: none;
|
||||
border-radius: 25px;
|
||||
padding: 12px 30px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background: linear-gradient(45deg, var(--danger-color), #ec7063);
|
||||
border: none;
|
||||
border-radius: 25px;
|
||||
padding: 12px 30px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.btn-warning {
|
||||
background: linear-gradient(45deg, var(--warning-color), #f7dc6f);
|
||||
border: none;
|
||||
border-radius: 25px;
|
||||
padding: 12px 30px;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.question-card {
|
||||
background: white;
|
||||
border-radius: 15px;
|
||||
padding: 2rem;
|
||||
margin-bottom: 2rem;
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.option-btn {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
margin-bottom: 10px;
|
||||
padding: 15px 20px;
|
||||
border-radius: 10px;
|
||||
border: 2px solid #e9ecef;
|
||||
background: white;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.option-btn:hover {
|
||||
border-color: var(--secondary-color);
|
||||
background: rgba(52, 152, 219, 0.1);
|
||||
}
|
||||
|
||||
.option-btn.selected {
|
||||
border-color: var(--secondary-color);
|
||||
background: rgba(52, 152, 219, 0.2);
|
||||
}
|
||||
|
||||
.option-btn.correct {
|
||||
border-color: var(--success-color);
|
||||
background: rgba(39, 174, 96, 0.2);
|
||||
}
|
||||
|
||||
.option-btn.incorrect {
|
||||
border-color: var(--danger-color);
|
||||
background: rgba(231, 76, 60, 0.2);
|
||||
}
|
||||
|
||||
.stats-card {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border-radius: 15px;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.progress {
|
||||
height: 10px;
|
||||
border-radius: 10px;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
animation: fadeIn 0.5s ease-in;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.question-image {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
border-radius: 10px;
|
||||
margin: 1rem 0;
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.loading {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border: 5px solid #f3f3f3;
|
||||
border-top: 5px solid var(--secondary-color);
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg navbar-dark">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="/">
|
||||
<i class="fas fa-car me-2"></i>
|
||||
Balotario Licencia A-I
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav ms-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/">
|
||||
<i class="fas fa-home me-1"></i>Inicio
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/study">
|
||||
<i class="fas fa-book me-1"></i>Estudiar
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/practice">
|
||||
<i class="fas fa-dumbbell me-1"></i>Practicar
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/exam">
|
||||
<i class="fas fa-clipboard-check me-1"></i>Examen
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<button class="btn btn-outline-light btn-sm ms-2" id="theme-toggle"
|
||||
title="Cambiar tema (Ctrl+D)">
|
||||
<i class="fas fa-moon" id="theme-icon"></i>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container">
|
||||
<div class="container-main">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="{{ url_for('static', filename='js/modules/bootstrap/bootstrap.bundle.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/app.js') }}"></script>
|
||||
|
||||
<!-- Modular JavaScript -->
|
||||
<script src="{{ url_for('static', filename='js/modules/base.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/modules/question-navigator.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/modules/study-mode.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/modules/practice-mode.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/modules/exam-mode.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/modules/stats-display.js') }}"></script>
|
||||
|
||||
<script>
|
||||
// Script para el botón de tema
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const themeToggle = document.getElementById('theme-toggle');
|
||||
const themeIcon = document.getElementById('theme-icon');
|
||||
|
||||
if (themeToggle) {
|
||||
themeToggle.addEventListener('click', function () {
|
||||
window.themeManager.toggleTheme();
|
||||
updateThemeIcon();
|
||||
Utils.playSound('click');
|
||||
});
|
||||
}
|
||||
|
||||
function updateThemeIcon() {
|
||||
if (themeIcon && window.themeManager) {
|
||||
const isDark = window.themeManager.currentTheme === 'dark';
|
||||
themeIcon.className = isDark ? 'fas fa-sun' : 'fas fa-moon';
|
||||
}
|
||||
}
|
||||
|
||||
// Inicializar icono después de que se cargue el themeManager
|
||||
setTimeout(() => {
|
||||
updateThemeIcon();
|
||||
// Asegurar que el tema se aplique al cargar la página
|
||||
if (window.themeManager) {
|
||||
window.themeManager.applyTheme();
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
</script>
|
||||
|
||||
{% block scripts %}{% endblock %}
|
||||
</body>
|
||||
|
||||
</html>
|
||||
329
templates/exam.html
Normal file
329
templates/exam.html
Normal file
@@ -0,0 +1,329 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Examen Simulado - Balotario Licencia A-I{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="text-center mb-4">
|
||||
<h2 class="fw-bold text-warning">
|
||||
<i class="fas fa-clipboard-check me-2"></i>
|
||||
Examen Simulado
|
||||
</h2>
|
||||
<p class="text-muted">Simula el examen real con tiempo limitado y obtén tu calificación final</p>
|
||||
</div>
|
||||
|
||||
<div id="exam-setup" class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-center mb-4">
|
||||
<i class="fas fa-cog me-2"></i>Configuración del Examen
|
||||
</h5>
|
||||
|
||||
<div class="row g-4">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Número de preguntas:</label>
|
||||
<select class="form-select" id="exam-questions">
|
||||
<option value="20">20 preguntas (Rápido)</option>
|
||||
<option value="30" selected>30 preguntas (Estándar)</option>
|
||||
<option value="40">40 preguntas (Completo)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Tiempo límite:</label>
|
||||
<select class="form-select" id="exam-time">
|
||||
<option value="15">15 minutos</option>
|
||||
<option value="30" selected>30 minutos</option>
|
||||
<option value="45">45 minutos</option>
|
||||
<option value="60">60 minutos</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info mt-4">
|
||||
<i class="fas fa-info-circle me-2"></i>
|
||||
<strong>Instrucciones:</strong>
|
||||
<ul class="mb-0 mt-2">
|
||||
<li>Responde todas las preguntas antes de que se acabe el tiempo</li>
|
||||
<li>Puedes navegar entre preguntas usando los botones</li>
|
||||
<li>Las preguntas no respondidas se marcarán como incorrectas</li>
|
||||
<li>Al finalizar verás tu calificación y las respuestas correctas</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-4">
|
||||
<button class="btn btn-warning btn-lg" id="start-exam">
|
||||
<i class="fas fa-play me-2"></i>Comenzar Examen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="exam-content" style="display: none;">
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-clock me-2"></i>
|
||||
Tiempo restante: <span id="timer" class="text-warning fw-bold">30:00</span>
|
||||
</h6>
|
||||
<div>
|
||||
<span class="badge bg-warning" id="question-progress">1 de 30</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-body text-center">
|
||||
<h6 class="mb-2">Progreso</h6>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<h5 class="text-success" id="answered-count">0</h5>
|
||||
<small>Respondidas</small>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<h5 class="text-muted" id="remaining-count">30</h5>
|
||||
<small>Restantes</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="question-card fade-in" id="exam-question-container">
|
||||
<!-- Question content is loaded here -->
|
||||
</div>
|
||||
|
||||
<div class="row mt-4">
|
||||
<div class="col-md-8">
|
||||
<div class="d-flex justify-content-between">
|
||||
<button class="btn btn-outline-secondary" id="prev-exam-btn" disabled>
|
||||
<i class="fas fa-chevron-left me-2"></i>Anterior
|
||||
</button>
|
||||
<button class="btn btn-warning" id="next-exam-btn">
|
||||
Siguiente<i class="fas fa-chevron-right ms-2"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<button class="btn btn-danger w-100" id="finish-exam">
|
||||
<i class="fas fa-flag-checkered me-2"></i>Finalizar Examen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Question Navigator -->
|
||||
<div class="card mt-4">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title">Navegador de Preguntas</h6>
|
||||
<div id="question-navigator" class="d-flex flex-wrap gap-2">
|
||||
<!-- Navigation buttons are generated here -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="exam-results" class="text-center" style="display: none;">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div id="result-icon" class="mb-4">
|
||||
<!-- Icon is generated based on result -->
|
||||
</div>
|
||||
<h3 class="mb-3" id="result-title">Examen Completado</h3>
|
||||
|
||||
<div class="row justify-content-center mb-4">
|
||||
<div class="col-md-8">
|
||||
<div class="row text-center">
|
||||
<div class="col-3">
|
||||
<h4 class="text-success" id="exam-correct">0</h4>
|
||||
<p class="mb-0">Correctas</p>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<h4 class="text-danger" id="exam-incorrect">0</h4>
|
||||
<p class="mb-0">Incorrectas</p>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<h4 class="text-muted" id="exam-unanswered">0</h4>
|
||||
<p class="mb-0">Sin responder</p>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<h4 class="text-primary" id="exam-score">0%</h4>
|
||||
<p class="mb-0">Calificación</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="progress mb-4" style="height: 25px;">
|
||||
<div class="progress-bar" id="exam-progress-bar" style="width: 0%"></div>
|
||||
</div>
|
||||
|
||||
<div id="pass-message" class="alert" style="display: none;">
|
||||
<!-- Pass/fail message -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex gap-2 justify-content-center">
|
||||
<button class="btn btn-warning" id="retake-exam">
|
||||
<i class="fas fa-redo me-2"></i>Repetir Examen
|
||||
</button>
|
||||
<button class="btn btn-outline-primary" id="review-answers">
|
||||
<i class="fas fa-eye me-2"></i>Revisar Respuestas
|
||||
</button>
|
||||
<a href="/" class="btn btn-outline-secondary">
|
||||
<i class="fas fa-home me-2"></i>Volver al Inicio
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="exam-review" style="display: none;">
|
||||
<div class="text-center mb-4">
|
||||
<h3 class="fw-bold text-primary">
|
||||
<i class="fas fa-eye me-2"></i>
|
||||
Revisión de Respuestas
|
||||
</h3>
|
||||
<p class="text-muted">Revisa tus respuestas y las correctas</p>
|
||||
</div>
|
||||
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h6 class="mb-0">
|
||||
<span class="badge bg-success me-2" id="review-correct-count">0</span>Correctas
|
||||
<span class="badge bg-danger me-2 ms-3" id="review-incorrect-count">0</span>Incorrectas
|
||||
<span class="badge bg-secondary me-2 ms-3" id="review-unanswered-count">0</span>Sin responder
|
||||
</h6>
|
||||
<div>
|
||||
<span class="badge bg-primary" id="review-progress">1 de 30</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="question-card fade-in" id="review-question-container">
|
||||
<!-- Review question content is loaded here -->
|
||||
</div>
|
||||
|
||||
<div class="row mt-4">
|
||||
<div class="col-md-8">
|
||||
<div class="d-flex justify-content-between">
|
||||
<button class="btn btn-outline-secondary" id="prev-review-btn" disabled>
|
||||
<i class="fas fa-chevron-left me-2"></i>Anterior
|
||||
</button>
|
||||
<button class="btn btn-primary" id="next-review-btn">
|
||||
Siguiente<i class="fas fa-chevron-right ms-2"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<button class="btn btn-outline-secondary w-100" id="back-to-results">
|
||||
<i class="fas fa-arrow-left me-2"></i>Volver a Resultados
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Question Navigator for Review -->
|
||||
<div class="card mt-4">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title">Navegador de Preguntas</h6>
|
||||
<div class="d-flex flex-wrap gap-2 mb-3">
|
||||
<span class="badge bg-success me-2">
|
||||
<i class="fas fa-check me-1"></i>Correcta
|
||||
</span>
|
||||
<span class="badge bg-danger me-2">
|
||||
<i class="fas fa-times me-1"></i>Incorrecta
|
||||
</span>
|
||||
<span class="badge bg-secondary me-2">
|
||||
<i class="fas fa-question me-1"></i>Sin responder
|
||||
</span>
|
||||
</div>
|
||||
<div id="review-navigator" class="d-flex flex-wrap gap-2">
|
||||
<!-- Navigation buttons are generated here -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Custom confirmation modal -->
|
||||
<div id="confirmModal" style="display: none;">
|
||||
<div id="confirmBackdrop" style="
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0,0,0,0.5);
|
||||
z-index: 1050;
|
||||
"></div>
|
||||
<div id="confirmDialog" style="
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 1055;
|
||||
background: white;
|
||||
border-radius: 15px;
|
||||
box-shadow: 0 15px 35px rgba(0,0,0,0.3);
|
||||
min-width: 400px;
|
||||
max-width: 500px;
|
||||
max-height: 90vh;
|
||||
overflow-y: auto;
|
||||
">
|
||||
<div style="
|
||||
padding: 20px 25px 15px 25px;
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
">
|
||||
<h5 style="margin: 0; color: #333;">Confirmar acción</h5>
|
||||
<button id="confirmModalClose" style="
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 24px;
|
||||
cursor: pointer;
|
||||
color: #666;
|
||||
padding: 0;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
">×</button>
|
||||
</div>
|
||||
<div style="padding: 20px 25px;">
|
||||
<p id="confirm-message" style="margin: 0 0 10px 0; color: #333;">¿Estás seguro de que quieres finalizar el examen?</p>
|
||||
<p style="margin: 0; color: #666; font-size: 14px;">Tienes <span id="unanswered-warning"></span> preguntas sin responder.</p>
|
||||
</div>
|
||||
<div style="
|
||||
padding: 15px 25px 20px 25px;
|
||||
border-top: 1px solid #dee2e6;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
justify-content: flex-end;
|
||||
">
|
||||
<button id="confirmModalCancel" class="btn btn-secondary">Cancelar</button>
|
||||
<button id="confirm-finish" class="btn btn-danger">Finalizar</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
// Exam mode is now handled by the ExamMode module
|
||||
// The module auto-initializes when the DOM is ready
|
||||
console.log('Exam mode template loaded - using modular JavaScript');
|
||||
</script>
|
||||
{% endblock %}
|
||||
269
templates/index.html
Normal file
269
templates/index.html
Normal file
@@ -0,0 +1,269 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="text-center mb-5">
|
||||
<h1 class="display-4 fw-bold text-primary mb-3">
|
||||
<i class="fas fa-graduation-cap me-3"></i>
|
||||
Balotario Licencia Clase A - Categoría I
|
||||
</h1>
|
||||
<p class="lead text-muted">Prepárate para tu examen de manejo con {{ total_questions }} preguntas oficiales del MTC
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="row g-4">
|
||||
<div class="col-md-6 col-lg-3">
|
||||
<div class="card h-100 text-center">
|
||||
<div class="card-body d-flex flex-column">
|
||||
<div class="mb-3">
|
||||
<i class="fas fa-book fa-3x text-primary"></i>
|
||||
</div>
|
||||
<h5 class="card-title">Modo Estudio</h5>
|
||||
<p class="card-text flex-grow-1">
|
||||
Revisa todas las preguntas con sus respuestas correctas. Perfecto para aprender.
|
||||
</p>
|
||||
<a href="/study" class="btn btn-primary">
|
||||
<i class="fas fa-play me-2"></i>Comenzar a Estudiar
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-3">
|
||||
<div class="card h-100 text-center">
|
||||
<div class="card-body d-flex flex-column">
|
||||
<div class="mb-3">
|
||||
<i class="fas fa-dumbbell fa-3x text-success"></i>
|
||||
</div>
|
||||
<h5 class="card-title">Modo Práctica</h5>
|
||||
<p class="card-text flex-grow-1">
|
||||
Practica con preguntas aleatorias y recibe retroalimentación inmediata.
|
||||
</p>
|
||||
<a href="/practice" class="btn btn-success">
|
||||
<i class="fas fa-play me-2"></i>Practicar Ahora
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-3">
|
||||
<div class="card h-100 text-center">
|
||||
<div class="card-body d-flex flex-column">
|
||||
<div class="mb-3">
|
||||
<i class="fas fa-clipboard-check fa-3x text-warning"></i>
|
||||
</div>
|
||||
<h5 class="card-title">Examen Simulado</h5>
|
||||
<p class="card-text flex-grow-1">
|
||||
Simula el examen real con tiempo limitado y obtén tu calificación final.
|
||||
</p>
|
||||
<a href="/exam" class="btn btn-warning">
|
||||
<i class="fas fa-clock me-2"></i>Tomar Examen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-3">
|
||||
<div class="card h-100 text-center stats-card">
|
||||
<div class="card-body d-flex flex-column">
|
||||
<div class="mb-3">
|
||||
<i class="fas fa-chart-line fa-3x text-white"></i>
|
||||
</div>
|
||||
<h5 class="card-title text-white">Estadísticas</h5>
|
||||
<div class="flex-grow-1">
|
||||
<div id="stats-content">
|
||||
<div class="row text-center">
|
||||
<div class="col-6">
|
||||
<h4 id="total-answered">0</h4>
|
||||
<small>Respondidas</small>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<h4 id="accuracy">0%</h4>
|
||||
<small>Precisión</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<div class="progress">
|
||||
<div class="progress-bar bg-success" id="accuracy-bar" style="width: 0%"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<button class="btn btn-outline-light btn-sm" id="reset-stats-btn"
|
||||
title="Restablecer estadísticas">
|
||||
<i class="fas fa-redo me-1"></i>Restablecer
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-5">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
<i class="fas fa-info-circle me-2"></i>
|
||||
Información del Balotario
|
||||
</h5>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<ul class="list-unstyled">
|
||||
<li><i class="fas fa-check text-success me-2"></i>{{ total_questions }} preguntas oficiales
|
||||
</li>
|
||||
<li><i class="fas fa-check text-success me-2"></i>Respuestas correctas marcadas</li>
|
||||
<li><i class="fas fa-check text-success me-2"></i>Imágenes de señales de tránsito</li>
|
||||
<li><i class="fas fa-check text-success me-2"></i>Seguimiento de progreso</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<ul class="list-unstyled">
|
||||
<li><i class="fas fa-check text-success me-2"></i>Interfaz intuitiva y moderna</li>
|
||||
<li><i class="fas fa-check text-success me-2"></i>Modo examen con cronómetro</li>
|
||||
<li><i class="fas fa-check text-success me-2"></i>Estadísticas detalladas</li>
|
||||
<li><i class="fas fa-check text-success me-2"></i>Responsive para móviles</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistics reset confirmation modal -->
|
||||
<div id="resetStatsModal" style="display: none;">
|
||||
<div id="resetStatsBackdrop" style="
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0,0,0,0.6);
|
||||
z-index: 1050;
|
||||
backdrop-filter: blur(3px);
|
||||
"></div>
|
||||
<div id="resetStatsDialog" style="
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 1055;
|
||||
background: white;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.3);
|
||||
min-width: 400px;
|
||||
max-width: 500px;
|
||||
max-height: 90vh;
|
||||
overflow-y: auto;
|
||||
animation: modalSlideIn 0.3s ease-out;
|
||||
">
|
||||
<div style="
|
||||
padding: 25px 30px 20px 30px;
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
">
|
||||
<div style="display: flex; align-items: center;">
|
||||
<i class="fas fa-exclamation-triangle text-warning me-3" style="font-size: 24px;"></i>
|
||||
<h5 style="margin: 0; color: #333; font-weight: 600;">Restablecer Estadísticas</h5>
|
||||
</div>
|
||||
<button id="resetStatsModalClose" style="
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 28px;
|
||||
cursor: pointer;
|
||||
color: #666;
|
||||
padding: 0;
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
transition: all 0.2s ease;
|
||||
" onmouseover="this.style.background='#f8f9fa'" onmouseout="this.style.background='none'">×</button>
|
||||
</div>
|
||||
<div style="padding: 25px 30px;">
|
||||
<div style="text-align: center; margin-bottom: 20px;">
|
||||
<i class="fas fa-chart-line text-primary" style="font-size: 48px; opacity: 0.7;"></i>
|
||||
</div>
|
||||
<p style="margin: 0 0 15px 0; color: #333; font-size: 16px; text-align: center;">
|
||||
¿Estás seguro de que quieres restablecer todas tus estadísticas?
|
||||
</p>
|
||||
<div
|
||||
style="background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 10px; padding: 15px; margin-bottom: 20px;">
|
||||
<div style="display: flex; align-items: flex-start;">
|
||||
<i class="fas fa-info-circle text-warning me-2" style="margin-top: 2px;"></i>
|
||||
<div style="font-size: 14px; color: #856404;">
|
||||
<strong>Esta acción eliminará:</strong>
|
||||
<ul style="margin: 8px 0 0 0; padding-left: 20px;">
|
||||
<li>Preguntas respondidas</li>
|
||||
<li>Porcentaje de precisión</li>
|
||||
<li>Racha de respuestas correctas</li>
|
||||
<li>Tiempo de estudio</li>
|
||||
<li>Historial de exámenes</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p style="margin: 0; color: #666; font-size: 14px; text-align: center;">
|
||||
<strong>Esta acción no se puede deshacer.</strong>
|
||||
</p>
|
||||
</div>
|
||||
<div style="
|
||||
padding: 20px 30px 25px 30px;
|
||||
border-top: 1px solid #dee2e6;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
justify-content: flex-end;
|
||||
">
|
||||
<button id="resetStatsModalCancel" class="btn btn-secondary" style="min-width: 100px;">
|
||||
<i class="fas fa-times me-1"></i>Cancelar
|
||||
</button>
|
||||
<button id="confirmResetStats" class="btn btn-danger" style="min-width: 120px;">
|
||||
<i class="fas fa-trash-alt me-1"></i>Restablecer
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@keyframes modalSlideIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translate(-50%, -60%);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes modalSlideOut {
|
||||
from {
|
||||
opacity: 1;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 0;
|
||||
transform: translate(-50%, -40%);
|
||||
}
|
||||
}
|
||||
|
||||
.modal-closing {
|
||||
animation: modalSlideOut 0.2s ease-in forwards;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
// Index page stats are now handled by the StatsDisplay module
|
||||
// The module auto-initializes when the DOM is ready
|
||||
console.log('Index page template loaded - using modular JavaScript');
|
||||
</script>
|
||||
{% endblock %}
|
||||
217
templates/practice.html
Normal file
217
templates/practice.html
Normal file
@@ -0,0 +1,217 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Modo Práctica - Balotario Licencia A-I{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="text-center mb-4">
|
||||
<h2 class="fw-bold text-success">
|
||||
<i class="fas fa-dumbbell me-2"></i>
|
||||
Modo Práctica
|
||||
</h2>
|
||||
<p class="text-muted">Practica con preguntas aleatorias y recibe retroalimentación inmediata</p>
|
||||
</div>
|
||||
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h6 class="mb-0">Configuración de Práctica</h6>
|
||||
<button class="btn btn-sm btn-outline-success" id="new-session">
|
||||
<i class="fas fa-refresh me-1"></i>Nueva Sesión
|
||||
</button>
|
||||
</div>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Número de preguntas:</label>
|
||||
<select class="form-select" id="question-count">
|
||||
<option value="10">10 preguntas</option>
|
||||
<option value="20" selected>20 preguntas</option>
|
||||
<option value="30">30 preguntas</option>
|
||||
<option value="50">50 preguntas</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label"> </label>
|
||||
<button class="btn btn-success w-100" id="start-practice">
|
||||
<i class="fas fa-play me-1"></i>Comenzar Práctica
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card stats-enhanced">
|
||||
<div class="card-body text-center position-relative">
|
||||
<h6 class="text-white mb-3">Estadísticas de Sesión</h6>
|
||||
<div class="row g-2">
|
||||
<div class="col-6 col-sm-4">
|
||||
<div class="stats-number" id="session-correct">0</div>
|
||||
<small class="d-block">Correctas</small>
|
||||
</div>
|
||||
<div class="col-6 col-sm-4">
|
||||
<div class="stats-number" id="session-incorrect">0</div>
|
||||
<small class="d-block">Incorrectas</small>
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<div class="stats-number" id="session-accuracy">0%</div>
|
||||
<small class="d-block">Precisión</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<div class="progress" style="height: 8px;">
|
||||
<div class="progress-bar bg-light" id="session-progress" style="width: 0%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="loading" class="loading">
|
||||
<div class="spinner"></div>
|
||||
</div>
|
||||
|
||||
<div id="practice-content" style="display: none;">
|
||||
<div class="question-card fade-in" id="question-container">
|
||||
<!-- Question content is loaded here -->
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between mt-4">
|
||||
<div>
|
||||
<span class="badge bg-primary fs-6" id="question-counter">1 de 20</span>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<button class="btn btn-outline-secondary" id="skip-question">
|
||||
<i class="fas fa-forward me-2"></i>Saltar
|
||||
</button>
|
||||
<button class="btn btn-success" id="next-question" style="display: none;">
|
||||
Siguiente<i class="fas fa-chevron-right ms-2"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="practice-complete" class="text-center" style="display: none;">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<i class="fas fa-trophy fa-4x text-warning mb-4"></i>
|
||||
<h3 class="mb-3">¡Práctica Completada!</h3>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="row text-center mb-4">
|
||||
<div class="col-4">
|
||||
<h4 class="text-success" id="final-correct">0</h4>
|
||||
<p class="mb-0">Correctas</p>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<h4 class="text-danger" id="final-incorrect">0</h4>
|
||||
<p class="mb-0">Incorrectas</p>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<h4 class="text-primary" id="final-accuracy">0%</h4>
|
||||
<p class="mb-0">Precisión</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress mb-4" style="height: 20px;">
|
||||
<div class="progress-bar bg-success" id="final-progress" style="width: 0%"></div>
|
||||
</div>
|
||||
<div class="d-flex gap-2 justify-content-center">
|
||||
<button class="btn btn-success" id="practice-again">
|
||||
<i class="fas fa-redo me-2"></i>Practicar de Nuevo
|
||||
</button>
|
||||
<a href="/" class="btn btn-outline-primary">
|
||||
<i class="fas fa-home me-2"></i>Volver al Inicio
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="welcome-message" class="text-center">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<i class="fas fa-play-circle fa-4x text-success mb-4"></i>
|
||||
<h4>¡Listo para Practicar!</h4>
|
||||
<p class="text-muted">Configura tu sesión de práctica y comienza a responder preguntas aleatorias.</p>
|
||||
<p class="small text-muted">
|
||||
<i class="fas fa-lightbulb me-1"></i>
|
||||
Tip: Recibirás retroalimentación inmediata después de cada respuesta.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
/* Mobile-specific improvements for session statistics */
|
||||
@media (max-width: 576px) {
|
||||
.stats-enhanced .card-body {
|
||||
padding: 1rem 0.75rem;
|
||||
}
|
||||
|
||||
.stats-enhanced h6 {
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 1rem !important;
|
||||
}
|
||||
|
||||
.stats-number {
|
||||
font-size: 1.5rem !important;
|
||||
font-weight: bold;
|
||||
line-height: 1.2;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.stats-enhanced small {
|
||||
font-size: 0.75rem;
|
||||
opacity: 0.9;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.stats-enhanced .row {
|
||||
margin: 0 -0.25rem;
|
||||
}
|
||||
|
||||
.stats-enhanced .row > div {
|
||||
padding: 0.5rem 0.25rem;
|
||||
}
|
||||
|
||||
/* Better spacing for the accuracy stat when it's full width */
|
||||
.stats-enhanced .col-12 {
|
||||
margin-top: 0.5rem;
|
||||
padding-top: 0.75rem;
|
||||
border-top: 1px solid rgba(255,255,255,0.2);
|
||||
}
|
||||
}
|
||||
|
||||
/* Tablet improvements */
|
||||
@media (min-width: 577px) and (max-width: 768px) {
|
||||
.stats-enhanced .stats-number {
|
||||
font-size: 1.75rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.stats-enhanced small {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* General stats number styling */
|
||||
.stats-number {
|
||||
font-size: 2rem;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
text-shadow: 0 1px 3px rgba(0,0,0,0.3);
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
// Practice mode is now handled by the PracticeMode module
|
||||
// The module auto-initializes when the DOM is ready
|
||||
console.log('Practice mode template loaded - using modular JavaScript');
|
||||
</script>
|
||||
{% endblock %}
|
||||
287
templates/study.html
Normal file
287
templates/study.html
Normal file
@@ -0,0 +1,287 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Modo Estudio - Balotario Licencia A-I{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="text-center mb-4">
|
||||
<h2 class="fw-bold text-primary">
|
||||
<i class="fas fa-book me-2"></i>
|
||||
Modo Estudio
|
||||
</h2>
|
||||
<p class="text-muted">Revisa todas las preguntas con sus respuestas correctas</p>
|
||||
</div>
|
||||
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h6 class="mb-0">Filtros de Estudio</h6>
|
||||
<button class="btn btn-sm btn-outline-primary" id="reset-filters">
|
||||
<i class="fas fa-refresh me-1"></i>Resetear
|
||||
</button>
|
||||
</div>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Desde pregunta:</label>
|
||||
<input type="number" class="form-control" id="start-question" min="1" max="200" value="1">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Hasta pregunta:</label>
|
||||
<input type="number" class="form-control" id="end-question" min="1" max="200" value="200">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label"> </label>
|
||||
<button class="btn btn-primary w-100" id="apply-filters">
|
||||
<i class="fas fa-filter me-1"></i>Aplicar Filtros
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card stats-card">
|
||||
<div class="card-body text-center">
|
||||
<h6 class="text-white mb-3">Progreso de Estudio</h6>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<h4 class="text-white" id="current-question">1</h4>
|
||||
<small>Pregunta Actual</small>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<h4 class="text-white" id="total-questions">0</h4>
|
||||
<small>Total</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress mt-3">
|
||||
<div class="progress-bar bg-light" id="study-progress" style="width: 0%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="loading" class="loading">
|
||||
<div class="spinner"></div>
|
||||
</div>
|
||||
|
||||
<div id="study-content" style="display: none;">
|
||||
<div class="question-card fade-in" id="question-container">
|
||||
<!-- Question content is loaded here -->
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between mt-4">
|
||||
<button class="btn btn-outline-secondary" id="prev-btn" disabled>
|
||||
<i class="fas fa-chevron-left me-2"></i>Anterior
|
||||
</button>
|
||||
<div class="d-flex gap-2">
|
||||
<button class="btn btn-outline-primary" id="show-answer">
|
||||
<i class="fas fa-eye me-2"></i>Mostrar Respuesta
|
||||
</button>
|
||||
<button class="btn btn-outline-primary" id="hide-answer" style="display: none;">
|
||||
<i class="fas fa-eye-slash me-2"></i>Ocultar Respuesta
|
||||
</button>
|
||||
</div>
|
||||
<button class="btn btn-primary" id="next-btn">
|
||||
Siguiente<i class="fas fa-chevron-right ms-2"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Question Navigator -->
|
||||
<div class="card mt-4">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h6 class="card-title mb-0">
|
||||
<i class="fas fa-map me-2"></i>Navegador de Preguntas
|
||||
</h6>
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
<small class="text-muted">Ir a:</small>
|
||||
<input type="number" class="form-control form-control-sm" id="jump-to-question"
|
||||
min="1" max="200" placeholder="#" style="width: 60px;">
|
||||
<button class="btn btn-sm btn-outline-primary" id="jump-btn" title="Ir a pregunta">
|
||||
<i class="fas fa-arrow-right"></i>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-outline-warning" id="reset-visited-btn" title="Limpiar preguntas visitadas">
|
||||
<i class="fas fa-redo"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="question-navigator" class="question-navigator">
|
||||
<!-- Question navigation buttons will be generated here -->
|
||||
</div>
|
||||
<div class="mt-2 d-flex justify-content-between align-items-center">
|
||||
<div class="navigator-legend">
|
||||
<small class="text-muted">
|
||||
<span class="badge bg-primary me-2">●</span>Actual
|
||||
<span class="badge bg-success me-2 ms-2">●</span>Visitada
|
||||
<span class="badge bg-outline-secondary me-2 ms-2">○</span>Pendiente
|
||||
</small>
|
||||
</div>
|
||||
<small class="text-muted" id="navigator-progress">0 de 0 visitadas</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="no-questions" class="text-center" style="display: none;">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<i class="fas fa-exclamation-triangle fa-3x text-warning mb-3"></i>
|
||||
<h5>No se encontraron preguntas</h5>
|
||||
<p class="text-muted">Ajusta los filtros para ver las preguntas disponibles.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
/* Question Navigator Styles */
|
||||
.question-navigator {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
padding: 8px;
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #dee2e6;
|
||||
}
|
||||
|
||||
.question-nav-btn {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
border: 1px solid #dee2e6;
|
||||
background: white;
|
||||
color: #6c757d;
|
||||
border-radius: 6px;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.question-nav-btn:hover {
|
||||
border-color: #3498db;
|
||||
background: #e3f2fd;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.question-nav-btn.current {
|
||||
background: #3498db;
|
||||
color: white;
|
||||
border-color: #2980b9;
|
||||
font-weight: bold;
|
||||
box-shadow: 0 2px 4px rgba(52, 152, 219, 0.3);
|
||||
}
|
||||
|
||||
.question-nav-btn.visited {
|
||||
background: #27ae60;
|
||||
color: white;
|
||||
border-color: #229954;
|
||||
}
|
||||
|
||||
.question-nav-btn.visited:hover {
|
||||
background: #2ecc71;
|
||||
border-color: #27ae60;
|
||||
}
|
||||
|
||||
.navigator-legend .badge {
|
||||
font-size: 0.7rem;
|
||||
padding: 0.25em 0.4em;
|
||||
}
|
||||
|
||||
/* Mobile responsive */
|
||||
@media (max-width: 576px) {
|
||||
.question-navigator {
|
||||
max-height: 150px;
|
||||
gap: 3px;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.question-nav-btn {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.navigator-legend {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#jump-to-question {
|
||||
width: 50px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tablet responsive */
|
||||
@media (min-width: 577px) and (max-width: 768px) {
|
||||
.question-navigator {
|
||||
max-height: 180px;
|
||||
}
|
||||
|
||||
.question-nav-btn {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Smooth scrolling for navigator */
|
||||
.question-navigator {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* Jump to question input styling */
|
||||
#jump-to-question {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#jump-to-question:focus {
|
||||
border-color: #3498db;
|
||||
box-shadow: 0 0 0 0.2rem rgba(52, 152, 219, 0.25);
|
||||
}
|
||||
|
||||
/* Reset visited button styling */
|
||||
#reset-visited-btn {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
#reset-visited-btn:hover {
|
||||
background: #ffc107;
|
||||
border-color: #ffc107;
|
||||
color: #000;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
#reset-visited-btn:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
/* Mobile adjustments for navigator controls */
|
||||
@media (max-width: 576px) {
|
||||
.card-title {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
#reset-visited-btn, #jump-btn {
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
#reset-visited-btn i, #jump-btn i {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
// Study mode is now handled by the StudyMode module
|
||||
// The module auto-initializes when the DOM is ready
|
||||
console.log('Study mode template loaded - using modular JavaScript');
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user