Preview:
@ -0,0 +1,159 @@
import {
  ButtonContent,
  DestructiveButton,
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
  Icon,
  If,
  Input,
  Toaster,
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from "ui";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import type * as z from "zod";
import React, { useEffect, useState } from "react";
import { toast } from "sonner";
import wretch from "wretch";
import {
  fieldsNameHelper,
  formSchema,
  numberFields,
  toTitleCase,
} from "./regularVesselInfoForm";

interface AddRegularVesselFormProps {
  fields: string[];
  vesselId?: string;
  imo?: string;
  returnIdentifier: (identifier: any) => void;
}

export const AddRegularVesselForm = ({
  fields,
  vesselId,
  imo,
  returnIdentifier,
}: AddRegularVesselFormProps) => {
  const excludeFields: string[] = ["id"];
  const disabledFields: string[] = ["vessel_id", "imo"];

  const [identifier, setIdentifier] = useState<string>(vesselId || imo || "");

  fields = fields?.sort().filter((item) => !excludeFields.includes(item));

  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      vessel_id: vesselId,
      imo: imo,
    },
  });

  async function onSubmit(values: z.infer<typeof formSchema>) {
    const addVessel: VesselInfo = Object.entries(values).reduce(
      (acc: VesselInfo, [key, value]) => {
        const vesselInfoKey: string = fieldsNameHelper[key].name;
        acc[vesselInfoKey] = (value || "").toString().toLowerCase();
        return acc;
      },
      {},
    );

    try {
      const response = await wretch("/api/form/regularVessel")
        .post(addVessel)
        .res();

      if (response.ok) {
        toast.success("Success!", {
          description: "Vessel details inserted.",
        });
        returnIdentifier({ vessel_id: values.vessel_id, imo: values.imo });
      } else {
        toast.error("Error submitting form");
      }
    } catch (error) {
      toast.error("Something went wrong", {
        description: (error as PostgrestError | null)?.message,
      });
    }
  }

  const reset = form.reset;

  useEffect(() => {
    reset({}, { keepValues: false });

    reset(
      {
        vessel_id: vesselId,
        imo: imo,
      },
      { keepValues: false },
    );
  }, [reset]);

  return (
    <div className={"mt-4"}>
      <Form {...form}>
        <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
          {Object.keys(formSchema.shape).map((key, index) => (
            <>
              <If condition={fields?.includes(fieldsNameHelper[key].name)}>
                <FormField
                  key={key + index}
                  control={form.control}
                  name={key as any}
                  render={({ field }) => (
                    <FormItem className={"flex flex-row items-center"}>
                      <FormLabel className={"w-64 text-lg font-light"}>
                        {toTitleCase(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
                          className={"text-md font-light"}
                          required={false}
                          {...field}
                          type={numberFields.includes(key) ? "number" : "text"}
                          value={field.value ?? ""}
                          disabled={disabledFields.includes(key)}
                        />
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />
              </If>
            </>
          ))}
          <div className="flex flex-row justify-end">
            <DestructiveButton type="submit" className="mt-4">
              <ButtonContent>Add vessel</ButtonContent>
            </DestructiveButton>
          </div>
          <Toaster />
        </form>
      </Form>
    </div>
  );
};
downloadDownload PNG downloadDownload JPEG downloadDownload SVG

Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!

Click to optimize width for Twitter