| <!DOCTYPE html> |
| <html lang="ro"> |
| <head> |
| <link rel="icon" type="image/svg+xml" href="favicon.svg"> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>IDEA | Seed Date</title> |
| <link rel="stylesheet" href="style.css"> |
| <style> |
| body { display:flex; flex-direction:column; align-items:center; justify-content:center; min-height:100dvh; padding:20px 14px; } |
| .wrap { width:100%; max-width:500px; } |
| .seed-row { display:grid; grid-template-columns:50px 1fr 90px 80px; gap:8px; padding:8px 12px; border-bottom:1px solid rgba(255,255,255,0.04); font-size:11px; align-items:center; } |
| .seed-row.head { font-size:9px; letter-spacing:2px; color:var(--white-dim); background:rgba(255,255,255,0.03); } |
| .seed-status { font-size:9px; padding:2px 6px; border:1px solid rgba(255,255,255,0.1); text-align:center; } |
| .seed-status.ok { border-color:rgba(60,120,60,0.5); color:#5a9a5a; } |
| .seed-status.err { border-color:rgba(120,40,40,0.5); color:#cc5555; } |
| .seed-status.wait { color:var(--white-dim); } |
| .log-box { background:rgba(255,255,255,0.03); border:1px solid rgba(255,255,255,0.07); padding:14px; font-size:11px; color:var(--white-dim); line-height:2; height:140px; overflow-y:auto; margin-top:14px; font-family:'DM Mono',monospace; } |
| </style> |
| </head> |
| <body> |
| <div class="wrap"> |
| <div class="login-header fade-in" style="text-align:center;margin-bottom:24px;"> |
| <img src="logo.svg" style="width:36px;height:36px;margin:0 auto 10px;display:block;"> |
| <h1 style="font-family:'Cormorant Garamond',serif;font-size:22px;letter-spacing:3px;">IDEA</h1> |
| <p style="font-size:9px;letter-spacing:2px;color:var(--white-dim);">SEED DATE — CLASA 7B</p> |
| </div> |
|
|
| <div class="card fade-in-2"> |
| <div class="card-title">Import automat elevi</div> |
| <p style="font-size:11px;color:var(--white-dim);margin-bottom:16px;line-height:1.8;"> |
| Această pagină va adăuga toți cei 32 de elevi ai clasei 7B în Firestore, fără parolă (pin: null). Elevii își vor seta parola la primul login. |
| </p> |
| <div style="margin-bottom:14px;"> |
| <div class="field"><label>Parolă Admin (verificare)</label> |
| <input type="password" id="admin-check" placeholder="••••••"> |
| </div> |
| </div> |
| <button class="btn-primary" onclick="runSeed()" id="btn-seed">PORNEȘTE IMPORT</button> |
| <div class="alert error" id="seed-err" style="margin-top:12px;"></div> |
| </div> |
|
|
| <div class="card fade-in-3" id="progress-card" style="display:none;"> |
| <div class="card-title" id="prog-title">Se importă...</div> |
| <div class="data-table"> |
| <div class="seed-row head"><div>NR.</div><div>ELEV</div><div>VPASS ID</div><div>STATUS</div></div> |
| <div id="seed-list"></div> |
| </div> |
| <div class="log-box" id="log-box">Inițializare...<br></div> |
| <div class="alert success" id="seed-ok" style="margin-top:12px;display:none;"> |
| ✓ Import finalizat! <a href="index.html" style="color:inherit;text-decoration:underline;">Mergi la login →</a> |
| </div> |
| </div> |
| </div> |
|
|
| <script type="module"> |
| import { initializeApp } from "https://www.gstatic.com/firebasejs/10.12.0/firebase-app.js"; |
| import { getFirestore, collection, addDoc, getDocs, query, where } from "https://www.gstatic.com/firebasejs/10.12.0/firebase-firestore.js"; |
| |
| const cfg = { |
| apiKey:"AIzaSyB9--Onx3-_YjD-YzblhZjaWSVVqTQJ1lU", authDomain:"vservers1.firebaseapp.com", |
| projectId:"vservers1", storageBucket:"vservers1.firebasestorage.app", |
| messagingSenderId:"42433037358", appId:"1:42433037358:web:fde70fec79542428b60bbf" |
| }; |
| const app = initializeApp(cfg); |
| const db = getFirestore(app); |
| |
| const ELEVI = [ |
| { pozitie:1, nume:"Andronic Aniela", vpassId:"AA-0001" }, |
| { pozitie:2, nume:"Badan Alexandra", vpassId:"BA-0002" }, |
| { pozitie:3, nume:"Bunescu Lavinia", vpassId:"BL-0003" }, |
| { pozitie:4, nume:"Bunescu Lorena", vpassId:"BL-0004" }, |
| { pozitie:5, nume:"Burdujan Damian", vpassId:"BD-0005" }, |
| { pozitie:6, nume:"Ceban Madalina", vpassId:"CM-0006" }, |
| { pozitie:7, nume:"Ceban Valeria", vpassId:"CV-0007" }, |
| { pozitie:8, nume:"Cebanu Nichita", vpassId:"CN-0008" }, |
| { pozitie:9, nume:"Chele Ilinca", vpassId:"CI-0009" }, |
| { pozitie:10, nume:"Chihai Mirela", vpassId:"CM-0010" }, |
| { pozitie:11, nume:"Cojocari Ciprian", vpassId:"CC-0011" }, |
| { pozitie:12, nume:"Creciun Leonard", vpassId:"CL-0012" }, |
| { pozitie:13, nume:"Lozovan Sanda", vpassId:"LS-0013" }, |
| { pozitie:14, nume:"Lungu Sergiu", vpassId:"LS-0014" }, |
| { pozitie:15, nume:"Mahnea Adelina", vpassId:"MA-0015" }, |
| { pozitie:16, nume:"Morcan Ina", vpassId:"MI-0016" }, |
| { pozitie:17, nume:"Morcan Ion", vpassId:"MI-0017" }, |
| { pozitie:18, nume:"Popa Cristina", vpassId:"PC-0018" }, |
| { pozitie:19, nume:"Pricob Adelina", vpassId:"PA-0019" }, |
| { pozitie:20, nume:"Prinos Catalina", vpassId:"PC-0020" }, |
| { pozitie:21, nume:"Radu Daniela", vpassId:"RD-0021" }, |
| { pozitie:22, nume:"Rosca Victor", vpassId:"RV-0022" }, |
| { pozitie:23, nume:"Rotari Cristian", vpassId:"RC-0023" }, |
| { pozitie:24, nume:"Rotaru Camelia", vpassId:"RC-0024" }, |
| { pozitie:25, nume:"Sambris Stanislav", vpassId:"SS-0025" }, |
| { pozitie:26, nume:"Sirbu Delia", vpassId:"SD-0026" }, |
| { pozitie:27, nume:"Soltoian Elena", vpassId:"SE-0027" }, |
| { pozitie:28, nume:"Tabuncic Chiril", vpassId:"TC-0028" }, |
| { pozitie:29, nume:"Turcan Gabriel", vpassId:"TG-0029" }, |
| { pozitie:30, nume:"Turcan Mihai", vpassId:"TM-0030" }, |
| { pozitie:31, nume:"Turcanu Ilie", vpassId:"TI-0031" }, |
| { pozitie:32, nume:"Virlan Daniela", vpassId:"VD-0032" }, |
| ]; |
| |
| const ADMIN_PASS = '122012'; |
| |
| function log(msg) { |
| const box = document.getElementById('log-box'); |
| box.innerHTML += msg + '<br>'; |
| box.scrollTop = box.scrollHeight; |
| } |
| |
| function setRowStatus(idx, status, text) { |
| const el = document.getElementById(`sr-${idx}`); |
| if (el) { el.className = 'seed-status ' + status; el.textContent = text; } |
| } |
| |
| window.runSeed = async function() { |
| if (document.getElementById('admin-check').value !== ADMIN_PASS) { |
| const e = document.getElementById('seed-err'); |
| e.textContent = 'err-020 — Parolă administrator incorectă.'; |
| e.classList.add('show'); return; |
| } |
| document.getElementById('seed-err').classList.remove('show'); |
| document.getElementById('btn-seed').disabled = true; |
| document.getElementById('progress-card').style.display = 'block'; |
| document.getElementById('progress-card').scrollIntoView({ behavior:'smooth' }); |
| |
| |
| const list = document.getElementById('seed-list'); |
| list.innerHTML = ELEVI.map((e,i) => ` |
| <div class="seed-row"> |
| <div style="color:var(--white-dim);">${String(e.pozitie).padStart(2,'0')}</div> |
| <div style="font-size:12px;">${e.nume}</div> |
| <div style="font-size:10px;color:var(--white-dim);letter-spacing:1px;">${e.vpassId}</div> |
| <div><span class="seed-status wait" id="sr-${i}">—</span></div> |
| </div>`).join(''); |
| |
| log('▶ Pornire import — ' + ELEVI.length + ' elevi...'); |
| |
| let ok = 0, skip = 0, fail = 0; |
| |
| for (let i = 0; i < ELEVI.length; i++) { |
| const e = ELEVI[i]; |
| try { |
| |
| const q = query(collection(db,'elevi'), where('vpassId','==',e.vpassId)); |
| const existing = await getDocs(q); |
| if (!existing.empty) { |
| setRowStatus(i, 'ok', 'EXISTA'); |
| log(`⚠ ${e.vpassId} — deja există, sărit`); |
| skip++; continue; |
| } |
| await addDoc(collection(db,'elevi'), { |
| nume: e.nume, |
| vpassId: e.vpassId, |
| pozitie: e.pozitie, |
| pin: null, |
| confirmed: false |
| }); |
| setRowStatus(i, 'ok', 'OK'); |
| log(`✓ ${e.vpassId} — ${e.nume}`); |
| ok++; |
| } catch(err) { |
| setRowStatus(i, 'err', 'ERR'); |
| log(`✗ ${e.vpassId} — err-025: ${err.message}`); |
| fail++; |
| } |
| await new Promise(r => setTimeout(r, 120)); |
| } |
| |
| log(`\n════ FINALIZAT: ${ok} adăugați, ${skip} existenți, ${fail} erori ════`); |
| document.getElementById('prog-title').textContent = 'Import finalizat'; |
| document.getElementById('seed-ok').style.display = 'block'; |
| }; |
| </script> |
| </body> |
| </html> |
|
|