chore: standardize quotes in pnpm-lock.yaml and clean up formatting in various files for improved readability

This commit is contained in:
Julien Froidefond
2025-12-06 12:38:45 +01:00
parent ad8b936c7a
commit a7f3433f5f
11 changed files with 4385 additions and 2512 deletions

View File

@@ -16,3 +16,4 @@ README.md

View File

@@ -62,10 +62,8 @@ function FolderDropZone({
export default function AccountsPage() {
const queryClient = useQueryClient();
const { data: metadata, isLoading: isLoadingMetadata } = useBankingMetadata();
const {
data: accountsWithStats,
isLoading: isLoadingAccounts,
} = useAccountsWithStats();
const { data: accountsWithStats, isLoading: isLoadingAccounts } =
useAccountsWithStats();
// refresh function is not used directly, invalidations are done inline
@@ -105,12 +103,19 @@ export default function AccountsPage() {
}),
);
if (isLoadingMetadata || !metadata || isLoadingAccounts || !accountsWithStats) {
if (
isLoadingMetadata ||
!metadata ||
isLoadingAccounts ||
!accountsWithStats
) {
return <LoadingState />;
}
// Convert accountsWithStats to regular accounts for compatibility
const accounts = accountsWithStats.map(({ transactionCount: _transactionCount, ...account }) => account);
const accounts = accountsWithStats.map(
({ transactionCount: _transactionCount, ...account }) => account,
);
const formatCurrency = (amount: number) => {
return new Intl.NumberFormat("fr-FR", {

View File

@@ -21,10 +21,7 @@ export async function GET(request: NextRequest) {
});
}
return NextResponse.json(
{ error: "Invalid request" },
{ status: 400 },
);
return NextResponse.json({ error: "Invalid request" }, { status: 400 });
} catch (error) {
console.error("Error fetching accounts:", error);
return NextResponse.json(

View File

@@ -21,10 +21,7 @@ export async function GET(request: NextRequest) {
});
}
return NextResponse.json(
{ error: "Invalid request" },
{ status: 400 },
);
return NextResponse.json({ error: "Invalid request" }, { status: 400 });
} catch (error) {
console.error("Error fetching category stats:", error);
return NextResponse.json(

View File

@@ -41,7 +41,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: "",
@@ -52,7 +52,7 @@ export default function CategoriesPage() {
});
const [searchQuery, setSearchQuery] = useState("");
const [recatResults, setRecatResults] = useState<RecategorizationResult[]>(
[]
[],
);
const [isRecatDialogOpen, setIsRecatDialogOpen] = useState(false);
const [isRecategorizing, setIsRecategorizing] = useState(false);
@@ -68,7 +68,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[] = [];
@@ -77,7 +77,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!]) {
@@ -136,7 +136,7 @@ export default function CategoriesPage() {
return { total, count };
},
[categoryStats, childrenByParent]
[categoryStats, childrenByParent],
);
if (isLoadingMetadata || !metadata || isLoadingStats || !categoryStats) {
@@ -248,7 +248,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");
@@ -261,11 +261,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 });
@@ -299,9 +299,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 (
@@ -346,9 +346,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);
@@ -435,7 +435,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", {

View File

