Replaced homeowner picker with cases

X-Lovable-Edit-ID: edt-0f59cdf7-e7cd-4d08-a3ef-ffdf0aaab32b
Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-04-18 23:27:18 +00:00
co-authored by renee-png
3 changed files with 108 additions and 7 deletions
@@ -0,0 +1,98 @@
import { useEffect, useMemo, useState } from "react";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Label } from "@/components/ui/label";
import {
fetchClients,
fetchAccessibleCases,
type ClientLite,
type CaseLite,
} from "@/lib/forms-shared";
export function ClientCasePicker({
clientId,
caseId,
onClientChange,
onCaseChange,
}: {
clientId: string;
caseId: string;
onClientChange: (id: string, client: ClientLite | null) => void;
onCaseChange: (id: string, kase: CaseLite | null) => void;
}) {
const [clients, setClients] = useState<ClientLite[]>([]);
const [cases, setCases] = useState<CaseLite[]>([]);
useEffect(() => {
fetchClients().then(setClients);
fetchAccessibleCases().then(setCases);
}, []);
const filteredCases = useMemo(() => {
if (!clientId) return [];
return cases.filter((c) => c.client_id === clientId);
}, [cases, clientId]);
return (
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<Label>Client / Association</Label>
<Select
value={clientId}
onValueChange={(id) => {
const c = clients.find((x) => x.id === id) ?? null;
onClientChange(id, c);
onCaseChange("", null);
}}
>
<SelectTrigger>
<SelectValue placeholder="Select a client" />
</SelectTrigger>
<SelectContent>
{clients.map((c) => (
<SelectItem key={c.id} value={c.id}>
{c.name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div>
<Label>Case (optional)</Label>
<Select
value={caseId}
onValueChange={(id) => {
const k = cases.find((x) => x.id === id) ?? null;
onCaseChange(id, k);
}}
disabled={!clientId}
>
<SelectTrigger>
<SelectValue placeholder={clientId ? "Select case" : "Pick client first"} />
</SelectTrigger>
<SelectContent>
{filteredCases.length === 0 ? (
<div className="px-2 py-1.5 text-xs text-muted-foreground">
{clientId ? "No cases for this client" : ""}
</div>
) : (
filteredCases.map((c) => (
<SelectItem key={c.id} value={c.id}>
<span className="font-mono text-xs text-muted-foreground mr-2">
{c.case_number}
</span>
{c.title}
</SelectItem>
))
)}
</SelectContent>
</Select>
</div>
</div>
);
}
+8 -6
View File
@@ -54,7 +54,7 @@ import {
Square,
ImagePlus,
} from "lucide-react";
import { ClientHomeownerPicker } from "./form-pickers";
import { ClientCasePicker } from "./client-case-picker";
import { FormFieldDefsDialog } from "./form-field-defs-dialog";
import { FormFieldsFillPanel } from "./form-fields-fill-panel";
import {
@@ -1417,16 +1417,18 @@ export function CustomFormBuilder() {
</Button>
</div>
</div>
<ClientHomeownerPicker
<ClientCasePicker
clientId={clientId}
homeownerId={homeownerId}
caseId={selectedCaseId}
onClientChange={(id, c) => {
setClientId(id);
setClient(c);
setSelectedCaseId("");
setHomeownerId("");
setHomeowner(null);
}}
onHomeownerChange={(id, h) => {
setHomeownerId(id);
setHomeowner(h);
onCaseChange={(id) => {
setSelectedCaseId(id);
}}
/>
<div className="grid grid-cols-1 md:grid-cols-[1fr_auto_auto_auto_auto] gap-3 items-end">
+2 -1
View File
@@ -331,12 +331,13 @@ export interface CaseLite {
id: string;
case_number: string;
title: string;
client_id: string | null;
}
export async function fetchAccessibleCases(): Promise<CaseLite[]> {
const { data } = await supabase
.from("cases")
.select("id,case_number,title")
.select("id,case_number,title,client_id")
.is("archived_at", null)
.order("opened_at", { ascending: false })
.limit(500);