feat(settings): unified settings modal with context switcher (Phase 1)

New unified settings modal accessible via `,` keyboard shortcut.
Three-context switcher: Site (with site dropdown), Workspace, Account.
Horizontal tabs per context with animated transitions.

Phase 1 tabs implemented:
- Site → General (name, timezone, domain, tracking script with copy)
- Site → Goals (CRUD with inline create/edit)
- Workspace → General (org name, slug, danger zone)
- Workspace → Billing (plan card, usage, cancel/resume, portal)
- Account → Profile (wraps existing ProfileSettings)

Phase 2 tabs show "Coming soon" placeholder:
- Site: Visibility, Privacy, Bot & Spam, Reports, Integrations
- Workspace: Members, Notifications, Audit Log
- Account: Security, Devices

Old settings pages and profile modal remain functional.
This commit is contained in:
Usman Baig
2026-03-23 20:57:20 +01:00
parent 345f4ff4e1
commit 3c17895d64
9 changed files with 1034 additions and 4 deletions

View File

@@ -16,7 +16,9 @@ import { setSessionAction } from '@/app/actions/auth'
import { LoadingOverlay } from '@ciphera-net/ui'
import { useRouter } from 'next/navigation'
import { SettingsModalProvider, useSettingsModal } from '@/lib/settings-modal-context'
import { UnifiedSettingsProvider } from '@/lib/unified-settings-context'
import SettingsModalWrapper from '@/components/settings/SettingsModalWrapper'
import UnifiedSettingsModal from '@/components/settings/unified/UnifiedSettingsModal'
const ORG_SWITCH_KEY = 'pulse_switching_org'
@@ -109,6 +111,7 @@ function LayoutInner({ children }: { children: React.ReactNode }) {
{showOfflineBar && <OfflineBanner isOnline={isOnline} />}
{children}
<SettingsModalWrapper />
<UnifiedSettingsModal />
</>
)
}
@@ -141,6 +144,7 @@ function LayoutInner({ children }: { children: React.ReactNode }) {
{children}
</main>
<SettingsModalWrapper />
<UnifiedSettingsModal />
</div>
)
}
@@ -165,7 +169,9 @@ function LayoutInner({ children }: { children: React.ReactNode }) {
export default function LayoutContent({ children }: { children: React.ReactNode }) {
return (
<SettingsModalProvider>
<LayoutInner>{children}</LayoutInner>
<UnifiedSettingsProvider>
<LayoutInner>{children}</LayoutInner>
</UnifiedSettingsProvider>
</SettingsModalProvider>
)
}