Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 87 additions & 13 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,96 @@
<script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js"></script>
</head>
<body>
<!-- Botones de control en la parte superior -->
<div id="progress-buttons">
<button id="save-progress">Guardar progreso</button>
<button id="load-progress">Cargar progreso</button>
<!-- Input oculto para cargar progreso (.json) -->
<input type="file" id="file-input" accept=".json" style="display:none">
<header class="main-header">
<button id="menu-toggle" class="menu-toggle" aria-label="Abrir menú">&#9776;</button>
<span id="collection-name" class="collection-name">Colección</span>
</header>
<aside id="side-menu" class="side-menu">
<button id="menu-close" class="menu-close" aria-label="Cerrar menú">&times;</button>
<div id="side-menu-buttons">
<div class="menu-section">
<button id="home-button" class="menu-item">
<span class="menu-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256">
<path d="M224,115.55V208a16,16,0,0,1-16,16H168a16,16,0,0,1-16-16V168a8,8,0,0,0-8-8H112a8,8,0,0,0-8,8v40a16,16,0,0,1-16,16H48a16,16,0,0,1-16-16V115.55a16,16,0,0,1,5.17-11.78l80-75.48.11-.11a16,16,0,0,1,21.53,0,1.14,1.14,0,0,0,.11.11l80,75.48A16,16,0,0,1,224,115.55Z"/>
</svg>
</span>
<span class="menu-text">Inicio</span>
</button>

<button id="load-csv-button">Cargar Nuevo CSV</button>
<!-- Input oculto para cargar nuevo CSV -->
<input type="file" id="csv-file-input" accept=".csv" style="display:none">
<button id="change-collection-button" class="menu-item">
<span class="menu-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256">
<path d="M216,72H131.31L104,44.69A15.86,15.86,0,0,0,92.69,40H40A16,16,0,0,0,24,56V200.62A15.4,15.4,0,0,0,39.38,216H216.89A15.13,15.13,0,0,0,232,200.89V88A16,16,0,0,0,216,72ZM40,56H92.69l16,16H40ZM216,200H40V88H216Z"/>
</svg>
</span>
<span class="menu-text">Cambiar Colección</span>
</button>
</div>
<div class="menu-section">

<button id="change-collection-button">Cambiar colección</button>
<button id="save-progress" class="menu-item">
<span class="menu-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256">
<path d="M219.31,80,176,36.69A15.86,15.86,0,0,0,164.69,32H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V91.31A15.86,15.86,0,0,0,219.31,80ZM168,208H88V152h80Zm40,0H184V152a16,16,0,0,0-16-16H88a16,16,0,0,0-16,16v56H48V48H164.69L208,91.31ZM160,72a8,8,0,0,1-8,8H96a8,8,0,0,1,0-16h56A8,8,0,0,1,160,72Z"/>
</svg>
</span>
<span class="menu-text">Guardar Progreso</span>
</button>

<button id="reset-progress-button">Reiniciar Progreso</button>
<button id="config-button">Configuración</button>
</div>
<button id="load-progress" class="menu-item">
<span class="menu-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256">
<path d="M219.31,80,176,36.69A15.86,15.86,0,0,0,164.69,32H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V91.31A15.86,15.86,0,0,0,219.31,80ZM168,208H88V152h80Zm40,0H184V152a16,16,0,0,0-16-16H88a16,16,0,0,0-16,16v56H48V48H164.69L208,91.31ZM160,72a8,8,0,0,1-8,8H96a8,8,0,0,1,0-16h56A8,8,0,0,1,160,72Z"/>
</svg>
</span>
<span class="menu-text">Cargar Progreso</span>
</button>
<!-- Input oculto para cargar progreso (.json) -->
<input type="file" id="file-input" accept=".json" style="display:none">

<button id="load-csv-button" class="menu-item">
<span class="menu-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256">
<path d="M213.66,82.34l-56-56A8,8,0,0,0,152,24H56A16,16,0,0,0,40,40V216a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V88A8,8,0,0,0,213.66,82.34ZM160,51.31,188.69,80H160ZM200,216H56V40h88V88a8,8,0,0,0,8,8h48V216Z"/>
</svg>
</span>
<span class="menu-text">Cargar Nuevo CSV</span>
</button>
<!-- Input oculto para cargar nuevo CSV -->
<input type="file" id="csv-file-input" accept=".csv" style="display:none">

