QuizZip / frontend.html
NathMen12's picture
Create frontend.html
834e0b2 verified
Raw
History Blame Contribute Delete
15.8 kB
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>QuizZap ⚡</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;600;700&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/style.css">
</head>
<body class="font-inter bg-zap-dark text-zap-light min-h-screen">
<!-- Toast Container -->
<div id="toast-container" class="fixed bottom-6 right-6 z-[100] flex flex-col gap-2"></div>
<!-- Auth Pages -->
<div id="page-auth" class="page min-h-screen flex items-center justify-center p-4 bg-gradient-to-br from-zap-dark via-zap-purple to-zap-dark">
<div class="w-full max-w-md bg-zap-card/90 backdrop-blur-sm rounded-2xl border border-zap-border p-8 shadow-2xl">
<div class="text-center mb-8"><h1 class="font-space text-4xl font-bold bg-gradient-to-r from-zap-yellow to-zap-orange bg-clip-text text-transparent">QuizZap</h1><p class="text-zap-muted mt-2">Crée, Joue, Gagne.</p></div>
<div id="auth-forms">
<!-- Login Form -->
<form id="form-login" class="space-y-4" data-page="login">
<h2 class="text-xl font-semibold text-center">Connexion</h2>
<div class="input-group"><label class="input-label">Email</label><input type="email" name="email" class="input-field" required></div>
<div class="input-group"><label class="input-label">Mot de passe</label><input type="password" name="password" class="input-field" required></div>
<button type="submit" class="btn btn-primary w-full mt-2">Se connecter</button>
<p class="text-center text-sm text-zap-muted">Pas de compte ? <a href="#" data-switch="register" class="text-zap-yellow hover:underline">S'inscrire</a></p>
</form>
<!-- Register Form -->
<form id="form-register" class="space-y-4 hidden" data-page="register">
<h2 class="text-xl font-semibold text-center">Inscription</h2>
<div class="input-group"><label class="input-label">Pseudo</label><input type="text" name="username" class="input-field" required minlength="3" maxlength="20"></div>
<div class="input-group"><label class="input-label">Email</label><input type="email" name="email" class="input-field" required></div>
<div class="input-group"><label class="input-label">Mot de passe</label><input type="password" name="password" class="input-field" required minlength="6"></div>
<button type="submit" class="btn btn-primary w-full mt-2">Créer mon compte</button>
<p class="text-center text-sm text-zap-muted">Déjà un compte ? <a href="#" data-switch="login" class="text-zap-yellow hover:underline">Se connecter</a></p>
</form>
</div>
</div>
</div>
<!-- Main App Layout (Hidden until login) -->
<div id="app-layout" class="page hidden flex flex-col h-screen">
<!-- Top Bar -->
<header class="bg-zap-card/80 backdrop-blur-md border-b border-zap-border px-4 py-2 flex items-center justify-between sticky top-0 z-10">
<a href="#" data-nav="dashboard" class="font-space text-xl font-bold bg-gradient-to-r from-zap-yellow to-zap-orange bg-clip-text text-transparent">QuizZap</a>
<nav class="flex items-center gap-4">
<span id="user-avatar" class="w-8 h-8 rounded-full bg-zap-purple flex items-center justify-center font-bold text-sm"></span>
<span id="user-name" class="font-medium hidden sm:block"></span>
<button id="btn-logout" class="btn btn-ghost text-sm">Déconnexion</button>
</nav>
</header>
<!-- Views Container -->
<main class="flex-1 overflow-y-auto p-4 md:p-6">
<!-- Dashboard View -->
<section id="view-dashboard" class="view">
<div class="flex flex-col md:flex-row md:items-end md:justify-between gap-4 mb-6">
<div><h2 class="font-space text-2xl font-bold">Mes Quiz</h2><p class="text-zap-muted">Crée, modifie et lance tes parties.</p></div>
<button id="btn-new-quiz" class="btn btn-primary"><svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path></svg>Nouveau Quiz</button>
</div>
<div id="quiz-list" class="grid gap-4 sm:grid-cols-2 lg:grid-cols-3"></div>
</section>
<!-- Public Quiz View -->
<section id="view-public" class="view hidden">
<div class="mb-6"><h2 class="font-space text-2xl font-bold">Quiz Publics</h2><p class="text-zap-muted">Découvre les quiz de la communauté.</p></div>
<div id="public-quiz-list" class="grid gap-4 sm:grid-cols-2 lg:grid-cols-3"></div>
</section>
<!-- Editor View -->
<section id="view-editor" class="view hidden">
<div class="max-w-4xl mx-auto">
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-6 sticky top-16 bg-zap-card/80 backdrop-blur-md z-10 p-4 rounded-xl border border-zap-border">
<div class="flex items-center gap-2">
<button data-nav="dashboard" class="btn btn-ghost p-2"><svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path></svg></button>
<h2 class="font-space text-xl font-bold" id="editor-title">Nouveau Quiz</h2>
<span id="quiz-visibility-badge" class="badge badge-secondary">Brouillon</span>
</div>
<div class="flex items-center gap-2">
<button id="btn-save-quiz" class="btn btn-secondary">Sauvegarder</button>
<button id="btn-play-quiz" class="btn btn-primary">Jouer ▶</button>
</div>
</div>
<!-- Quiz Meta -->
<div class="bg-zap-card rounded-xl border border-zap-border p-6 mb-6 space-y-4">
<div class="grid gap-4 sm:grid-cols-2">
<div class="input-group"><label class="input-label">Titre du Quiz *</label><input type="text" id="quiz-title" class="input-field" placeholder="Ex: Culture Générale 2024"></div>
<div class="input-group"><label class="input-label">Description</label><textarea id="quiz-desc" class="input-field" rows="2" placeholder="Description courte..."></textarea></div>
</div>
<div class="flex items-center gap-4">
<label class="flex items-center gap-2 cursor-pointer"><input type="checkbox" id="quiz-public" class="toggle toggle-primary"> Rendre Public</label>
<label class="flex items-center gap-2 cursor-pointer"><input type="checkbox" id="quiz-random" class="toggle toggle-primary"> Mélanger questions</label>
</div>
<div class="input-group"><label class="input-label">Image de couverture</label>
<div class="flex gap-2"><input type="file" id="quiz-cover-input" accept="image/*" class="hidden" onchange="uploadImage(this, 'quiz-cover-preview')">
<button type="button" onclick="document.getElementById('quiz-cover-input').click()" class="btn btn-outline">Choisir image</button>
<img id="quiz-cover-preview" class="w-16 h-16 rounded-lg object-cover border border-zap-border hidden" src="">
</div>
</div>
</div>
<!-- Questions List -->
<div class="bg-zap-card rounded-xl border border-zap-border overflow-hidden">
<div class="p-4 border-b border-zap-border flex items-center justify-between">
<h3 class="font-semibold">Questions (<span id="q-count">0</span>)</h3>
<div class="flex gap-2">
<button id="btn-add-quiz" class="btn btn-outline btn-sm" data-type="quiz"><svg class="w-4 h-4 mr-1" fill="currentColor" viewBox="0 0 20 20"><path d="M10 3a1 1 0 011 1v5h5a1 1 0 110 2h-5v5a1 1 0 11-2 0v-5H4a1 1 0 110-2h5V4a1 1 0 011-1z"/></svg>Quiz</button>
<button id="btn-add-tf" class="btn btn-outline btn-sm" data-type="true_false"><svg class="w-4 h-4 mr-1" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-6a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 4zm0 10a.75.75 0 111.5 0 .75.75 0 01-1.5 0z"/></svg>Vrai/Faux</button>
<button id="btn-add-type" class="btn btn-outline btn-sm" data-type="type_answer"><svg class="w-4 h-4 mr-1" fill="currentColor" viewBox="0 0 20 20"><path d="M13.586 3.586a2 2 0 112.828 2.828l-3 3a2 2 0 01-2.828 0v2a2 2 0 01-2-2V7.414l-3-3a2 2 0 112.828-2.828l3 3a2 2 0 010 2.828v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2a2 2 0 01.586-1.414l3-3z"/></svg>Saisie</button>
<button id="btn-add-puzzle" class="btn btn-outline btn-sm" data-type="puzzle"><svg class="w-4 h-4 mr-1" fill="currentColor" viewBox="0 0 20 20"><path d="M4 4a2 2 0 00-2 2v1h16V6a2 2 0 00-2-2H4zm0 4a2 2 0 00-2 2v1h16v-1a2 2 0 00-2-2H4zm0 4a2 2 0 00-2 2v1h16v-1a2 2 0 00-2-2H4z"/></svg>Ordre</button>
<button id="btn-add-slider" class="btn btn-outline btn-sm" data-type="slider"><svg class="w-4 h-4 mr-1" fill="currentColor" viewBox="0 0 20 20"><path d="M14.707 10.293a1 1 0 010 1.414l-4 4a1 1 0 01-1.414-1.414L12.586 11H4a1 1 0 010-2h8.586l-1.879-1.879a1 1 0 111.414-1.414l4 4z"/></svg>Curseur</button>
</div>
</div>
<div id="questions-container" class="divide-y divide-zap-border max-h-[60vh] overflow-y-auto"></div>
</div>
</div>
</section>
<!-- Game Host View -->
<section id="view-host" class="view hidden h-full flex flex-col">
<div class="flex-1 flex flex-col" id="host-content">
<!-- Lobby State -->
<div id="host-lobby" class="flex-1 flex flex-col items-center justify-center p-8 text-center hidden">
<div class="mb-8"><div class="font-space text-4xl font-bold" id="host-pin-display">------</div><p class="text-zap-muted mt-2">Partage ce code</p></div>
<div class="w-full max-w-md bg-zap-card rounded-xl border border-zap-border p-4">
<h3 class="font-semibold mb-3 flex items-center justify-between">Joueurs (<span id="lobby-count">0</span>/<span id="lobby-max">0</span>)</h3>
<ul id="lobby-players" class="space-y-2 max-h-60 overflow-y-auto text-left"></ul>
</div>
<button id="btn-start-game" class="btn btn-primary btn-lg mt-6 w-full max-w-xs" disabled><svg class="w-6 h-6 mr-2" fill="currentColor" viewBox="0 0 20 20"><path d="M6.3 2.841A1.5 1.5 0 004 4.11V16a1.5 1.5 0 002.3 1.269l9.344-5.945a1.5 1.5 0 000-2.538L6.3 2.84z"/></svg>Démarrer la partie</button>
<p id="host-queue-msg" class="text-zap-yellow text-sm mt-2 hidden">En file d'attente... Position: <span id="queue-pos">-</span></p>
</div>
<!-- Question State -->
<div id="host-question" class="flex-1 flex flex-col hidden">
<div class="flex items-center justify-between p-4 bg-zap-card border-b border-zap-border">
<div class="flex items-center gap-4">
<div class="font-space text-xl font-bold" id="host-q-num">Q 1/5</div>
<div class="w-48 h-3 bg-zap-bg rounded-full overflow-hidden"><div id="host-timer-bar" class="h-full bg-zap-yellow transition-all duration-100 ease-linear" style="width: 100%"></div></div>
</div>
<div id="host-responses" class="text-zap-muted text-sm">Réponses: 0/5</div>
</div>
<div class="flex-1 flex items-center justify-center p-8">
<div class="w-full max-w-3xl text-center" id="host-q-content"></div>
</div>
<div class="p-4 bg-zap-card border-t border-zap-border flex justify-center">
<button id="btn-next-q" class="btn btn-primary btn-lg w-full max-w-xs hidden">Question Suivante</button>
</div>
</div>
<!-- Leaderboard State -->
<div id="host-leaderboard" class="flex-1 flex flex-col hidden">
<div class="p-4 bg-zap-card border-b border-zap-border text-center"><h3 class="font-space text-xl font-bold">Classement Intermédiaire</h3></div>
<div class="flex-1 overflow-y-auto p-4" id="host-lb-list"></div>
<div class="p-4 bg-zap-card border-t border-zap-border"><button id="btn-next-q-lb" class="btn btn-primary btn-lg w-full max-w-xs mx-auto block">Question Suivante</button></div>
</div>
<!-- End State -->
<div id="host-end" class="flex-1 flex flex-col items-center justify-center p-8 text-center hidden">
<div class="font-space text-4xl font-bold text-zap-yellow mb-2">🏆 Partie Terminée !</div>
<div id="host-final-podium" class="w-full max-w-md mb-6"></div>
<button data-nav="dashboard" class="btn btn-secondary">Retour au tableau de bord</button>
</div>
</div>
</section>
<!-- Game Player View -->
<section id="view-player" class="view hidden h-full flex flex-col">
<div class="flex-1 flex flex-col items-center justify-center p-4" id="player-content">
<!-- Lobby Wait -->
<div id="player-lobby" class="flex-1 flex flex-col items-center justify-center text-center w-full hidden">
<div class="font-space text-5xl font-bold mb-2" id="player-pin">------</div>
<p class="text-zap-muted">En attente de l'hôte...</p>
<div class="w-32 h-32 border-4 border-zap-border-t border-zap-yellow rounded-full animate-spin mt-8 mb-4"></div>
</div>
<!-- Question Answering -->
<div id="player-question" class="flex-1 flex flex-col w-full max-w-xl hidden">
<div class="w-full mb-4 flex items-center justify-between">
<div class="font-space text-xl font-bold" id="player-q-num">Q 1/5</div>
<div class="w-40 h-2 bg-zap-bg rounded-full overflow-hidden"><div id="player-timer-bar" class="h-full bg-zap-yellow transition-all duration-100 ease-linear" style="width: 100%"></div></div>
</div>
<div class="flex-1 flex items-center justify-center overflow-y-auto p-4" id="player-q-content"></div>
<div class="p-4" id="player-feedback" class="hidden"></div>
</div>
<!-- Result Screen -->
<div id="player-result" class="flex-1 flex flex-col items-center justify-center w-full max-w-xl p-4 hidden">
<div class="text-4xl font-bold mb-2" id="player-result-icon"></div>
<div class="text-xl font-semibold mb-1" id="player-result-text">En attente...</div>
<div class="text-zap-muted mb-4" id="player-result-points">+0 pts</div>
<div class="w-full bg-zap-card rounded-xl border border-zap-border p-4 mb-4">
<div class="font-semibold mb-2">Ton Classement</div>
<div class="flex items-center justify-between text-lg"><span id="player-rank">-</span><span id="player-score">0 pts</span></div>
<div class="mt-2 text-sm text-zap-muted">Streak: <span id="player-streak">0</span></div>
</div>
</div>
<!-- Final End -->
<div id="player-end" class="flex-1 flex flex-col items-center justify-center w-full p-4 hidden text-center">
<div class="font-space text-4xl font-bold text-zap-yellow mb-4">Partie Terminée</div>
<div id="player-final-rank" class="text-6xl font-bold font-space text-zap-orange mb-2">#1</div>
<div class="text-zap-muted" id="player-final-score">2500 pts</div>
<button data-nav="dashboard" class="btn btn-primary mt-8">Jouer à nouveau</button>
</div>
</div>
</section>
</main>
</div>
<!-- Question Editor Modal (Dynamic) -->
<div id="modal-root"></div>
<script type="module" src="/app.js"></script>
</body>
</html>