import { Button } from "@minmon/ui/components/button"; import { StatusBadge } from "@minmon/ui/components/status-badge"; import { useForm } from "@tanstack/react-form"; import { useMutation, useQuery } from "@tanstack/react-query"; import { createFileRoute, Link, useNavigate } from "@tanstack/react-router"; import { useEffect } from "react"; import { toast } from "sonner"; import { DetailCard, FormCard, PageSection, QueryStateCard, ResourceListCard, SelectField, TextAreaField, TextField } from "@/components/dashboard-ui"; import { queryClient, trpc, trpcClient } from "@/utils/trpc"; export const Route = createFileRoute("/dashboard/servers_/$serverId")({ component: RouteComponent, }); type ServerFormValues = { name: string; primaryIpAddress: string; secondaryIpAddress: string; operatingSystem: string; location: string; provider: string; description: string; status: "active" | "maintenance" | "inactive"; }; const serverStatusOptions = [ { value: "active", label: "Active" }, { value: "maintenance", label: "Maintenance" }, { value: "inactive", label: "Inactive" }, ] as const; function RouteComponent() { const { serverId } = Route.useParams(); const navigate = useNavigate(); const server = useQuery(trpc.servers.byId.queryOptions({ id: serverId })); const notes = useQuery(trpc.notes.list.queryOptions({ serverId })); const updateServer = useMutation({ mutationFn: async (values: ServerFormValues) => trpcClient.servers.update.mutate({ id: serverId, ...values, secondaryIpAddress: values.secondaryIpAddress || null, operatingSystem: values.operatingSystem || null, location: values.location || null, provider: values.provider || null, description: values.description || null, }), onSuccess: async () => { toast.success("Server updated"); await queryClient.invalidateQueries(); }, onError: (error) => toast.error(error.message), }); const defaultValues: ServerFormValues = { name: "", primaryIpAddress: "", secondaryIpAddress: "", operatingSystem: "", location: "", provider: "", description: "", status: "active", }; const form = useForm({ defaultValues, onSubmit: async ({ value }) => { await updateServer.mutateAsync(value); }, }); useEffect(() => { if (!server.data) { return; } form.reset({ name: server.data.name, primaryIpAddress: server.data.primaryIpAddress, secondaryIpAddress: server.data.secondaryIpAddress ?? "", operatingSystem: server.data.operatingSystem ?? "", location: server.data.location ?? "", provider: server.data.provider ?? "", description: server.data.description ?? "", status: server.data.status, }); }, [server.data, form]); if (server.isLoading) { return ; } if (server.isError || !server.data) { return ; } return (
{server.data.status} }, { label: "Primary IP", value: server.data.primaryIpAddress }, { label: "Secondary IP", value: server.data.secondaryIpAddress || "-" }, { label: "Operating system", value: server.data.operatingSystem || "-" }, { label: "Location", value: server.data.location || "-" }, { label: "Provider", value: server.data.provider || "-" }, { label: "Services", value: String(server.data.summary.services) }, { label: "Notes", value: String(server.data.summary.notes) }, ]} /> {notes.isLoading ? ( ) : notes.isError || !notes.data ? ( ) : ( } > (
{item.title} {item.content}
), }, { key: "category", header: "Category", render: (item: (typeof notes.data)[number]) => item.category || "-", }, { key: "updatedAt", header: "Updated", render: (item: (typeof notes.data)[number]) => new Date(item.updatedAt).toLocaleString(), }, ]} items={notes.data} emptyTitle="No notes for this server" emptyDescription="Add a note to document maintenance, incidents, or internal server context." />
)}
{ e.preventDefault(); e.stopPropagation(); form.handleSubmit(); }} > ({ isSubmitting: state.isSubmitting })}> {({ isSubmitting }) => } } >
{(field) => field.handleChange(e.target.value)} />} {(field) => field.handleChange(e.target.value)} />} {(field) => field.handleChange(e.target.value)} />} {(field) => field.handleChange(e.target.value)} />} {(field) => field.handleChange(e.target.value)} />} {(field) => field.handleChange(e.target.value)} />} {(field) => field.handleChange(value as ServerFormValues["status"])} placeholder="Select server status" options={[...serverStatusOptions]} />}
{(field) => field.handleChange(e.target.value)} />}
); }