Added client picker & filter
X-Lovable-Edit-ID: edt-5729796b-5fc7-4f1a-bfc4-619dc06a9dd0 Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
@@ -36,6 +36,11 @@ interface CaseOption {
|
||||
id: string;
|
||||
case_number: string;
|
||||
title: string;
|
||||
client_id: string | null;
|
||||
}
|
||||
interface ClientOption {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
interface Profile {
|
||||
id: string;
|
||||
@@ -64,8 +69,10 @@ export function NewTaskDialog({
|
||||
const [priority, setPriority] = useState<"low" | "normal" | "high" | "urgent">("normal");
|
||||
const [dueDate, setDueDate] = useState<Date | undefined>();
|
||||
const [caseId, setCaseId] = useState<string | null>(defaultCaseId ?? null);
|
||||
const [clientId, setClientId] = useState<string | null>(null);
|
||||
const [assigneeIds, setAssigneeIds] = useState<string[]>([]);
|
||||
const [cases, setCases] = useState<CaseOption[]>([]);
|
||||
const [clients, setClients] = useState<ClientOption[]>([]);
|
||||
const [profiles, setProfiles] = useState<Profile[]>([]);
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [showPicker, setShowPicker] = useState(false);
|
||||
@@ -73,21 +80,40 @@ export function NewTaskDialog({
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
setCaseId(defaultCaseId ?? null);
|
||||
setClientId(null);
|
||||
setTitle("");
|
||||
setDescription("");
|
||||
setPriority("normal");
|
||||
setDueDate(undefined);
|
||||
setAssigneeIds(user ? [user.id] : []);
|
||||
(async () => {
|
||||
const [c, p] = await Promise.all([
|
||||
supabase.from("cases").select("id, case_number, title").order("case_number"),
|
||||
const [c, cl, p] = await Promise.all([
|
||||
supabase
|
||||
.from("cases")
|
||||
.select("id, case_number, title, client_id")
|
||||
.is("archived_at", null)
|
||||
.neq("status", "closed")
|
||||
.order("case_number"),
|
||||
supabase
|
||||
.from("clients")
|
||||
.select("id, name")
|
||||
.is("archived_at", null)
|
||||
.order("name"),
|
||||
supabase.from("profiles").select("id, full_name, email").order("full_name"),
|
||||
]);
|
||||
setCases((c.data ?? []) as CaseOption[]);
|
||||
const caseList = (c.data ?? []) as CaseOption[];
|
||||
setCases(caseList);
|
||||
setClients((cl.data ?? []) as ClientOption[]);
|
||||
setProfiles((p.data ?? []) as Profile[]);
|
||||
if (defaultCaseId) {
|
||||
const k = caseList.find((x) => x.id === defaultCaseId);
|
||||
if (k?.client_id) setClientId(k.client_id);
|
||||
}
|
||||
})();
|
||||
}, [open, defaultCaseId, user]);
|
||||
|
||||
const filteredCases = clientId ? cases.filter((c) => c.client_id === clientId) : cases;
|
||||
|
||||
const submit = async () => {
|
||||
if (!user || !title.trim()) return;
|
||||
setSubmitting(true);
|
||||
@@ -184,21 +210,50 @@ export function NewTaskDialog({
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-xs">Case</Label>
|
||||
<Select value={caseId ?? "_none"} onValueChange={(v) => setCaseId(v === "_none" ? null : v)}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="No case" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="_none">No case</SelectItem>
|
||||
{cases.map((c) => (
|
||||
<SelectItem key={c.id} value={c.id}>
|
||||
{c.case_number} — {c.title}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<Label className="text-xs">Client (optional)</Label>
|
||||
<Select
|
||||
value={clientId ?? "_none"}
|
||||
onValueChange={(v) => {
|
||||
const next = v === "_none" ? null : v;
|
||||
setClientId(next);
|
||||
// Clear case if it doesn't belong to selected client
|
||||
if (next && caseId) {
|
||||
const k = cases.find((c) => c.id === caseId);
|
||||
if (k && k.client_id !== next) setCaseId(null);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="No client" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="_none">No client</SelectItem>
|
||||
{clients.map((c) => (
|
||||
<SelectItem key={c.id} value={c.id}>
|
||||
{c.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-xs">Case (optional)</Label>
|
||||
<Select value={caseId ?? "_none"} onValueChange={(v) => setCaseId(v === "_none" ? null : v)}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="No case" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="_none">No case</SelectItem>
|
||||
{filteredCases.map((c) => (
|
||||
<SelectItem key={c.id} value={c.id}>
|
||||
{c.case_number} — {c.title}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-xs">Assignees</Label>
|
||||
|
||||
Reference in New Issue
Block a user