feat: refactor dashboard and account pages to utilize new layout components, enhancing structure and loading states

This commit is contained in:
Julien Froidefond
2025-11-27 12:44:44 +01:00
parent e469656e0d
commit 88937579e2
40 changed files with 2781 additions and 2226 deletions

View File

@@ -0,0 +1,119 @@
"use client";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { Trash2, Tags } from "lucide-react";
interface DangerZoneCardProps {
categorizedCount: number;
onClearCategories: () => void;
onResetData: () => void;
}
export function DangerZoneCard({
categorizedCount,
onClearCategories,
onResetData,
}: DangerZoneCardProps) {
return (
<Card className="border-red-200">
<CardHeader>
<CardTitle className="flex items-center gap-2 text-red-600">
<Trash2 className="w-5 h-5" />
Zone dangereuse
</CardTitle>
<CardDescription>
Actions irréversibles - procédez avec prudence
</CardDescription>
</CardHeader>
<CardContent className="space-y-3">
{/* Supprimer catégories des opérations */}
<AlertDialog>
<AlertDialogTrigger asChild>
<Button
variant="outline"
className="w-full justify-start border-orange-300 text-orange-700 hover:bg-orange-50"
>
<Tags className="w-4 h-4 mr-2" />
Supprimer les catégories des opérations
<span className="ml-auto text-xs text-muted-foreground">
{categorizedCount} opération
{categorizedCount > 1 ? "s" : ""} catégorisée
{categorizedCount > 1 ? "s" : ""}
</span>
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>
Supprimer toutes les catégories ?
</AlertDialogTitle>
<AlertDialogDescription>
Cette action va retirer la catégorie de {categorizedCount}{" "}
opération{categorizedCount > 1 ? "s" : ""}. Les catégories
elles-mêmes ne seront pas supprimées, seulement leur
affectation aux opérations.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Annuler</AlertDialogCancel>
<AlertDialogAction
onClick={onClearCategories}
className="bg-orange-600 hover:bg-orange-700"
>
Supprimer les affectations
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
{/* Réinitialiser toutes les données */}
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant="destructive" className="w-full justify-start">
<Trash2 className="w-4 h-4 mr-2" />
Réinitialiser toutes les données
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Êtes-vous sûr ?</AlertDialogTitle>
<AlertDialogDescription>
Cette action supprimera définitivement tous vos comptes,
transactions, catégories et dossiers. Cette action est
irréversible.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Annuler</AlertDialogCancel>
<AlertDialogAction
onClick={onResetData}
className="bg-red-600 hover:bg-red-700"
>
Supprimer tout
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</CardContent>
</Card>
);
}

View File

@@ -0,0 +1,73 @@
"use client";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Download, Upload, Database } from "lucide-react";
import type { BankingData } from "@/lib/types";
interface DataCardProps {
data: BankingData;
importing: boolean;
onExport: () => void;
onImport: () => void;
}
export function DataCard({
data,
importing,
onExport,
onImport,
}: DataCardProps) {
return (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Database className="w-5 h-5" />
Données
</CardTitle>
<CardDescription>
Exportez ou importez vos données pour les sauvegarder ou les
transférer
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="flex items-center justify-between p-4 bg-muted rounded-lg">
<div>
<p className="font-medium">Statistiques</p>
<p className="text-sm text-muted-foreground">
{data.accounts.length} comptes, {data.transactions.length}{" "}
transactions, {data.categories.length} catégories
</p>
</div>
</div>
<div className="flex gap-2">
<Button
onClick={onExport}
variant="outline"
className="flex-1 bg-transparent"
>
<Download className="w-4 h-4 mr-2" />
Exporter (JSON)
</Button>
<Button
onClick={onImport}
variant="outline"
className="flex-1 bg-transparent"
disabled={importing}
>
<Upload className="w-4 h-4 mr-2" />
{importing ? "Import..." : "Importer"}
</Button>
</div>
</CardContent>
</Card>
);
}

View File

@@ -0,0 +1,4 @@
export { DataCard } from "./data-card";
export { DangerZoneCard } from "./danger-zone-card";
export { OFXInfoCard } from "./ofx-info-card";

View File

@@ -0,0 +1,41 @@
"use client";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { FileJson } from "lucide-react";
export function OFXInfoCard() {
return (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<FileJson className="w-5 h-5" />
Format OFX
</CardTitle>
<CardDescription>
Informations sur l'import de fichiers
</CardDescription>
</CardHeader>
<CardContent>
<div className="prose prose-sm text-muted-foreground">
<p>
L'application accepte les fichiers au format OFX (Open Financial
Exchange) ou QFX. Ces fichiers sont généralement disponibles depuis
l'espace client de votre banque.
</p>
<p className="mt-2">
Lors de l'import, les transactions sont automatiquement
catégorisées selon les mots-clés définis. Les doublons sont détectés
et ignorés automatiquement.
</p>
</div>
</CardContent>
</Card>
);
}