new system prototype
This commit is contained in:
103
website/js/app.js
Normal file
103
website/js/app.js
Normal file
@ -0,0 +1,103 @@
|
||||
import { addRoute, startRouter, navigate } from './router.js';
|
||||
import { loginPage } from './pages/login.js';
|
||||
import { dashboardPage } from './pages/dashboard.js';
|
||||
import { editorPage } from './pages/editor.js';
|
||||
import { resultsPage } from './pages/results.js';
|
||||
import { exportPage } from './pages/export.js';
|
||||
import { usersPage } from './pages/users.js';
|
||||
import { assignmentsPage } from './pages/assignments.js';
|
||||
|
||||
// Auth state
|
||||
export function isLoggedIn() {
|
||||
return !!localStorage.getItem('qdb_token');
|
||||
}
|
||||
export function getRole() {
|
||||
return localStorage.getItem('qdb_role') || '';
|
||||
}
|
||||
export function getUser() {
|
||||
return localStorage.getItem('qdb_user') || '';
|
||||
}
|
||||
export function canEdit() {
|
||||
const r = getRole();
|
||||
return r === 'admin' || r === 'supervisor';
|
||||
}
|
||||
|
||||
export function showToast(message, type = 'info') {
|
||||
const container = document.getElementById('toastContainer');
|
||||
const toast = document.createElement('div');
|
||||
toast.className = `toast toast-${type}`;
|
||||
toast.textContent = message;
|
||||
container.appendChild(toast);
|
||||
requestAnimationFrame(() => toast.classList.add('show'));
|
||||
setTimeout(() => {
|
||||
toast.classList.remove('show');
|
||||
setTimeout(() => toast.remove(), 300);
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
function authGuard(handler) {
|
||||
return (params) => {
|
||||
if (!isLoggedIn()) { navigate('#/login'); return; }
|
||||
return handler(params);
|
||||
};
|
||||
}
|
||||
|
||||
function updateNav() {
|
||||
const nav = document.getElementById('mainNav');
|
||||
const userInfo = document.getElementById('userInfo');
|
||||
if (isLoggedIn()) {
|
||||
nav.style.display = '';
|
||||
const role = getRole();
|
||||
userInfo.textContent = `${getUser()} (${role})`;
|
||||
|
||||
// Show/hide role-gated nav items
|
||||
document.querySelectorAll('[data-nav-roles]').forEach(li => {
|
||||
const allowed = li.dataset.navRoles.split(' ');
|
||||
li.style.display = allowed.includes(role) ? '' : 'none';
|
||||
});
|
||||
|
||||
// Highlight active nav link
|
||||
const hash = window.location.hash.slice(1) || '/';
|
||||
document.querySelectorAll('.sidebar-nav a').forEach(a => {
|
||||
const href = a.getAttribute('href').slice(1); // strip leading #
|
||||
a.classList.toggle('active', hash === href || (href !== '/' && hash.startsWith(href)));
|
||||
});
|
||||
} else {
|
||||
nav.style.display = 'none';
|
||||
userInfo.textContent = '';
|
||||
}
|
||||
}
|
||||
|
||||
function roleGuard(roles, handler) {
|
||||
return (params) => {
|
||||
if (!isLoggedIn()) { navigate('#/login'); return; }
|
||||
if (!roles.includes(getRole())) { navigate('#/'); return; }
|
||||
return handler(params);
|
||||
};
|
||||
}
|
||||
|
||||
// Routes
|
||||
addRoute('/login', loginPage);
|
||||
addRoute('/', authGuard(dashboardPage));
|
||||
addRoute('/dashboard', authGuard(dashboardPage));
|
||||
addRoute('/questionnaire/new', authGuard(editorPage));
|
||||
addRoute('/questionnaire/:id/results', authGuard(resultsPage));
|
||||
addRoute('/questionnaire/:id', authGuard(editorPage));
|
||||
addRoute('/export', authGuard(exportPage));
|
||||
addRoute('/users', roleGuard(['admin', 'supervisor'], usersPage));
|
||||
addRoute('/assignments', roleGuard(['admin', 'supervisor'], assignmentsPage));
|
||||
|
||||
// Nav link handling & logout
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
document.getElementById('logoutBtn').addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
localStorage.removeItem('qdb_token');
|
||||
localStorage.removeItem('qdb_user');
|
||||
localStorage.removeItem('qdb_role');
|
||||
navigate('#/login');
|
||||
});
|
||||
|
||||
window.addEventListener('hashchange', updateNav);
|
||||
updateNav();
|
||||
startRouter();
|
||||
});
|
||||
Reference in New Issue
Block a user