refactor: standardize quotation marks in pnpm-lock.yaml and improve code formatting across various components; enhance readability and maintain consistency in code style
This commit is contained in:
@@ -134,7 +134,11 @@ export default function AccountsPage() {
|
||||
|
||||
// Convert accountsWithStats to regular accounts for compatibility
|
||||
const accounts = accountsWithStats.map(
|
||||
({ transactionCount: _transactionCount, calculatedBalance: _calculatedBalance, ...account }) => account,
|
||||
({
|
||||
transactionCount: _transactionCount,
|
||||
calculatedBalance: _calculatedBalance,
|
||||
...account
|
||||
}) => account,
|
||||
);
|
||||
|
||||
const formatCurrency = (amount: number) => {
|
||||
@@ -165,10 +169,11 @@ export default function AccountsPage() {
|
||||
// Calculer le balance à partir du solde total et du solde initial
|
||||
// balance = totalBalance - initialBalance
|
||||
const balance = formData.totalBalance - formData.initialBalance;
|
||||
|
||||
|
||||
// Convertir "folder-root" en null
|
||||
const folderId = formData.folderId === "folder-root" ? null : formData.folderId;
|
||||
|
||||
const folderId =
|
||||
formData.folderId === "folder-root" ? null : formData.folderId;
|
||||
|
||||
const updatedAccount = {
|
||||
...editingAccount,
|
||||
name: formData.name,
|
||||
@@ -325,10 +330,10 @@ export default function AccountsPage() {
|
||||
|
||||
const result = await response.json();
|
||||
invalidateAllAccountQueries(queryClient);
|
||||
|
||||
|
||||
// Réinitialiser la sélection
|
||||
setSelectedAccounts(new Set());
|
||||
|
||||
|
||||
// Afficher un message de succès
|
||||
alert(
|
||||
`Fusion réussie ! ${result.transactionCount} transactions déplacées vers le compte de destination.`,
|
||||
@@ -384,7 +389,16 @@ export default function AccountsPage() {
|
||||
// Update cache directly
|
||||
queryClient.setQueryData(
|
||||
["accounts-with-stats"],
|
||||
(old: Array<Account & { transactionCount: number; calculatedBalance: number }> | undefined) => {
|
||||
(
|
||||
old:
|
||||
| Array<
|
||||
Account & {
|
||||
transactionCount: number;
|
||||
calculatedBalance: number;
|
||||
}
|
||||
>
|
||||
| undefined,
|
||||
) => {
|
||||
if (!old) return old;
|
||||
return old.map((a) => (a.id === accountId ? updatedAccount : a));
|
||||
},
|
||||
@@ -564,25 +578,27 @@ export default function AccountsPage() {
|
||||
(f: FolderType) => f.id === account.folderId,
|
||||
);
|
||||
|
||||
const accountWithStats = accountsWithStats.find(
|
||||
(a) => a.id === account.id,
|
||||
);
|
||||
return (
|
||||
<AccountCard
|
||||
key={account.id}
|
||||
account={account}
|
||||
folder={folder}
|
||||
transactionCount={getTransactionCount(account.id)}
|
||||
calculatedBalance={accountWithStats?.calculatedBalance}
|
||||
onEdit={handleEdit}
|
||||
onDelete={handleDelete}
|
||||
formatCurrency={formatCurrency}
|
||||
isSelected={selectedAccounts.has(account.id)}
|
||||
onSelect={toggleSelectAccount}
|
||||
draggableId={`account-${account.id}`}
|
||||
compact={isCompactView}
|
||||
/>
|
||||
);
|
||||
const accountWithStats = accountsWithStats.find(
|
||||
(a) => a.id === account.id,
|
||||
);
|
||||
return (
|
||||
<AccountCard
|
||||
key={account.id}
|
||||
account={account}
|
||||
folder={folder}
|
||||
transactionCount={getTransactionCount(account.id)}
|
||||
calculatedBalance={
|
||||
accountWithStats?.calculatedBalance
|
||||
}
|
||||
onEdit={handleEdit}
|
||||
onDelete={handleDelete}
|
||||
formatCurrency={formatCurrency}
|
||||
isSelected={selectedAccounts.has(account.id)}
|
||||
onSelect={toggleSelectAccount}
|
||||
draggableId={`account-${account.id}`}
|
||||
compact={isCompactView}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</FolderDropZone>
|
||||
@@ -694,7 +710,9 @@ export default function AccountsPage() {
|
||||
account={account}
|
||||
folder={accountFolder}
|
||||
transactionCount={getTransactionCount(account.id)}
|
||||
calculatedBalance={accountWithStats?.calculatedBalance}
|
||||
calculatedBalance={
|
||||
accountWithStats?.calculatedBalance
|
||||
}
|
||||
onEdit={handleEdit}
|
||||
onDelete={handleDelete}
|
||||
formatCurrency={formatCurrency}
|
||||
|
||||
@@ -126,4 +126,3 @@ export async function POST(request: NextRequest) {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,4 +66,3 @@ export async function POST(request: NextRequest) {
|
||||
return NextResponse.json({ error: errorMessage }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ export default function CategoriesPage() {
|
||||
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
||||
const [editingCategory, setEditingCategory] = useState<Category | null>(null);
|
||||
const [expandedParents, setExpandedParents] = useState<Set<string>>(
|
||||
new Set()
|
||||
new Set(),
|
||||
);
|
||||
const [formData, setFormData] = useState({
|
||||
name: "",
|
||||
@@ -55,7 +55,7 @@ export default function CategoriesPage() {
|
||||
});
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const [recatResults, setRecatResults] = useState<RecategorizationResult[]>(
|
||||
[]
|
||||
[],
|
||||
);
|
||||
const [isRecatDialogOpen, setIsRecatDialogOpen] = useState(false);
|
||||
const [isRecategorizing, setIsRecategorizing] = useState(false);
|
||||
@@ -63,7 +63,7 @@ export default function CategoriesPage() {
|
||||
// Persister l'état "tout déplier" dans le localStorage
|
||||
const [expandAllByDefault, setExpandAllByDefault] = useLocalStorage(
|
||||
"categories-expand-all-by-default",
|
||||
true
|
||||
true,
|
||||
);
|
||||
|
||||
// Organiser les catégories par parent
|
||||
@@ -77,7 +77,7 @@ export default function CategoriesPage() {
|
||||
};
|
||||
|
||||
const parents = metadata.categories.filter(
|
||||
(c: Category) => c.parentId === null
|
||||
(c: Category) => c.parentId === null,
|
||||
);
|
||||
const children: Record<string, Category[]> = {};
|
||||
const orphans: Category[] = [];
|
||||
@@ -86,7 +86,7 @@ export default function CategoriesPage() {
|
||||
.filter((c: Category) => c.parentId !== null)
|
||||
.forEach((child: Category) => {
|
||||
const parentExists = parents.some(
|
||||
(p: Category) => p.id === child.parentId
|
||||
(p: Category) => p.id === child.parentId,
|
||||
);
|
||||
if (parentExists) {
|
||||
if (!children[child.parentId!]) {
|
||||
@@ -110,7 +110,7 @@ export default function CategoriesPage() {
|
||||
if (parentCategories.length > 0 && expandedParents.size === 0) {
|
||||
if (expandAllByDefault) {
|
||||
setExpandedParents(
|
||||
new Set(parentCategories.map((p: Category) => p.id))
|
||||
new Set(parentCategories.map((p: Category) => p.id)),
|
||||
);
|
||||
} else {
|
||||
setExpandedParents(new Set());
|
||||
@@ -150,7 +150,7 @@ export default function CategoriesPage() {
|
||||
|
||||
return { total, count };
|
||||
},
|
||||
[categoryStats, childrenByParent]
|
||||
[categoryStats, childrenByParent],
|
||||
);
|
||||
|
||||
if (isLoadingMetadata || !metadata || isLoadingStats || !categoryStats) {
|
||||
@@ -264,7 +264,7 @@ export default function CategoriesPage() {
|
||||
try {
|
||||
// Fetch uncategorized transactions
|
||||
const uncategorizedResponse = await fetch(
|
||||
"/api/banking/transactions?limit=1000&offset=0&includeUncategorized=true"
|
||||
"/api/banking/transactions?limit=1000&offset=0&includeUncategorized=true",
|
||||
);
|
||||
if (!uncategorizedResponse.ok) {
|
||||
throw new Error("Failed to fetch uncategorized transactions");
|
||||
@@ -277,11 +277,11 @@ export default function CategoriesPage() {
|
||||
for (const transaction of uncategorized) {
|
||||
const categoryId = autoCategorize(
|
||||
transaction.description + " " + (transaction.memo || ""),
|
||||
metadata.categories
|
||||
metadata.categories,
|
||||
);
|
||||
if (categoryId) {
|
||||
const category = metadata.categories.find(
|
||||
(c: Category) => c.id === categoryId
|
||||
(c: Category) => c.id === categoryId,
|
||||
);
|
||||
if (category) {
|
||||
results.push({ transaction, category });
|
||||
@@ -315,9 +315,9 @@ export default function CategoriesPage() {
|
||||
return children.some(
|
||||
(c) =>
|
||||
c.name.toLowerCase().includes(query) ||
|
||||
c.keywords.some((k) => k.toLowerCase().includes(query))
|
||||
c.keywords.some((k) => k.toLowerCase().includes(query)),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -362,9 +362,9 @@ export default function CategoriesPage() {
|
||||
(c) =>
|
||||
c.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
c.keywords.some((k) =>
|
||||
k.toLowerCase().includes(searchQuery.toLowerCase())
|
||||
k.toLowerCase().includes(searchQuery.toLowerCase()),
|
||||
) ||
|
||||
parent.name.toLowerCase().includes(searchQuery.toLowerCase())
|
||||
parent.name.toLowerCase().includes(searchQuery.toLowerCase()),
|
||||
)
|
||||
: allChildren;
|
||||
const stats = getCategoryStats(parent.id, true);
|
||||
@@ -451,7 +451,7 @@ export default function CategoriesPage() {
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground truncate">
|
||||
{new Date(result.transaction.date).toLocaleDateString(
|
||||
"fr-FR"
|
||||
"fr-FR",
|
||||
)}
|
||||
{" • "}
|
||||
{new Intl.NumberFormat("fr-FR", {
|
||||
|
||||
@@ -36,17 +36,15 @@ export default function RulesPage() {
|
||||
const { data: metadata, isLoading: isLoadingMetadata } = useBankingMetadata();
|
||||
|
||||
// Fetch uncategorized transactions only
|
||||
const {
|
||||
data: transactionsData,
|
||||
isLoading: isLoadingTransactions,
|
||||
} = useTransactions(
|
||||
{
|
||||
limit: 10000, // Large limit to get all uncategorized
|
||||
offset: 0,
|
||||
includeUncategorized: true,
|
||||
},
|
||||
!!metadata,
|
||||
);
|
||||
const { data: transactionsData, isLoading: isLoadingTransactions } =
|
||||
useTransactions(
|
||||
{
|
||||
limit: 10000, // Large limit to get all uncategorized
|
||||
offset: 0,
|
||||
includeUncategorized: true,
|
||||
},
|
||||
!!metadata,
|
||||
);
|
||||
|
||||
const _refresh = useCallback(() => {
|
||||
invalidateAllTransactionQueries(queryClient);
|
||||
|
||||
@@ -55,23 +55,23 @@ export default function StatisticsPage() {
|
||||
const { data, isLoading } = useBankingData();
|
||||
const isMobile = useIsMobile();
|
||||
const [sheetOpen, setSheetOpen] = useState(false);
|
||||
|
||||
|
||||
// Persister les filtres dans le localStorage
|
||||
const [period, setPeriod] = useLocalStorage<Period>(
|
||||
"statistics-period",
|
||||
"6months"
|
||||
"6months",
|
||||
);
|
||||
const [selectedAccounts, setSelectedAccounts] = useLocalStorage<string[]>(
|
||||
"statistics-selected-accounts",
|
||||
["all"]
|
||||
["all"],
|
||||
);
|
||||
const [selectedCategories, setSelectedCategories] = useLocalStorage<string[]>(
|
||||
"statistics-selected-categories",
|
||||
["all"]
|
||||
["all"],
|
||||
);
|
||||
const [excludeInternalTransfers, setExcludeInternalTransfers] =
|
||||
useLocalStorage("statistics-exclude-internal-transfers", true);
|
||||
|
||||
|
||||
// Pour les dates, on stocke les ISO strings et on les convertit
|
||||
const [customStartDateISO, setCustomStartDateISO] = useLocalStorage<
|
||||
string | null
|
||||
@@ -79,17 +79,17 @@ export default function StatisticsPage() {
|
||||
const [customEndDateISO, setCustomEndDateISO] = useLocalStorage<
|
||||
string | null
|
||||
>("statistics-custom-end-date", null);
|
||||
|
||||
|
||||
// Convertir les ISO strings en Date
|
||||
const customStartDate = useMemo(
|
||||
() => (customStartDateISO ? new Date(customStartDateISO) : undefined),
|
||||
[customStartDateISO]
|
||||
[customStartDateISO],
|
||||
);
|
||||
const customEndDate = useMemo(
|
||||
() => (customEndDateISO ? new Date(customEndDateISO) : undefined),
|
||||
[customEndDateISO]
|
||||
[customEndDateISO],
|
||||
);
|
||||
|
||||
|
||||
// Fonctions pour mettre à jour les dates avec persistance
|
||||
const setCustomStartDate = (date: Date | undefined) => {
|
||||
setCustomStartDateISO(date ? date.toISOString() : null);
|
||||
@@ -97,7 +97,7 @@ export default function StatisticsPage() {
|
||||
const setCustomEndDate = (date: Date | undefined) => {
|
||||
setCustomEndDateISO(date ? date.toISOString() : null);
|
||||
};
|
||||
|
||||
|
||||
const [isCustomDatePickerOpen, setIsCustomDatePickerOpen] = useState(false);
|
||||
|
||||
// Nettoyer les dates personnalisées quand on change de période (sauf si on passe à "custom")
|
||||
@@ -106,7 +106,13 @@ export default function StatisticsPage() {
|
||||
setCustomStartDateISO(null);
|
||||
setCustomEndDateISO(null);
|
||||
}
|
||||
}, [period, customStartDateISO, customEndDateISO, setCustomStartDateISO, setCustomEndDateISO]);
|
||||
}, [
|
||||
period,
|
||||
customStartDateISO,
|
||||
customEndDateISO,
|
||||
setCustomStartDateISO,
|
||||
setCustomEndDateISO,
|
||||
]);
|
||||
|
||||
// Get start date based on period
|
||||
const startDate = useMemo(() => {
|
||||
@@ -1031,7 +1037,11 @@ export default function StatisticsPage() {
|
||||
selected={customStartDate}
|
||||
onSelect={(date) => {
|
||||
setCustomStartDate(date);
|
||||
if (date && customEndDate && date > customEndDate) {
|
||||
if (
|
||||
date &&
|
||||
customEndDate &&
|
||||
date > customEndDate
|
||||
) {
|
||||
setCustomEndDate(undefined);
|
||||
}
|
||||
}}
|
||||
@@ -1071,26 +1081,26 @@ export default function StatisticsPage() {
|
||||
</div>
|
||||
{customStartDate && customEndDate && (
|
||||
<div className="flex gap-2 pt-2 border-t px-3 pb-3">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="flex-1"
|
||||
onClick={() => {
|
||||
setCustomStartDate(undefined);
|
||||
setCustomEndDate(undefined);
|
||||
}}
|
||||
>
|
||||
Réinitialiser
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
className="flex-1"
|
||||
onClick={() => setIsCustomDatePickerOpen(false)}
|
||||
>
|
||||
Valider
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="flex-1"
|
||||
onClick={() => {
|
||||
setCustomStartDate(undefined);
|
||||
setCustomEndDate(undefined);
|
||||
}}
|
||||
>
|
||||
Réinitialiser
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
className="flex-1"
|
||||
onClick={() => setIsCustomDatePickerOpen(false)}
|
||||
>
|
||||
Valider
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
)}
|
||||
|
||||
@@ -156,7 +156,7 @@ export default function TransactionsPage() {
|
||||
handleBulkReconcile(reconciled, selectedTransactions);
|
||||
clearSelection();
|
||||
},
|
||||
[handleBulkReconcile, selectedTransactions, clearSelection]
|
||||
[handleBulkReconcile, selectedTransactions, clearSelection],
|
||||
);
|
||||
|
||||
const handleBulkSetCategoryWithClear = useCallback(
|
||||
@@ -164,13 +164,13 @@ export default function TransactionsPage() {
|
||||
handleBulkSetCategory(categoryId, selectedTransactions);
|
||||
clearSelection();
|
||||
},
|
||||
[handleBulkSetCategory, selectedTransactions, clearSelection]
|
||||
[handleBulkSetCategory, selectedTransactions, clearSelection],
|
||||
);
|
||||
|
||||
// Stabilize transactions reference to prevent unnecessary re-renders
|
||||
const filteredTransactions = useMemo(
|
||||
() => transactionsData?.transactions || [],
|
||||
[transactionsData?.transactions]
|
||||
[transactionsData?.transactions],
|
||||
);
|
||||
const totalTransactions = transactionsData?.total || 0;
|
||||
const hasMore = transactionsData?.hasMore || false;
|
||||
@@ -188,7 +188,7 @@ export default function TransactionsPage() {
|
||||
const reconciledPercent = useMemo(() => {
|
||||
if (chartTransactions.length === 0) return "0.00";
|
||||
const reconciledCount = chartTransactions.filter(
|
||||
(t) => t.isReconciled
|
||||
(t) => t.isReconciled,
|
||||
).length;
|
||||
return ((reconciledCount / chartTransactions.length) * 100).toFixed(2);
|
||||
}, [chartTransactions]);
|
||||
@@ -196,7 +196,7 @@ export default function TransactionsPage() {
|
||||
const categorizedPercent = useMemo(() => {
|
||||
if (chartTransactions.length === 0) return "0.00";
|
||||
const categorizedCount = chartTransactions.filter(
|
||||
(t) => t.categoryId !== null
|
||||
(t) => t.categoryId !== null,
|
||||
).length;
|
||||
return ((categorizedCount / chartTransactions.length) * 100).toFixed(2);
|
||||
}, [chartTransactions]);
|
||||
@@ -204,7 +204,7 @@ export default function TransactionsPage() {
|
||||
// Persist statistics collapsed state in localStorage
|
||||
const [isStatsExpanded, setIsStatsExpanded] = useLocalStorage(
|
||||
"transactions-stats-expanded",
|
||||
true
|
||||
true,
|
||||
);
|
||||
|
||||
// Early return for loading state - prevents sidebar flash
|
||||
|
||||
Reference in New Issue
Block a user