// NOTE: the frontend server provides a proxy to the backend on the /api route
// see: next.config.js if you need to change this
import { useForm, SubmitHandler, Controller } from "react-hook-form";
import { NumericFormat } from "react-number-format";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
const formSchema = z.object({
amount: z.string(),
department: z.string(),
managerApprovalRequired: z.boolean(),
});
type Inputs = z.infer<typeof formSchema>;
export default function Home() {
const { register, handleSubmit, control, watch } = useForm<Inputs>({
resolver: zodResolver(formSchema),
});
const onSubmit = async (invoiceData: Inputs) => {
const response = await fetch("/api/invoice", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(invoiceData),
});
const data = await response.json();
alert(data.result);
};
console.log(watch("amount")); // watch input value by passing the name of it
return (
<main className="flex min-h-screen w-full p-24">
<form onSubmit={handleSubmit(onSubmit)} className="mx-auto">
{/* Tailwind UI CSS Form Stacked */}
<div className="space-y-12">
<div className="border-b border-gray-900/10 pb-12 text-gray-900">
<h2 className="font-semibold">Invoice</h2>
<div className="mt-10 flex flex-col mt-10 gap-x-6 gap-y-8">
<div>
<label
htmlFor="amount"
className="block text-sm font-medium leading-6"
>
Amount (USD)
</label>
<div className="mt-2">
<Controller
name="amount"
control={control}
render={({ field: { ref, ...rest } }) => (
<NumericFormat
className="block w-full rounded-md border-0 p-1.5 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
thousandSeparator=","
decimalSeparator="."
prefix="$ "
decimalScale={2}
getInputRef={ref}
{...rest}
/>
)}
/>
</div>
</div>
<div>
<fieldset>
<legend className="block text-sm font-medium leading-6">
Requires Approval
</legend>
<div className="mt-6 flex gap-x-3">
<input
// className="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600"
className="h-6"
id="requiresManagerApproval"
{...register("managerApprovalRequired")}
type="checkbox"
/>
<div className="text-sm leading-6">
<label
htmlFor="managerApprovalRequired"
className="font-medium text-gray-900"
>
Manager
</label>
<p className="text-gray-500">
This invoice requires approval by the Manager.
</p>
</div>
</div>
</fieldset>
</div>
<div>
<label
htmlFor="department"
className="block text-sm font-medium leading-6"
>
Department
</label>
<div className="mt-2">
<select
className="block w-full rounded-md border-0 py-1.5 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:max-w-xs sm:text-sm sm:leading-6"
id="department"
autoComplete="department"
{...register("department", { required: true })}
>
<option value="marketing">Marketing</option>
<option value="finance">Finance</option>
{/* TODO: Use a dynamic list of departments from the backend */}
</select>
</div>
<div className="text-sm text-gray-500 mt-2">
Select Marketing if the invoice is related to marketing
purchases.
</div>
</div>
</div>
</div>
</div>
<button
type="submit"
className="rounded-md mt-6 w-full bg-indigo-600 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
>
Submit
</button>
</form>
</main>
);
}