'use client' import { useState, useCallback, useEffect } from 'react' import { AnimatePresence, motion } from 'framer-motion' import { X, GearSix, Buildings, User } from '@phosphor-icons/react' import { useUnifiedSettings } from '@/lib/unified-settings-context' import { useAuth } from '@/lib/auth/context' import { useSite } from '@/lib/swr/dashboard' import { listSites, type Site } from '@/lib/api/sites' // Tab content components — Site import SiteGeneralTab from './tabs/SiteGeneralTab' import SiteGoalsTab from './tabs/SiteGoalsTab' import SiteVisibilityTab from './tabs/SiteVisibilityTab' import SitePrivacyTab from './tabs/SitePrivacyTab' import SiteBotSpamTab from './tabs/SiteBotSpamTab' import SiteReportsTab from './tabs/SiteReportsTab' import SiteIntegrationsTab from './tabs/SiteIntegrationsTab' // Tab content components — Workspace import WorkspaceGeneralTab from './tabs/WorkspaceGeneralTab' import WorkspaceBillingTab from './tabs/WorkspaceBillingTab' import WorkspaceMembersTab from './tabs/WorkspaceMembersTab' import WorkspaceNotificationsTab from './tabs/WorkspaceNotificationsTab' import WorkspaceAuditTab from './tabs/WorkspaceAuditTab' // Tab content components — Account import AccountProfileTab from './tabs/AccountProfileTab' import AccountSecurityTab from './tabs/AccountSecurityTab' import AccountDevicesTab from './tabs/AccountDevicesTab' // ─── Types ────────────────────────────────────────────────────── type SettingsContext = 'site' | 'workspace' | 'account' interface TabDef { id: string label: string } const SITE_TABS: TabDef[] = [ { id: 'general', label: 'General' }, { id: 'goals', label: 'Goals' }, { id: 'visibility', label: 'Visibility' }, { id: 'privacy', label: 'Privacy' }, { id: 'bot-spam', label: 'Bot & Spam' }, { id: 'reports', label: 'Reports' }, { id: 'integrations', label: 'Integrations' }, ] const WORKSPACE_TABS: TabDef[] = [ { id: 'general', label: 'General' }, { id: 'members', label: 'Members' }, { id: 'billing', label: 'Billing' }, { id: 'notifications', label: 'Notifications' }, { id: 'audit', label: 'Audit Log' }, ] const ACCOUNT_TABS: TabDef[] = [ { id: 'profile', label: 'Profile' }, { id: 'security', label: 'Security' }, { id: 'devices', label: 'Devices' }, ] // ─── Context Switcher ─────────────────────────────────────────── function ContextSwitcher({ active, onChange, activeSiteDomain, }: { active: SettingsContext onChange: (ctx: SettingsContext) => void activeSiteDomain: string | null }) { return (
{/* Site button — locked to current site, no dropdown */} {activeSiteDomain && ( )}
) } // ─── Tab Bar ──────────────────────────────────────────────────── function TabBar({ tabs, activeTab, onChange, }: { tabs: TabDef[] activeTab: string onChange: (id: string) => void }) { return (
{tabs.map(tab => ( ))}
) } // ─── Tab Content ──────────────────────────────────────────────── function ComingSoon({ label }: { label: string }) { return (

{label}

This section is being migrated. For now, use the existing settings page.

) } function TabContent({ context, activeTab, siteId, }: { context: SettingsContext activeTab: string siteId: string | null }) { // Site tabs if (context === 'site' && siteId) { switch (activeTab) { case 'general': return case 'goals': return case 'visibility': return case 'privacy': return case 'bot-spam': return case 'reports': return case 'integrations': return } } // Workspace tabs if (context === 'workspace') { switch (activeTab) { case 'general': return case 'billing': return case 'members': return case 'notifications': return case 'audit': return } } // Account tabs if (context === 'account') { switch (activeTab) { case 'profile': return case 'security': return case 'devices': return } } return null } // ─── Main Modal ───────────────────────────────────────────────── export default function UnifiedSettingsModal() { const { isOpen, openUnifiedSettings, closeUnifiedSettings: closeSettings, initialTab: initTab } = useUnifiedSettings() const { user } = useAuth() const [context, setContext] = useState('site') const [siteTabs, setSiteTabs] = useState('general') const [workspaceTabs, setWorkspaceTabs] = useState('general') const [accountTabs, setAccountTabs] = useState('profile') const [sites, setSites] = useState([]) const [activeSiteId, setActiveSiteId] = useState(null) // Apply initial tab when modal opens useEffect(() => { if (isOpen && initTab) { if (initTab.context) setContext(initTab.context) if (initTab.tab) { if (initTab.context === 'site') setSiteTabs(initTab.tab) else if (initTab.context === 'workspace') setWorkspaceTabs(initTab.tab) else if (initTab.context === 'account') setAccountTabs(initTab.tab) } } }, [isOpen, initTab]) // Detect site from URL and load sites list when modal opens useEffect(() => { if (!isOpen || !user?.org_id) return // Pick up site ID from URL — this is the only site the user can configure if (typeof window !== 'undefined') { const match = window.location.pathname.match(/\/sites\/([a-f0-9-]+)/) if (match) { setActiveSiteId(match[1]) setContext('site') } else { // Not on a site page — default to organization context setActiveSiteId(null) if (!initTab?.context) setContext('workspace') } } // Load sites for domain display listSites().then(data => { setSites(Array.isArray(data) ? data : []) }).catch(() => {}) }, [isOpen, user?.org_id]) // Global keyboard shortcuts: `,` toggles settings, Escape closes useEffect(() => { const handler = (e: KeyboardEvent) => { const tag = (e.target as HTMLElement)?.tagName if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return if (e.key === ',' && !e.metaKey && !e.ctrlKey && !e.altKey) { e.preventDefault() if (isOpen) closeSettings() else openUnifiedSettings() } if (e.key === 'Escape' && isOpen) { closeSettings() } } window.addEventListener('keydown', handler) return () => window.removeEventListener('keydown', handler) }, [isOpen, openUnifiedSettings, closeSettings]) const tabs = context === 'site' ? SITE_TABS : context === 'workspace' ? WORKSPACE_TABS : ACCOUNT_TABS const activeTab = context === 'site' ? siteTabs : context === 'workspace' ? workspaceTabs : accountTabs const setActiveTab = context === 'site' ? setSiteTabs : context === 'workspace' ? setWorkspaceTabs : setAccountTabs const handleContextChange = useCallback((ctx: SettingsContext) => { setContext(ctx) }, []) return ( {isOpen && ( <> {/* Backdrop */} {/* Modal */}
e.stopPropagation()} > {/* Header */}

Settings

{/* Context Switcher */} s.id === activeSiteId)?.domain ?? null} /> {/* Tabs */}
{/* Content — parent has fixed h-[85vh] so this fills remaining space without jumping */}
)}
) }