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

@@ -0,0 +1,44 @@
'use client'
import { createContext, useContext, useState, useCallback } from 'react'
type InitialTab = { context?: 'site' | 'workspace' | 'account'; tab?: string } | null
interface UnifiedSettingsContextType {
isOpen: boolean
openUnifiedSettings: (initialTab?: InitialTab) => void
closeUnifiedSettings: () => void
initialTab: InitialTab
}
const UnifiedSettingsContext = createContext<UnifiedSettingsContextType>({
isOpen: false,
openUnifiedSettings: () => {},
closeUnifiedSettings: () => {},
initialTab: null,
})
export function UnifiedSettingsProvider({ children }: { children: React.ReactNode }) {
const [isOpen, setIsOpen] = useState(false)
const [initialTab, setInitialTab] = useState<InitialTab>(null)
const openUnifiedSettings = useCallback((init?: InitialTab) => {
setInitialTab(init || null)
setIsOpen(true)
}, [])
const closeUnifiedSettings = useCallback(() => {
setIsOpen(false)
setInitialTab(null)
}, [])
return (
<UnifiedSettingsContext.Provider value={{ isOpen, openUnifiedSettings, closeUnifiedSettings, initialTab }}>
{children}
</UnifiedSettingsContext.Provider>
)
}
export function useUnifiedSettings() {
return useContext(UnifiedSettingsContext)
}