BillTracker/client/components/transactions/CategoryPicker.jsx

58 lines
2.4 KiB
React
Raw Normal View History

import React, { useState, useEffect, useRef } from 'react';
import { Tag } from 'lucide-react';
// ── Category picker dropdown ─────────────────────────────────────────────────
export function CategoryPicker({ categories, current, currentLabel, onSelect }) {
const [open, setOpen] = useState(false);
const ref = useRef(null);
useEffect(() => {
if (!open) return;
const close = e => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
document.addEventListener('mousedown', close);
return () => document.removeEventListener('mousedown', close);
}, [open]);
const currentCat = categories.find(c => c.id === current);
return (
<div ref={ref} className="relative">
<button
type="button"
onClick={() => setOpen(v => !v)}
className="flex items-center gap-1.5 rounded-md border border-border/60 bg-background px-2 py-1 text-xs text-muted-foreground hover:border-primary/40 hover:text-foreground transition-colors"
>
<Tag className="h-3 w-3 shrink-0" />
<span className="max-w-[100px] truncate">{currentCat?.name ?? currentLabel ?? 'Uncategorized'}</span>
</button>
{open && (
<div className="absolute right-0 top-full z-50 mt-1 w-48 rounded-lg border border-border/60 bg-popover shadow-lg overflow-hidden">
<button
type="button"
onMouseDown={e => { e.preventDefault(); onSelect(null, false); setOpen(false); }}
className="w-full px-3 py-2 text-left text-xs text-muted-foreground hover:bg-muted/50 transition-colors"
>
Uncategorized
</button>
{categories.length === 0 ? (
<p className="px-3 py-2 text-xs text-muted-foreground italic">
No spending categories. Enable some in Categories.
</p>
) : categories.map(cat => (
<button
key={cat.id}
type="button"
onMouseDown={e => { e.preventDefault(); onSelect(cat.id, false); setOpen(false); }}
className={`w-full px-3 py-2 text-left text-xs hover:bg-muted/50 transition-colors ${cat.id === current ? 'text-primary font-medium' : ''}`}
>
{cat.name}
</button>
))}
</div>
)}
</div>
);
}