"use client"; import { Invoice, InvoiceSchema } from "@/models/invoice"; import { zodResolver } from "@hookform/resolvers/zod"; import { useFieldArray, useForm, useWatch, SubmitHandler, } from "react-hook-form"; import { Input } from "./ui/input"; import { cn } from "@/utils/cn"; import { Button } from "./ui/button"; import { generateInvoice } from "@/lib/generate"; const defaultItem = { description: "", quantity: 1, rate: 0, }; const defaultValues: Invoice = { invoice_number: 0, from: "", line_items: [defaultItem], currency: "USD", }; export const InvoiceGenerator = () => { const { register, handleSubmit, control, watch, formState: { errors }, } = useForm({ resolver: zodResolver(InvoiceSchema), defaultValues, }); const { fields, append, remove } = useFieldArray({ control, name: "line_items", }); const lineItems = useWatch({ control, name: "line_items" }); const currency = watch("currency", "USD"); const onSubmit: SubmitHandler = async (data) => { console.log(data); const blob = await generateInvoice(data); const a = document.createElement("a"); a.href = URL.createObjectURL(blob); a.download = "invoice.pdf"; document.body.appendChild(a); a.click(); document.body.removeChild(a); a.remove(); }; return (
{errors["from"] && (

{errors["from"].message ?? "Error"}

)}

Your Items

Item

Quantity

Rate

Amount

{fields.map((f, ind) => (

{( (lineItems[ind]?.rate ?? 0) * (lineItems[ind]?.quantity ?? 0) ).toLocaleString(undefined, { style: "currency", currency })}

))}
Subtotal:{" "} {lineItems .reduce( (acc, cur) => acc + (cur.rate ?? 0) * (cur.quantity ?? 0), 0, ) .toLocaleString(undefined, { style: "currency", currency })}
); };