import React, { useState, useEffect } from 'react'; import { UserRole, CalendarEvent, AppSettings, UserStatus } from './types'; import { LoginScreen } from './components/LoginScreen'; import { CalendarView } from './components/CalendarView'; import { EventModal } from './components/EventModal'; import { SettingsModal } from './components/SettingsModal'; import { AssistantView } from './components/AssistantView'; import { SpaceBackground } from './components/SpaceBackground'; import { FairyDust } from './components/FairyDust'; import { getStoredEvents, saveEvent, seedInitialData, deleteEvent, getSettings, saveSettings } from './services/storageService'; import { mcpService } from './services/mcpService'; import { generateDailyHoroscope } from './services/aiService'; import { parseISO, set } from 'date-fns'; const App: React.FC = () => { const [isAuthenticated, setIsAuthenticated] = useState(false); const [currentUser, setCurrentUser] = useState(null); const [currentStatus, setCurrentStatus] = useState('online'); const [events, setEvents] = useState([]); const [settings, setSettings] = useState(getSettings()); // Modal State const [isModalOpen, setIsModalOpen] = useState(false); const [isSettingsOpen, setIsSettingsOpen] = useState(false); const [isAssistantOpen, setIsAssistantOpen] = useState(false); const [selectedDate, setSelectedDate] = useState(undefined); const [selectedEvent, setSelectedEvent] = useState(null); // Theme Injection useEffect(() => { const root = document.documentElement; root.style.setProperty('--mom-primary', settings.momColor); root.style.setProperty('--dad-primary', settings.dadColor); root.style.setProperty('--mom-soft', `${settings.momColor}33`); root.style.setProperty('--dad-soft', `${settings.dadColor}33`); }, [settings]); useEffect(() => { seedInitialData(); setEvents(getStoredEvents()); const storedUser = localStorage.getItem('ourtime_user'); if (storedUser) { setCurrentUser(storedUser as UserRole); setIsAuthenticated(true); } }, []); // Daily Horoscope Check useEffect(() => { const checkHoroscope = async () => { if (!isAuthenticated || !currentUser || settings.momZodiac === 'Unknown' || settings.dadZodiac === 'Unknown') return; const today = new Date(); const todayStr = today.toISOString().split('T')[0]; const horoscopeId = `horoscope-${todayStr}`; // Check if we already have a magic event for today with this ID const hasHoroscope = events.some(e => e.id === horoscopeId); if (!hasHoroscope) { // Generate it console.log("Generating daily horoscope..."); const prediction = await generateDailyHoroscope(settings.momZodiac, settings.dadZodiac, settings); const newEvent: CalendarEvent = { id: horoscopeId, title: `✨ ${prediction}`, description: `Daily guidance for ${settings.momZodiac} & ${settings.dadZodiac}`, startTime: new Date().toISOString(), // Use current time/date endTime: new Date().toISOString(), isAllDay: true, category: 'magic', createdBy: currentUser }; handleSaveEvent(newEvent); } }; // Slight delay to ensure load const timer = setTimeout(checkHoroscope, 2000); return () => clearTimeout(timer); }, [isAuthenticated, currentUser, events, settings]); // MCP Service Connection useEffect(() => { if (settings.enableMcp && settings.mcpServerUrl) { mcpService.connect(settings.mcpServerUrl); const unsubscribe = mcpService.subscribe((newEvent) => { handleSaveEvent(newEvent); }); return () => { unsubscribe(); mcpService.disconnect(); }; } else { mcpService.disconnect(); } }, [settings.enableMcp, settings.mcpServerUrl]); const handleLogin = (role: UserRole) => { setCurrentUser(role); setIsAuthenticated(true); localStorage.setItem('ourtime_user', role); }; const handleLogout = () => { setCurrentUser(null); setIsAuthenticated(false); localStorage.removeItem('ourtime_user'); }; const handleAddEventClick = (date?: Date) => { setSelectedEvent(null); setSelectedDate(date); setIsModalOpen(true); }; const handleEditEventClick = (event: CalendarEvent) => { setSelectedEvent(event); setSelectedDate(parseISO(event.startTime)); setIsModalOpen(true); }; const handleSaveEvent = (event: CalendarEvent) => { const updatedEvents = saveEvent(event); setEvents(updatedEvents); }; const handleMoveEvent = (eventId: string, newDate: Date) => { const event = events.find(e => e.id === eventId); if (!event) return; const oldStart = parseISO(event.startTime); const oldEnd = parseISO(event.endTime); const duration = oldEnd.getTime() - oldStart.getTime(); // Create new start time with the new date but keeping the old hours/minutes const newStart = set(newDate, { hours: oldStart.getHours(), minutes: oldStart.getMinutes(), seconds: oldStart.getSeconds() }); const newEnd = new Date(newStart.getTime() + duration); const updatedEvent = { ...event, startTime: newStart.toISOString(), endTime: newEnd.toISOString() }; handleSaveEvent(updatedEvent); }; const handleDeleteEvent = (id: string) => { const updatedEvents = deleteEvent(id); setEvents(updatedEvents); }; const handleSaveSettings = (newSettings: AppSettings) => { setSettings(newSettings); saveSettings(newSettings); }; if (!isAuthenticated || !currentUser) { return ( <> ); } return (
setIsSettingsOpen(true)} onOpenAssistant={() => setIsAssistantOpen(true)} settings={settings} /> setIsModalOpen(false)} onSave={handleSaveEvent} onDelete={handleDeleteEvent} currentUserRole={currentUser} selectedDate={selectedDate} initialEvent={selectedEvent} /> setIsSettingsOpen(false)} settings={settings} onSave={handleSaveSettings} /> setIsAssistantOpen(false)} currentUser={currentUser} settings={settings} onEventCreated={handleSaveEvent} />
); }; export default App;