Major additions: - Territory manager system with application workflow - Custom pricing and page builder with Craft.js - Enhanced Stripe Connect onboarding - CodeReadr QR scanning integration - Kiosk mode for venue sales - Super admin dashboard and analytics - MCP integration for AI-powered operations Infrastructure improvements: - Centralized API client and routing system - Enhanced authentication with organization context - Comprehensive theme management system - Advanced event management with custom tabs - Performance monitoring and accessibility features Database schema updates: - Territory management tables - Custom pages and pricing structures - Kiosk PIN system - Enhanced organization profiles - CodeReadr integration tables 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
113 lines
3.9 KiB
Plaintext
113 lines
3.9 KiB
Plaintext
---
|
|
export interface Props {
|
|
title: string;
|
|
}
|
|
|
|
const { title } = Astro.props;
|
|
import Footer from '../components/Footer.astro';
|
|
import CookieConsent from '../components/CookieConsent.astro';
|
|
---
|
|
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="description" content="Professional ticketing platform for events" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
<meta name="generator" content={Astro.generator} />
|
|
<title>{title}</title>
|
|
|
|
<!-- Critical theme initialization - prevents FOUC -->
|
|
<script>
|
|
(function() {
|
|
// Get theme immediately - no localStorage check to avoid blocking
|
|
const savedTheme = (function() {
|
|
try {
|
|
return localStorage.getItem('theme') ||
|
|
(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
|
|
} catch (e) {
|
|
return 'dark';
|
|
}
|
|
})();
|
|
|
|
// Apply theme immediately to prevent flash
|
|
document.documentElement.setAttribute('data-theme', savedTheme);
|
|
document.documentElement.classList.add(savedTheme);
|
|
|
|
// Store for later use
|
|
window.__INITIAL_THEME__ = savedTheme;
|
|
})();
|
|
</script>
|
|
|
|
<!-- Import stylesheets -->
|
|
<link rel="stylesheet" href="/src/styles/global.css" />
|
|
<link rel="stylesheet" href="/src/styles/glassmorphism.css" />
|
|
</head>
|
|
<body class="min-h-screen flex flex-col">
|
|
<!-- Skip Links for Accessibility -->
|
|
<a href="#main-content" class="skip-link">Skip to main content</a>
|
|
<a href="#navigation" class="skip-link">Skip to navigation</a>
|
|
|
|
<div class="flex-1">
|
|
<main id="main-content" tabindex="-1">
|
|
<slot />
|
|
</main>
|
|
</div>
|
|
<Footer />
|
|
<CookieConsent />
|
|
|
|
<!-- Initialize theme management, accessibility, and performance optimizations -->
|
|
<script>
|
|
// Theme management
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
// Apply initial theme to body
|
|
const initialTheme = window.__INITIAL_THEME__ || 'dark';
|
|
document.body.classList.remove('light', 'dark');
|
|
document.body.classList.add(initialTheme);
|
|
|
|
// Initialize performance optimizations
|
|
import('/src/lib/performance.js').then(({ initializePerformanceOptimizations }) => {
|
|
initializePerformanceOptimizations();
|
|
}).catch(() => {
|
|
// Fallback for browsers that don't support dynamic imports
|
|
console.log('Performance optimizations not available');
|
|
});
|
|
|
|
// Listen for theme changes
|
|
window.addEventListener('themeChanged', (e) => {
|
|
const newTheme = e.detail.theme;
|
|
|
|
// Update document element
|
|
document.documentElement.setAttribute('data-theme', newTheme);
|
|
document.documentElement.classList.remove('light', 'dark');
|
|
document.documentElement.classList.add(newTheme);
|
|
|
|
// Update body
|
|
document.body.classList.remove('light', 'dark');
|
|
document.body.classList.add(newTheme);
|
|
|
|
// Store theme
|
|
localStorage.setItem('theme', newTheme);
|
|
|
|
// Force style recalculation
|
|
document.body.style.display = 'none';
|
|
document.body.offsetHeight;
|
|
document.body.style.display = '';
|
|
});
|
|
});
|
|
|
|
// Initialize accessibility features
|
|
import { initializeAccessibility, initializeHighContrastSupport, initializeReducedMotionSupport } from '../lib/accessibility';
|
|
|
|
// Initialize all accessibility features
|
|
initializeAccessibility();
|
|
initializeHighContrastSupport();
|
|
initializeReducedMotionSupport();
|
|
</script>
|
|
</body>
|
|
</html>
|
|
|
|
<style is:global>
|
|
@import '../styles/global.css';
|
|
</style> |