import { type } from "arktype"; import { Copy, Folder } from "lucide-react"; import { useState } from "react"; import { useFetcher } from "react-router"; import { toast } from "sonner"; import { createVolume, deleteVolume, listVolumes } from "~/api-client"; import { CreateVolumeDialog, formSchema } from "~/components/create-volume-dialog"; import { Button } from "~/components/ui/button"; import { Input } from "~/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "~/components/ui/select"; import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from "~/components/ui/table"; import { parseError } from "~/lib/errors"; import { cn } from "~/lib/utils"; import type { Route } from "./+types/home"; export function meta(_: Route.MetaArgs) { return [ { title: "Ironmount" }, { name: "description", content: "Create, manage, monitor, and automate your Docker volumes with ease.", }, ]; } export async function clientAction({ request }: Route.ClientActionArgs) { const formData = await request.formData(); const { _action, ...rest } = Object.fromEntries(formData.entries()); if (_action === "delete") { const name = rest.name as string; const { error } = await deleteVolume({ path: { name: name } }); if (error) { toast.error("Failed to delete volume", { description: parseError(error)?.message, }); } else { toast.success("Volume deleted successfully"); } return { error: parseError(error), _action: "delete" as const }; } if (_action === "create") { const validationResult = formSchema(rest); if (validationResult instanceof type.errors) { toast.error("Invalid form data", { description: "Please check your input and try again.", }); return { error: validationResult, _action: "create" as const }; } const validatedData = validationResult as typeof formSchema.infer; const { error } = await createVolume({ body: { name: validatedData.name, config: validatedData } }); if (error) { toast.error("Failed to create volume", { description: parseError(error)?.message, }); } else { toast.success("Volume created successfully"); } return { error: parseError(error), _action: "create" as const }; } } export async function clientLoader(_: Route.ClientLoaderArgs) { const volumes = await listVolumes(); return volumes.data; } export default function Home({ loaderData, actionData }: Route.ComponentProps) { const [open, setOpen] = useState(false); const createFetcher = useFetcher>(); const deleteFetcher = useFetcher>(); createFetcher.data; deleteFetcher.data; const isDeleting = deleteFetcher.state === "submitting"; const isCreating = createFetcher.state === "submitting"; console.log(createFetcher); const handleDeleteConfirm = (name: string) => { deleteFetcher.submit({ _action: "delete", name }, { method: "DELETE" }); }; return (

Ironmount

Create, manage, monitor, and automate your Docker volumes with ease.

createFetcher.submit({ _action: "create", ...values }, { method: "POST" })} />
A list of your managed Docker volumes. Name Backend Mountpoint Status Actions {loaderData?.volumes.map((volume) => ( {volume.name} Volume {volume.path} ))}
); }