'use client'; import { getSubscribeType } from '@/services/admin/system'; import { zodResolver } from '@hookform/resolvers/zod'; import { Icon } from '@iconify/react'; import { useQuery } from '@tanstack/react-query'; import { Button } from '@workspace/ui/components/button'; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from '@workspace/ui/components/form'; import { ScrollArea } from '@workspace/ui/components/scroll-area'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@workspace/ui/components/select'; import { Sheet, SheetContent, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, } from '@workspace/ui/components/sheet'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@workspace/ui/components/tabs'; import { ArrayInput } from '@workspace/ui/custom-components/dynamic-Inputs'; import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input'; import { UploadImage } from '@workspace/ui/custom-components/upload-image'; import { useTranslations } from 'next-intl'; import { assign, shake } from 'radash'; import { useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; import { z } from 'zod'; const platforms = ['windows', 'macos', 'linux', 'android', 'ios', 'harmony']; const defaultValues = { subscribe_type: 'Clash', name: '', icon: '', url: '', }; const versionSchema = z.object({ url: z.string(), version: z.string().optional(), description: z.string().optional(), is_default: z.boolean().optional(), }); const formSchema = z.object({ icon: z.string(), name: z.string(), subscribe_type: z.string(), platform: z.object({ windows: z.array(versionSchema).optional(), macos: z.array(versionSchema).optional(), linux: z.array(versionSchema).optional(), android: z.array(versionSchema).optional(), ios: z.array(versionSchema).optional(), harmony: z.array(versionSchema).optional(), }), }); interface FormProps { trigger: React.ReactNode | string; title: string; initialValues?: Partial; onSubmit: (values: T) => Promise; loading?: boolean; } export default function SubscribeAppForm< T extends API.CreateApplicationRequest | API.UpdateApplicationRequest, >({ trigger, title, loading, initialValues, onSubmit }: FormProps) { const t = useTranslations('product.app'); const [open, setOpen] = useState(false); type FormSchema = z.infer; const form = useForm({ resolver: zodResolver(formSchema), defaultValues: assign( defaultValues, shake(initialValues, (value) => value === null), ), }); useEffect(() => { form.reset( assign( defaultValues, shake(initialValues, (value) => value === null), ), ); }, [form, initialValues]); const { data: subscribe_types } = useQuery({ queryKey: ['getSubscribeType'], queryFn: async () => { const { data } = await getSubscribeType(); return data.data?.subscribe_types || []; }, }); return ( {typeof trigger === 'string' ? : trigger} {title}
( {t('appIcon')} { form.setValue(field.name, value as string); }} /> } value={field.value} onValueChange={(value) => { form.setValue(field.name, value as string); }} /> )} /> ( {t('appName')} { form.setValue(field.name, value as string); }} /> )} /> ( {t('subscriptionProtocol')} )} />
{t('platform')} {platforms.map((platform) => ( {platform} ))} {platforms.map((platform) => ( ( { const filteredValue = value.filter((item) => item.url); const newDefaultIndex = value.findIndex( (item, idx) => item.is_default && (!field.value?.[idx] || !field.value[idx].is_default), ); let finalValue = filteredValue; if (newDefaultIndex >= 0 && filteredValue[newDefaultIndex]) { finalValue = filteredValue.map((item, index) => ({ ...item, is_default: index === newDefaultIndex, })); } else if ( !filteredValue.some((item) => item.is_default) && filteredValue.length > 0 ) { finalValue = filteredValue.map((item, index) => ({ ...item, is_default: index === 0, })); } form.setValue(field.name, finalValue as any); }} /> )} /> ))}
); }