garage-erp/apps/dashboard/modules/estimates/create-job-card-from-estimate-button.tsx
humam kerdiah fcbba6247d feat: add document sharing functionality across various modules
- Introduced ShareDocumentButton component for sharing documents.
- Added ShareDocumentDialog for email and WhatsApp sharing options.
- Integrated document sharing in estimates, invoices, inspections, job cards, bills, and purchase orders.
- Implemented useDocumentShare hook for handling share logic.
- Created DocumentShareClient for API interactions related to document sharing.
- Updated layouts and actions to include sharing options for relevant entities.
2026-05-14 12:21:01 +04:00

67 lines
2.5 KiB
TypeScript

"use client"
import { useState } from "react"
import { ClipboardList, Loader2 } 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)
const promise = api.estimates.convertToJobCard(estimateId, {})
toast.promise(promise, {
loading: "Generating job card...",
success: "Estimate converted to job card successfully",
error: (error: unknown) =>
error instanceof ApiError && error.status === 409
? "A job card already exists for this estimate."
: "Failed to convert estimate to job card",
})
try {
const response = await promise
const jobCardId = response?.data?.id
if (jobCardId) {
router.push(`/sales/job-cards/${jobCardId}`)
return
}
} catch (error) {
if (error instanceof ApiError && error.status === 409) {
const jobCardId = (error.payload?.data as { job_card_id?: number } | undefined)?.job_card_id
if (jobCardId) {
router.push(`/sales/job-cards/${jobCardId}`)
return
}
}
}
setIsConverting(false)
}
return (
<Button variant="outline" size="sm" onClick={handleConvert} disabled={isConverting}>
{isConverting ? <Loader2 className="me-2 size-4 animate-spin" /> : <ClipboardList className="me-2 size-4" />}
{isConverting ? "Generating..." : "Generate Job Card"}
</Button>
)
}