import type { ComponentType, ReactNode } from 'react'; import { useState } from 'react'; import type { LucideIcon } from 'lucide-react'; import { useGlobal } from 'hooks/useGlobal'; import { Input } from '@/components/ui/input'; export type SettingsSection = { key: string; icon: LucideIcon; title: string; description: string; content: ReactNode; }; export type SettingsSectionGroup = { label: string; icon: LucideIcon; sections: SettingsSection[]; }; type SettingsSidebarProps = { globalKey: string; icon: LucideIcon; label: string; sections: SettingsSection[]; groups?: SettingsSectionGroup[]; hideHeader?: boolean; }; const SectionButton = ({ section, isActive, onClick, }: { section: SettingsSection; isActive: boolean; onClick: () => void; }) => ( {section.title} {section.description} ); export const SettingsSidebar = ({ globalKey, icon: Icon, label, sections, groups, hideHeader }: SettingsSidebarProps) => { const allSections = groups ? groups.flatMap((g) => g.sections) : sections; const [selectedKey, setSelectedKey] = useGlobal(globalKey, allSections[0]?.key ?? null); const [search, setSearch] = useState(''); const query = search.toLowerCase(); const matchesSearch = (s: SettingsSection) => s.title.toLowerCase().includes(query) || s.description.toLowerCase().includes(query); return ( {!hideHeader && ( {label} )} setSearch(ev.target.value)} className="h-8 text-xs" /> {groups ? groups.map((group) => { const filtered = group.sections.filter(matchesSearch); if (filtered.length === 0) return null; return ( {group.label} {filtered.map((s) => ( setSelectedKey(s.key)} /> ))} ); }) : sections.filter(matchesSearch).map((s) => ( setSelectedKey(s.key)} /> ))} ); }; type SettingsContentProps = { globalKey: string; sections: SettingsSection[]; }; export const SettingsContent = ({ globalKey, sections }: SettingsContentProps) => { const [selectedKey] = useGlobal(globalKey, sections[0]?.key ?? null); const section = sections.find((s) => s.key === selectedKey); if (!section) { return ( Select a section ); } return ( {section.title} {section.description} {section.content} ); }; type CreateSettingsPanelParams = { globalKey: string; sidebarIcon: LucideIcon; sidebarLabel: string; sections?: SettingsSection[]; groups?: SettingsSectionGroup[]; }; export const createSettingsPanelComponents = ({ globalKey, sidebarIcon, sidebarLabel, sections = [], groups }: CreateSettingsPanelParams) => { const allSections = groups ? groups.flatMap((g) => g.sections) : sections; const Sidebar: ComponentType = () => ( ); const Content: ComponentType = () => ; return { Sidebar, Content }; };
Select a section
{section.description}