Stop_smoking_website_ver2/src/lib/theme-context.tsx
nicholai 890bdf13e4 Feat: Add public landing page for non-authenticated users
- Create /home route with SEO metadata and JSON-LD structured data
- Add hero section with dual CTAs (sign-up and PWA install)
- Add features section showcasing dual tracking, health timeline, achievements, savings
- Add animated phone demo with rotating screens (auto-advance, pause on hover)
- Add final CTA section and footer with affiliate disclosure
- Extract usePWAInstall hook for reusable PWA install logic
- Enhance theme-context with system preference auto-detection

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 19:30:46 -07:00

74 lines
1.9 KiB
TypeScript

'use client';
import { createContext, useContext, useState, useEffect, ReactNode } from 'react';
type Theme = 'dark' | 'light';
interface ThemeContextType {
theme: Theme;
toggleTheme: () => void;
}
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
export function ThemeProvider({ children }: { children: ReactNode }) {
const [theme, setTheme] = useState<Theme>('dark');
useEffect(() => {
// Check localStorage first
const saved = localStorage.getItem('theme') as Theme | null;
if (saved) {
setTheme(saved);
return;
}
// Fall back to system preference
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
setTheme(prefersDark ? 'dark' : 'light');
}, []);
// Listen for system preference changes (only if no manual preference set)
useEffect(() => {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const handleChange = (e: MediaQueryListEvent) => {
// Only update if user hasn't manually set a preference
if (!localStorage.getItem('theme')) {
setTheme(e.matches ? 'dark' : 'light');
}
};
mediaQuery.addEventListener('change', handleChange);
return () => mediaQuery.removeEventListener('change', handleChange);
}, []);
useEffect(() => {
const root = document.documentElement;
if (theme === 'dark') {
root.classList.add('dark');
} else {
root.classList.remove('dark');
}
}, [theme]);
const toggleTheme = () => {
const newTheme = theme === 'dark' ? 'light' : 'dark';
setTheme(newTheme);
localStorage.setItem('theme', newTheme);
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}
export function useTheme() {
const context = useContext(ThemeContext);
if (!context) {
throw new Error('useTheme must be used within a ThemeProvider');
}
return context;
}