Spaces:
Sleeping
Sleeping
| import { useState, useEffect } from 'react' | |
| import Sidebar from './components/Sidebar' | |
| import MainContent from './components/MainContent' | |
| import DetailContent from './components/DetailContent' | |
| import OriginalDetailContent from './components/OriginalDetailContent' | |
| import { chatService } from './services/chatService' | |
| import type { ChatSession } from './services/chatService' | |
| function App() { | |
| const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false) | |
| // Responsive Sidebar Logic | |
| useEffect(() => { | |
| const handleResize = () => { | |
| if (window.innerWidth < 1024) { | |
| setIsSidebarCollapsed(true) | |
| } else { | |
| setIsSidebarCollapsed(false) | |
| } | |
| } | |
| // Initial check | |
| handleResize() | |
| window.addEventListener('resize', handleResize) | |
| return () => window.removeEventListener('resize', handleResize) | |
| }, []) | |
| const [activeView, setActiveView] = useState<'home' | 'detail' | 'original'>(() => { | |
| if (typeof window !== 'undefined') { | |
| const saved = localStorage.getItem('activeView') | |
| return (saved as 'home' | 'detail' | 'original') || 'home' | |
| } | |
| return 'home' | |
| }) | |
| const [isDarkMode, setIsDarkMode] = useState(() => { | |
| if (typeof window !== 'undefined') { | |
| const saved = localStorage.getItem('theme') | |
| if (saved) return saved === 'dark' | |
| return window.matchMedia('(prefers-color-scheme: dark)').matches | |
| } | |
| return false | |
| }) | |
| // Chat State | |
| const [sessions, setSessions] = useState<ChatSession[]>(() => chatService.getHistory()) | |
| const [currentSessionId, setCurrentSessionId] = useState<string | null>(() => { | |
| if (typeof window !== 'undefined') { | |
| return localStorage.getItem('currentSessionId') | |
| } | |
| return null | |
| }) | |
| useEffect(() => { | |
| if (isDarkMode) { | |
| document.documentElement.classList.add('dark') | |
| localStorage.setItem('theme', 'dark') | |
| } else { | |
| document.documentElement.classList.remove('dark') | |
| localStorage.setItem('theme', 'light') | |
| } | |
| }, [isDarkMode]) | |
| // Persist navigation state | |
| useEffect(() => { | |
| localStorage.setItem('activeView', activeView) | |
| }, [activeView]) | |
| useEffect(() => { | |
| if (currentSessionId) { | |
| localStorage.setItem('currentSessionId', currentSessionId) | |
| } else { | |
| localStorage.removeItem('currentSessionId') | |
| } | |
| }, [currentSessionId]) | |
| const toggleTheme = () => setIsDarkMode(!isDarkMode) | |
| const resetToDefault = () => { | |
| setActiveView('home') | |
| setCurrentSessionId(null) | |
| } | |
| const handleNewChat = (message: string) => { | |
| const newSession = chatService.createSession(message) | |
| setSessions(prevSessions => { | |
| const updatedSessions = [newSession, ...prevSessions] | |
| chatService.saveHistory(updatedSessions) | |
| return updatedSessions | |
| }) | |
| setCurrentSessionId(newSession.id) | |
| setActiveView('detail') | |
| } | |
| const handleSelectSession = (sessionId: string) => { | |
| setCurrentSessionId(sessionId) | |
| setActiveView('detail') | |
| // Auto-close sidebar on mobile after selection | |
| if (window.innerWidth < 1024) { | |
| setIsSidebarCollapsed(true) | |
| } | |
| } | |
| const handleUpdateSession = (updatedSession: ChatSession) => { | |
| setSessions(prevSessions => { | |
| const updatedSessions = prevSessions.map(s => s.id === updatedSession.id ? updatedSession : s) | |
| chatService.saveHistory(updatedSessions) | |
| return updatedSessions | |
| }) | |
| } | |
| const handleRenameSession = (sessionId: string, newTitle: string) => { | |
| setSessions(prevSessions => { | |
| const updatedSessions = prevSessions.map(s => | |
| s.id === sessionId ? { ...s, title: newTitle } : s | |
| ); | |
| chatService.saveHistory(updatedSessions); | |
| return updatedSessions; | |
| }); | |
| }; | |
| const handleDeleteSession = (sessionId: string) => { | |
| setSessions(prevSessions => { | |
| const updatedSessions = prevSessions.filter(s => s.id !== sessionId); | |
| chatService.saveHistory(updatedSessions); | |
| return updatedSessions; | |
| }); | |
| if (currentSessionId === sessionId) { | |
| setCurrentSessionId(null); | |
| setActiveView('home'); | |
| } | |
| }; | |
| const currentSession = sessions.find(s => s.id === currentSessionId) | |
| return ( | |
| <div className="flex w-full h-screen bg-white dark:bg-gray-900 overflow-hidden font-sans text-gray-900 dark:text-gray-100 transition-colors duration-300"> | |
| <Sidebar | |
| isCollapsed={isSidebarCollapsed} | |
| toggleSidebar={() => setIsSidebarCollapsed(!isSidebarCollapsed)} | |
| activeView={activeView} | |
| onNavigate={setActiveView} | |
| onReset={resetToDefault} | |
| sessions={sessions} | |
| currentSessionId={currentSessionId} | |
| onSelectSession={handleSelectSession} | |
| onRenameSession={handleRenameSession} | |
| onDeleteSession={handleDeleteSession} | |
| /> | |
| {activeView === 'home' ? ( | |
| <MainContent | |
| isDarkMode={isDarkMode} | |
| toggleTheme={toggleTheme} | |
| onNewChat={handleNewChat} | |
| onToggleSidebar={() => setIsSidebarCollapsed(!isSidebarCollapsed)} | |
| /> | |
| ) : activeView === 'detail' ? ( | |
| <DetailContent | |
| key={currentSession?.id} | |
| isDarkMode={isDarkMode} | |
| toggleTheme={toggleTheme} | |
| session={currentSession} | |
| onUpdateSession={handleUpdateSession} | |
| onToggleSidebar={() => setIsSidebarCollapsed(!isSidebarCollapsed)} | |
| /> | |
| ) : ( | |
| <OriginalDetailContent | |
| isDarkMode={isDarkMode} | |
| toggleTheme={toggleTheme} | |
| /> | |
| )} | |
| </div> | |
| ) | |
| } | |
| export default App | |