feat: add template checkpoint edit dialog and vendor management components
- Implemented TemplateCheckpointEditDialog for creating and editing inspection checkpoints. - Added VendorActions component for managing vendor actions including edit, activate/deactivate, and delete. - Created VendorContext for managing vendor state across components. - Developed VendorGeneralInfo component to display detailed vendor information. - Introduced AedSymbol and Money components for consistent currency representation. - Added PromptDialog for user input prompts throughout the application. - Implemented RelationLink component for unified related-data display in CRUD tables. - Created InspectionTemplatesClient for API interactions related to inspection templates.
This commit is contained in:
@@ -37,6 +37,14 @@ export default function JobCardDropdown({ id }: { id: string }) {
|
||||
router.push(`/sales/job-cards/${id}/appointments?create=1`)
|
||||
}
|
||||
|
||||
const existingInvoice = (jobCard as any)?.invoices?.[0] as { id: number | string; invoice_number?: string | null } | undefined
|
||||
|
||||
const handleOpenExistingInvoice = () => {
|
||||
if (existingInvoice?.id != null) {
|
||||
router.push(`/sales/invoice/${existingInvoice.id}`)
|
||||
}
|
||||
}
|
||||
|
||||
const handleConvertToInvoice = async () => {
|
||||
const confirmed = await confirm({
|
||||
title: "Convert to Invoice",
|
||||
@@ -95,10 +103,17 @@ export default function JobCardDropdown({ id }: { id: string }) {
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
{jobCard?.status !== "draft" && (
|
||||
<Button variant="outline" onClick={handleConvertToInvoice} disabled={isConverting}>
|
||||
{isConverting ? <Loader2 className="size-4 animate-spin" /> : <FileText className="size-4" />}
|
||||
{isConverting ? "Converting..." : "Convert to Invoice"}
|
||||
</Button>
|
||||
existingInvoice ? (
|
||||
<Button variant="outline" onClick={handleOpenExistingInvoice}>
|
||||
<FileText className="size-4" />
|
||||
{existingInvoice.invoice_number ? `Invoice #${existingInvoice.invoice_number}` : "View Invoice"}
|
||||
</Button>
|
||||
) : (
|
||||
<Button variant="outline" onClick={handleConvertToInvoice} disabled={isConverting}>
|
||||
{isConverting ? <Loader2 className="size-4 animate-spin" /> : <FileText className="size-4" />}
|
||||
{isConverting ? "Converting..." : "Convert to Invoice"}
|
||||
</Button>
|
||||
)
|
||||
)}
|
||||
|
||||
<Button variant="outline" onClick={handleCreateAppointment}>
|
||||
@@ -133,10 +148,17 @@ export default function JobCardDropdown({ id }: { id: string }) {
|
||||
Create Appointment
|
||||
</DropdownMenuItem>
|
||||
{jobCard?.status !== "draft" && (
|
||||
<DropdownMenuItem onClick={handleConvertToInvoice} disabled={isConverting}>
|
||||
<FileText className="size-4" />
|
||||
{isConverting ? "Converting..." : "Convert to Invoice"}
|
||||
</DropdownMenuItem>
|
||||
existingInvoice ? (
|
||||
<DropdownMenuItem onClick={handleOpenExistingInvoice}>
|
||||
<FileText className="size-4" />
|
||||
{existingInvoice.invoice_number ? `Invoice #${existingInvoice.invoice_number}` : "View Invoice"}
|
||||
</DropdownMenuItem>
|
||||
) : (
|
||||
<DropdownMenuItem onClick={handleConvertToInvoice} disabled={isConverting}>
|
||||
<FileText className="size-4" />
|
||||
{isConverting ? "Converting..." : "Convert to Invoice"}
|
||||
</DropdownMenuItem>
|
||||
)
|
||||
)}
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem variant="destructive" onClick={handleDelete}>
|
||||
|
||||
@@ -16,8 +16,9 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/shared/components/ui
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/shared/components/ui/collapsible"
|
||||
import { Button } from "@/shared/components/ui/button"
|
||||
import { useJobCard } from "./job-card-context"
|
||||
import { formatDate, formatCurrency } from "@/shared/utils/formatters"
|
||||
import { formatDate } from "@/shared/utils/formatters"
|
||||
import { useState } from "react"
|
||||
import { Money } from "@/shared/components/money"
|
||||
|
||||
export default function JobCardPaymentsReceived() {
|
||||
const jobCard = useJobCard()
|
||||
@@ -88,7 +89,7 @@ export default function JobCardPaymentsReceived() {
|
||||
<div className="flex items-center gap-2">
|
||||
<BadgeDollarSignIcon className="h-4 w-4 text-emerald-600" />
|
||||
<span className="font-semibold text-emerald-700 dark:text-emerald-400">
|
||||
{formatCurrency(item.amount_received)}
|
||||
{<Money value={item.amount_received} />}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user