feat: refactor dashboard and account pages to utilize new layout components, enhancing structure and loading states
This commit is contained in:
140
components/categories/parent-category-row.tsx
Normal file
140
components/categories/parent-category-row.tsx
Normal file
@@ -0,0 +1,140 @@
|
||||
"use client";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import {
|
||||
Collapsible,
|
||||
CollapsibleContent,
|
||||
CollapsibleTrigger,
|
||||
} from "@/components/ui/collapsible";
|
||||
import { CategoryIcon } from "@/components/ui/category-icon";
|
||||
import {
|
||||
Plus,
|
||||
MoreVertical,
|
||||
Pencil,
|
||||
Trash2,
|
||||
ChevronDown,
|
||||
ChevronRight,
|
||||
} from "lucide-react";
|
||||
import { CategoryCard } from "./category-card";
|
||||
import type { Category } from "@/lib/types";
|
||||
|
||||
interface ParentCategoryRowProps {
|
||||
parent: Category;
|
||||
children: Category[];
|
||||
stats: { total: number; count: number };
|
||||
isExpanded: boolean;
|
||||
onToggleExpanded: () => void;
|
||||
formatCurrency: (amount: number) => string;
|
||||
getCategoryStats: (categoryId: string) => { total: number; count: number };
|
||||
onEdit: (category: Category) => void;
|
||||
onDelete: (categoryId: string) => void;
|
||||
onNewCategory: (parentId: string) => void;
|
||||
}
|
||||
|
||||
export function ParentCategoryRow({
|
||||
parent,
|
||||
children,
|
||||
stats,
|
||||
isExpanded,
|
||||
onToggleExpanded,
|
||||
formatCurrency,
|
||||
getCategoryStats,
|
||||
onEdit,
|
||||
onDelete,
|
||||
onNewCategory,
|
||||
}: ParentCategoryRowProps) {
|
||||
return (
|
||||
<div className="border rounded-lg bg-card">
|
||||
<Collapsible open={isExpanded} onOpenChange={onToggleExpanded}>
|
||||
<div className="flex items-center justify-between px-3 py-2">
|
||||
<CollapsibleTrigger asChild>
|
||||
<button className="flex items-center gap-2 hover:opacity-80 transition-opacity flex-1 min-w-0">
|
||||
{isExpanded ? (
|
||||
<ChevronDown className="w-4 h-4 text-muted-foreground shrink-0" />
|
||||
) : (
|
||||
<ChevronRight className="w-4 h-4 text-muted-foreground shrink-0" />
|
||||
)}
|
||||
<div
|
||||
className="w-7 h-7 rounded-full flex items-center justify-center shrink-0"
|
||||
style={{ backgroundColor: `${parent.color}20` }}
|
||||
>
|
||||
<CategoryIcon
|
||||
icon={parent.icon}
|
||||
color={parent.color}
|
||||
size={14}
|
||||
/>
|
||||
</div>
|
||||
<span className="font-medium text-sm truncate">{parent.name}</span>
|
||||
<span className="text-sm text-muted-foreground shrink-0">
|
||||
{children.length} • {stats.count} opération
|
||||
{stats.count > 1 ? "s" : ""} • {formatCurrency(stats.total)}
|
||||
</span>
|
||||
</button>
|
||||
</CollapsibleTrigger>
|
||||
|
||||
<div className="flex items-center gap-1 shrink-0 ml-2">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-7 w-7"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onNewCategory(parent.id);
|
||||
}}
|
||||
>
|
||||
<Plus className="w-4 h-4" />
|
||||
</Button>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" size="icon" className="h-7 w-7">
|
||||
<MoreVertical className="w-4 h-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem onClick={() => onEdit(parent)}>
|
||||
<Pencil className="w-4 h-4 mr-2" />
|
||||
Modifier
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={() => onDelete(parent.id)}
|
||||
className="text-red-600"
|
||||
>
|
||||
<Trash2 className="w-4 h-4 mr-2" />
|
||||
Supprimer
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<CollapsibleContent>
|
||||
{children.length > 0 ? (
|
||||
<div className="px-3 pb-2 space-y-1 ml-6 border-l-2 border-muted ml-5">
|
||||
{children.map((child) => (
|
||||
<CategoryCard
|
||||
key={child.id}
|
||||
category={child}
|
||||
stats={getCategoryStats(child.id)}
|
||||
formatCurrency={formatCurrency}
|
||||
onEdit={onEdit}
|
||||
onDelete={onDelete}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="px-3 pb-2 ml-11 text-xs text-muted-foreground italic">
|
||||
Aucune sous-catégorie
|
||||
</div>
|
||||
)}
|
||||
</CollapsibleContent>
|
||||
</Collapsible>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user