import * as z from 'zod' import type { Resolver } from 'react-hook-form' import { zodResolver } from '@hookform/resolvers/zod' import { RotateCcw } from 'lucide-react' import { useTranslation } from 'react-i18next' import { Button } from '@/components/ui/button' import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from '@/components/ui/form' import { Input } from '@/components/ui/input' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { Textarea } from '@/components/ui/textarea' import { FormDirtyIndicator } from '../components/form-dirty-indicator' import { FormNavigationGuard } from '../components/form-navigation-guard' import { SettingsSection } from '../components/settings-section' import { useSettingsForm } from '../hooks/use-settings-form' import { useUpdateOption } from '../hooks/use-update-option' const _systemInfoSchema = z.object({ theme: z.object({ frontend: z.enum(['default', 'classic']), }), Notice: z.string().optional(), SystemName: z.string().min(1), ServerAddress: z.string().optional(), Logo: z.string().url().optional().or(z.literal('')), Footer: z.string().optional(), About: z.string().optional(), HomePageContent: z.string().optional(), legal: z.object({ user_agreement: z.string().optional(), privacy_policy: z.string().optional(), }), }) type SystemInfoFormValues = z.infer type SystemInfoSectionProps = { defaultValues: SystemInfoFormValues } function normalizeValue(value: unknown): string { if (value === undefined || value === null) return '' return typeof value === 'string' ? value : String(value) } export function SystemInfoSection({ defaultValues }: SystemInfoSectionProps) { const { t } = useTranslation() const updateOption = useUpdateOption() const normalizedDefaults: SystemInfoFormValues = { theme: { frontend: defaultValues.theme?.frontend === 'classic' ? 'classic' : 'default', }, Notice: normalizeValue(defaultValues.Notice), SystemName: normalizeValue(defaultValues.SystemName), ServerAddress: normalizeValue(defaultValues.ServerAddress), Logo: normalizeValue(defaultValues.Logo), Footer: normalizeValue(defaultValues.Footer), About: normalizeValue(defaultValues.About), HomePageContent: normalizeValue(defaultValues.HomePageContent), legal: { user_agreement: normalizeValue(defaultValues.legal?.user_agreement), privacy_policy: normalizeValue(defaultValues.legal?.privacy_policy), }, } const systemInfoSchemaWithI18n = z.object({ theme: z.object({ frontend: z.enum(['default', 'classic']), }), Notice: z.string().optional(), SystemName: z.string().min(1, { error: () => t('System name is required'), }), ServerAddress: z.string().optional(), Logo: z.string().url().optional().or(z.literal('')), Footer: z.string().optional(), About: z.string().optional(), HomePageContent: z.string().optional(), legal: z.object({ user_agreement: z.string().optional(), privacy_policy: z.string().optional(), }), }) const { form, handleSubmit, handleReset, isDirty, isSubmitting } = useSettingsForm({ resolver: zodResolver(systemInfoSchemaWithI18n) as Resolver< SystemInfoFormValues, unknown, SystemInfoFormValues >, defaultValues: normalizedDefaults, onSubmit: async (_data, changedFields) => { for (const [key, value] of Object.entries(changedFields)) { let v = normalizeValue(value) if (key === 'ServerAddress') { v = v.replace(/\/+$/, '') } await updateOption.mutateAsync({ key, value: v, }) } }, }) return ( <>
( {t('Frontend Theme')} {t( 'Switch between the new frontend and the classic frontend. Changes take effect after page reload.' )} )} /> ( {t('Notice')}