/*
* proto.js — shared behaviour for the mobile-app prototypes.
*
* Deliberately tiny: a theme toggle, plus opt-in interactions (segmented
* controls, in-screen tabs, chips, bottom sheets, switches) that pages get
* for free by using the right data attribute. No framework, no build step.
*/
(function () {
// ---- device chrome ------------------------------------------------------
//
const SIGNAL =
' ';
const WIFI =
' ';
const WIFI_OFF =
' ';
const BATTERY =
' ';
document.querySelectorAll('[data-status]').forEach((bar) => {
const offline = bar.hasAttribute('data-offline');
bar.innerHTML = `${bar.dataset.status} ${offline ? '' : SIGNAL}${
offline ? WIFI_OFF : WIFI
}${BATTERY} `;
});
//
const TAB_ICONS = {
home: ' ',
learn:
' ',
compliance:
' ',
teach:
' ',
community: ' ',
profile: ' '
};
const LEARNER_TABS = [
{ id: 'home', label: 'Home', href: 'home.html' },
{ id: 'learn', label: 'Learn', href: 'learn.html' },
{ id: 'compliance', label: 'Compliance', href: 'compliance.html' },
{ id: 'community', label: 'Community', href: 'community.html' },
{ id: 'profile', label: 'Profile', href: 'profile.html' }
];
const TUTOR_TABS = [
{ id: 'home', label: 'Home', href: 'home.html' },
{ id: 'learn', label: 'Learn', href: 'learn.html' },
{ id: 'teach', label: 'Teach', href: 'tutor-grading.html' },
{ id: 'community', label: 'Community', href: 'community.html' },
{ id: 'profile', label: 'Profile', href: 'profile.html' }
];
document.querySelectorAll('[data-tabbar]').forEach((bar) => {
const active = bar.dataset.tabbar;
const badges = (bar.dataset.badges || '').split(',').filter(Boolean);
const tabs = bar.dataset.role === 'tutor' ? TUTOR_TABS : LEARNER_TABS;
bar.innerHTML = tabs
.map((tab) => {
const badge = badges.find((entry) => entry.startsWith(`${tab.id}:`));
const value = badge ? badge.split(':')[1] : '';
const marker =
value === 'dot' ? ' ' : value ? `${value} ` : '';
return `${
TAB_ICONS[tab.id]
} ${tab.label}${marker} `;
})
.join('');
});
// ---- theme toggle -------------------------------------------------------
const toggle = document.querySelector('.theme-toggle');
if (toggle) {
toggle.addEventListener('click', () => {
const dark = document.documentElement.classList.toggle('dark');
localStorage.cioTheme = dark ? 'dark' : 'light';
});
}
// ---- exclusive selection groups ----------------------------------------
// Any container with [data-select] makes its direct children mutually
// exclusive on click: .segmented, .tabs, .chips, option lists.
document.querySelectorAll('[data-select]').forEach((group) => {
const activeClass = group.dataset.select || 'on';
group.addEventListener('click', (event) => {
const target = event.target.closest('[data-option]');
if (!target || !group.contains(target)) return;
group.querySelectorAll('[data-option]').forEach((option) => option.classList.remove(activeClass));
target.classList.add(activeClass);
});
});
// ---- bottom sheets ------------------------------------------------------
// [data-sheet-open="id"] shows #id and its scrim; [data-sheet-close] hides.
function setSheet(id, open) {
const sheet = document.getElementById(id);
if (!sheet) return;
const scrim = sheet.parentElement.querySelector(`[data-scrim-for="${id}"]`);
sheet.style.display = open ? 'flex' : 'none';
if (scrim) scrim.style.display = open ? 'block' : 'none';
}
document.querySelectorAll('[data-sheet-open]').forEach((trigger) => {
trigger.addEventListener('click', () => setSheet(trigger.dataset.sheetOpen, true));
});
document.querySelectorAll('[data-sheet-close]').forEach((trigger) => {
trigger.addEventListener('click', () => setSheet(trigger.dataset.sheetClose, false));
});
document.querySelectorAll('[data-scrim-for]').forEach((scrim) => {
scrim.addEventListener('click', () => setSheet(scrim.dataset.scrimFor, false));
});
})();