'use client'; import { zodResolver } from '@hookform/resolvers/zod'; import { Badge } from '@workspace/ui/components/badge'; import { Button } from '@workspace/ui/components/button'; import { Card, CardContent } from '@workspace/ui/components/card'; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from '@workspace/ui/components/form'; import { ScrollArea } from '@workspace/ui/components/scroll-area'; import { Sheet, SheetContent, SheetFooter, SheetHeader, SheetTitle, } from '@workspace/ui/components/sheet'; import { Textarea } from '@workspace/ui/components/textarea'; import { Icon } from '@workspace/ui/custom-components/icon'; import { useTranslations } from 'next-intl'; import Image from 'next/image'; import { useState } from 'react'; import { useForm } from 'react-hook-form'; import { z } from 'zod'; interface Client { name: string; platforms: string[]; } const clientFormSchema = z.object({ template: z.string().optional(), }); const clientsConfig = [ { name: 'Hiddify', platforms: ['Windows', 'macOS', 'Linux', 'iOS', 'Android'], }, { name: 'SingBox', platforms: ['Windows', 'macOS', 'Linux', 'iOS', 'Android'], }, { name: 'Clash', platforms: ['Windows', 'macOS', 'Linux', 'Android'], }, { name: 'V2rayN', platforms: ['Windows', 'macOS', 'Linux'], }, { name: 'Stash', platforms: ['macOS', 'iOS'], }, { name: 'Surge', platforms: ['macOS', 'iOS'], }, { name: 'V2Box', platforms: ['macOS', 'iOS'], }, { name: 'Shadowrocket', platforms: ['iOS'], }, { name: 'Quantumult', platforms: ['iOS'], }, { name: 'Loon', platforms: ['iOS'], }, { name: 'Egern', platforms: ['iOS'], }, { name: 'V2rayNG', platforms: ['Android'], }, { name: 'Surfboard', platforms: ['Android'], }, { name: 'Netch', platforms: ['Windows'], }, ]; type ClientFormData = z.infer; export function ProtocolForm() { const t = useTranslations('subscribe'); const [selectedClient, setSelectedClient] = useState(null); const [open, setOpen] = useState(false); const [loading, setLoading] = useState(false); const form = useForm({ resolver: zodResolver(clientFormSchema), defaultValues: { template: '', }, }); const clients: Client[] = clientsConfig; const handleClientClick = (client: Client) => { setSelectedClient(client); // 请求当前客户端的配置模板 // 这里可以替换为实际的API调用 // 模拟获取模板数据 const mockTemplate = `# ${client.name} 配置模板`; form.reset({ template: mockTemplate, }); setOpen(true); }; const onSubmit = async (data: ClientFormData) => { setLoading(true); try { // TODO: 实现保存逻辑 console.log('Save client template:', { name: selectedClient?.name, template: data.template, }); // 模拟API调用 await new Promise((resolve) => setTimeout(resolve, 1000)); setOpen(false); } catch (error) { console.error('Failed to save client template:', error); } finally { setLoading(false); } }; return (
{clients.map((client) => ( handleClientClick(client)} >
{client.name} { console.log(`Failed to load image for ${client.name}`); }} />

{client.name}

{client.platforms.map((platform) => ( {platform} ))}

{t(`protocol.clients.${client.name.toLowerCase().replace(/\s+/g, '')}.features`)}

))}
{t('protocol.subscribeTemplate')} - {selectedClient?.name}
( {t('protocol.templateContent')}