const API_URL = '/api/v1/index.php?request='; const state = { user: JSON.parse(localStorage.getItem('user')) || null, token: localStorage.getItem('token') || null, }; const routes = { '/': homePage, '/login': loginPage, '/learners': learnersPage, '/assessments': assessmentsPage, '/events': eventsPage, '/collaboration': collaborationPage, '/leaderboard': leaderboardPage, '/super-admin': superAdminPage, }; async function init() { window.addEventListener('hashchange', router); router(); updateNav(); } function router() { const hash = window.location.hash || '#/'; const path = hash.substring(1); // Auth guard if (!state.token && path !== '/login') { window.location.hash = '#/login'; return; } const page = routes[path] || routes['/']; page(); } function updateNav() { const navLinks = document.getElementById('nav-links'); if (!state.token) { navLinks.innerHTML = ` `; return; } let html = ``; if (state.user.role === 'Super Admin') { html += ``; } html += ` `; navLinks.innerHTML = html; document.getElementById('logout-btn').addEventListener('click', (e) => { e.preventDefault(); logout(); }); } function logout() { localStorage.removeItem('token'); localStorage.removeItem('user'); state.token = null; state.user = null; window.location.hash = '#/login'; updateNav(); } async function apiFetch(endpoint, options = {}) { const url = API_URL + endpoint; const defaultOptions = { headers: { 'Content-Type': 'application/json', ...(state.token ? { 'Authorization': `Bearer ${state.token}` } : {}) } }; const response = await fetch(url, { ...defaultOptions, ...options }); if (response.status === 401) { logout(); throw new Error('Unauthorized'); } const data = await response.json(); if (!response.ok) throw new Error(data.error || 'API Error'); return data; } function render(html) { document.getElementById('content').innerHTML = html; } async function homePage() { render(`

Welcome back, ${state.user.email}

You are logged in as ${state.user.role}.


Learners
Manage
Assessments
Open Hub
Events
Calendar
Leaderboard
View Rankings
`); } function loginPage() { render(`

SOMS Platform

Demo Credentials
Super Admin: superadmin@system.com / password
Admin: admin@sowetohigh.edu.za / password
`); document.getElementById('login-form').addEventListener('submit', async (e) => { e.preventDefault(); const email = document.getElementById('email').value; const password = document.getElementById('password').value; try { const data = await apiFetch('/auth/login', { method: 'POST', body: JSON.stringify({ email, password }) }); if (data.token) { localStorage.setItem('token', data.token); localStorage.setItem('user', JSON.stringify(data.user)); state.token = data.token; state.user = data.user; updateNav(); window.location.hash = '#/'; } } catch (err) { alert('Login failed: ' + err.message); } }); } async function superAdminPage() { render('
'); try { const stats = await apiFetch('/schools/stats'); const schools = await apiFetch('/schools'); let html = `

Super Admin Console

Global platform management

Total Schools
${stats.total_schools}
Total Learners
${stats.total_learners}
System Uptime
${stats.uptime}
Data Storage
${stats.storage}
Participating Schools
`; schools.forEach(s => { html += ` `; }); html += '
Name Province District Actions
${s.name} ${s.province} ${s.district}
'; render(html); } catch (err) { render('
Access Denied: Super Admin only
'); } } async function learnersPage() { render('
'); try { const learners = await apiFetch('/learners'); let html = `

Learners

`; learners.forEach(l => { html += ` `; }); html += '
Full Name Grade Student ID Actions
${l.full_name} ${l.grade} ${l.student_id}
'; render(html); } catch (err) { render('
Failed to load learners
'); } } async function assessmentsPage() { render('
'); try { const assessments = await apiFetch('/assessments'); let html = `

Assessments

`; assessments.forEach(a => { html += `
${a.title || a.name}
${a.subject || a.grade} — ${a.type}
`; }); html += '
'; render(html); } catch (err) { render('
Failed to load assessments
'); } } async function eventsPage() { render('
'); try { const events = await apiFetch('/events'); let html = `

School Calendar

`; if (events.length === 0) html += '

No upcoming events.

'; events.forEach(e => { html += `
${new Date(e.start_datetime).getDate()}
${new Date(e.start_datetime).toLocaleString('default', { month: 'short' })}
${e.title}

${new Date(e.start_datetime).toLocaleTimeString()} — ${e.location || 'No location'}

`; }); html += '
'; render(html); } catch (err) { render('
Failed to load events
'); } } async function collaborationPage() { render('
'); try { const resources = await apiFetch('/collaboration/resources'); let html = `

Collaboration Hub

`; resources.forEach(r => { html += `
${r.title}
${r.is_public == 1 ? 'Public' : 'School Only'}

${r.description}

${r.teacher_email}
`; }); html += '
'; render(html); } catch (err) { render('
Failed to load resources
'); } } async function leaderboardPage() { render('
'); try { const rankings = await apiFetch('/leaderboard'); let html = `

Student Rankings

`; rankings.forEach((r, index) => { const color = index === 0 ? 'text-warning' : (index === 1 ? 'text-secondary' : (index === 2 ? 'text-brown' : '')); html += ` `; }); html += '
Rank Learner Performance Average
#${index + 1}
${r.full_name}
${parseFloat(r.average_percent).toFixed(1)}%
'; render(html); } catch (err) { render('
Failed to load leaderboard
'); } } init();