feat: integrate monthly chart with collapsible feature in transactions page; update transaction period to default to last 3 months
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { useCallback } from "react";
|
||||
import { useCallback, useState } from "react";
|
||||
import { PageLayout, PageHeader } from "@/components/layout";
|
||||
import { RefreshCw } from "lucide-react";
|
||||
import { RefreshCw, Maximize2, Minimize2 } from "lucide-react";
|
||||
import {
|
||||
TransactionFilters,
|
||||
TransactionBulkActions,
|
||||
@@ -13,15 +13,24 @@ import {
|
||||
} from "@/components/transactions";
|
||||
import { RuleCreateDialog } from "@/components/rules";
|
||||
import { OFXImportDialog } from "@/components/import/ofx-import-dialog";
|
||||
import { MonthlyChart } from "@/components/statistics";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Upload } from "lucide-react";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import { useTransactionsPage } from "@/hooks/use-transactions-page";
|
||||
import { useTransactionMutations } from "@/hooks/use-transaction-mutations";
|
||||
import { useTransactionRules } from "@/hooks/use-transaction-rules";
|
||||
import { useTransactionsChartData } from "@/hooks/use-transactions-chart-data";
|
||||
|
||||
export default function TransactionsPage() {
|
||||
const queryClient = useQueryClient();
|
||||
const [isFullscreen, setIsFullscreen] = useState(false);
|
||||
|
||||
// Main page state and logic
|
||||
const {
|
||||
@@ -88,6 +97,17 @@ export default function TransactionsPage() {
|
||||
metadata,
|
||||
});
|
||||
|
||||
// Chart data
|
||||
const { monthlyData, isLoading: isLoadingChart } = useTransactionsChartData({
|
||||
selectedAccounts,
|
||||
selectedCategories,
|
||||
period,
|
||||
customStartDate,
|
||||
customEndDate,
|
||||
showReconciled,
|
||||
searchQuery,
|
||||
});
|
||||
|
||||
const invalidateAll = useCallback(() => {
|
||||
invalidateTransactions();
|
||||
queryClient.invalidateQueries({ queryKey: ["banking-metadata"] });
|
||||
@@ -98,7 +118,7 @@ export default function TransactionsPage() {
|
||||
handleBulkReconcile(reconciled, selectedTransactions);
|
||||
clearSelection();
|
||||
},
|
||||
[handleBulkReconcile, selectedTransactions, clearSelection],
|
||||
[handleBulkReconcile, selectedTransactions, clearSelection]
|
||||
);
|
||||
|
||||
const handleBulkSetCategoryWithClear = useCallback(
|
||||
@@ -106,7 +126,7 @@ export default function TransactionsPage() {
|
||||
handleBulkSetCategory(categoryId, selectedTransactions);
|
||||
clearSelection();
|
||||
},
|
||||
[handleBulkSetCategory, selectedTransactions, clearSelection],
|
||||
[handleBulkSetCategory, selectedTransactions, clearSelection]
|
||||
);
|
||||
|
||||
const filteredTransactions = transactionsData?.transactions || [];
|
||||
@@ -179,6 +199,21 @@ export default function TransactionsPage() {
|
||||
transactionsForCategoryFilter={transactionsForCategoryFilter}
|
||||
/>
|
||||
|
||||
{!isLoadingChart && monthlyData.length > 0 && (
|
||||
<div className="mb-6">
|
||||
<MonthlyChart
|
||||
data={monthlyData}
|
||||
formatCurrency={formatCurrency}
|
||||
collapsible
|
||||
defaultExpanded={true}
|
||||
showDots={
|
||||
period !== "all" &&
|
||||
(period === "12months" || monthlyData.length <= 12)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<TransactionBulkActions
|
||||
selectedCount={selectedTransactions.size}
|
||||
categories={metadata.categories}
|
||||
@@ -192,6 +227,19 @@ export default function TransactionsPage() {
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="flex-1" />
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setIsFullscreen(true)}
|
||||
className="gap-2"
|
||||
>
|
||||
<Maximize2 className="w-4 h-4" />
|
||||
Plein écran
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<TransactionTable
|
||||
transactions={filteredTransactions}
|
||||
accounts={metadata.accounts}
|
||||
@@ -224,6 +272,74 @@ export default function TransactionsPage() {
|
||||
</>
|
||||
)}
|
||||
|
||||
<Dialog open={isFullscreen} onOpenChange={setIsFullscreen}>
|
||||
<DialogContent
|
||||
className="!max-w-none !max-h-none !w-full !h-full !p-0 flex flex-col !rounded-none !translate-x-0 !translate-y-0 !top-0 !left-0 !right-0 !bottom-0 !m-0"
|
||||
showCloseButton={false}
|
||||
style={{
|
||||
width: "100vw",
|
||||
height: "100vh",
|
||||
maxWidth: "100vw",
|
||||
maxHeight: "100vh",
|
||||
}}
|
||||
>
|
||||
<DialogHeader className="px-6 pt-6 pb-4 border-b shrink-0">
|
||||
<div className="flex items-center justify-between">
|
||||
<DialogTitle>Transactions</DialogTitle>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => setIsFullscreen(false)}
|
||||
className="gap-2"
|
||||
>
|
||||
<Minimize2 className="w-4 h-4" />
|
||||
Réduire
|
||||
</Button>
|
||||
</div>
|
||||
</DialogHeader>
|
||||
<div className="flex-1 overflow-auto px-6 pb-6 min-h-0">
|
||||
<div className="mb-4">
|
||||
<TransactionBulkActions
|
||||
selectedCount={selectedTransactions.size}
|
||||
categories={metadata.categories}
|
||||
onReconcile={handleBulkReconcileWithClear}
|
||||
onSetCategory={handleBulkSetCategoryWithClear}
|
||||
/>
|
||||
</div>
|
||||
<TransactionTable
|
||||
transactions={filteredTransactions}
|
||||
accounts={metadata.accounts}
|
||||
categories={metadata.categories}
|
||||
selectedTransactions={selectedTransactions}
|
||||
sortField={sortField}
|
||||
sortOrder={sortOrder}
|
||||
onSortChange={onSortChange}
|
||||
onToggleSelectAll={onToggleSelectAll}
|
||||
onToggleSelectTransaction={onToggleSelectTransaction}
|
||||
onToggleReconciled={toggleReconciled}
|
||||
onMarkReconciled={markReconciled}
|
||||
onSetCategory={setCategory}
|
||||
onCreateRule={handleCreateRule}
|
||||
onDelete={deleteTransaction}
|
||||
formatCurrency={formatCurrency}
|
||||
formatDate={formatDate}
|
||||
updatingTransactionIds={updatingTransactionIds}
|
||||
duplicateIds={duplicateIds}
|
||||
highlightDuplicates={showDuplicates}
|
||||
/>
|
||||
<div className="mt-4">
|
||||
<TransactionPagination
|
||||
page={page}
|
||||
pageSize={pageSize}
|
||||
total={totalTransactions}
|
||||
hasMore={hasMore}
|
||||
onPageChange={onPageChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<RuleCreateDialog
|
||||
open={ruleDialogOpen}
|
||||
onOpenChange={setRuleDialogOpen}
|
||||
|
||||
Reference in New Issue
Block a user