@@ -12,10 +12,7 @@ import { useQueryClient } from "@tanstack/react-query";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Sparkles, RefreshCw } from "lucide-react";
import {
updateCategory,
autoCategorize,
} from "@/lib/store-db";
import { updateCategory, autoCategorize } from "@/lib/store-db";
import {
normalizeDescription,
suggestKeyword,
@@ -260,7 +257,12 @@ export default function RulesPage() {
[refresh],
);
if (isLoadingMetadata || !metadata || isLoadingTransactions || !transactionsData) {
if (
isLoadingMetadata ||
!metadata ||
isLoadingTransactions ||
!transactionsData
) {
return <LoadingState />;
}

View File

@@ -60,20 +60,20 @@ export default function TransactionsPage() {
const [showReconciled, setShowReconciled] = useState<string>("all");
const [period, setPeriod] = useState<Period>("all");
const [customStartDate, setCustomStartDate] = useState<Date | undefined>(
undefined
undefined,
);
const [customEndDate, setCustomEndDate] = useState<Date | undefined>(
undefined
undefined,
);
const [isCustomDatePickerOpen, setIsCustomDatePickerOpen] = useState(false);
const [sortField, setSortField] = useState<SortField>("date");
const [sortOrder, setSortOrder] = useState<SortOrder>("desc");
const [selectedTransactions, setSelectedTransactions] = useState<Set<string>>(
new Set()
new Set(),
);
const [ruleDialogOpen, setRuleDialogOpen] = useState(false);
const [ruleTransaction, setRuleTransaction] = useState<Transaction | null>(
null
null,
);
// Get start date based on period
@@ -188,7 +188,7 @@ export default function TransactionsPage() {
// Use transactions from current page to find similar ones
const normalizedDesc = normalizeDescription(ruleTransaction.description);
const similarTransactions = transactionsData.transactions.filter(
(t) => normalizeDescription(t.description) === normalizedDesc
(t) => normalizeDescription(t.description) === normalizedDesc,
);
if (similarTransactions.length === 0) return null;
@@ -199,7 +199,7 @@ export default function TransactionsPage() {
transactions: similarTransactions,
totalAmount: similarTransactions.reduce((sum, t) => sum + t.amount, 0),
suggestedKeyword: suggestKeyword(
similarTransactions.map((t) => t.description)
similarTransactions.map((t) => t.description),
),
};
}, [ruleTransaction, transactionsData]);
@@ -215,7 +215,7 @@ export default function TransactionsPage() {
// 1. Add keyword to category
const category = metadata.categories.find(
(c: { id: string }) => c.id === ruleData.categoryId
(c: { id: string }) => c.id === ruleData.categoryId,
);
if (!category) {
throw new Error("Category not found");
@@ -223,7 +223,7 @@ export default function TransactionsPage() {
// Check if keyword already exists
const keywordExists = category.keywords.some(
(k: string) => k.toLowerCase() === ruleData.keyword.toLowerCase()
(k: string) => k.toLowerCase() === ruleData.keyword.toLowerCase(),
);
if (!keywordExists) {
@@ -241,8 +241,8 @@ export default function TransactionsPage() {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ id, categoryId: ruleData.categoryId }),
})
)
}),
),
);
}
@@ -251,7 +251,7 @@ export default function TransactionsPage() {
queryClient.invalidateQueries({ queryKey: ["banking-metadata"] });
setRuleDialogOpen(false);
},
[metadata, queryClient]
[metadata, queryClient],
);
const invalidateAll = useCallback(() => {
@@ -282,7 +282,7 @@ export default function TransactionsPage() {
if (!transactionsData) return;
const transaction = transactionsData.transactions.find(
(t) => t.id === transactionId
(t) => t.id === transactionId,
);
if (!transaction) return;
@@ -307,7 +307,7 @@ export default function TransactionsPage() {
if (!transactionsData) return;
const transaction = transactionsData.transactions.find(
(t) => t.id === transactionId
(t) => t.id === transactionId,
);
if (!transaction || transaction.isReconciled) return;
@@ -330,12 +330,12 @@ export default function TransactionsPage() {
const setCategory = async (
transactionId: string,
categoryId: string | null
categoryId: string | null,
) => {
if (!transactionsData) return;
const transaction = transactionsData.transactions.find(
(t) => t.id === transactionId
(t) => t.id === transactionId,
);
if (!transaction) return;
@@ -357,7 +357,7 @@ export default function TransactionsPage() {
if (!transactionsData) return;
const transactionsToUpdate = transactionsData.transactions.filter((t) =>
selectedTransactions.has(t.id)
selectedTransactions.has(t.id),
);
setSelectedTransactions(new Set());
@@ -369,8 +369,8 @@ export default function TransactionsPage() {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ ...t, isReconciled: reconciled }),
})
)
}),
),
);
invalidateTransactions();
} catch (error) {
@@ -382,7 +382,7 @@ export default function TransactionsPage() {
if (!transactionsData) return;
const transactionsToUpdate = transactionsData.transactions.filter((t) =>
selectedTransactions.has(t.id)
selectedTransactions.has(t.id),
);
setSelectedTransactions(new Set());
@@ -394,8 +394,8 @@ export default function TransactionsPage() {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ ...t, categoryId }),
})
)
}),
),
);
invalidateTransactions();
} catch (error) {
@@ -409,7 +409,7 @@ export default function TransactionsPage() {
setSelectedTransactions(new Set());
} else {
setSelectedTransactions(
new Set(transactionsData.transactions.map((t) => t.id))
new Set(transactionsData.transactions.map((t) => t.id)),
);
}
};
@@ -445,7 +445,7 @@ export default function TransactionsPage() {
`/api/banking/transactions?id=${transactionId}`,
{
method: "DELETE",
}
},
);
if (!response.ok) throw new Error("Failed to delete transaction");
invalidateTransactions();

View File

@@ -22,4 +22,3 @@ export function QueryProvider({ children }: { children: React.ReactNode }) {
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);
}

View File

@@ -137,7 +137,9 @@ export function useTransactions(
export function useCategoryStats() {
return useQuery({
queryKey: ["category-stats"],
queryFn: async (): Promise<Record<string, { count: number; total: number }>> => {
queryFn: async (): Promise<
Record<string, { count: number; total: number }>
> => {
const response = await fetch("/api/banking/categories?statsOnly=true");
if (!response.ok) {
throw new Error("Failed to fetch category stats");

6735
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -154,10 +154,7 @@ export const bankingService = {
if (categoryIds && categoryIds.length > 0) {
if (includeUncategorized) {
categoryFilter.push({
OR: [
{ categoryId: { in: categoryIds } },
{ categoryId: null },
],
OR: [{ categoryId: { in: categoryIds } }, { categoryId: null }],
});
} else {
categoryFilter.push({ categoryId: { in: categoryIds } });
@@ -311,7 +308,9 @@ export const bankingService = {
};
},
async getCategoryStats(): Promise<Record<string, { count: number; total: number }>> {
async getCategoryStats(): Promise<
Record<string, { count: number; total: number }>
> {
// Get stats for all categories in one query using aggregation
// We need to sum absolute values, so we'll do it in two steps
const stats = await prisma.transaction.groupBy({
@@ -380,8 +379,7 @@ export const bankingService = {
countMap.set(tc.accountId, tc._count.id);
});
return accounts.map(
(a): Account & { transactionCount: number } => ({
return accounts.map((a): Account & { transactionCount: number } => ({
id: a.id,
name: a.name,
bankId: a.bankId,
@@ -394,7 +392,6 @@ export const bankingService = {
lastImport: a.lastImport,
externalUrl: a.externalUrl,
transactionCount: countMap.get(a.id) || 0,
}),
);
}));
},
};