-
-
+
+
+
+ {filteredParentCategories.map((parent) => {
+ const allChildren = childrenByParent[parent.id] || [];
+ const children = searchQuery.trim()
+ ? allChildren.filter(
+ (c) =>
+ c.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
+ c.keywords.some((k) =>
+ k.toLowerCase().includes(searchQuery.toLowerCase())
+ ) ||
+ parent.name.toLowerCase().includes(searchQuery.toLowerCase())
+ )
+ : allChildren;
+ const stats = getCategoryStats(parent.id, true);
+ const isExpanded =
+ expandedParents.has(parent.id) ||
+ (searchQuery.trim() !== "" && children.length > 0);
+
+ return (
+
toggleExpanded(parent.id)}
+ formatCurrency={formatCurrency}
+ getCategoryStats={(id) => getCategoryStats(id)}
+ onEdit={handleEdit}
+ onDelete={handleDelete}
+ onNewCategory={handleNewCategory}
+ />
+ );
+ })}
+
+ {orphanCategories.length > 0 && (
+
+
+
+ Catégories non classées ({orphanCategories.length})
+
-
- {/* Nom */}
-
-
-
- setFormData({ ...formData, name: e.target.value })
- }
- placeholder="Ex: Alimentation"
- />
-
-
- {/* Couleur */}
-
-
-
- {categoryColors.map((color) => (
-
-
-
- {/* Mots-clés */}
-
-
-
-
setNewKeyword(e.target.value)}
- placeholder="Ajouter un mot-clé"
- onKeyDown={(e) =>
- e.key === "Enter" && (e.preventDefault(), addKeyword())
- }
+
+ {orphanCategories.map((category) => (
+
-
-
-
- {formData.keywords.map((keyword) => (
-
- {keyword}
-
-
- ))}
-
-
-
- {/* Actions */}
-
-
-
+ ))}
-
-
-
+ )}
+
+
+
+
);
}
diff --git a/app/folders/page.tsx b/app/folders/page.tsx
index 26ce9c4..cff54ef 100644
--- a/app/folders/page.tsx
+++ b/app/folders/page.tsx
@@ -1,43 +1,16 @@
"use client";
import { useState } from "react";
-import { Sidebar } from "@/components/dashboard/sidebar";
+import { PageLayout, LoadingState, PageHeader } from "@/components/layout";
+import {
+ FolderTreeItem,
+ FolderEditDialog,
+ AccountFolderDialog,
+} from "@/components/folders";
import { useBankingData } from "@/lib/hooks";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
-import { Input } from "@/components/ui/input";
-import { Label } from "@/components/ui/label";
-import {
- Dialog,
- DialogContent,
- DialogHeader,
- DialogTitle,
-} from "@/components/ui/dialog";
-import {
- Select,
- SelectContent,
- SelectItem,
- SelectTrigger,
- SelectValue,
-} from "@/components/ui/select";
-import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuItem,
- DropdownMenuTrigger,
-} from "@/components/ui/dropdown-menu";
-import {
- Plus,
- MoreVertical,
- Pencil,
- Trash2,
- Folder,
- FolderOpen,
- ChevronRight,
- ChevronDown,
- Building2,
- RefreshCw,
-} from "lucide-react";
+import { Plus } from "lucide-react";
import {
addFolder,
updateFolder,
@@ -45,189 +18,6 @@ import {
updateAccount,
} from "@/lib/store-db";
import type { Folder as FolderType, Account } from "@/lib/types";
-import { cn } from "@/lib/utils";
-import Link from "next/link";
-
-const folderColors = [
- { value: "#6366f1", label: "Indigo" },
- { value: "#22c55e", label: "Vert" },
- { value: "#f59e0b", label: "Orange" },
- { value: "#ec4899", label: "Rose" },
- { value: "#3b82f6", label: "Bleu" },
- { value: "#ef4444", label: "Rouge" },
-];
-
-interface FolderTreeItemProps {
- folder: FolderType;
- accounts: Account[];
- allFolders: FolderType[];
- level: number;
- onEdit: (folder: FolderType) => void;
- onDelete: (folderId: string) => void;
- onEditAccount: (account: Account) => void;
- formatCurrency: (amount: number) => string;
-}
-
-function FolderTreeItem({
- folder,
- accounts,
- allFolders,
- level,
- onEdit,
- onDelete,
- onEditAccount,
- formatCurrency,
-}: FolderTreeItemProps) {
- const [isExpanded, setIsExpanded] = useState(true);
-
- // Pour le dossier "Mes Comptes" (folder-root), inclure aussi les comptes sans dossier
- const folderAccounts = accounts.filter(
- (a) =>
- a.folderId === folder.id ||
- (folder.id === "folder-root" && a.folderId === null),
- );
- const childFolders = allFolders.filter((f) => f.parentId === folder.id);
- const hasChildren = childFolders.length > 0 || folderAccounts.length > 0;
-
- const folderTotal = folderAccounts.reduce((sum, a) => sum + a.balance, 0);
-
- return (
-
-
0 && "ml-6",
- )}
- >
-
-
-
- {isExpanded ? (
-
- ) : (
-
- )}
-
-
-
{folder.name}
-
- {folderAccounts.length > 0 && (
-
= 0 ? "text-emerald-600" : "text-red-600",
- )}
- >
- {formatCurrency(folderTotal)}
-
- )}
-
-
-
-
-
-
- onEdit(folder)}>
-
- Modifier
-
- {folder.id !== "folder-root" && (
- onDelete(folder.id)}
- className="text-red-600"
- >
-
- Supprimer
-
- )}
-
-
-
-
- {isExpanded && (
-
- {folderAccounts.map((account) => (
-
-
-
- {account.name}
-
-
= 0 ? "text-emerald-600" : "text-red-600",
- )}
- >
- {formatCurrency(account.balance)}
-
-
-
- ))}
-
- {childFolders.map((child) => (
-
- ))}
-
- )}
-
- );
-}
-
-const accountTypeLabels = {
- CHECKING: "Compte courant",
- SAVINGS: "Épargne",
- CREDIT_CARD: "Carte de crédit",
- OTHER: "Autre",
-};
export default function FoldersPage() {
const { data, isLoading, refresh } = useBankingData();
@@ -249,14 +39,7 @@ export default function FoldersPage() {
});
if (isLoading || !data) {
- return (
-
-
-
-
-
-
- );
+ return
;
}
const formatCurrency = (amount: number) => {
@@ -315,7 +98,7 @@ export default function FoldersPage() {
const handleDelete = async (folderId: string) => {
if (
!confirm(
- "Supprimer ce dossier ? Les comptes seront déplacés à la racine.",
+ "Supprimer ce dossier ? Les comptes seront déplacés à la racine."
)
)
return;
@@ -362,196 +145,59 @@ export default function FoldersPage() {
};
return (
-
-
-
-
-
-
-
- Organisation
-
-
- Organisez vos comptes en dossiers
-
-
-
-
+
+
+
+ Nouveau dossier
+
+ }
+ />
-
-
- Arborescence des comptes
-
-
-
- {rootFolders.map((folder) => (
-
- ))}
-
-
-
-
-
-
-