"use client" import { createContext, useCallback, useContext, useMemo, useState, type ReactNode, } from "react" import { useQueryState } from "nuqs" import { Dialog, DialogClose, DialogContent, DialogTitle, } from "@ui/components/dialog" import { X } from "lucide-react" import { cn } from "@lib/utils" import { dmSansClassName, dmSans125ClassName } from "@/lib/fonts" import { analytics } from "@/lib/analytics" import { SettingsContent, TABS, type SettingsTab, } from "@/components/settings/settings-content" const SETTINGS_PARAM = "settings" /** Integrations is a link-out, not a modal tab, so it falls back to account. */ function parseTab(value: string | null): SettingsTab { if ( value && value !== "integrations" && TABS.includes(value as SettingsTab) ) { return value as SettingsTab } return "account" } type SettingsModalContextValue = { open: boolean openSettings: (tab?: SettingsTab) => void close: () => void } const SettingsModalContext = createContext( null, ) export function SettingsModalProvider({ children }: { children: ReactNode }) { const [param, setParam] = useQueryState(SETTINGS_PARAM) const [settingsDialogContent, setSettingsDialogContent] = useState(null) const open = param !== null const tab = parseTab(param) const openSettings = useCallback( (next?: SettingsTab) => { setParam(next ?? "account") }, [setParam], ) const close = useCallback(() => setParam(null), [setParam]) const handleTabChange = useCallback( (next: SettingsTab) => { setParam(next) analytics.settingsTabChanged({ tab: next }) }, [setParam], ) const value = useMemo( () => ({ open, openSettings, close }), [open, openSettings, close], ) return ( {children} { if (!next) setParam(null) }} >
Settings Close
) } export function useSettingsModal() { const ctx = useContext(SettingsModalContext) if (!ctx) { throw new Error( "useSettingsModal must be used within a SettingsModalProvider", ) } return ctx }