Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-04-19 17:05:42 +00:00
co-authored by renee-png
parent c51314771f
commit f5404ea7e6
+39 -51
View File
@@ -12,13 +12,7 @@ import {
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { SearchableSelect } from "@/components/ui/searchable-select";
import { Pause, Play, Square, Timer as TimerIcon, Loader2, X, PlusCircle } from "lucide-react";
import { toast } from "sonner";
import { NewFeeItemDialog } from "@/components/fees/new-fee-item-dialog";
@@ -209,44 +203,37 @@ export function HeaderTimer() {
<div className="p-4 space-y-3">
<div className="space-y-1.5">
<Label className="text-xs">Client</Label>
<Select
<SearchableSelect
value={timer.clientId ?? ""}
onValueChange={(v) => setClient(v || null)}
>
<SelectTrigger>
<SelectValue placeholder="Select client" />
</SelectTrigger>
<SelectContent>
{clients.map((c) => (
<SelectItem key={c.id} value={c.id}>{c.name}</SelectItem>
))}
</SelectContent>
</Select>
placeholder="Select client"
searchPlaceholder="Search clients…"
emptyText="No clients found."
options={clients.map((c) => ({ value: c.id, label: c.name, keywords: c.name }))}
/>
</div>
<div className="space-y-1.5">
<Label className="text-xs">Case</Label>
<Select
<SearchableSelect
value={timer.caseId ?? ""}
onValueChange={(v) => setCase(v || null)}
disabled={!timer.clientId}
>
<SelectTrigger>
<SelectValue placeholder={timer.clientId ? "Select case" : "Pick a client first"} />
</SelectTrigger>
<SelectContent>
{filteredCases.length === 0 ? (
<div className="px-2 py-1.5 text-xs text-muted-foreground">No cases for this client.</div>
) : (
filteredCases.map((c) => (
<SelectItem key={c.id} value={c.id}>
<span className="text-muted-foreground mr-2">{c.case_number}</span>
{c.title}
</SelectItem>
))
)}
</SelectContent>
</Select>
placeholder={timer.clientId ? "Select case" : "Pick a client first"}
searchPlaceholder="Search cases…"
emptyText="No cases for this client."
options={filteredCases.map((c) => ({
value: c.id,
label: `${c.case_number} — ${c.title}`,
keywords: `${c.case_number} ${c.title}`,
render: (
<span>
<span className="text-muted-foreground mr-2">{c.case_number}</span>
{c.title}
</span>
),
}))}
/>
</div>
<div className="space-y-1.5">
@@ -263,26 +250,27 @@ export function HeaderTimer() {
</Button>
</div>
{feeItems.length > 0 ? (
<Select
value={feeItemId || "__none"}
onValueChange={(v) => handleSelectFee(v === "__none" ? "" : v)}
>
<SelectTrigger>
<SelectValue placeholder="No fee item" />
</SelectTrigger>
<SelectContent>
<SelectItem value="__none">No fee item</SelectItem>
{feeItems.map((f) => (
<SelectItem key={f.id} value={f.id}>
<SearchableSelect
value={feeItemId}
onValueChange={(v) => handleSelectFee(v)}
placeholder="No fee item"
searchPlaceholder="Search fee items…"
emptyText="No fee items found."
options={feeItems.map((f) => ({
value: f.id,
label: `${f.name} — ${formatCurrency(f.amount)}${f.pricing_type === "flat" ? " flat" : "/hr"}`,
keywords: `${f.name} ${f.description ?? ""}`,
render: (
<span>
<span className="mr-2">{f.name}</span>
<span className="text-muted-foreground">
{formatCurrency(f.amount)}
{f.pricing_type === "flat" ? " flat" : "/hr"}
</span>
</SelectItem>
))}
</SelectContent>
</Select>
</span>
),
}))}
/>
) : (
<p className="text-[11px] text-muted-foreground">
No saved items yet. Click "Add new item" to save one for reuse.