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');
+ });
+