Legacy settings removal, performance improvements, modal polish #70
@@ -1,32 +1,32 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useState, useCallback, useEffect, useRef } from 'react'
|
import { useState, useCallback, useEffect, useRef } from 'react'
|
||||||
|
import dynamic from 'next/dynamic'
|
||||||
import { AnimatePresence, motion } from 'framer-motion'
|
import { AnimatePresence, motion } from 'framer-motion'
|
||||||
import { X, GearSix, Buildings, User } from '@phosphor-icons/react'
|
import { X, GearSix, Buildings, User } from '@phosphor-icons/react'
|
||||||
import { Button } from '@ciphera-net/ui'
|
import { Button, Spinner } from '@ciphera-net/ui'
|
||||||
import { useUnifiedSettings } from '@/lib/unified-settings-context'
|
import { useUnifiedSettings } from '@/lib/unified-settings-context'
|
||||||
import { useAuth } from '@/lib/auth/context'
|
import { useAuth } from '@/lib/auth/context'
|
||||||
import { useSite } from '@/lib/swr/dashboard'
|
import { useSite } from '@/lib/swr/dashboard'
|
||||||
import { listSites, type Site } from '@/lib/api/sites'
|
import { listSites, type Site } from '@/lib/api/sites'
|
||||||
|
|
||||||
// Tab content components — Site
|
// Lazy-load tab components — only loaded when the tab is first rendered
|
||||||
import SiteGeneralTab from './tabs/SiteGeneralTab'
|
const tabLoader = () => <div className="flex items-center justify-center py-12"><Spinner className="w-6 h-6 text-neutral-500" /></div>
|
||||||
import SiteGoalsTab from './tabs/SiteGoalsTab'
|
const SiteGeneralTab = dynamic(() => import('./tabs/SiteGeneralTab'), { loading: tabLoader })
|
||||||
import SiteVisibilityTab from './tabs/SiteVisibilityTab'
|
const SiteGoalsTab = dynamic(() => import('./tabs/SiteGoalsTab'), { loading: tabLoader })
|
||||||
import SitePrivacyTab from './tabs/SitePrivacyTab'
|
const SiteVisibilityTab = dynamic(() => import('./tabs/SiteVisibilityTab'), { loading: tabLoader })
|
||||||
import SiteBotSpamTab from './tabs/SiteBotSpamTab'
|
const SitePrivacyTab = dynamic(() => import('./tabs/SitePrivacyTab'), { loading: tabLoader })
|
||||||
import SiteReportsTab from './tabs/SiteReportsTab'
|
const SiteBotSpamTab = dynamic(() => import('./tabs/SiteBotSpamTab'), { loading: tabLoader })
|
||||||
import SiteIntegrationsTab from './tabs/SiteIntegrationsTab'
|
const SiteReportsTab = dynamic(() => import('./tabs/SiteReportsTab'), { loading: tabLoader })
|
||||||
// Tab content components — Workspace
|
const SiteIntegrationsTab = dynamic(() => import('./tabs/SiteIntegrationsTab'), { loading: tabLoader })
|
||||||
import WorkspaceGeneralTab from './tabs/WorkspaceGeneralTab'
|
const WorkspaceGeneralTab = dynamic(() => import('./tabs/WorkspaceGeneralTab'), { loading: tabLoader })
|
||||||
import WorkspaceBillingTab from './tabs/WorkspaceBillingTab'
|
const WorkspaceBillingTab = dynamic(() => import('./tabs/WorkspaceBillingTab'), { loading: tabLoader })
|
||||||
import WorkspaceMembersTab from './tabs/WorkspaceMembersTab'
|
const WorkspaceMembersTab = dynamic(() => import('./tabs/WorkspaceMembersTab'), { loading: tabLoader })
|
||||||
import WorkspaceNotificationsTab from './tabs/WorkspaceNotificationsTab'
|
const WorkspaceNotificationsTab = dynamic(() => import('./tabs/WorkspaceNotificationsTab'), { loading: tabLoader })
|
||||||
import WorkspaceAuditTab from './tabs/WorkspaceAuditTab'
|
const WorkspaceAuditTab = dynamic(() => import('./tabs/WorkspaceAuditTab'), { loading: tabLoader })
|
||||||
// Tab content components — Account
|
const AccountProfileTab = dynamic(() => import('./tabs/AccountProfileTab'), { loading: tabLoader })
|
||||||
import AccountProfileTab from './tabs/AccountProfileTab'
|
const AccountSecurityTab = dynamic(() => import('./tabs/AccountSecurityTab'), { loading: tabLoader })
|
||||||
import AccountSecurityTab from './tabs/AccountSecurityTab'
|
const AccountDevicesTab = dynamic(() => import('./tabs/AccountDevicesTab'), { loading: tabLoader })
|
||||||
import AccountDevicesTab from './tabs/AccountDevicesTab'
|
|
||||||
|
|
||||||
// ─── Types ──────────────────────────────────────────────────────
|
// ─── Types ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -326,9 +326,12 @@ export default function UnifiedSettingsModal() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
listSites().then(data => {
|
// Only fetch sites if we don't have them yet
|
||||||
setSites(Array.isArray(data) ? data : [])
|
if (sites.length === 0) {
|
||||||
}).catch(() => {})
|
listSites().then(data => {
|
||||||
|
setSites(Array.isArray(data) ? data : [])
|
||||||
|
}).catch(() => {})
|
||||||
|
}
|
||||||
}, [isOpen, user?.org_id])
|
}, [isOpen, user?.org_id])
|
||||||
|
|
||||||
// Global keyboard shortcuts: `,` toggles settings, Escape closes
|
// Global keyboard shortcuts: `,` toggles settings, Escape closes
|
||||||
@@ -437,13 +440,12 @@ export default function UnifiedSettingsModal() {
|
|||||||
|
|
||||||
{/* Content */}
|
{/* Content */}
|
||||||
<div className="flex-1 overflow-y-auto overflow-x-hidden">
|
<div className="flex-1 overflow-y-auto overflow-x-hidden">
|
||||||
<AnimatePresence mode="wait">
|
<AnimatePresence initial={false}>
|
||||||
<motion.div
|
<motion.div
|
||||||
key={`${context}-${activeTab}`}
|
key={`${context}-${activeTab}`}
|
||||||
initial={{ opacity: 0 }}
|
initial={{ opacity: 0 }}
|
||||||
animate={{ opacity: 1 }}
|
animate={{ opacity: 1 }}
|
||||||
exit={{ opacity: 0 }}
|
transition={{ duration: 0.08 }}
|
||||||
transition={{ duration: 0.12 }}
|
|
||||||
className="p-6"
|
className="p-6"
|
||||||
>
|
>
|
||||||
<TabContent context={context} activeTab={activeTab} siteId={activeSiteId} onDirtyChange={handleDirtyChange} onRegisterSave={handleRegisterSave} />
|
<TabContent context={context} activeTab={activeTab} siteId={activeSiteId} onDirtyChange={handleDirtyChange} onRegisterSave={handleRegisterSave} />
|
||||||
|
|||||||
Reference in New Issue
Block a user