diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index 84f1288..bc19b41 100644 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -20,215 +20,220 @@ const { title, description = 'ForensicPathways - A comprehensive directory of di {title} - ForensicPathways - + + (window as any).themeUtils = { + initTheme, + toggleTheme, + getStoredTheme + }; + + async function checkClientAuth(context = 'general') { + try { + const response = await fetch('/api/auth/status'); + const data = await response.json(); + + switch (context) { + case 'contributions': + return { + authenticated: data.contributionAuthenticated, + authRequired: data.contributionAuthRequired, + expires: data.expires + }; + case 'ai': + return { + authenticated: data.aiAuthenticated, + authRequired: data.aiAuthRequired, + expires: data.expires + }; + default: + return { + authenticated: data.authenticated, + authRequired: data.contributionAuthRequired || data.aiAuthRequired, + expires: data.expires + }; + } + } catch (error) { + console.error('Auth check failed:', error); + return { + authenticated: false, + authRequired: true + }; + } + } + + async function requireClientAuth(callback, returnUrl, context = 'general') { + const authStatus = await checkClientAuth(context); + + if (authStatus.authRequired && !authStatus.authenticated) { + const targetUrl = returnUrl || window.location.href; + window.location.href = `/api/auth/login?returnTo=${encodeURIComponent(targetUrl)}`; + return false; + } else { + if (typeof callback === 'function') { + callback(); + } + return true; + } + } + + async function showIfAuthenticated(selector, context = 'general') { + const authStatus = await checkClientAuth(context); + const element = document.querySelector(selector); + + if (element) { + element.style.display = (!authStatus.authRequired || authStatus.authenticated) + ? 'inline-flex' + : 'none'; + } + } + + function setupAuthButtons(selector = '[data-contribute-button]') { + document.addEventListener('click', async (e) => { + if (!e.target) return; + + const button = (e.target as Element).closest(selector); + if (!button) return; + + e.preventDefault(); + + console.log('[AUTH] Contribute button clicked:', button.getAttribute('data-contribute-button')); + + await requireClientAuth(() => { + console.log('[AUTH] Navigation approved, redirecting to:', (button as HTMLAnchorElement).href); + window.location.href = (button as HTMLAnchorElement).href; + }, (button as HTMLAnchorElement).href, 'contributions'); + }); + } + + (window as any).checkClientAuth = checkClientAuth; + (window as any).requireClientAuth = requireClientAuth; + (window as any).showIfAuthenticated = showIfAuthenticated; + (window as any).setupAuthButtons = setupAuthButtons; + + initTheme(); + setupAuthButtons('[data-contribute-button]'); + + const initAIButton = async () => { + await showIfAuthenticated('#ai-view-toggle', 'ai'); + }; + initAIButton(); + + console.log('[CONSOLIDATED] All utilities loaded and initialized'); + }); +