feat: refactor to SI Quiz with Space Invaders arcade interface
- Updated Dockerfile to Python 3.11, selective COPY for cleaner image - Expanded .gitignore with Python/OS patterns - Added config.json, questions.json, env_example, and static assets - Updated templates (host, player, scores) with Space Invaders UI - Rewrote README for SI Quiz branding and setup docs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+36
-6
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>NI Quiz · Host</title>
|
||||
<title>{{ app_name }} · Host</title>
|
||||
<!-- QR Code library -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
|
||||
<style>
|
||||
@@ -155,15 +155,35 @@ html,body{width:100%;height:100vh;background:var(--bg);color:var(--text);font-fa
|
||||
}
|
||||
#auth-btn:hover{opacity:.85;}
|
||||
#auth-err{font-family:var(--pixel);font-size:.4rem;color:var(--red);min-height:1rem;}
|
||||
|
||||
/* ── THEME TOGGLE ── */
|
||||
.theme-toggle{
|
||||
position:fixed;top:1rem;right:1rem;z-index:10000;
|
||||
display:flex;gap:.3rem;
|
||||
background:var(--surface);border:1px solid var(--border);
|
||||
border-radius:6px;padding:.3rem .4rem;
|
||||
}
|
||||
.t-btn{
|
||||
padding:.28rem .55rem;border-radius:4px;font-size:.5rem;cursor:pointer;
|
||||
border:1px solid transparent;background:transparent;color:var(--muted);
|
||||
font-family:var(--pixel);transition:all .15s;
|
||||
}
|
||||
.t-btn:hover{color:var(--text);}
|
||||
.t-btn.active{background:var(--accent);color:#000;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="theme-toggle">
|
||||
<button class="t-btn" onclick="setTheme('dark')" id="t-dark">DARK</button>
|
||||
<button class="t-btn" onclick="setTheme('light')" id="t-light">LIGHT</button>
|
||||
<button class="t-btn" onclick="setTheme('hc')" id="t-hc">HC</button>
|
||||
</div>
|
||||
<div class="grid-bg"></div>
|
||||
|
||||
<!-- LOBBY -->
|
||||
<div class="screen active" id="lobby-screen">
|
||||
<div class="logo">🌐 NI QUIZ</div>
|
||||
<div class="tagline">Network Intelligence · LCPR — Host Panel</div>
|
||||
<div class="logo">🌐 {{ app_name }}</div>
|
||||
<div class="tagline">{{ org_name }}{% if org_name %} — {% endif %}Host Panel</div>
|
||||
<div class="lobby-main">
|
||||
<div class="qr-box">
|
||||
<div class="qr-label">SCAN TO PLAY</div>
|
||||
@@ -256,7 +276,8 @@ document.getElementById('join-url').textContent = baseUrl;
|
||||
new QRCode(document.getElementById('qrcode'), {
|
||||
text: baseUrl,
|
||||
width: 160, height: 160,
|
||||
colorDark: '#00c8ff', colorLight: '#0d1117',
|
||||
colorDark: getComputedStyle(document.documentElement).getPropertyValue('--qr-dark').trim() || '#00c8ff',
|
||||
colorLight: getComputedStyle(document.documentElement).getPropertyValue('--qr-light').trim() || '#0d1117',
|
||||
correctLevel: QRCode.CorrectLevel.M
|
||||
});
|
||||
|
||||
@@ -416,8 +437,17 @@ function confetti() {
|
||||
}
|
||||
}
|
||||
|
||||
// ── THEME ─────────────────────────────────────────────────────────────────────
|
||||
function setTheme(t) {
|
||||
document.documentElement.setAttribute('data-theme', t);
|
||||
localStorage.setItem('si-quiz-theme', t);
|
||||
document.querySelectorAll('.t-btn').forEach(b => b.classList.remove('active'));
|
||||
document.getElementById('t-' + t)?.classList.add('active');
|
||||
}
|
||||
(function(){ setTheme(localStorage.getItem('si-quiz-theme') || 'dark'); })();
|
||||
|
||||
// ── AUTH ─────────────────────────────────────────────────────────────────────
|
||||
const HOST_PASSWORD = 'ni2026'; // ← cambia esto
|
||||
const HOST_PASSWORD = '{{ host_password }}';
|
||||
|
||||
function checkAuth() {
|
||||
const saved = sessionStorage.getItem('host_auth');
|
||||
@@ -428,7 +458,7 @@ function checkAuth() {
|
||||
gate.id = 'auth-gate';
|
||||
gate.innerHTML = `
|
||||
<div id="auth-box">
|
||||
<div id="auth-logo">🌐 NI QUIZ</div>
|
||||
<div id="auth-logo">🌐 {{ app_name }}</div>
|
||||
<div id="auth-sub">Host Panel · Acceso restringido</div>
|
||||
<input id="auth-input" type="password" placeholder="contraseña" autocomplete="off" />
|
||||
<button id="auth-btn">ENTRAR →</button>
|
||||
|
||||
+8
-11
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<title>NI Quiz · Arcade</title>
|
||||
<title>{{ app_name }} · Arcade</title>
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&family=DM+Sans:wght@400;500&display=swap');
|
||||
*{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent;}
|
||||
@@ -156,16 +156,16 @@ body::after{content:'';position:fixed;inset:0;background:repeating-linear-gradie
|
||||
|
||||
<!-- SPLASH — goes straight to join -->
|
||||
<div class="screen active" id="lang-screen">
|
||||
<div class="title">🌐 NI QUIZ</div>
|
||||
<div class="subtitle">NETWORK INTELLIGENCE · LCPR</div>
|
||||
<div class="title">🌐 {{ app_name }}</div>
|
||||
<div class="subtitle">{{ org_name }}</div>
|
||||
|
||||
<button class="lang-btn es" onclick="goJoin()">▶ JUGAR / PLAY</button>
|
||||
</div>
|
||||
|
||||
<!-- JOIN -->
|
||||
<div class="screen" id="join-screen">
|
||||
<div class="logo">🚀 NI QUIZ</div>
|
||||
<div class="sub" id="join-sub">Network Intelligence · LCPR</div>
|
||||
<div class="logo">🚀 {{ app_name }}</div>
|
||||
<div class="sub" id="join-sub">{{ org_name }}</div>
|
||||
<div class="field-wrap">
|
||||
<label id="lbl-fname">FIRST NAME</label>
|
||||
<input id="inp-fname" type="text" maxlength="20" autocomplete="off" autocorrect="off" autocapitalize="words">
|
||||
@@ -178,11 +178,8 @@ body::after{content:'';position:fixed;inset:0;background:repeating-linear-gradie
|
||||
<label id="lbl-dept">DEPARTMENT</label>
|
||||
<select id="inp-dept">
|
||||
<option value="">-- Select --</option>
|
||||
<option>Finanzas</option>
|
||||
<option>People</option>
|
||||
<option>Legal</option>
|
||||
<option>B2B</option>
|
||||
<option>B2C</option>
|
||||
{% for dept in departments %}<option>{{ dept }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<button id="join-btn">▶ ENTER GAME</button>
|
||||
@@ -227,7 +224,7 @@ body::after{content:'';position:fixed;inset:0;background:repeating-linear-gradie
|
||||
<!-- PODIUM -->
|
||||
<div class="screen" id="podium-screen">
|
||||
<h2 id="pod-title">🏆 GAME OVER</h2>
|
||||
<p class="sub" id="pod-sub">Network Intelligence · LCPR</p>
|
||||
<p class="sub" id="pod-sub">{{ org_name }}</p>
|
||||
<div class="podium-list" id="podium-list"></div>
|
||||
<button class="exit-btn" onclick="exitGame()">✕ salir</button>
|
||||
</div>
|
||||
|
||||
+25
-2
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>NI Quiz · Historial</title>
|
||||
<title>{{ app_name }} · Historial</title>
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Share+Tech+Mono&family=Exo+2:wght@400;600;800;900&display=swap');
|
||||
|
||||
@@ -156,6 +156,21 @@ tbody tr:hover{background:var(--surface2);}
|
||||
/* animations */
|
||||
@keyframes fadeUp{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
|
||||
.fade-up{animation:fadeUp .4s ease both;}
|
||||
|
||||
/* ── THEME TOGGLE ── */
|
||||
.theme-toggle{
|
||||
position:fixed;top:1rem;right:1rem;z-index:10000;
|
||||
display:flex;gap:.3rem;
|
||||
background:var(--surface);border:1px solid var(--border);
|
||||
border-radius:6px;padding:.3rem .4rem;box-shadow:0 2px 8px rgba(0,0,0,.15);
|
||||
}
|
||||
.t-btn{
|
||||
padding:.28rem .55rem;border-radius:4px;font-size:.7rem;cursor:pointer;
|
||||
border:1px solid transparent;background:transparent;color:var(--muted);
|
||||
font-weight:700;transition:all .15s;
|
||||
}
|
||||
.t-btn:hover{color:var(--text);}
|
||||
.t-btn.active{background:var(--accent);color:#000;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -163,7 +178,7 @@ tbody tr:hover{background:var(--surface2);}
|
||||
<header>
|
||||
<div class="header-left">
|
||||
<h1>NI<span>QUIZ</span></h1>
|
||||
<p>// HISTORIAL DE SCORES · NETWORK INTELLIGENCE · LCPR</p>
|
||||
<p>// HISTORIAL DE SCORES · {{ org_name }}</p>
|
||||
</div>
|
||||
<nav class="nav-links">
|
||||
<a href="/host">← HOST PANEL</a>
|
||||
@@ -238,6 +253,14 @@ tbody tr:hover{background:var(--surface2);}
|
||||
</main>
|
||||
|
||||
<script>
|
||||
function setTheme(t) {
|
||||
document.documentElement.setAttribute('data-theme', t);
|
||||
localStorage.setItem('si-quiz-theme', t);
|
||||
document.querySelectorAll('.t-btn').forEach(b => b.classList.remove('active'));
|
||||
document.getElementById('t-' + t)?.classList.add('active');
|
||||
}
|
||||
(function(){ setTheme(localStorage.getItem('si-quiz-theme') || 'dark'); })();
|
||||
|
||||
const medals = ['🥇','🥈','🥉'];
|
||||
const rankClass = ['gold','silver','bronze'];
|
||||
const DEPT_COLORS = [
|
||||
|
||||
Reference in New Issue
Block a user