<button id="reset-progress-button" class="menu-item">
<span class="menu-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256">
<path d="M224,128a96,96,0,0,1-94.71,96H128A95.38,95.38,0,0,1,62.1,197.8a8,8,0,0,1,11-11.63A80,80,0,1,0,71.43,71.39a3.07,3.07,0,0,1-.26.25L44.59,96H72a8,8,0,0,1,0,16H24a8,8,0,0,1-8-8V56a8,8,0,0,1,16,0V85.8L60.25,60A96,96,0,0,1,224,128Z"/>
</svg>
</span>
<span class="menu-text">Reiniciar Progreso</span>
</button>

</div>
<div class="menu-section">
<button id="config-button" class="menu-item">
<span class="menu-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256">
<path d="M128,80a48,48,0,1,0,48,48A48.05,48.05,0,0,0,128,80Zm0,80a32,32,0,1,1,32-32A32,32,0,0,1,128,160Zm88-29.84q.06-2.16,0-4.32l14.92-18.64a8,8,0,0,0,1.48-7.06,107.21,107.21,0,0,0-10.88-26.25,8,8,0,0,0-6-3.93l-23.72-2.64q-1.48-1.56-3-3L186,40.54a8,8,0,0,0-3.94-6,107.71,107.71,0,0,0-26.25-10.87,8,8,0,0,0-7.06,1.49L130.16,40Q128,40,125.84,40L107.2,25.11a8,8,0,0,0-7.06-1.48A107.6,107.6,0,0,0,73.89,34.51a8,8,0,0,0-3.93,6L67.32,64.27q-1.56,1.49-3,3L40.54,70a8,8,0,0,0-6,3.94,107.71,107.71,0,0,0-10.87,26.25,8,8,0,0,0,1.49,7.06L40,125.84Q40,128,40,130.16L25.11,148.8a8,8,0,0,0-1.48,7.06,107.21,107.21,0,0,0,10.88,26.25,8,8,0,0,0,6,3.93l23.72,2.64q1.49,1.56,3,3L70,215.46a8,8,0,0,0,3.94,6,107.71,107.71,0,0,0,26.25,10.87,8,8,0,0,0,7.06-1.49L125.84,216q2.16.06,4.32,0l18.64,14.92a8,8,0,0,0,7.06,1.48,107.21,107.21,0,0,0,26.25-10.88,8,8,0,0,0,3.93-6l2.64-23.72q1.56-1.48,3-3L215.46,186a8,8,0,0,0,6-3.94,107.71,107.71,0,0,0,10.87-26.25,8,8,0,0,0-1.49-7.06Zm-16.1-6.5a73.93,73.93,0,0,1,0,8.68,8,8,0,0,0,1.74,5.48l14.19,17.73a91.57,91.57,0,0,1-6.23,15L187,173.11a8,8,0,0,0-5.1,2.64,74.11,74.11,0,0,1-6.14,6.14,8,8,0,0,0-2.64,5.1l-2.51,22.58a91.32,91.32,0,0,1-15,6.23l-17.74-14.19a8,8,0,0,0-5-1.75h-.48a73.93,73.93,0,0,1-8.68,0,8,8,0,0,0-5.48,1.74L100.45,215.8a91.57,91.57,0,0,1-15-6.23L82.89,187a8,8,0,0,0-2.64-5.1,74.11,74.11,0,0,1-6.14-6.14,8,8,0,0,0-5.1-2.64L46.43,170.6a91.32,91.32,0,0,1-6.23-15l14.19-17.74a8,8,0,0,0,1.74-5.48,73.93,73.93,0,0,1,0-8.68,8,8,0,0,0-1.74-5.48L40.2,100.45a91.57,91.57,0,0,1,6.23-15L69,82.89a8,8,0,0,0,5.1-2.64,74.11,74.11,0,0,1,6.14-6.14A8,8,0,0,0,82.89,69L85.4,46.43a91.32,91.32,0,0,1,15-6.23l17.74,14.19a8,8,0,0,0,5.48,1.74,73.93,73.93,0,0,1,8.68,0,8,8,0,0,0,5.48-1.74L155.55,40.2a91.57,91.57,0,0,1,15,6.23L173.11,69a8,8,0,0,0,2.64,5.1,74.11,74.11,0,0,1,6.14,6.14,8,8,0,0,0,5.1,2.64l22.58,2.51a91.32,91.32,0,0,1,6.23,15l-14.19,17.74A8,8,0,0,0,199.87,123.66Z"/>
</svg>
</span>
<span class="menu-text">Ajustes</span>
</button>

