import { Link } from '@tanstack/react-router' import { route } from '@/constants/routes' import { useTranslation } from '@/i18n/react-i18next-compat' import { useState, useEffect } from 'react' import { IconChevronDown, IconChevronRight, IconMenu2, IconX, } from '@tabler/icons-react' import { useMatches, useNavigate } from '@tanstack/react-router' import { cn } from '@/lib/utils' import { useModelProvider } from '@/hooks/useModelProvider' import { getProviderTitle } from '@/lib/utils' import ProvidersAvatar from '@/containers/ProvidersAvatar' import { PlatformFeatures } from '@/lib/platform/const' import { PlatformFeature } from '@/lib/platform/types' const SettingsMenu = () => { const { t } = useTranslation() const [expandedProviders, setExpandedProviders] = useState(false) const [isMenuOpen, setIsMenuOpen] = useState(false) const matches = useMatches() const navigate = useNavigate() const { providers } = useModelProvider() // Filter providers that have active API keys (or are llama.cpp which doesn't need one) // On web: exclude llamacpp provider as it's not available const activeProviders = providers.filter((provider) => { if (!provider.active) return false // On web version, hide llamacpp provider if (!PlatformFeatures[PlatformFeature.LOCAL_INFERENCE] && provider.provider === 'llama.cpp') { return false } return true }) // Check if current route has a providerName parameter and expand providers submenu useEffect(() => { const hasProviderName = matches.some( (match) => match.routeId === '/settings/providers/$providerName' && 'providerName' in match.params ) const isProvidersRoute = matches.some( (match) => match.routeId === '/settings/providers/' ) if (hasProviderName || isProvidersRoute) { setExpandedProviders(true) } }, [matches]) // Check if we're in the setup remote provider step const stepSetupRemoteProvider = matches.some( (match) => match.search && typeof match.search === 'object' && 'step' in match.search && match.search.step === 'setup_remote_provider' ) const menuSettings = [ { title: 'common:general', route: route.settings.general, hasSubMenu: false, isEnabled: true, }, { title: 'common:appearance', route: route.settings.appearance, hasSubMenu: false, isEnabled: true, }, { title: 'common:privacy', route: route.settings.privacy, hasSubMenu: false, isEnabled: PlatformFeatures[PlatformFeature.ANALYTICS], }, { title: 'common:modelProviders', route: route.settings.model_providers, hasSubMenu: activeProviders.length > 0, isEnabled: PlatformFeatures[PlatformFeature.MODEL_PROVIDER_SETTINGS], }, { title: 'common:keyboardShortcuts', route: route.settings.shortcuts, hasSubMenu: false, isEnabled: true, }, { title: 'common:hardware', route: route.settings.hardware, hasSubMenu: false, isEnabled: PlatformFeatures[PlatformFeature.HARDWARE_MONITORING], }, { title: 'common:mcp-servers', route: route.settings.mcp_servers, hasSubMenu: false, isEnabled: PlatformFeatures[PlatformFeature.MCP_SERVERS_SETTINGS], }, { title: 'common:local_api_server', route: route.settings.local_api_server, hasSubMenu: false, isEnabled: PlatformFeatures[PlatformFeature.LOCAL_API_SERVER], }, { title: 'common:https_proxy', route: route.settings.https_proxy, hasSubMenu: false, isEnabled: PlatformFeatures[PlatformFeature.HTTPS_PROXY], }, { title: 'common:extensions', route: route.settings.extensions, hasSubMenu: false, isEnabled: PlatformFeatures[PlatformFeature.EXTENSIONS_SETTINGS], }, ] const toggleProvidersExpansion = () => { setExpandedProviders(!expandedProviders) } const toggleMenu = () => { setIsMenuOpen(!isMenuOpen) } return ( <>