Checkpoint: Ajout d'un sélecteur Période (année + mois) dans la barre de filtres de Factures BAP, cumulable avec les filtres de statut existants. Le sélecteur mois est désactivé si "Toute année" est sélectionné. Bouton Réinitialiser visible si un filtre est actif.

This commit is contained in:
Manus
2026-04-15 08:20:43 -04:00
parent 62b7a61bf5
commit 54f3f8eeef

View File

@@ -32,7 +32,8 @@ import {
TableRow, TableRow,
} from "@/components/ui/table"; } from "@/components/ui/table";
import { trpc } from "@/lib/trpc"; import { trpc } from "@/lib/trpc";
import { Search, FileText, Download, FileSpreadsheet, Trash2, Edit, Trash, CheckCircle, CheckCircle2, ShieldCheck, RefreshCw, FolderDown, ChevronDown, ChevronRight, ChevronsUpDown } from "lucide-react"; import { Search, FileText, Download, FileSpreadsheet, Trash2, Edit, Trash, CheckCircle, CheckCircle2, ShieldCheck, RefreshCw, FolderDown, ChevronDown, ChevronRight, ChevronsUpDown, CalendarDays } from "lucide-react";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
// Helper : télécharge un ZIP de plusieurs PDFs annotés BAP // Helper : télécharge un ZIP de plusieurs PDFs annotés BAP
async function downloadBapZip( async function downloadBapZip(
@@ -124,6 +125,10 @@ export default function InvoicesBAP() {
// Accordéon : lignes dépliées // Accordéon : lignes dépliées
const [expandedIds, setExpandedIds] = useState<Set<number>>(new Set()); const [expandedIds, setExpandedIds] = useState<Set<number>>(new Set());
const [allExpanded, setAllExpanded] = useState(false); const [allExpanded, setAllExpanded] = useState(false);
// Filtre par période
const currentYear = new Date().getFullYear();
const [selectedYear, setSelectedYear] = useState<string>(String(currentYear));
const [selectedMonth, setSelectedMonth] = useState<string>("all"); // "all" ou "01".."12"
const toggleRow = (id: number) => { const toggleRow = (id: number) => {
setExpandedIds(prev => { setExpandedIds(prev => {
@@ -354,6 +359,16 @@ export default function InvoicesBAP() {
if (!matchesSearch) return false; if (!matchesSearch) return false;
} }
// Filter by period (year + optional month)
if (selectedYear !== "all") {
const invDate = inv.invoiceDate ? new Date(inv.invoiceDate) : null;
const fallbackDate = inv.createdAt ? new Date(inv.createdAt) : null;
const dateToUse = invDate || fallbackDate;
if (!dateToUse) return false;
if (dateToUse.getFullYear() !== parseInt(selectedYear)) return false;
if (selectedMonth !== "all" && (dateToUse.getMonth() + 1) !== parseInt(selectedMonth)) return false;
}
// Filter by export status // Filter by export status
if (statusFilter !== "all") { if (statusFilter !== "all") {
if (statusFilter === "exported" && inv.exportStatus !== "exported") return false; if (statusFilter === "exported" && inv.exportStatus !== "exported") return false;
@@ -614,8 +629,56 @@ export default function InvoicesBAP() {
</div> </div>
</div> </div>
{/* Period Filter + Status Filters */}
<div className="flex flex-wrap items-center gap-2 mb-3 p-3 bg-slate-50 dark:bg-slate-900/50 rounded-lg border border-slate-200 dark:border-slate-700">
<div className="flex items-center gap-1.5 text-sm font-medium text-slate-600 dark:text-slate-400">
<CalendarDays className="w-4 h-4" />
Période :
</div>
{/* Year selector */}
<Select value={selectedYear} onValueChange={(v) => { setSelectedYear(v); if (v === "all") setSelectedMonth("all"); }}>
<SelectTrigger className="w-28 h-8 text-sm">
<SelectValue placeholder="Année" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all">Toute année</SelectItem>
{Array.from({ length: 5 }, (_, i) => currentYear - i).map(y => (
<SelectItem key={y} value={String(y)}>{y}</SelectItem>
))}
</SelectContent>
</Select>
{/* Month selector — disabled when year = all */}
<Select
value={selectedMonth}
onValueChange={setSelectedMonth}
disabled={selectedYear === "all"}
>
<SelectTrigger className="w-36 h-8 text-sm">
<SelectValue placeholder="Mois" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all">Tous les mois</SelectItem>
{[
["01","Janvier"],["02","Février"],["03","Mars"],["04","Avril"],
["05","Mai"],["06","Juin"],["07","Juillet"],["08","Août"],
["09","Septembre"],["10","Octobre"],["11","Novembre"],["12","Décembre"]
].map(([v, label]) => (
<SelectItem key={v} value={v}>{label}</SelectItem>
))}
</SelectContent>
</Select>
{(selectedYear !== "all" || selectedMonth !== "all") && (
<button
onClick={() => { setSelectedYear(String(currentYear)); setSelectedMonth("all"); }}
className="text-xs text-slate-500 hover:text-slate-700 underline"
>
Réinitialiser
</button>
)}
</div>
{/* Status Filters */} {/* Status Filters */}
<div className="flex gap-2 mb-4"> <div className="flex flex-wrap gap-2 mb-4">
<Button <Button
variant={statusFilter === "all" ? "default" : "outline"} variant={statusFilter === "all" ? "default" : "outline"}
onClick={() => setStatusFilter("all")} onClick={() => setStatusFilter("all")}