fix: add staleTime to job card expense, parts, and services queries; update job card general info and payments received components
This commit is contained in:
@@ -5,7 +5,8 @@ import { AlertTriangle, Plus, Save } from "lucide-react"
|
||||
|
||||
import { Button } from "@/shared/components/ui/button"
|
||||
import { Alert, AlertTitle } from "@/shared/components/ui/alert"
|
||||
import { FieldGroup } from "@/shared/components/ui/field"
|
||||
import { Field, FieldGroup, FieldLabel } from "@/shared/components/ui/field"
|
||||
import { Input } from "@/shared/components/ui/input"
|
||||
import {
|
||||
Rhform,
|
||||
RhfTextField,
|
||||
@@ -36,6 +37,8 @@ export type PaymentReceivedFormProps = {
|
||||
invoiceId?: string | null
|
||||
invoiceCustomer?: { id?: number | null; first_name?: string | null; last_name?: string | null } | null
|
||||
invoiceAmount?: number | string | null
|
||||
lockJobCard?: boolean
|
||||
lockCustomer?: boolean
|
||||
}
|
||||
|
||||
// ── Default values ──
|
||||
@@ -90,27 +93,33 @@ const STORE_OBJECT = { getOptionValue: (o: any) => o, getOptionLabel: (o: any) =
|
||||
|
||||
// ── Component ──
|
||||
|
||||
export function PaymentReceivedForm({ resourceId, initialData, onSuccess, defaultJobCard, invoiceId, invoiceCustomer, invoiceAmount }: PaymentReceivedFormProps) {
|
||||
export function PaymentReceivedForm({ resourceId, initialData, onSuccess, defaultJobCard, invoiceId, invoiceCustomer, invoiceAmount, lockJobCard, lockCustomer }: PaymentReceivedFormProps) {
|
||||
const api = useAuthApi()
|
||||
|
||||
const isJobCardLocked = !resourceId && (lockJobCard ?? !!defaultJobCard?.id)
|
||||
const isCustomerLocked = !resourceId && (lockCustomer ?? !!invoiceCustomer?.id)
|
||||
|
||||
const customerLabel = invoiceCustomer?.first_name
|
||||
? `${invoiceCustomer.first_name} ${invoiceCustomer.last_name || ""}`.trim()
|
||||
: (invoiceCustomer as any)?.company_name || (invoiceCustomer as any)?.name || ""
|
||||
|
||||
const resolvedInitialData = useMemo(() => {
|
||||
const base: any = { ...(initialData as any) }
|
||||
if (!resourceId) {
|
||||
if (defaultJobCard?.id != null) {
|
||||
base.job_card = toRelation(defaultJobCard.id, defaultJobCard.title ?? undefined)
|
||||
base.job_card_id = defaultJobCard.id
|
||||
base.job_card_name = defaultJobCard.title ?? undefined
|
||||
}
|
||||
if (invoiceCustomer?.id != null) {
|
||||
const customerLabel = invoiceCustomer.first_name
|
||||
? `${invoiceCustomer.first_name} ${invoiceCustomer.last_name || ""}`.trim()
|
||||
: (invoiceCustomer as any).company_name || (invoiceCustomer as any).name || undefined
|
||||
base.customer = toRelation(invoiceCustomer.id, customerLabel)
|
||||
base.customer_id = invoiceCustomer.id
|
||||
base.customer_name = customerLabel
|
||||
}
|
||||
if (invoiceAmount != null && invoiceAmount !== "") {
|
||||
base.amount_received = Number(invoiceAmount)
|
||||
}
|
||||
}
|
||||
return Object.keys(base).length ? base : initialData
|
||||
}, [resourceId, defaultJobCard, initialData, invoiceCustomer, invoiceAmount])
|
||||
}, [resourceId, defaultJobCard, initialData, invoiceCustomer, invoiceAmount, customerLabel])
|
||||
|
||||
const { form, isEditing } = useResourceForm<PaymentReceivedFormValues, any>({
|
||||
schema: paymentReceivedFormSchema,
|
||||
@@ -153,33 +162,49 @@ export function PaymentReceivedForm({ resourceId, initialData, onSuccess, defaul
|
||||
|
||||
<FieldGroup>
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<RhfAsyncSelectField
|
||||
name="customer"
|
||||
label="Customer"
|
||||
placeholder="Select customer"
|
||||
required
|
||||
queryKey={[CUSTOMER_ROUTES.INDEX]}
|
||||
listFn={() => api.customers.list()}
|
||||
mapOption={(item: any) => ({
|
||||
value: String(item.id),
|
||||
label: item.first_name
|
||||
? `${item.first_name} ${item.last_name || ""}`.trim()
|
||||
: item.name || `#${item.id}`,
|
||||
})}
|
||||
{...STORE_OBJECT}
|
||||
/>
|
||||
<RhfAsyncSelectField
|
||||
name="job_card"
|
||||
label="Job Card"
|
||||
placeholder="Select job card"
|
||||
queryKey={[JOB_CARD_ROUTES.INDEX]}
|
||||
listFn={() => api.jobCards.list()}
|
||||
mapOption={(item: any) => ({
|
||||
value: String(item.id),
|
||||
label: item.title,
|
||||
})}
|
||||
{...STORE_OBJECT}
|
||||
/>
|
||||
{isCustomerLocked ? (
|
||||
<Field>
|
||||
<FieldLabel>
|
||||
Customer<span className="text-destructive ms-0.5">*</span>
|
||||
</FieldLabel>
|
||||
<Input value={customerLabel} readOnly disabled />
|
||||
</Field>
|
||||
) : (
|
||||
<RhfAsyncSelectField
|
||||
name="customer"
|
||||
label="Customer"
|
||||
placeholder="Select customer"
|
||||
required
|
||||
queryKey={[CUSTOMER_ROUTES.INDEX]}
|
||||
listFn={() => api.customers.list()}
|
||||
mapOption={(item: any) => ({
|
||||
value: String(item.id),
|
||||
label: item.first_name
|
||||
? `${item.first_name} ${item.last_name || ""}`.trim()
|
||||
: item.name || `#${item.id}`,
|
||||
})}
|
||||
{...STORE_OBJECT}
|
||||
/>
|
||||
)}
|
||||
{isJobCardLocked ? (
|
||||
<Field>
|
||||
<FieldLabel>Job Card</FieldLabel>
|
||||
<Input value={defaultJobCard?.title ?? ""} readOnly disabled />
|
||||
</Field>
|
||||
) : (
|
||||
<RhfAsyncSelectField
|
||||
name="job_card"
|
||||
label="Job Card"
|
||||
placeholder="Select job card"
|
||||
queryKey={[JOB_CARD_ROUTES.INDEX]}
|
||||
listFn={() => api.jobCards.list()}
|
||||
mapOption={(item: any) => ({
|
||||
value: String(item.id),
|
||||
label: item.title,
|
||||
})}
|
||||
{...STORE_OBJECT}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
|
||||
Reference in New Issue
Block a user