Reuse CategoryPicker in transactions page
This commit is contained in:
@@ -28,6 +28,7 @@ import { Badge } from "@/components/ui/badge";
|
||||
import { amountClass, formatAmount, formatDate, formatMonth } from "@/lib/format";
|
||||
import { TransactionFormDialog } from "@/components/transactions/TransactionFormDialog";
|
||||
import { AssignMonthDialog } from "@/components/transactions/AssignMonthDialog";
|
||||
import { CategoryPicker } from "@/components/transactions/CategoryPicker";
|
||||
import { toast } from "sonner";
|
||||
import {
|
||||
getVisibleSelectionState,
|
||||
@@ -82,64 +83,18 @@ const AccountCell = memo(function AccountCell({ name }: { name: string | undefin
|
||||
const CategoryCell = memo(function CategoryCell({
|
||||
tx,
|
||||
categories,
|
||||
categoryMap,
|
||||
onUpdate,
|
||||
}: {
|
||||
tx: Tx;
|
||||
categories: Category[] | undefined;
|
||||
categoryMap: Map<Id<"categories">, Category>;
|
||||
onUpdate: (id: Id<"transactions">, categoryId: Id<"categories">) => void;
|
||||
onUpdate: (id: Id<"transactions">, categoryId: Id<"categories">) => Promise<void>;
|
||||
}) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const cat = tx.categoryId ? categoryMap.get(tx.categoryId) : null;
|
||||
|
||||
if (!open) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setOpen(true)}
|
||||
className="inline-flex h-6 items-center rounded px-1.5 text-xs hover:bg-accent"
|
||||
>
|
||||
{cat ? (
|
||||
<Badge style={{ backgroundColor: cat.color, color: "#fff", border: "none" }}>
|
||||
{cat.name}
|
||||
</Badge>
|
||||
) : (
|
||||
<span className="text-muted-foreground">Kategorie…</span>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Select
|
||||
defaultOpen
|
||||
value={tx.categoryId ?? "none"}
|
||||
onValueChange={(v) => {
|
||||
if (v !== "none") onUpdate(tx._id, v as Id<"categories">);
|
||||
setOpen(false);
|
||||
}}
|
||||
onOpenChange={(o) => {
|
||||
if (!o) setOpen(false);
|
||||
}}
|
||||
>
|
||||
<SelectTrigger className="h-7 w-[130px]">
|
||||
<SelectValue placeholder="Kategorie" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{categories?.map((c) => (
|
||||
<SelectItem key={c._id} value={c._id}>
|
||||
<span className="inline-flex items-center gap-1.5">
|
||||
<span
|
||||
className="inline-block h-2.5 w-2.5 rounded-full"
|
||||
style={{ backgroundColor: c.color }}
|
||||
/>
|
||||
{c.name}
|
||||
</span>
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<CategoryPicker
|
||||
categories={categories}
|
||||
value={tx.categoryId}
|
||||
onSelect={(categoryId) => onUpdate(tx._id, categoryId)}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -228,10 +183,6 @@ export function TransactionsPage() {
|
||||
{ initialNumItems: 50 },
|
||||
);
|
||||
|
||||
const categoryMap = useMemo(
|
||||
() => new Map(categories?.map((c) => [c._id, c])),
|
||||
[categories],
|
||||
);
|
||||
const accountMap = useMemo(
|
||||
() => new Map(accounts?.map((a) => [a._id, a.name])),
|
||||
[accounts],
|
||||
@@ -247,8 +198,8 @@ export function TransactionsPage() {
|
||||
);
|
||||
|
||||
const handleUpdateCategory = useCallback(
|
||||
(id: Id<"transactions">, categoryId: Id<"categories">) => {
|
||||
void updateTx({ id, categoryId });
|
||||
async (id: Id<"transactions">, categoryId: Id<"categories">) => {
|
||||
await updateTx({ id, categoryId });
|
||||
},
|
||||
[updateTx],
|
||||
);
|
||||
@@ -343,7 +294,6 @@ export function TransactionsPage() {
|
||||
<CategoryCell
|
||||
tx={row.original}
|
||||
categories={categories}
|
||||
categoryMap={categoryMap}
|
||||
onUpdate={handleUpdateCategory}
|
||||
/>
|
||||
),
|
||||
@@ -382,7 +332,6 @@ export function TransactionsPage() {
|
||||
],
|
||||
[
|
||||
categories,
|
||||
categoryMap,
|
||||
accountMap,
|
||||
handleUpdateCategory,
|
||||
handleEdit,
|
||||
|
||||
Reference in New Issue
Block a user