Skip to main content
Glama
ad-form.tsx6.43 kB
import { zodResolver } from "@hookform/resolvers/zod"; import { CreateAds, zCreateAdsSchema } from "@repo/db/types"; import { Button } from "@repo/ui/components/ui/button"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from "@repo/ui/components/ui/form"; import { Input } from "@repo/ui/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@repo/ui/components/ui/select"; import { Textarea } from "@repo/ui/components/ui/textarea"; import { useEffect } from "react"; import { useForm } from "react-hook-form"; import { FormFileUpload } from "@/components/file-uploader"; interface AdFormProps { initialData?: CreateAds; onSubmit: (data: CreateAds) => Promise<void>; isLoading?: boolean; } export function AdForm({ initialData, onSubmit, isLoading }: AdFormProps) { const form = useForm<CreateAds>({ resolver: zodResolver(zCreateAdsSchema), defaultValues: { title: "", description: "", type: "banner", startDate: new Date(), endDate: new Date(), price: 0, budget: 0, ...initialData, }, }); useEffect(() => { if (initialData) { Object.entries(initialData).forEach(([key, value]) => { form.setValue(key as keyof CreateAds, value); }); } }, [initialData, form]); const handleImageUpload = (assetIds: string[]) => { if (assetIds.length > 0) { form.setValue("imageUrl", assetIds[0]); } }; return ( <Form {...form}> <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6"> <div className="grid gap-6 md:grid-cols-2"> <div className="space-y-4"> <FormField control={form.control} name="title" render={({ field }) => ( <FormItem> <FormLabel>广告名称</FormLabel> <FormControl> <Input {...field} /> </FormControl> <FormMessage /> </FormItem> )} /> <FormField control={form.control} name="type" render={({ field }) => ( <FormItem> <FormLabel>广告类型</FormLabel> <Select value={field.value} onValueChange={field.onChange}> <FormControl> <SelectTrigger> <SelectValue /> </SelectTrigger> </FormControl> <SelectContent> <SelectItem value="banner">横幅广告</SelectItem> <SelectItem value="listing">列表广告</SelectItem> </SelectContent> </Select> <FormMessage /> </FormItem> )} /> <FormField control={form.control} name="startDate" render={({ field }) => ( <FormItem> <FormLabel>开始日期</FormLabel> <FormControl> <Input type="date" value={field.value ? new Date(field.value).toISOString().split("T")[0] : ""} onChange={(e) => field.onChange(new Date(e.target.value))} /> </FormControl> <FormMessage /> </FormItem> )} /> <FormField control={form.control} name="endDate" render={({ field }) => ( <FormItem> <FormLabel>结束日期</FormLabel> <FormControl> <Input type="date" value={field.value ? new Date(field.value).toISOString().split("T")[0] : ""} onChange={(e) => field.onChange(new Date(e.target.value))} /> </FormControl> <FormMessage /> </FormItem> )} /> </div> <div className="space-y-4"> <FormField control={form.control} name="price" render={({ field }) => ( <FormItem> <FormLabel>单价 (¥)</FormLabel> <FormControl> <Input type="number" {...field} onChange={(e) => field.onChange(Number(e.target.value))} /> </FormControl> <FormMessage /> </FormItem> )} /> <FormField control={form.control} name="budget" render={({ field }) => ( <FormItem> <FormLabel>预算 (¥)</FormLabel> <FormControl> <Input type="number" {...field} onChange={(e) => field.onChange(Number(e.target.value))} /> </FormControl> <FormMessage /> </FormItem> )} /> <FormField control={form.control} name="imageUrl" render={({ field }) => ( <FormItem> <FormLabel>广告图片 {field.value}</FormLabel> <FormControl> <FormFileUpload label="上传广告图片" description="支持 PNG、JPG、WebP 格式,建议尺寸 1200x628" assetType="ad" onUploadComplete={handleImageUpload} initialPreviews={field.value ? [{ assetId: field.value }] : []} /> </FormControl> <FormMessage /> </FormItem> )} /> </div> </div> <FormField control={form.control} name="description" render={({ field }) => ( <FormItem> <FormLabel>广告描述</FormLabel> <FormControl> <Textarea {...field} rows={4} /> </FormControl> <FormMessage /> </FormItem> )} /> <div className="flex justify-end gap-4"> <Button type="submit" disabled={isLoading}> {isLoading ? "保存中..." : "保存"} </Button> </div> </form> </Form> ); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/metacode0602/open-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server