<button id="login-button" class="menu-item">
<span class="menu-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256">
<path d="M230.92,212c-15.23-26.33-38.7-45.21-66.09-54.16a72,72,0,1,0-73.66,0C63.78,166.78,40.31,185.66,25.08,212a8,8,0,1,0,13.85,8c18.84-32.56,52.14-52,89.07-52s70.23,19.44,89.07,52a8,8,0,1,0,13.85-8ZM72,96a56,56,0,1,1,56,56A56.06,56.06,0,0,1,72,96Z"/>
</svg>
</span>
<span class="menu-text">Iniciar Sesión</span>
</button>
</div>
</div>
</aside>
<div class="quiz-container">
<div id="quiz"></div>
<!-- Elemento para mostrar mensajes de estado (opcional) -->
Expand Down
32 changes: 31 additions & 1 deletion script.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ let quizContainerDiv = null; // <-- NUEVO: Referencia al contenedor principal
let timeProgressDiv = null;
let timeBarDiv = null;
let timeRemainingSpan = null;
let menuToggle = null;
let sideMenu = null;
let menuClose = null;
let collectionNameSpan = null;

let initialTotalRepetitions = 0;
let questionStartTime = null;
Expand Down Expand Up @@ -81,6 +85,10 @@ document.addEventListener('DOMContentLoaded', function() {
timeProgressDiv = document.getElementById('time-progress');
timeBarDiv = document.getElementById('time-bar');
timeRemainingSpan = document.getElementById('time-remaining');
menuToggle = document.getElementById('menu-toggle');
menuClose = document.getElementById('menu-close');
collectionNameSpan = document.getElementById('collection-name');
sideMenu = document.getElementById('side-menu');
collectionSelect = document.getElementById('collection-select');
changeCollectionButton = document.getElementById('change-collection-button');
collectionModalOverlay = document.getElementById('collection-modal-overlay');
Expand All @@ -102,7 +110,8 @@ document.addEventListener('DOMContentLoaded', function() {
!timeProgressDiv || !timeBarDiv || !timeRemainingSpan || !collectionSelect ||
!changeCollectionButton || !collectionModalOverlay || !collectionModal || !confirmCollectionButton ||
!configButton || !configModalOverlay || !configModal || !configRepsOnErrorInput ||
!configInitialRepsInput || !configThemeSelect || !saveConfigButton || !closeModalButton || !closeModalXButton) {
!configInitialRepsInput || !configThemeSelect || !saveConfigButton || !closeModalButton || !closeModalXButton ||
!menuToggle || !menuClose || !collectionNameSpan || !sideMenu) {
console.error("Error: No se encontraron elementos esenciales del DOM (quiz, status, inputs, o elementos del modal).");
if(quizDiv) quizDiv.innerHTML = "<p class='error-message'>Error crítico: Faltan elementos HTML esenciales para el quiz o la configuración.</p>";
return;
Expand All @@ -128,6 +137,16 @@ function setupEventListeners() {
document.getElementById('reset-progress-button')?.addEventListener('click', resetCurrentProgress);
configButton?.addEventListener('click', openConfigModal);

// Menú lateral
menuToggle?.addEventListener("click", function() {
sideMenu.classList.add("open");
menuToggle.style.display = "none";
});
menuClose?.addEventListener("click", function() {
sideMenu.classList.remove("open");
menuToggle.style.display = "";
});

// Inputs de archivo
fileInput.addEventListener('change', handleProgressFileSelect);
csvFileInput.addEventListener('change', handleCsvFileSelect);
Expand Down Expand Up @@ -211,6 +230,7 @@ async function loadCollections() {
if (!customOption.disabled && saved === 'custom') {
collectionSelect.value = 'custom';
updateUrlForCollection('custom', true);
updateCollectionName();
} else {
updateUrlForCollection(null, true);
openCollectionModal();
Expand All @@ -220,6 +240,7 @@ async function loadCollections() {
localStorage.setItem(COLLECTION_STORAGE_KEY, pathId);
updateUrlForCollection(pathId, true);
await loadQuestionsFromCollection(pathId);
updateCollectionName();
return;
} else {
updateUrlForCollection(null, true);
Expand All @@ -228,11 +249,13 @@ async function loadCollections() {
} else if (saved && collectionSelect.querySelector(`option[value="${saved}"]`)) {
collectionSelect.value = saved;
updateUrlForCollection(saved, true);
updateCollectionName();
if (saved !== 'custom') {
await loadQuestionsFromCollection(saved);
}
} else if (availableCollections.length > 0) {
collectionSelect.value = availableCollections[0].id;
updateCollectionName();
updateUrlForCollection(null, true);
openCollectionModal();
} else {
Expand Down Expand Up @@ -293,6 +316,12 @@ function openCollectionModal() {
function closeCollectionModal() {
if (collectionModalOverlay) collectionModalOverlay.classList.add('hidden');
}
function updateCollectionName() {
const opt = collectionSelect.options[collectionSelect.selectedIndex];
if (opt) {
collectionNameSpan.textContent = opt.textContent;
}
}

function confirmCollectionSelection() {
const id = collectionSelect.value;
Expand All @@ -304,6 +333,7 @@ function confirmCollectionSelection() {
localStorage.setItem(COLLECTION_STORAGE_KEY, 'custom');
updateUrlForCollection('custom');
}
updateCollectionName();
closeCollectionModal();
}

Expand Down
117 changes: 88 additions & 29 deletions styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -104,33 +104,100 @@ body {
min-height: 100vh; /* Asegura que el cuerpo ocupe al menos toda la altura de la vista */
}

#progress-buttons {
#side-menu-buttons {
.main-header {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 10px;
padding: 2px 15px;
/* background-color: #343a40; */ /* Darker menu background */
color: black;
width: 100%;
/* box-shadow: 0 2px 4px rgba(0,0,0,0.1); */
/* position: sticky; top: 0; z-index: 100; */ /* Opción para menú pegajoso */
align-items: center;
gap: 1rem;
padding: 0.5rem 1rem;
background-color: var(--container-bg);
color: var(--text-color);
position: sticky;
top: 0;
z-index: 1000;
}

#progress-buttons button {
padding: 0.6em 1em;
#menu-toggle {
background: none;
border: none;
color: var(--text-color);
font-size: 1.4rem;
cursor: pointer;
background-color: #007bff;
color: #000;
}
#menu-toggle:hover {
background-color: var(--option-hover-bg);
}
.menu-close {
background: none;
border: none;
color: var(--text-color);
font-size: 1.4rem;
cursor: pointer;
margin-bottom: 0.5rem;
}
.menu-section {
margin-bottom: 0.75rem;
padding-bottom: 0.5rem;
border-bottom: 1px solid var(--option-border);
}
.menu-section:last-child {
border-bottom: none;
}

display: flex;
flex-direction: column;
gap: 0.5rem;
padding: 1rem;
}

.menu-item {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.6em 0.8em;
cursor: pointer;
background-color: transparent;
color: var(--text-color);
border: none;
border-radius: 4px;
font-size: 0.9rem; /* Relativo al font-size de html */
font-size: 0.95rem;
transition: background-color 0.2s ease;
flex-grow: 0; /* No crecer para llenar espacio por defecto */
flex-shrink: 0; /* No encogerse por defecto */
flex-basis: auto; /* Tamaño basado en contenido */
width: 100%;
text-align: left;
}

.menu-item:hover {
background-color: var(--option-hover-bg);
}

.menu-icon svg {
width: 24px;
height: 24px;
}
}

.side-menu {
position: fixed;
top: 0;
left: 0;
width: 220px;
height: 100%;
background-color: var(--container-bg);
box-shadow: 2px 0 5px rgba(0,0,0,0.1);
transform: translateX(-100%);
transition: transform 0.3s ease;
z-index: 1050;
overflow-y: auto;
}

.side-menu.open {
transform: translateX(0);
}

#side-menu #side-menu-buttons {
flex-direction: column;
align-items: stretch;
}

.modal-content select {
padding: 0.55em 0.8em;
Expand All @@ -141,9 +208,6 @@ body {
font-size: 0.9rem;
}

#progress-buttons button:hover {
background-color: #0056b3;
}

.quiz-container {
background-color: var(--container-bg);
Expand Down Expand Up @@ -410,7 +474,7 @@ body {
margin: 1.25rem auto;
}
#quiz h2 { font-size: 1.3rem; }
#progress-buttons button { font-size: 0.85rem; padding: 0.5em 0.8em; }
.menu-item { font-size: 0.85rem; padding: 0.5em 0.8em; }
.modal-content select { font-size: 0.85rem; padding: 0.45em 0.7em; }
}

Expand All @@ -419,15 +483,10 @@ body {
font-size: 14px; /* Aumentar ligeramente la base para móviles para que no sea tan pequeño */
/* El valor original era 14px, si se sigue viendo pequeño, probar con 15px o 16px */
}
#progress-buttons {
padding: 10px 8px;
gap: 8px;
}
#progress-buttons button {
.side-menu { width: 80%; }
.menu-item {
font-size: 0.85rem; /* Ajustar según necesidad */
padding: 0.5em 0.7em;
flex-grow: 1; /* Permite que los botones se expandan un poco */
flex-basis: calc(50% - 4px); /* Dos botones por línea */
}

.quiz-container {
Expand Down