import { useCallback, useEffect, useState } from 'react' import { LayoutDashboard, Upload, Cloud, Settings as SettingsIcon, LogOut, Menu, X, Server, Users } from 'lucide-react' import clsx from 'clsx' import AccountManagerContainer from '../features/account/AccountManagerContainer' import ApiTesterContainer from '../features/apiTester/ApiTesterContainer' import BatchImport from '../components/BatchImport' import VercelSyncContainer from '../features/vercel/VercelSyncContainer' import SettingsContainer from '../features/settings/SettingsContainer' import LanguageToggle from '../components/LanguageToggle' import { useI18n } from '../i18n' export default function DashboardShell({ token, onLogout, config, fetchConfig, showMessage, message, onForceLogout, isVercel }) { const { t } = useI18n() const [activeTab, setActiveTab] = useState('accounts') const [sidebarOpen, setSidebarOpen] = useState(false) const navItems = [ { id: 'accounts', label: t('nav.accounts.label'), icon: Users, description: t('nav.accounts.desc') }, { id: 'test', label: t('nav.test.label'), icon: Server, description: t('nav.test.desc') }, { id: 'import', label: t('nav.import.label'), icon: Upload, description: t('nav.import.desc') }, { id: 'vercel', label: t('nav.vercel.label'), icon: Cloud, description: t('nav.vercel.desc') }, { id: 'settings', label: t('nav.settings.label'), icon: SettingsIcon, description: t('nav.settings.desc') }, ] const authFetch = useCallback(async (url, options = {}) => { const headers = { ...options.headers, 'Authorization': `Bearer ${token}` } const res = await fetch(url, { ...options, headers }) if (res.status === 401) { onLogout() throw new Error(t('auth.expired')) } return res }, [onLogout, t, token]) const [versionInfo, setVersionInfo] = useState(null) useEffect(() => { let disposed = false async function loadVersion() { try { const res = await authFetch('/admin/version') const data = await res.json() if (!disposed) { setVersionInfo(data) } } catch (_err) { if (!disposed) { setVersionInfo(null) } } } loadVersion() return () => { disposed = true } }, [authFetch]) const renderTab = () => { switch (activeTab) { case 'accounts': return case 'test': return case 'import': return case 'vercel': return case 'settings': return default: return null } } return (
{sidebarOpen && (
setSidebarOpen(false)} /> )}
DS2API

{navItems.find(n => n.id === activeTab)?.label}

{navItems.find(n => n.id === activeTab)?.description}

{message && (
{message.type === 'error' ? :
} {message.text}
)}
{renderTab()}
) }