# TimeSync - Detailed Documentation for AI Assistants ## Project Structure ### Core Components **TimeZoneDisplay.tsx** - Main component for displaying individual timezone cards - Manages edit/view state with isEditing boolean - Converts between local time and UTC using Luxon - Props: timeZone, baseHour, baseMinute, onTimeChange, onRemove, isMain, showDivider - Features tap-to-edit interaction and Done button to exit edit mode **TimeCarousel.tsx** - Reusable carousel component for selecting hours/minutes - Props: initialValue, min, max, onChange, padZero, showControls - Supports both 12-hour (1-12) and 24-hour (0-23) ranges - showControls prop conditionally displays up/down arrows **CitySearch.tsx** - Autocomplete search for cities using city-timezones library - Filters results by city name - Returns IANA timezone identifier for selected city ### Context Providers **TimeContext.tsx** - Manages global time state (baseHour, baseMinute in UTC) - Handles timezone list (main + comparison timezones) - Provides addTimeZone, removeTimeZone, updateBaseTime methods - Persists timezone selections to localStorage **TimeFormatContext.tsx** - Manages 12h/24h time format preference - Provides is12Hour and is24Hour boolean helpers - Persists format preference to localStorage with key 'timeFormat' **ThemeContext.tsx** - Manages light/dark theme preference - Applies .light-theme or .dark-theme class to document root - Persists theme to localStorage **CookieConsentContext.tsx** - Manages GDPR cookie consent state (pending, accepted, rejected) - Controls Google Analytics initialization - Provides resetConsent method for privacy page - Persists consent to localStorage with key 'cookieConsent' ### Utility Functions **timeFormat.ts** - `convertTo12Hour(hour24)`: Converts 0-23 hour to 1-12 with AM/PM - Edge cases: 0 → 12 AM (midnight), 12 → 12 PM (noon) - `convertTo24Hour(hour12, period)`: Converts 12-hour + period to 0-23 - `getPeriod(hour24)`: Returns 'AM' or 'PM' based on hour - `formatHourDisplay(hour, is12h)`: Formats hour with optional zero-padding **analytics.ts** - `initializeAnalytics()`: Loads Google Analytics script if consent given - `trackPageView(path)`: Sends pageview event to GA4 - Only initializes after explicit user consent ### Styling System **Color Palette** - Primary/Accent: Red (#DC2626 / hsl(0, 72%, 51%)) - Gray: #6B7280 for secondary text - Background: White/Black with slate card backgrounds - Slate-100 (light), Slate-800 (dark) for time cards **Typography** - Display Font: Departure Mono (monospace, 400 weight, -14% letter-spacing) - Used for time display (hours, minutes, colon) - UI Font: Inter (sans-serif) for interface text **CSS Classes** - `.time-card`: Rounded card with slate background, p-6, rounded-xl - `.time-card-view-mode`: Adds cursor-pointer and hover effect - `.time-carousel-item`: 8xl text size with Departure Mono font - `.time-colon`: Red colon between hours and minutes ### Data Flow **Time Synchronization** 1. User edits time in any timezone card (local time) 2. Component converts local time to UTC using Luxon 3. UTC time updates in TimeContext via onTimeChange 4. All other timezone cards recalculate their local times from new UTC 5. Result: All timezones stay synchronized **12-Hour Format Handling** 1. Internal state always stored as 24-hour (0-23) 2. TimeZoneDisplay converts to 12-hour for display if is12Hour is true 3. Carousel shows 1-12 range in 12h mode, 0-23 in 24h mode 4. User interaction converts back to 24h before updating UTC time 5. AM/PM period derived from 24h local time (<12 = AM, ≥12 = PM) ### Key Algorithms **Timezone Calculation** (TimeZoneDisplay.tsx:33-38) ```typescript const calculateLocalTime = (hour: number, minute: number, ianaName: string) => { const today = DateTime.now(); const utcTime = DateTime.utc(today.year, today.month, today.day, hour, minute); const localTime = utcTime.setZone(ianaName); return { hour: localTime.hour, minute: localTime.minute }; }; ``` **Hour Change Handler** (TimeZoneDisplay.tsx:58-70) 1. If 12h mode: Convert carousel value (1-12) to 24h using period 2. Create DateTime object in local timezone 3. Convert to UTC 4. Update global state ### Pages **Index (/)**: Main application page with timezone cards and city search **Privacy (/privacy)**: GDPR-compliant privacy policy with SwirlyPeak contact **NotFound (*)**: 404 page for invalid routes ### State Persistence All user preferences persist across sessions via localStorage: - `timeFormat`: '12h' | '24h' - `theme`: 'light' | 'dark' - `timezones`: Array of selected timezone objects - `cookieConsent`: 'pending' | 'accepted' | 'rejected' ### External Dependencies - **Luxon**: DateTime manipulation and timezone conversions - **city-timezones**: City database for search functionality - **React Router**: Client-side routing - **shadcn/ui**: Pre-built accessible components (Dialog, Button, Switch, etc.) - **Tailwind CSS**: Utility-first styling - **Lucide React**: Icon library (ChevronUp, ChevronDown, Search, X, etc.) ### SEO & Metadata **Open Graph Tags** (index.html) - Title: "TimeSync | Time Zone Comparison Tool" - Description: "A minimal, beautifully designed time zone comparison web app for professionals coordinating international meetings." - Image: /og-image.png (2942x2104) - URL: https://time-sync-five.vercel.app/ **Twitter Card** - Type: summary_large_image - Same title, description, and image as OG tags ### Analytics & Privacy **Cookie Consent Banner** (CookieConsentBanner.tsx) - Appears on first visit (consent state = 'pending') - User can Accept or Reject analytics cookies - Link to privacy policy included - Disappears after user makes choice **Google Analytics Integration** - Measurement ID: G-KM5NJZZK87 - Only loads if user accepts cookies - Tracks page views via AnalyticsTracker component - No PII collected ### API Endpoints None - fully client-side application ### Browser Support - Modern browsers with ES6+ support - CSS Grid and Flexbox - localStorage API required - JavaScript required (no SSR) ### Performance Considerations - Vite for fast builds and HMR - Code splitting via React Router lazy loading (if implemented) - Font loading optimized with preconnect - Tailwind CSS purged in production - Analytics script loaded asynchronously - Image optimization for og-image.png ### Accessibility - Semantic HTML structure - ARIA labels on interactive elements (via shadcn/ui) - Keyboard navigation support - Focus management in modals - Color contrast follows WCAG guidelines - Screen reader friendly time display ### Future Enhancement Ideas - Drag-and-drop to reorder timezones - Save timezone presets - Share timezone comparison via URL - Calendar integration - World clock widget mode - Multiple time comparison (e.g., "What time is 3pm EST in other zones?") - Timezone abbreviation display (EST, PST, etc.) - Meeting scheduler with availability overlay