garage-erp/apps/dashboard/modules/estimates/create-job-card-from-estimate-button.tsx
2026-04-24 12:28:30 +03:00

64 lines
2.2 KiB
TypeScript

"use client"
import { useState } from "react"
import { ClipboardList } from "lucide-react"
import { useRouter } from "next/navigation"
import { ApiError } from "@garage/api"
import { Button } from "@/shared/components/ui/button"
import { confirm } from "@/shared/components/confirm-dialog"
import { toast } from "sonner"
import { useAuthApi } from "@/shared/useApi"
import { useEstimate } from "./estimate-context"
export function CreateJobCardFromEstimateButton() {
const [isConverting, setIsConverting] = useState(false)
const estimateContext = useEstimate()
const api = useAuthApi()
const router = useRouter()
const estimateId = String(estimateContext?.id ?? "")
if (!estimateContext || !estimateId) return null
const handleConvert = async () => {
const confirmed = await confirm({
title: "Generate Job Card",
description: "This will create a job card from this estimate. Do you want to continue?",
confirmLabel: "Generate",
})
if (!confirmed) return
setIsConverting(true)
try {
const response = await api.estimates.convertToJobCard(estimateId, {})
const jobCardId = response?.data?.id
toast.success("Estimate converted to job card successfully")
if (jobCardId) {
router.push(`/sales/job-cards/${jobCardId}`)
}
} catch (error) {
if (error instanceof ApiError && error.status === 409) {
const jobCardId = (error.payload?.data as { job_card_id?: number } | undefined)?.job_card_id
toast.info("A job card already exists for this estimate.")
if (jobCardId) {
router.push(`/sales/job-cards/${jobCardId}`)
return
}
}
toast.error("Failed to convert estimate to job card")
} finally {
setIsConverting(false)
}
}
return (
<Button variant="outline" size="sm" onClick={handleConvert} disabled={isConverting}>
<ClipboardList className="me-2 size-4" />
{isConverting ? "Generating..." : "Generate Job Card"}
</Button>
)
}