feat(ui): wire OwnerPicker into invoice billing-entity field

This commit is contained in:
Matt Ciaccio
2026-04-24 16:04:07 +02:00
parent 9d7decfc5b
commit d133d6d656

View File

@@ -19,6 +19,7 @@ import {
SelectValue, SelectValue,
} from '@/components/ui/select'; } from '@/components/ui/select';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { OwnerPicker } from '@/components/shared/owner-picker';
import { InvoiceLineItems } from '@/components/invoices/invoice-line-items'; import { InvoiceLineItems } from '@/components/invoices/invoice-line-items';
import { apiFetch } from '@/lib/api/client'; import { apiFetch } from '@/lib/api/client';
import { createInvoiceSchema, type CreateInvoiceInput } from '@/lib/validators/invoices'; import { createInvoiceSchema, type CreateInvoiceInput } from '@/lib/validators/invoices';
@@ -156,27 +157,18 @@ export default function NewInvoicePage() {
<CardTitle className="text-base">Client Information</CardTitle> <CardTitle className="text-base">Client Information</CardTitle>
</CardHeader> </CardHeader>
<CardContent className="space-y-4"> <CardContent className="space-y-4">
<div className="space-y-1"> <div className="space-y-2">
<Label htmlFor="billingEntityType"> <Label>
Billing Entity <span className="text-destructive">*</span> Billing entity <span className="text-destructive">*</span>
</Label> </Label>
<div className="grid grid-cols-2 gap-2"> <OwnerPicker
<Select value={watchedValues.billingEntity ?? null}
defaultValue="client" onChange={(ref) => {
onValueChange={(v) => if (ref) {
setValue('billingEntity.type', v as 'client' | 'company') setValue('billingEntity', ref, { shouldValidate: true });
} }
> }}
<SelectTrigger id="billingEntityType"> />
<SelectValue placeholder="Type" />
</SelectTrigger>
<SelectContent>
<SelectItem value="client">Client</SelectItem>
<SelectItem value="company">Company</SelectItem>
</SelectContent>
</Select>
<Input {...register('billingEntity.id')} placeholder="Entity ID" />
</div>
{errors.billingEntity && ( {errors.billingEntity && (
<p className="text-xs text-destructive"> <p className="text-xs text-destructive">
{errors.billingEntity.message ?? {errors.billingEntity.message ??
@@ -185,7 +177,8 @@ export default function NewInvoicePage() {
</p> </p>
)} )}
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground">
Picker UI is coming in Task 10.2 for now paste the client or company ID. Select the client or company to invoice. Their name will be snapshotted into the
invoice.
</p> </p>
</div> </div>
@@ -299,7 +292,16 @@ export default function NewInvoicePage() {
<div> <div>
<span className="text-muted-foreground">Billing Entity</span> <span className="text-muted-foreground">Billing Entity</span>
<p className="font-medium mt-0.5"> <p className="font-medium mt-0.5">
{watchedValues.billingEntity?.type}: {watchedValues.billingEntity?.id} {watchedValues.billingEntity ? (
<>
<span className="capitalize">{watchedValues.billingEntity.type}</span>{' '}
<span className="text-xs opacity-60">
{watchedValues.billingEntity.id.slice(0, 12)}
</span>
</>
) : (
<span className="text-muted-foreground italic">Not selected</span>
)}
</p> </p>
</div> </div>
<div> <div>