import { useMemo } from 'react'; import { useNavigate, useParams } from 'react-router'; import { Puzzle, KeyRound, Globe, Wrench, CalendarDays } from 'lucide-react'; import type { LayoutNode, PanelComponents } from 'officerdev'; import { WorkspaceLayout } from 'officerdev'; import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { SettingsRoute, SettingsSidebar, SettingsContent, type SettingsSection } from '../SettingsPanel'; import { GoogleOAuthConfig } from './GoogleOAuthConfig'; // import { GoogleAccount } from './GoogleAccount'; // hidden — email uses IMAP app password now import { ApifyConfig } from './ApifyConfig'; import { useTranslation } from '@/lib/i18n'; const BASE_PATH = '/settings/integrations'; const enterpriseSections: SettingsSection[] = [ { key: 'google-oauth', icon: KeyRound, titleKey: 'settings.sections.googleOauth.label', descriptionKey: 'settings.sections.googleOauth.description', content: , }, { key: 'apify', icon: Wrench, titleKey: 'settings.sections.apify.label', descriptionKey: 'settings.sections.apify.description', content: , }, ]; const personalSections: SettingsSection[] = [ // Email account management left with the feature on 2026-08-18 (`plugins/email/`). A plugin contributes // panels, not settings sections, so it now lives inside the email workspace itself. // Google OAuth is left in place (code + DB) but hidden — email now uses an app password over IMAP, // so there's no reason to reconnect Google here. Re-enable this section to bring it back. // { // key: 'google-account', // icon: UserCircle, // title: 'Google Account', // descriptionKey: 'settings.sections.apify.description', // content: , // }, // DAV app passwords left with the caldav plugin on 2026-08-27. A plugin cannot contribute a settings // section — it ships panels — so the form is a modal on the Calendar screen, the same answer the email // plugin reached for account management when it was extracted. ]; // The Enterprise/Personal tab is not a second thing to remember — it is a fact about which section is // open, so it is derived from the URL rather than kept in its own global. That also fixes the deep link: // with the tab held separately, `/settings/integrations/apify` would have arrived with the tab // still on Enterprise and the content pane showing "Select a section". const allSections = [...enterpriseSections, ...personalSections]; const tabForSection = (section: string | undefined) => personalSections.some((s) => s.key === section) ? 'personal' : 'enterprise'; const IntegrationsSidebar = () => { const { t } = useTranslation(); const { section } = useParams<{ section?: string }>(); const navigate = useNavigate(); const tab = tabForSection(section); const sections = tab === 'enterprise' ? enterpriseSections : personalSections; // Switching tab is a navigation, so it lands on that tab's first section rather than leaving the // content pane showing a section the sidebar no longer lists. const setTab = (next: string) => { const first = (next === 'enterprise' ? enterpriseSections : personalSections)[0]; if (first) navigate(`${BASE_PATH}/${first.key}`); }; return (
{t('settings.nav.integrations')}
{t('settings.integrations.enterprise')} {t('settings.integrations.personal')}
); }; // Both tabs' sections, because the URL alone says which one is open and the pane no longer has to agree // with the sidebar about the tab to find it. const IntegrationsContent = () => ; const layout: LayoutNode = { type: 'group', id: 'integrations-root', direction: 'horizontal', children: [ { node: { type: 'panel', id: 'integrations-left', appType: null }, size: 20 }, { node: { type: 'panel', id: 'integrations-right', appType: null }, size: 80 }, ], }; export const IntegrationsSettings = () => { const panelComponents: PanelComponents = useMemo( () => ({ 'integrations-left': IntegrationsSidebar, 'integrations-right': IntegrationsContent, }), [], ); return (
{}} components={panelComponents} />
); };