vesselInfoForm.tsx
Wed May 29 2024 08:39:38 GMT+0000 (Coordinated Universal Time)
Saved by @rafal_rydz
import {
ButtonContent,
DestructiveButton,
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
Icon,
Input,
Toaster,
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "ui";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import * as z from "zod";
import React, { useState } from "react";
import { toast } from "sonner";
import wretch from "wretch";
import { useGetVesselFromIMO } from "@/hooks";
const formSchema = z.object({
imo: z.string().max(7),
cargo_type: z.string().optional(),
cargo_sub_type: z.string().optional(),
mmsi: z.string().max(9).optional(),
vessel_name: z.string().optional(),
year_of_build: z.string().optional(),
flag: z.string().optional(),
grt: z.string().optional(),
dwt: z.string().optional(),
overall_length: z.string().optional(),
beam: z.string().optional(),
});
const fieldsNameHelper = {
imo: {
name: "IMO",
description: "International Maritime Organization identifier",
},
cargo_type: {
name: "Cargo Type",
description: "The type of cargo the vessel carries",
},
cargo_sub_type: {
name: "Cargo Sub Type",
description: "The subtype of cargo the vessel carries",
},
mmsi: { name: "MMSI", description: "Maritime Mobile Service Identity" },
vessel_name: { name: "Vessel Name", description: "The name of the vessel" },
year_of_build: {
name: "Year of Build",
description: "The year the vessel was built",
},
flag: { name: "Flag", description: "The flag country code" },
grt: { name: "GRT", description: "Gross Registered Tonnage" },
dwt: { name: "DWT", description: "Dead Weight Tonnage" },
overall_length: {
name: "Overall Length",
description: "The overall length of the vessel",
},
beam: { name: "Beam", description: "The beam of the vessel" },
};
export function VesselInfoForm() {
const [imoChecked, setImoChecked] = useState(false);
const [updateError, setUpdateError] = useState(null);
const form = useForm({
resolver: zodResolver(formSchema),
defaultValues: {},
});
const imoValue = form.watch("imo");
const {
data: vesselData,
isError,
isLoading,
} = useGetVesselFromIMO(imoValue);
async function onSubmit(values) {
setUpdateError(null);
try {
if (!imoChecked) {
setImoChecked(true);
if (vesselData?.length) {
toast.error("Vessel already exists");
}
} else {
const response = await wretch("/api/form/insertVessel")
.post(values)
.res();
if (response.ok) {
toast.success("Success!", {
description: "Vessel details added.",
});
form.reset();
setImoChecked(false);
} else {
throw new Error("Error submitting form");
}
}
} catch (error) {
setUpdateError(error);
}
}
return (
<div className={"mt-4"}>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
<FormField
control={form.control}
name="imo"
render={({ field }) => (
<FormItem className={"flex flex-row items-center"}>
<FormLabel className={"w-64 text-lg font-light"}>
{fieldsNameHelper.imo.name}
</FormLabel>
<div className={"mr-2"}>
<TooltipProvider>
<Tooltip>
<TooltipTrigger className="text-black hover:text-black/50 dark:text-white dark:hover:text-white/50">
<Icon name="unknown" style="h-5 w-5" />
</TooltipTrigger>
<TooltipContent>
<p>{fieldsNameHelper.imo.description}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
<FormControl className={"w-full"}>
<Input
{...field}
className={"text-md font-light"}
type="text"
value={field.value ?? ""}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
{imoChecked && vesselData && vesselData.length > 0 ? (
<div className="vessel-info">
<h2 className="text-lg font-semibold">Vessel Information</h2>
<ul>
{Object.keys(fieldsNameHelper).map(
(key) =>
vesselData[0][key] && (
<li key={key}>
<strong>{fieldsNameHelper[key].name}:</strong>{" "}
{vesselData[0][key]}
</li>
),
)}
</ul>
</div>
) : null}
{imoChecked &&
(!vesselData || vesselData.length === 0) &&
Object.keys(formSchema.shape).map(
(key, index) =>
key !== "imo" && (
<FormField
key={key + index}
control={form.control}
name={key}
render={({ field }) => (
<FormItem className={"flex flex-row items-center"}>
<FormLabel className={"w-64 text-lg font-light"}>
{fieldsNameHelper[key].name}
</FormLabel>
<div className={"mr-2"}>
<TooltipProvider>
<Tooltip>
<TooltipTrigger className="text-black hover:text-black/50 dark:text-white dark:hover:text-white/50">
<Icon name="unknown" style="h-5 w-5" />
</TooltipTrigger>
<TooltipContent>
<p>{fieldsNameHelper[key].description}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
<FormControl className={"w-full"}>
<Input
{...field}
className={"text-md font-light"}
type="text"
value={field.value ?? ""}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
),
)}
<div className="flex flex-row justify-end">
<DestructiveButton type="submit" className="mt-4">
<ButtonContent>
{imoChecked ? "Add Vessel" : "Check IMO"}
</ButtonContent>
</DestructiveButton>
</div>
<Toaster />
</form>
</Form>
</div>
);
}



Comments