Welcome to Polyvera Lingua
This demonstration account panel is not connected to a live authentication service.
Your learning plan
Cart
Your enquiry is prepared
This demonstration does not process payment. Please contact Polyvera Lingua so an advisor can discuss availability and next steps.
Contact Polyvera Lingua
`;
const footerHTML = `
`;
headerEl.innerHTML = headerHTML;
footerEl.innerHTML = footerHTML;
// Mobile menu
const mobileToggle = document.getElementById('mobile-menu-toggle');
const mobileNav = document.getElementById('mobile-navigation');
if (mobileToggle && mobileNav) {
mobileToggle.addEventListener('click', () => {
mobileNav.classList.toggle('hidden');
const expanded = mobileNav.classList.contains('hidden') ? 'false' : 'true';
mobileToggle.setAttribute('aria-expanded', expanded);
});
}
// Theme toggle
const themeToggle = document.getElementById('theme-toggle');
if (themeToggle) {
const savedTheme = localStorage.getItem('polyveraTheme');
if (savedTheme === 'light') {
document.body.classList.add('bg-[#f7f3eb]', 'text-[#172338]');
document.body.classList.remove('bg-[#071426]', 'text-[#f5f1e8]');
themeToggle.textContent = 'Dark';
}
themeToggle.addEventListener('click', () => {
if (document.body.classList.contains('bg-[#f7f3eb]')) {
document.body.classList.remove('bg-[#f7f3eb]', 'text-[#172338]');
document.body.classList.add('bg-[#071426]', 'text-[#f5f1e8]');
themeToggle.textContent = 'Light';
localStorage.setItem('polyveraTheme', 'dark');
} else {
document.body.classList.add('bg-[#f7f3eb]', 'text-[#172338]');
document.body.classList.remove('bg-[#071426]', 'text-[#f5f1e8]');
themeToggle.textContent = 'Dark';
localStorage.setItem('polyveraTheme', 'light');
}
});
}
// Auth modal
const authModal = document.getElementById('auth-modal');
const authClose = document.getElementById('auth-close');
document.querySelectorAll('[data-auth]').forEach(btn => {
btn.addEventListener('click', () => {
if (authModal) authModal.classList.remove('hidden');
});
});
if (authClose && authModal) {
authClose.addEventListener('click', () => authModal.classList.add('hidden'));
}
// Cookie banner
const banner = document.getElementById('cookie-banner');
const acceptBtn = document.getElementById('accept-cookies');
if (banner && acceptBtn) {
const key = 'polyveraCookiesAccepted';
if (localStorage.getItem(key) === 'true') {
banner.style.display = 'none';
} else {
banner.style.display = 'flex';
acceptBtn.addEventListener('click', () => {
localStorage.setItem(key, 'true');
banner.style.display = 'none';
});
}
}
}
async function initCart() {
await loadShared();
const cartContainer = document.getElementById('cart-lines');
const totalEl = document.getElementById('cart-total');
const checkoutBtn = document.getElementById('checkout');
const checkoutModal = document.getElementById('checkout-modal');
const closeCheckout = document.getElementById('close-checkout');
let cart = JSON.parse(localStorage.getItem('polyveraCart') || '[]');
let catalog = [];
try {
const res = await fetch('./catalog.json');
catalog = await res.json();
} catch (e) {
catalog = [];
}
function saveCart() {
localStorage.setItem('polyveraCart', JSON.stringify(cart));
}
function calculateTotal() {
let total = 0;
cart.forEach(item => {
const program = catalog.find(p => p.id === item.id);
if (program) total += program.price * item.quantity;
});
totalEl.textContent = '$' + total.toFixed(2);
}
function renderCart() {
cartContainer.innerHTML = '';
if (cart.length === 0) {
cartContainer.innerHTML = `
Your cart is empty.
Browse programs
`;
totalEl.textContent = '$0.00';
return;
}
cart.forEach((item, index) => {
const program = catalog.find(p => p.id === item.id);
if (!program) return;
const line = document.createElement('div');
line.className = 'border border-[#304563] bg-[#10233d] p-7 flex flex-col md:flex-row md:items-center md:justify-between gap-4';
line.innerHTML = `
${program.title}
${program.language} • ${program.level} • ${program.format}
$${program.price} × ${item.quantity}
${item.quantity}
`;
line.querySelector('.qty-dec').addEventListener('click', () => {
if (item.quantity > 1) {
item.quantity--;
saveCart();
renderCart();
calculateTotal();
}
});
line.querySelector('.qty-inc').addEventListener('click', () => {
item.quantity++;
saveCart();
renderCart();
calculateTotal();
});
line.querySelector('.remove').addEventListener('click', () => {
cart.splice(index, 1);
saveCart();
renderCart();
calculateTotal();
});
cartContainer.appendChild(line);
});
calculateTotal();
}
renderCart();
checkoutBtn.addEventListener('click', () => {
checkoutModal.classList.remove('hidden');
});
closeCheckout.addEventListener('click', () => {
checkoutModal.classList.add('hidden');
});
checkoutModal.addEventListener('click', (e) => {
if (e.target === checkoutModal) checkoutModal.classList.add('hidden');
});
}
initCart();