import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { KeyRound, Sparkles, Settings, HardDrive } from 'lucide-react'; import { Dialog, DialogContent, DialogTitle, DialogDescription, } from '@/components/ui/dialog'; import { Sidebar, SidebarContent, SidebarGroup, SidebarGroupContent, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarProvider, } from '@/components/ui/sidebar'; import { cn } from '@/lib/utils'; import AccountSettingsPanel from '@/app/home/components/account-settings-dialog/AccountSettingsPanel'; import ApiIntegrationPanel from '@/app/home/components/api-integration-dialog/ApiIntegrationPanel'; import ModelsPanel from '@/app/home/components/models-dialog/ModelsPanel'; import StorageAnalysisPanel from '@/app/home/components/storage-analysis-dialog/StorageAnalysisPanel'; // The set of settings sections shown in the unified dialog. The string values // are also reused as the ?action= query param suffix so deep links keep working. export type SettingsSection = | 'account' | 'apiIntegration' | 'models' | 'storageAnalysis'; // Map between a section id and its ?action= query value, so existing deep links // (showAccountSettings, showApiIntegrationSettings, showModelSettings, // showStorageAnalysis) continue to resolve to the right section. export const SETTINGS_ACTION_BY_SECTION: Record = { account: 'showAccountSettings', apiIntegration: 'showApiIntegrationSettings', models: 'showModelSettings', storageAnalysis: 'showStorageAnalysis', }; export const SETTINGS_SECTION_BY_ACTION: Record = Object.fromEntries( Object.entries(SETTINGS_ACTION_BY_SECTION).map(([section, action]) => [ action, section as SettingsSection, ]), ); interface SettingsDialogProps { open: boolean; onOpenChange: (open: boolean) => void; section: SettingsSection; onSectionChange: (section: SettingsSection) => void; } export default function SettingsDialog({ open, onOpenChange, section, onSectionChange, }: SettingsDialogProps) { const { t } = useTranslation(); // A nested modal (e.g. the provider form) can request that we ignore // outer-close until it is dismissed. const [blocking, setBlocking] = useState(false); // Only the Models panel can raise a blocking nested modal. When we navigate // away from it (or close the dialog) the panel unmounts without resetting, // so clear the flag here to avoid getting stuck unable to close. useEffect(() => { if (section !== 'models' || !open) { setBlocking(false); } }, [section, open]); const navItems: { id: SettingsSection; label: string; title: string; description: string; icon: React.ReactNode; }[] = [ { id: 'models', label: t('settingsDialog.nav.models'), title: t('models.title'), description: t('models.description'), icon: , }, { id: 'apiIntegration', label: t('settingsDialog.nav.api'), title: t('common.apiIntegration'), description: t('common.apiIntegrationDescription'), icon: , }, { id: 'storageAnalysis', label: t('settingsDialog.nav.storage'), title: t('storageAnalysis.title'), description: t('storageAnalysis.description'), icon: , }, { id: 'account', label: t('settingsDialog.nav.account'), title: t('account.settings'), description: t('account.settingsDescription'), icon: , }, ]; const activeItem = navItems.find((item) => item.id === section); const activeLabel = activeItem?.title ?? t('settingsDialog.title'); return ( { if (!newOpen && blocking) return; onOpenChange(newOpen); }} > {t('settingsDialog.title')} {activeLabel} {/* Override the SidebarProvider wrapper's default h-svh so the two columns fill the dialog's fixed height instead of the viewport. */}
{t('settingsDialog.title')}
{navItems.map((item) => ( onSectionChange(item.id)} > {item.icon} {item.label} ))}
{/* Mobile section switcher (sidebar is hidden on small screens) */}
{navItems.map((item) => ( ))}
{/* Unified section header (shared across all tabs). The extra right padding keeps the title clear of the dialog's close X. */}

{activeItem?.icon} {activeItem?.title}

{activeItem?.description && (

{activeItem.description}

)}
{section === 'models' && ( )} {section === 'apiIntegration' && ( )} {section === 'storageAnalysis' && ( )} {section === 'account' && ( )}
); }