import React, { useState } from "react"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Card, CardContent } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Separator } from "@/components/ui/separator"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Settings, Palette, Monitor, Sun, Moon, Smartphone, Check, GitBranch, Layers, Brain, Zap, Clock, DollarSign, } from "lucide-react"; import { useKGDisplayMode } from "@/context/KGDisplayModeContext"; import { useModelPreferences } from "@/hooks/useModelPreferences"; import { AVAILABLE_MODELS, ModelConfig } from "@/lib/models"; interface SettingsModalProps { open: boolean; onOpenChange: (open: boolean) => void; } type Theme = "light" | "dark" | "system"; export function SettingsModal({ open, onOpenChange }: SettingsModalProps) { const [activeSection, setActiveSection] = useState("appearance"); const [currentTheme, setCurrentTheme] = useState("system"); const { mode: kgDisplayMode, setMode: setKGDisplayMode } = useKGDisplayMode(); const { selectedModel, currentModelConfig, updateModelPreference, isLoading, } = useModelPreferences(); const handleThemeChange = (theme: Theme) => { setCurrentTheme(theme); // Apply theme to document const root = document.documentElement; if (theme === "dark") { root.classList.add("dark"); } else if (theme === "light") { root.classList.remove("dark"); } else { // System theme - detect user preference const prefersDark = window.matchMedia( "(prefers-color-scheme: dark)" ).matches; if (prefersDark) { root.classList.add("dark"); } else { root.classList.remove("dark"); } } // Save to localStorage localStorage.setItem("theme", theme); }; React.useEffect(() => { // Load saved theme on mount const savedTheme = localStorage.getItem("theme") as Theme; if (savedTheme) { setCurrentTheme(savedTheme); handleThemeChange(savedTheme); } }, []); const themeOptions = [ { id: "light" as Theme, name: "Light", description: "Light mode for bright environments", icon: Sun, }, { id: "dark" as Theme, name: "Dark", description: "Dark mode for low-light environments", icon: Moon, }, { id: "system" as Theme, name: "System", description: "Follows your system preference", icon: Monitor, }, ]; const sidebarSections = [ { id: "appearance", name: "Appearance", icon: Palette, }, { id: "models", name: "Models", icon: Brain, }, { id: "general", name: "General", icon: Settings, }, ]; const getCostLevelColor = (costLevel: string) => { switch (costLevel) { case "low": return "text-green-600"; case "medium": return "text-yellow-600"; case "high": return "text-red-600"; default: return "text-gray-600"; } }; const getSpeedIcon = (speed: string) => { switch (speed) { case "fast": return Zap; case "medium": return Clock; case "slow": return Brain; default: return Clock; } }; const renderModelCard = (model: ModelConfig) => { const SpeedIcon = getSpeedIcon(model.speed); const isSelected = selectedModel === model.id; return ( updateModelPreference(model.id)} >

{model.name}

{model.recommended && ( Recommended )}

{model.description}

{model.speed}
{model.costLevel} cost
{model.contextWindow} context
{isSelected && (
)}
); }; const renderModelsSection = () => (
{isLoading ? (
Loading model preferences...
) : ( <> {/* Current Model Indicator */} {currentModelConfig && (

Currently Selected

Active for all new graph generations

{currentModelConfig.name}

{currentModelConfig.description}

)}

Standard Models

{AVAILABLE_MODELS.standard.map(renderModelCard)}

Reasoning Models

Specialized models for complex analysis and multi-step reasoning tasks.

{AVAILABLE_MODELS.reasoning.map(renderModelCard)}
Model Selection

Your selected model will be used for all knowledge graph extractions. Changes apply to new generations only.

)}
); const renderAppearanceSection = () => (

Theme Selection

{themeOptions.map((option) => ( handleThemeChange(option.id)} >

{option.name}

{option.description}

{currentTheme === option.id && (
)}
))}

Color Customization

Coming Soon Future Update

Custom color themes and accent colors will be available in a future update.

); const renderGeneralSection = () => (

Knowledge Graph Display

{[ { id: "multiple" as const, name: "Multiple Knowledge Graphs", description: "Show all knowledge graphs for research and comparison", icon: Layers, }, { id: "single" as const, name: "Single Knowledge Graph", description: "Show only the most recent/best knowledge graph per trace", icon: GitBranch, }, ].map((option) => ( setKGDisplayMode(option.id)} >

{option.name}

{option.description}

{kgDisplayMode === option.id && (
)}
))}

Additional Settings

More Options Coming Soon

More configuration options including language preferences, default views, and notification settings will be available soon.

); const renderSection = () => { switch (activeSection) { case "appearance": return renderAppearanceSection(); case "models": return renderModelsSection(); case "general": return renderGeneralSection(); default: return renderAppearanceSection(); } }; return ( Settings & Preferences Customize your AgentGraph experience
{/* Navigation Sidebar */}
{/* Content Area */}
{renderSection()}
Changes are saved automatically
); }