chore: Perform codebase cleanup and refactor App state management
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useState, useEffect } from "react"
|
||||
import { useState, useEffect, createContext, useContext } from "react"
|
||||
import { Routes, Route } from "react-router-dom"
|
||||
import { MainLayout } from "./components/layout/MainLayout"
|
||||
import { LoginForm } from "./components/auth/LoginForm"
|
||||
@@ -9,12 +9,42 @@ import { ChatService, type MessageResponse } from "./services/chat"
|
||||
import { type Conversation } from "./components/layout/HistorySidebar"
|
||||
import { registerUnauthorizedCallback } from "./services/api"
|
||||
import { Button } from "./components/ui/button"
|
||||
import { useTheme } from "./components/theme-provider"
|
||||
import { ThemeProvider, useTheme } from "./components/theme-provider"
|
||||
|
||||
function App() {
|
||||
const { setThemeLocal } = useTheme()
|
||||
// --- Auth Context ---
|
||||
interface AuthContextType {
|
||||
isAuthenticated: boolean
|
||||
setIsAuthenticated: (val: boolean) => void
|
||||
user: UserResponse | null
|
||||
setUser: (user: UserResponse | null) => void
|
||||
}
|
||||
|
||||
const AuthContext = createContext<AuthContextType | undefined>(undefined)
|
||||
|
||||
function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
const [isAuthenticated, setIsAuthenticated] = useState(false)
|
||||
const [user, setUser] = useState<UserResponse | null>(null)
|
||||
|
||||
return (
|
||||
<AuthContext.Provider value={{ isAuthenticated, setIsAuthenticated, user, setUser }}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
function useAuth() {
|
||||
const context = useContext(AuthContext)
|
||||
if (context === undefined) {
|
||||
throw new Error("useAuth must be used within an AuthProvider")
|
||||
}
|
||||
return context
|
||||
}
|
||||
|
||||
// --- App Content ---
|
||||
function AppContent() {
|
||||
const { setThemeLocal } = useTheme()
|
||||
const { isAuthenticated, setIsAuthenticated, user, setUser } = useAuth()
|
||||
|
||||
const [authMode, setAuthMode] = useState<"login" | "register">("login")
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
const [selectedThreadId, setSelectedThreadId] = useState<string | null>(null)
|
||||
@@ -22,13 +52,13 @@ function App() {
|
||||
const [threadMessages, setThreadMessages] = useState<Record<string, MessageResponse[]>>({})
|
||||
|
||||
useEffect(() => {
|
||||
// Register callback to handle session expiration from anywhere in the app
|
||||
registerUnauthorizedCallback(() => {
|
||||
setIsAuthenticated(false)
|
||||
setUser(null)
|
||||
setConversations([])
|
||||
setSelectedThreadId(null)
|
||||
setThreadMessages({})
|
||||
setThemeLocal("light")
|
||||
})
|
||||
|
||||
const initAuth = async () => {
|
||||
@@ -39,7 +69,6 @@ function App() {
|
||||
if (userData.theme_preference) {
|
||||
setThemeLocal(userData.theme_preference)
|
||||
}
|
||||
// Load history after successful auth
|
||||
loadHistory()
|
||||
} catch (err: unknown) {
|
||||
console.log("No active session found", err)
|
||||
@@ -50,7 +79,7 @@ function App() {
|
||||
}
|
||||
|
||||
initAuth()
|
||||
}, [])
|
||||
}, [setIsAuthenticated, setThemeLocal, setUser])
|
||||
|
||||
const loadHistory = async () => {
|
||||
try {
|
||||
@@ -86,13 +115,12 @@ function App() {
|
||||
setSelectedThreadId(null)
|
||||
setConversations([])
|
||||
setThreadMessages({})
|
||||
setThemeLocal("light")
|
||||
}
|
||||
}
|
||||
|
||||
const handleSelectConversation = async (id: string) => {
|
||||
setSelectedThreadId(id)
|
||||
// Always fetch messages to avoid stale cache issues when switching back
|
||||
// or if the session was updated from elsewhere
|
||||
try {
|
||||
const msgs = await ChatService.getMessages(id)
|
||||
setThreadMessages(prev => ({ ...prev, [id]: msgs }))
|
||||
@@ -125,7 +153,6 @@ function App() {
|
||||
try {
|
||||
await ChatService.deleteConversation(id)
|
||||
setConversations(prev => prev.filter(c => c.id !== id))
|
||||
// Also clear from cache
|
||||
setThreadMessages(prev => {
|
||||
const next = { ...prev }
|
||||
delete next[id]
|
||||
@@ -202,7 +229,7 @@ function App() {
|
||||
<div className="flex-1 min-h-0">
|
||||
{selectedThreadId ? (
|
||||
<ChatInterface
|
||||
key={selectedThreadId} // Force remount on thread change
|
||||
key={selectedThreadId}
|
||||
threadId={selectedThreadId}
|
||||
initialMessages={threadMessages[selectedThreadId] || []}
|
||||
onMessagesFinal={(msgs) => handleMessagesFinal(selectedThreadId, msgs)}
|
||||
@@ -249,4 +276,23 @@ function App() {
|
||||
)
|
||||
}
|
||||
|
||||
function ThemeWrapper({ children }: { children: React.ReactNode }) {
|
||||
const { isAuthenticated } = useAuth()
|
||||
return (
|
||||
<ThemeProvider isAuthenticated={isAuthenticated}>
|
||||
{children}
|
||||
</ThemeProvider>
|
||||
)
|
||||
}
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<AuthProvider>
|
||||
<ThemeWrapper>
|
||||
<AppContent />
|
||||
</ThemeWrapper>
|
||||
</AuthProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
||||
|
||||
@@ -15,9 +15,11 @@ const ThemeContext = createContext<ThemeContextType | undefined>(undefined)
|
||||
export function ThemeProvider({
|
||||
children,
|
||||
initialTheme = "light",
|
||||
isAuthenticated = false,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
initialTheme?: Theme
|
||||
isAuthenticated?: boolean
|
||||
}) {
|
||||
const [theme, setThemeState] = useState<Theme>(initialTheme)
|
||||
|
||||
@@ -29,10 +31,12 @@ export function ThemeProvider({
|
||||
|
||||
const setTheme = async (newTheme: Theme) => {
|
||||
setThemeState(newTheme)
|
||||
try {
|
||||
await AuthService.updateTheme(newTheme)
|
||||
} catch (error) {
|
||||
console.error("Failed to sync theme to backend:", error)
|
||||
if (isAuthenticated) {
|
||||
try {
|
||||
await AuthService.updateTheme(newTheme)
|
||||
} catch (error) {
|
||||
console.error("Failed to sync theme to backend:", error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,11 +9,9 @@ import { ThemeProvider } from "./components/theme-provider"
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<StrictMode>
|
||||
<BrowserRouter>
|
||||
<ThemeProvider>
|
||||
<TooltipProvider>
|
||||
<App />
|
||||
</TooltipProvider>
|
||||
</ThemeProvider>
|
||||
<TooltipProvider>
|
||||
<App />
|
||||
</TooltipProvider>
|
||||
</BrowserRouter>
|
||||
</StrictMode>,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user