garage-erp/apps/dashboard/modules/estimates/create-invoice-from-estimate-button.tsx
2026-04-15 04:59:05 +03:00

71 lines
2.3 KiB
TypeScript

"use client"
import { useState } from "react"
import { FileText } from "lucide-react"
import { Button } from "@/shared/components/ui/button"
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from "@/shared/components/ui/dialog"
import { ScrollArea } from "@/shared/components/ui/scroll-area"
import { InvoiceForm } from "@/modules/invoices/invoice-form"
import { toRelation } from "@/shared/lib/utils"
import { useEstimate } from "./estimate-context"
/**
* Maps an Estimate data object to an InvoiceFormValues shape so that
* useResourceForm's shallow spread correctly pre-fills all relational fields.
*/
function mapEstimateToInvoiceInitialData(estimate: Record<string, any>) {
return {
subject: estimate.title ?? "",
notes: estimate.footer ?? "",
// Relation fields — must be { value, label } objects for RhfAsyncSelectField
customer: toRelation(estimate.customer_id, estimate.customer_name),
vehicle: toRelation(estimate.vehicle_id, estimate.vehicle_name),
department: toRelation(estimate.department_id, estimate.department_name),
invoice_number: "",
invoice_date: estimate.date ?? "",
due_date: "",
status: "draft" as const,
}
}
export function CreateInvoiceFromEstimateButton() {
const [open, setOpen] = useState(false)
const estimateContext = useEstimate()
if (!estimateContext) return null
const initialData = estimateContext.data
? mapEstimateToInvoiceInitialData(estimateContext.data)
: undefined
return (
<>
<Button variant="outline" size="sm" onClick={() => setOpen(true)}>
<FileText className="me-2 size-4" />
Generate Invoice
</Button>
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent className="min-w-2xl">
<DialogHeader>
<DialogTitle>Generate Invoice from Estimate</DialogTitle>
</DialogHeader>
<ScrollArea className="max-h-[75vh] px-1">
<InvoiceForm
initialData={initialData}
onSuccess={() => setOpen(false)}
/>
</ScrollArea>
</DialogContent>
</Dialog>
</>
)
}