|
import * as RadixDialog from '@radix-ui/react-dialog'; |
|
import { motion } from 'framer-motion'; |
|
import { useState, type ReactElement } from 'react'; |
|
import { classNames } from '~/utils/classNames'; |
|
import { DialogTitle, dialogVariants, dialogBackdropVariants } from '~/components/ui/Dialog'; |
|
import { IconButton } from '~/components/ui/IconButton'; |
|
import styles from './Settings.module.scss'; |
|
import ProvidersTab from './providers/ProvidersTab'; |
|
import { useSettings } from '~/lib/hooks/useSettings'; |
|
import FeaturesTab from './features/FeaturesTab'; |
|
import DebugTab from './debug/DebugTab'; |
|
import EventLogsTab from './event-logs/EventLogsTab'; |
|
import ConnectionsTab from './connections/ConnectionsTab'; |
|
import DataTab from './data/DataTab'; |
|
|
|
interface SettingsProps { |
|
open: boolean; |
|
onClose: () => void; |
|
} |
|
|
|
type TabType = 'data' | 'providers' | 'features' | 'debug' | 'event-logs' | 'connection'; |
|
|
|
export const SettingsWindow = ({ open, onClose }: SettingsProps) => { |
|
const { debug, eventLogs } = useSettings(); |
|
const [activeTab, setActiveTab] = useState<TabType>('data'); |
|
|
|
const tabs: { id: TabType; label: string; icon: string; component?: ReactElement }[] = [ |
|
{ id: 'data', label: 'Data', icon: 'i-ph:database', component: <DataTab /> }, |
|
{ id: 'providers', label: 'Providers', icon: 'i-ph:key', component: <ProvidersTab /> }, |
|
{ id: 'connection', label: 'Connection', icon: 'i-ph:link', component: <ConnectionsTab /> }, |
|
{ id: 'features', label: 'Features', icon: 'i-ph:star', component: <FeaturesTab /> }, |
|
...(debug |
|
? [ |
|
{ |
|
id: 'debug' as TabType, |
|
label: 'Debug Tab', |
|
icon: 'i-ph:bug', |
|
component: <DebugTab />, |
|
}, |
|
] |
|
: []), |
|
...(eventLogs |
|
? [ |
|
{ |
|
id: 'event-logs' as TabType, |
|
label: 'Event Logs', |
|
icon: 'i-ph:list-bullets', |
|
component: <EventLogsTab />, |
|
}, |
|
] |
|
: []), |
|
]; |
|
|
|
return ( |
|
<RadixDialog.Root open={open}> |
|
<RadixDialog.Portal> |
|
<RadixDialog.Overlay asChild onClick={onClose}> |
|
<motion.div |
|
className="bg-black/50 fixed inset-0 z-max backdrop-blur-sm" |
|
initial="closed" |
|
animate="open" |
|
exit="closed" |
|
variants={dialogBackdropVariants} |
|
/> |
|
</RadixDialog.Overlay> |
|
<RadixDialog.Content aria-describedby={undefined} asChild> |
|
<motion.div |
|
className="fixed top-[50%] left-[50%] z-max h-[85vh] w-[90vw] max-w-[900px] translate-x-[-50%] translate-y-[-50%] border border-bolt-elements-borderColor rounded-lg shadow-lg focus:outline-none overflow-hidden" |
|
initial="closed" |
|
animate="open" |
|
exit="closed" |
|
variants={dialogVariants} |
|
> |
|
<div className="flex h-full"> |
|
<div |
|
className={classNames( |
|
'w-48 border-r border-bolt-elements-borderColor bg-bolt-elements-background-depth-1 p-4 flex flex-col justify-between', |
|
styles['settings-tabs'], |
|
)} |
|
> |
|
<DialogTitle className="flex-shrink-0 text-lg font-semibold text-bolt-elements-textPrimary mb-2"> |
|
Settings |
|
</DialogTitle> |
|
{tabs.map((tab) => ( |
|
<button |
|
key={tab.id} |
|
onClick={() => setActiveTab(tab.id)} |
|
className={classNames(activeTab === tab.id ? styles.active : '')} |
|
> |
|
<div className={tab.icon} /> |
|
{tab.label} |
|
</button> |
|
))} |
|
<div className="mt-auto flex flex-col gap-2"> |
|
<a |
|
href="https://github.com/stackblitz-labs/bolt.diy" |
|
target="_blank" |
|
rel="noopener noreferrer" |
|
className={classNames(styles['settings-button'], 'flex items-center gap-2')} |
|
> |
|
<div className="i-ph:github-logo" /> |
|
GitHub |
|
</a> |
|
<a |
|
href="https://stackblitz-labs.github.io/bolt.diy/" |
|
target="_blank" |
|
rel="noopener noreferrer" |
|
className={classNames(styles['settings-button'], 'flex items-center gap-2')} |
|
> |
|
<div className="i-ph:book" /> |
|
Docs |
|
</a> |
|
</div> |
|
</div> |
|
|
|
<div className="flex-1 flex flex-col p-8 pt-10 bg-bolt-elements-background-depth-2"> |
|
<div className="flex-1 overflow-y-auto">{tabs.find((tab) => tab.id === activeTab)?.component}</div> |
|
</div> |
|
</div> |
|
<RadixDialog.Close asChild onClick={onClose}> |
|
<IconButton icon="i-ph:x" className="absolute top-[10px] right-[10px]" /> |
|
</RadixDialog.Close> |
|
</motion.div> |
|
</RadixDialog.Content> |
|
</RadixDialog.Portal> |
|
</RadixDialog.Root> |
|
); |
|
}; |
|
|