"use client"; import type { BankingData, Account, Transaction, Folder, Category, } from "./types"; const API_BASE = "/api/banking"; export async function loadData(): Promise { const response = await fetch(API_BASE); if (!response.ok) { throw new Error("Failed to load data"); } return response.json(); } export async function addAccount( account: Omit, ): Promise { const response = await fetch(`${API_BASE}/accounts`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(account), }); if (!response.ok) { throw new Error("Failed to add account"); } return response.json(); } export async function updateAccount(account: Account): Promise { const response = await fetch(`${API_BASE}/accounts`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(account), }); if (!response.ok) { throw new Error("Failed to update account"); } return response.json(); } export async function deleteAccount(accountId: string): Promise { const response = await fetch(`${API_BASE}/accounts?id=${accountId}`, { method: "DELETE", }); if (!response.ok) { throw new Error("Failed to delete account"); } } export async function addTransactions( transactions: Transaction[], ): Promise<{ count: number; transactions: Transaction[] }> { const response = await fetch(`${API_BASE}/transactions`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(transactions), }); if (!response.ok) { throw new Error("Failed to add transactions"); } return response.json(); } export async function updateTransaction( transaction: Transaction, ): Promise { const response = await fetch(`${API_BASE}/transactions`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(transaction), }); if (!response.ok) { throw new Error("Failed to update transaction"); } return response.json(); } export async function addFolder(folder: Omit): Promise { const response = await fetch(`${API_BASE}/folders`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(folder), }); if (!response.ok) { throw new Error("Failed to add folder"); } return response.json(); } export async function updateFolder(folder: Folder): Promise { const response = await fetch(`${API_BASE}/folders`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(folder), }); if (!response.ok) { throw new Error("Failed to update folder"); } return response.json(); } export async function deleteFolder(folderId: string): Promise { const response = await fetch(`${API_BASE}/folders?id=${folderId}`, { method: "DELETE", }); if (!response.ok) { throw new Error("Failed to delete folder"); } } export async function addCategory( category: Omit, ): Promise { const response = await fetch(`${API_BASE}/categories`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(category), }); if (!response.ok) { throw new Error("Failed to add category"); } return response.json(); } export async function updateCategory(category: Category): Promise { const response = await fetch(`${API_BASE}/categories`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(category), }); if (!response.ok) { throw new Error("Failed to update category"); } return response.json(); } export async function deleteCategory(categoryId: string): Promise { const response = await fetch(`${API_BASE}/categories?id=${categoryId}`, { method: "DELETE", }); if (!response.ok) { throw new Error("Failed to delete category"); } } // Auto-categorize a transaction based on keywords export function autoCategorize( description: string, categories: Category[], ): string | null { const lowerDesc = description.toLowerCase(); for (const category of categories) { for (const keyword of category.keywords) { const lowerKeyword = keyword.toLowerCase(); // Pour les keywords courts (< 6 chars), matcher uniquement des mots entiers // Évite les faux positifs comme "chat" dans "achat" if (lowerKeyword.length < 6) { const wordBoundary = new RegExp(`\\b${escapeRegex(lowerKeyword)}\\b`); if (wordBoundary.test(lowerDesc)) { return category.id; } } else { // Pour les keywords plus longs, includes() suffit if (lowerDesc.includes(lowerKeyword)) { return category.id; } } } } return null; } // Échappe les caractères spéciaux pour les regex function escapeRegex(str: string): string { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } export function generateId(): string { return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; }