195 lines
9.6 KiB
HTML
195 lines
9.6 KiB
HTML
|
|
<!DOCTYPE html>
|
||
|
|
<html lang="sv">
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
|
<title>quiXzoom Academy — Certifiering</title>
|
||
|
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||
|
|
<style>
|
||
|
|
:root{--ink:#0A0A0A;--text-secondary:#6E6E73;--surface:#F5F5F7;--card:#FFFFFF;--blue:#0066FF;--green:#00C853}
|
||
|
|
*{box-sizing:border-box;margin:0;padding:0}
|
||
|
|
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:var(--surface);color:var(--ink);line-height:1.6}
|
||
|
|
.container{max-width:800px;margin:0 auto;padding:24px}
|
||
|
|
.nav{display:flex;align-items:center;justify-content:space-between;padding:16px 24px;background:rgba(255,255,255,0.9);backdrop-filter:blur(20px);position:sticky;top:0;z-index:100;border-bottom:1px solid rgba(0,0,0,0.06)}
|
||
|
|
.nav-logo{font-size:18px;font-weight:800;color:var(--ink);text-decoration:none;letter-spacing:-0.3px}
|
||
|
|
.nav-logo span{color:var(--blue)}
|
||
|
|
.hero{text-align:center;padding:60px 24px 40px}
|
||
|
|
.hero h1{font-size:42px;font-weight:800;margin-bottom:16px;letter-spacing:-0.5px}
|
||
|
|
.hero p{font-size:18px;color:var(--text-secondary);max-width:500px;margin:0 auto}
|
||
|
|
|
||
|
|
.cert-card{background:var(--card);border-radius:20px;padding:40px;margin:24px 0;box-shadow:0 4px 24px rgba(0,0,0,0.08);text-align:center}
|
||
|
|
.cert-icon{font-size:80px;margin-bottom:24px}
|
||
|
|
.cert-title{font-size:28px;font-weight:800;margin-bottom:12px}
|
||
|
|
.cert-status{font-size:18px;color:var(--text-secondary);margin-bottom:32px}
|
||
|
|
|
||
|
|
.progress-ring{position:relative;width:200px;height:200px;margin:0 auto 32px}
|
||
|
|
.progress-ring svg{transform:rotate(-90deg)}
|
||
|
|
.progress-ring-circle{fill:none;stroke:#E5E5EA;stroke-width:12}
|
||
|
|
.progress-ring-progress{fill:none;stroke:var(--blue);stroke-width:12;stroke-linecap:round;transition:stroke-dashoffset 1s ease}
|
||
|
|
.progress-text{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:48px;font-weight:800;color:var(--ink)}
|
||
|
|
|
||
|
|
.stats-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:16px;margin:32px 0}
|
||
|
|
.stat-card{background:var(--surface);border-radius:16px;padding:24px;text-align:center}
|
||
|
|
.stat-value{font-size:36px;font-weight:800;color:var(--blue)}
|
||
|
|
.stat-label{font-size:14px;color:var(--text-secondary);margin-top:8px}
|
||
|
|
|
||
|
|
.modules-list{display:grid;gap:16px;margin:32px 0}
|
||
|
|
.module-item{background:var(--card);border-radius:16px;padding:24px;display:flex;align-items:center;gap:16px;box-shadow:0 2px 12px rgba(0,0,0,0.06)}
|
||
|
|
.module-status{width:48px;height:48px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:24px;flex-shrink:0}
|
||
|
|
.module-status.complete{background:var(--green);color:white}
|
||
|
|
.module-status.incomplete{background:#E5E5EA;color:var(--text-secondary)}
|
||
|
|
.module-info{flex:1}
|
||
|
|
.module-name{font-size:18px;font-weight:700}
|
||
|
|
.module-progress{font-size:14px;color:var(--text-secondary);margin-top:4px}
|
||
|
|
|
||
|
|
.btn{display:inline-flex;align-items:center;gap:8px;background:var(--blue);color:white;padding:16px 32px;border-radius:12px;text-decoration:none;font-weight:700;font-size:16px;border:none;cursor:pointer;transition:all 0.2s}
|
||
|
|
.btn:hover{transform:translateY(-2px);box-shadow:0 8px 24px rgba(0,102,255,0.3)}
|
||
|
|
.btn:disabled{background:#E5E5EA;color:var(--text-secondary);cursor:not-allowed;transform:none;box-shadow:none}
|
||
|
|
|
||
|
|
.certificate{background:linear-gradient(135deg,#1a1a2e 0%,#16213e 50%,#0f3460 100%);color:white;border-radius:20px;padding:48px;margin:32px 0;text-align:center;position:relative;overflow:hidden}
|
||
|
|
.certificate::before{content:'';position:absolute;top:-50%;left:-50%;width:200%;height:200%;background:radial-gradient(circle,rgba(255,255,255,0.1) 1px,transparent 1px);background-size:20px 20px;opacity:0.3}
|
||
|
|
.cert-badge{font-size:64px;margin-bottom:16px}
|
||
|
|
.cert-name{font-size:32px;font-weight:800;margin-bottom:8px}
|
||
|
|
.cert-date{font-size:16px;opacity:0.8}
|
||
|
|
.cert-id{font-size:14px;opacity:0.6;margin-top:16px;font-family:monospace}
|
||
|
|
|
||
|
|
.footer{text-align:center;padding:40px 24px;color:var(--text-secondary);font-size:14px;border-top:1px solid rgba(0,0,0,0.06)}
|
||
|
|
|
||
|
|
@media(max-width:640px){.hero h1{font-size:32px}.hero{padding:40px 24px 30px}.cert-card{padding:24px}}
|
||
|
|
</style>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<nav class="nav">
|
||
|
|
<a href="/" class="nav-logo">qui<span style="color:var(--blue);font-weight:900">X</span>zoom</a>
|
||
|
|
<a href="/academy/" style="color:var(--blue);text-decoration:none;font-weight:600;font-size:14px">← Academy</a>
|
||
|
|
</nav>
|
||
|
|
|
||
|
|
<div class="hero">
|
||
|
|
<h1>Din Certifiering</h1>
|
||
|
|
<p>Tracka din framsteg och bli en certifierad Zoomer</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="container">
|
||
|
|
<div class="cert-card">
|
||
|
|
<div id="certContent">
|
||
|
|
<!-- Fylls i av JavaScript -->
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="modules-list" id="modulesList">
|
||
|
|
<!-- Fylls i av JavaScript -->
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="footer">
|
||
|
|
<p>quiXzoom Academy — Learn. Earn. Grow.</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<script src="/academy/academy-auth-integration.js"></script>
|
||
|
|
<script>
|
||
|
|
// Initiera auth
|
||
|
|
const auth = new AcademyAuth();
|
||
|
|
|
||
|
|
// Hämta progress från backend om inloggad
|
||
|
|
auth.fetchProgress().then(() => {
|
||
|
|
renderPage();
|
||
|
|
});
|
||
|
|
|
||
|
|
const modules = [
|
||
|
|
{ id: 'm1', name: 'Komma Igång', lessons: ['m1l1','m1l2','m1l3','m1l4'] },
|
||
|
|
{ id: 'm2', name: 'Fotokvalitet', lessons: ['m2l1','m2l2','m2l3','m2l4'] },
|
||
|
|
{ id: 'm3', name: 'Uppdragstyper', lessons: ['m3l1','m3l2','m3l3'] },
|
||
|
|
{ id: 'm4', name: 'Avancerade Tekniker', lessons: ['m4l1','m4l2','m4l3'] },
|
||
|
|
{ id: 'm5', name: 'Tjäna Mer', lessons: ['m5l1','m5l2','m5l3'] },
|
||
|
|
{ id: 'm6', name: 'Pro Zoomer', lessons: ['m6l1','m6l2','m6l3','m6l4'] }
|
||
|
|
];
|
||
|
|
|
||
|
|
const completedLessons = JSON.parse(localStorage.getItem('academyProgress') || '[]');
|
||
|
|
const totalLessons = modules.reduce((sum,m) => sum + m.lessons.length, 0);
|
||
|
|
const completedCount = completedLessons.length;
|
||
|
|
const progressPercent = Math.round((completedCount / totalLessons) * 100);
|
||
|
|
const isCertified = progressPercent >= 100;
|
||
|
|
|
||
|
|
// Rendera certifierings-status
|
||
|
|
const certContent = document.getElementById('certContent');
|
||
|
|
if (isCertified) {
|
||
|
|
const certId = 'QZ-' + Date.now().toString(36).toUpperCase();
|
||
|
|
certContent.innerHTML = `
|
||
|
|
<div class="certificate">
|
||
|
|
<div class="cert-badge">🎓</div>
|
||
|
|
<div class="cert-name">Certifierad Zoomer</div>
|
||
|
|
<div class="cert-date">Utfärdad ${new Date().toLocaleDateString('sv-SE')}</div>
|
||
|
|
<div class="cert-id">ID: ${certId}</div>
|
||
|
|
</div>
|
||
|
|
<p style="margin-top:24px;color:var(--text-secondary)">Grattis! Du har slutfört alla lektioner och är nu en certifierad Zoomer.</p>
|
||
|
|
<button class="btn" onclick="shareCertificate()">📤 Dela certifikat</button>
|
||
|
|
`;
|
||
|
|
} else {
|
||
|
|
const circumference = 2 * Math.PI * 90;
|
||
|
|
const offset = circumference - (progressPercent / 100) * circumference;
|
||
|
|
|
||
|
|
certContent.innerHTML = `
|
||
|
|
<div class="progress-ring">
|
||
|
|
<svg width="200" height="200">
|
||
|
|
<circle class="progress-ring-circle" cx="100" cy="100" r="90"/>
|
||
|
|
<circle class="progress-ring-progress" cx="100" cy="100" r="90"
|
||
|
|
stroke-dasharray="${circumference}"
|
||
|
|
stroke-dashoffset="${offset}"/>
|
||
|
|
</svg>
|
||
|
|
<div class="progress-text">${progressPercent}%</div>
|
||
|
|
</div>
|
||
|
|
<div class="cert-title">På väg mot certifiering</div>
|
||
|
|
<div class="cert-status">${completedCount} av ${totalLessons} lektioner slutförda</div>
|
||
|
|
<div class="stats-grid">
|
||
|
|
<div class="stat-card">
|
||
|
|
<div class="stat-value">${completedCount}</div>
|
||
|
|
<div class="stat-label">Lektioner klara</div>
|
||
|
|
</div>
|
||
|
|
<div class="stat-card">
|
||
|
|
<div class="stat-value">${totalLessons - completedCount}</div>
|
||
|
|
<div class="stat-label">Kvar att göra</div>
|
||
|
|
</div>
|
||
|
|
<div class="stat-card">
|
||
|
|
<div class="stat-value">${modules.filter(m => m.lessons.every(l => completedLessons.includes(l))).length}</div>
|
||
|
|
<div class="stat-label">Moduler klara</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<a href="/academy/" class="btn">Fortsätt lära dig →</a>
|
||
|
|
`;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Rendera modul-lista
|
||
|
|
const modulesList = document.getElementById('modulesList');
|
||
|
|
modules.forEach(module => {
|
||
|
|
const moduleCompleted = module.lessons.filter(l => completedLessons.includes(l)).length;
|
||
|
|
const isComplete = moduleCompleted === module.lessons.length;
|
||
|
|
|
||
|
|
const moduleEl = document.createElement('div');
|
||
|
|
moduleEl.className = 'module-item';
|
||
|
|
moduleEl.innerHTML = `
|
||
|
|
<div class="module-status ${isComplete ? 'complete' : 'incomplete'}">
|
||
|
|
${isComplete ? '✅' : '📚'}
|
||
|
|
</div>
|
||
|
|
<div class="module-info">
|
||
|
|
<div class="module-name">${module.name}</div>
|
||
|
|
<div class="module-progress">${moduleCompleted} av ${module.lessons.length} lektioner</div>
|
||
|
|
</div>
|
||
|
|
${isComplete ? '<span style="color:var(--green);font-weight:700">Klar!</span>' : `<a href="/academy/${module.id}/${module.lessons[moduleCompleted]}/" class="btn" style="padding:8px 16px;font-size:14px">Fortsätt</a>`}
|
||
|
|
`;
|
||
|
|
modulesList.appendChild(moduleEl);
|
||
|
|
});
|
||
|
|
|
||
|
|
function shareCertificate() {
|
||
|
|
if (navigator.share) {
|
||
|
|
navigator.share({
|
||
|
|
title: 'Jag är certifierad Zoomer!',
|
||
|
|
text: 'Jag har slutfört quiXzoom Academy och är nu en certifierad Zoomer.',
|
||
|
|
url: window.location.href
|
||
|
|
});
|
||
|
|
} else {
|
||
|
|
alert('Certifikat kopierat till urklipp!');
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
</body>
|
||
|
|
</html>
|