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
@@ -169,6 +169,7 @@ export function EstimateExpenseItemsSection({ estimateId }: { estimateId: string
onOpenChange={setPickerOpen}
selectionMode="single"
onConfirm={handlePickerConfirm}
searchPlaceholder="Search expense items..."
crudProps={{
routeKey: EXPENSE_ITEM_ROUTES.INDEX,
getClient: (api) => api.expenseItems,
@@ -168,6 +168,7 @@ export function EstimatePartsSection({ estimateId }: { estimateId: string }) {
onOpenChange={setPickerOpen}
selectionMode="single"
onConfirm={handlePickerConfirm}
searchPlaceholder="Search parts by title, SKU, or part number..."
crudProps={{
routeKey: PARTS_ROUTES.INDEX,
getClient: (api) => api.parts,
@@ -181,6 +181,7 @@ export function EstimateServicesSection({ estimateId }: { estimateId: string })
onOpenChange={setPickerOpen}
selectionMode="single"
onConfirm={handlePickerConfirm}
searchPlaceholder="Search services..."
crudProps={{
routeKey: SERVICE_ROUTES.INDEX,
getClient: (api) => api.services,
@@ -2,8 +2,9 @@
import { Card, CardContent } from "@/shared/components/ui/card"
import { Separator } from "@/shared/components/ui/separator"
import { formatCurrency, formatEnum } from "@/shared/utils/formatters"
import { formatEnum } from "@/shared/utils/formatters"
import { useEstimate } from "./estimate-context"
import { Money } from "@/shared/components/money"
export function EstimateTotalsSummary() {
const estimate = useEstimate()
@@ -39,19 +40,19 @@ export function EstimateTotalsSummary() {
{parts.length > 0 && (
<div className="flex justify-between text-sm">
<span className="text-muted-foreground">Parts ({parts.length})</span>
<span>{formatCurrency(lineTotal(parts))}</span>
<span>{<Money value={lineTotal(parts)} />}</span>
</div>
)}
{services.length > 0 && (
<div className="flex justify-between text-sm">
<span className="text-muted-foreground">Services ({services.length})</span>
<span>{formatCurrency(lineTotal(services))}</span>
<span>{<Money value={lineTotal(services)} />}</span>
</div>
)}
{expenses.length > 0 && (
<div className="flex justify-between text-sm">
<span className="text-muted-foreground">Expenses ({expenses.length})</span>
<span>{formatCurrency(lineTotal(expenses))}</span>
<span>{<Money value={lineTotal(expenses)} />}</span>
</div>
)}
<Separator />
@@ -60,7 +61,7 @@ export function EstimateTotalsSummary() {
<div className="flex justify-between text-sm font-medium">
<span>Subtotal</span>
<span>{formatCurrency(subTotal)}</span>
<span>{<Money value={subTotal} />}</span>
</div>
{discount && discount !== "no" && (
@@ -74,7 +75,7 @@ export function EstimateTotalsSummary() {
<div className="flex justify-between text-base font-semibold">
<span>Total</span>
<span>{formatCurrency(displayTotal)}</span>
<span>{<Money value={displayTotal} />}</span>
</div>
</div>
</CardContent>