"use client"; import { useRouter } from "next/navigation"; import { useEffect } from "react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { createMyMeshInputSchema, type CreateMyMeshInput, } from "@turbostarter/api/schema"; import { handle } from "@turbostarter/api/utils"; import { Button } from "@turbostarter/ui-web/button"; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "@turbostarter/ui-web/form"; import { Input } from "@turbostarter/ui-web/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@turbostarter/ui-web/select"; import { pathsConfig } from "~/config/paths"; import { api } from "~/lib/api/client"; const slugify = (s: string) => s .toLowerCase() .trim() .replace(/[^a-z0-9]+/g, "-") .replace(/^-+|-+$/g, "") .slice(0, 40); export const CreateMeshForm = () => { const router = useRouter(); const form = useForm({ resolver: zodResolver(createMyMeshInputSchema), defaultValues: { name: "", slug: "", visibility: "private", transport: "managed", }, }); const nameValue = form.watch("name"); const slugDirty = form.formState.dirtyFields.slug; useEffect(() => { if (!slugDirty && nameValue) { form.setValue("slug", slugify(nameValue)); } }, [nameValue, slugDirty, form]); const onSubmit = async (values: CreateMyMeshInput) => { try { const res = (await handle(api.my.meshes.$post)({ json: values, })) as { id: string; slug: string } | { error: string }; if ("error" in res) { form.setError("slug", { message: res.error }); return; } router.push(pathsConfig.dashboard.user.meshes.mesh(res.id)); } catch (e) { form.setError("root", { message: e instanceof Error ? e.message : "Failed to create mesh.", }); } }; return (
( Name Display name — what teammates see. )} /> ( Slug URL-safe identifier: lowercase letters, digits, hyphens. )} /> ( Visibility )} /> ( Transport How peers reach the broker. )} /> {form.formState.errors.root && (

{form.formState.errors.root.message}

)} ); };