import { useEffect, useMemo, useState } from 'react' import { Button } from '@/components/ui/button' import { toast } from '@/components/ui/use-toast' import { getClientBehaviorSettings, setClientBehaviorSettings } from '@/lib/settings' import { cn } from '@/lib/utils' import type { FC, ReactNode } from 'react' import type { ClientAnimationMode, ClientBehaviorSettings, ClientEmbedAutoLoadMode, ClientLinkPreloadMode, ClientTagRelationDisplayMode } from '@/lib/settings' type Props = { sectionClassName: string onDirtyStateChange?: ( dirty: boolean, discard: () => void, ) => void } type SegmentedOption = { value: T label: string } type SegmentedControlProps = { value: T options: SegmentedOption[] onChange: (value: T) => void } type SettingBlockProps = { title: string description?: string children: ReactNode } const animationOptions: SegmentedOption[] = [ { value: 'off', label: 'なし' }, { value: 'reduced', label: '控えめ' }, { value: 'normal', label: '通常' }] const embedAutoLoadOptions: SegmentedOption[] = [ { value: 'off', label: '読み込まない' }, { value: 'manual', label: 'クリック時' }, { value: 'auto', label: '自動' }] const linkPreloadOptions: SegmentedOption[] = [ { value: 'off', label: 'しない' }, { value: 'intent', label: 'する' }] const tagRelationDisplayOptions: SegmentedOption[] = [ { value: 'flat', label: 'まとめない' }, { value: 'grouped', label: 'まとめる' }] const SegmentedControl = ( { value, options, onChange }: SegmentedControlProps, ) => { return (
{options.map (option => ( ))}
) } const SettingBlock: FC = ( { title, description, children }, ) => (

{title}

{description}

{children}
) const BehaviourSettingsSection: FC = ( { sectionClassName, onDirtyStateChange }, ) => { const [savedSettings, setSavedSettings] = useState (() => getClientBehaviorSettings ()) const [draftSettings, setDraftSettings] = useState (() => getClientBehaviorSettings ()) useEffect (() => { const current = getClientBehaviorSettings () setSavedSettings (current) setDraftSettings (current) }, []) const hasUnsavedChanges = useMemo ( () => JSON.stringify (draftSettings) !== JSON.stringify (savedSettings), [draftSettings, savedSettings]) const updateDraft = ( key: Key, value: ClientBehaviorSettings[Key], ) => { setDraftSettings (current => ({ ...current, [key]: value })) } const handleSave = () => { const next = setClientBehaviorSettings (draftSettings) setSavedSettings (next) setDraftSettings (next) toast ({ title: '動作設定を保存しました' }) } const handleDiscard = () => { setDraftSettings (savedSettings) } useEffect (() => { onDirtyStateChange?.(hasUnsavedChanges, handleDiscard) return () => { onDirtyStateChange?.(false, () => { }) } }, [handleDiscard, hasUnsavedChanges, onDirtyStateChange]) return (

動作

updateDraft ('animation', value)}/> updateDraft ('linkPreload', value)}/> updateDraft ('tagRelationDisplay', value)}/> updateDraft ('embedAutoLoad', value)}/>
) } export default BehaviourSettingsSection