"use client"; import { Card, CardContent } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Badge } from "@/components/ui/badge"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { CategoryFilterCombobox } from "@/components/ui/category-filter-combobox"; import { AccountFilterCombobox } from "@/components/ui/account-filter-combobox"; import { CategoryIcon } from "@/components/ui/category-icon"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; import { Calendar as CalendarComponent } from "@/components/ui/calendar"; import { Button } from "@/components/ui/button"; import { Search, X, Filter, Wallet, Calendar } from "lucide-react"; import { format } from "date-fns"; import { fr } from "date-fns/locale"; import type { Account, Category, Folder, Transaction } from "@/lib/types"; type Period = "1month" | "3months" | "6months" | "12months" | "custom" | "all"; interface TransactionFiltersProps { searchQuery: string; onSearchChange: (query: string) => void; selectedAccounts: string[]; onAccountsChange: (accounts: string[]) => void; selectedCategories: string[]; onCategoriesChange: (categories: string[]) => void; showReconciled: string; onReconciledChange: (value: string) => void; period: Period; onPeriodChange: (period: Period) => void; customStartDate?: Date; customEndDate?: Date; onCustomStartDateChange: (date: Date | undefined) => void; onCustomEndDateChange: (date: Date | undefined) => void; isCustomDatePickerOpen: boolean; onCustomDatePickerOpenChange: (open: boolean) => void; accounts: Account[]; folders: Folder[]; categories: Category[]; transactionsForAccountFilter?: Transaction[]; // Filtered by categories, search, reconciled, period (not accounts) transactionsForCategoryFilter?: Transaction[]; // Filtered by accounts, search, reconciled, period (not categories) } export function TransactionFilters({ searchQuery, onSearchChange, selectedAccounts, onAccountsChange, selectedCategories, onCategoriesChange, showReconciled, onReconciledChange, period, onPeriodChange, customStartDate, customEndDate, onCustomStartDateChange, onCustomEndDateChange, isCustomDatePickerOpen, onCustomDatePickerOpenChange, accounts, folders, categories, transactionsForAccountFilter, transactionsForCategoryFilter, }: TransactionFiltersProps) { return (
onSearchChange(e.target.value)} className="pl-9" />
{period === "custom" && (
{ onCustomStartDateChange(date); if (date && customEndDate && date > customEndDate) { onCustomEndDateChange(undefined); } }} locale={fr} />
{ if (date && customStartDate && date < customStartDate) { return; } onCustomEndDateChange(date); if (date && customStartDate) { onCustomDatePickerOpenChange(false); } }} disabled={(date) => { if (!customStartDate) return true; return date < customStartDate; }} locale={fr} />
{customStartDate && customEndDate && (
)}
)}
onSearchChange("")} selectedAccounts={selectedAccounts} onRemoveAccount={(id) => { const newAccounts = selectedAccounts.filter((a) => a !== id); onAccountsChange(newAccounts.length > 0 ? newAccounts : ["all"]); }} onClearAccounts={() => onAccountsChange(["all"])} selectedCategories={selectedCategories} onRemoveCategory={(id) => { const newCategories = selectedCategories.filter((c) => c !== id); onCategoriesChange( newCategories.length > 0 ? newCategories : ["all"], ); }} onClearCategories={() => onCategoriesChange(["all"])} showReconciled={showReconciled} onClearReconciled={() => onReconciledChange("all")} period={period} onClearPeriod={() => { onPeriodChange("all"); onCustomStartDateChange(undefined); onCustomEndDateChange(undefined); }} customStartDate={customStartDate} customEndDate={customEndDate} accounts={accounts} categories={categories} />
); } function ActiveFilters({ searchQuery, onClearSearch, selectedAccounts, onRemoveAccount, onClearAccounts, selectedCategories, onRemoveCategory, onClearCategories, showReconciled, onClearReconciled, period, onClearPeriod, customStartDate, customEndDate, accounts, categories, }: { searchQuery: string; onClearSearch: () => void; selectedAccounts: string[]; onRemoveAccount: (id: string) => void; onClearAccounts: () => void; selectedCategories: string[]; onRemoveCategory: (id: string) => void; onClearCategories: () => void; showReconciled: string; onClearReconciled: () => void; period: Period; onClearPeriod: () => void; customStartDate?: Date; customEndDate?: Date; accounts: Account[]; categories: Category[]; }) { const hasSearch = searchQuery.trim() !== ""; const hasAccounts = !selectedAccounts.includes("all"); const hasCategories = !selectedCategories.includes("all"); const hasReconciled = showReconciled !== "all"; const hasPeriod = period !== "all"; const hasActiveFilters = hasSearch || hasAccounts || hasCategories || hasReconciled || hasPeriod; if (!hasActiveFilters) return null; const selectedAccs = accounts.filter((a) => selectedAccounts.includes(a.id)); const selectedCats = categories.filter((c) => selectedCategories.includes(c.id), ); const isUncategorized = selectedCategories.includes("uncategorized"); const clearAll = () => { onClearSearch(); onClearAccounts(); onClearCategories(); onClearReconciled(); onClearPeriod(); }; return (
{hasSearch && ( Recherche: "{searchQuery}" )} {selectedAccs.map((acc) => ( {acc.name} ))} {isUncategorized && ( Non catégorisé )} {selectedCats.map((cat) => ( {cat.name} ))} {hasReconciled && ( {showReconciled === "reconciled" ? "Pointées" : "Non pointées"} )} {hasPeriod && ( {period === "custom" && customStartDate && customEndDate ? `${format(customStartDate, "d MMM", { locale: fr })} - ${format(customEndDate, "d MMM yyyy", { locale: fr })}` : period === "1month" ? "1 mois" : period === "3months" ? "3 mois" : period === "6months" ? "6 mois" : period === "12months" ? "12 mois" : "Période"} )}
); }