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:
2026-05-18 12:08:42 +04:00
parent 54d11f01b4
commit 4bfd8c84a9
111 changed files with 5002 additions and 1047 deletions
@@ -32,8 +32,11 @@ import {
} from "@/shared/components/ui/dialog"
import { confirm } from "@/shared/components/confirm-dialog"
import { useAuthApi } from "@/shared/useApi"
import { getFullName } from "@/shared/utils/getFullName"
import { PAYMENT_MADE_ROUTES } from "@garage/api"
import type { PaymentMadesClient } from "@garage/api"
import { RelationLink } from "@/shared/components/relation-link"
import { Building2 } from "lucide-react"
// ── Attachment helpers ──
@@ -208,10 +211,13 @@ function AttachmentsDialog({
type PaymentMadeItem = {
id: number
payment_number?: string
vendor?: { id?: number | string; company_name?: string | null; first_name?: string | null; last_name?: string | null; name?: string | null } | null
vendor_name?: string
employee?: { id?: number | string; first_name?: string | null; last_name?: string | null; name?: string | null } | null
employee_name?: string
payment_for?: string
payment_made?: string | number
payment_mode?: { name?: string | null; title?: string | null } | null
payment_mode_name?: string
payment_date?: string
paid_through?: string
@@ -230,14 +236,20 @@ export default function PaymentsMadePage() {
<ResourcePage<PaymentMadesClient>
pageTitle="Payments Made"
routeKey={PAYMENT_MADE_ROUTES.INDEX}
searchable
searchPlaceholder="Search payments..."
getClient={(api) => api.paymentMades}
headerProps={({ invalidateQuery }) => ({
headerProps={({ selectedItem, invalidateQuery }) => ({
actions: (
<FormDialog title="Record Payment">
{(resourceId) => (
{(resourceId, { close }) => (
<PaymentMadeForm
resourceId={resourceId}
onSuccess={invalidateQuery}
initialData={selectedItem}
onSuccess={() => {
invalidateQuery()
close()
}}
/>
)}
</FormDialog>
@@ -262,11 +274,27 @@ export default function PaymentsMadePage() {
header: ({ column }) => <ColumnHeader column={column} title="Vendor" />,
cell: ({ row }) => {
const item = row.original as unknown as PaymentMadeItem
const isVendor =
item.vendor?.company_name ||
getFullName(item.vendor) ||
item.vendor?.name ||
item.vendor_name
const label =
isVendor ||
getFullName(item.employee) ||
item.employee?.name ||
item.employee_name
const href = isVendor && item.vendor?.id
? `/purchase/vendor/${item.vendor.id}`
: item.employee?.id
? `/productivity/employees/${item.employee.id}`
: null
return (
<div className="flex items-center gap-2">
<UserIcon className="h-4 w-4 text-muted-foreground" />
<span>{item.vendor_name || "—"}</span>
</div>
<RelationLink
href={href}
icon={isVendor ? Building2 : UserIcon}
label={label}
/>
)
},
},
@@ -309,10 +337,15 @@ export default function PaymentsMadePage() {
header: ({ column }) => <ColumnHeader column={column} title="Payment Mode" />,
cell: ({ row }) => {
const item = row.original as unknown as PaymentMadeItem
const label =
item.payment_mode?.name ||
item.payment_mode?.title ||
item.payment_mode_name ||
"—"
return (
<div className="flex items-center gap-2">
<CreditCardIcon className="h-4 w-4 text-muted-foreground" />
<span className="capitalize">{item.payment_mode_name || "—"}</span>
<span className="capitalize">{label}</span>
</div>
)
},