chore: init from v0
This commit is contained in:
224
lib/store.ts
Normal file
224
lib/store.ts
Normal file
@@ -0,0 +1,224 @@
|
||||
"use client"
|
||||
|
||||
import type { BankingData, Account, Transaction, Folder, Category } from "./types"
|
||||
|
||||
const STORAGE_KEY = "banking-app-data"
|
||||
|
||||
const defaultCategories: Category[] = [
|
||||
{
|
||||
id: "cat-1",
|
||||
name: "Alimentation",
|
||||
color: "#22c55e",
|
||||
icon: "shopping-cart",
|
||||
keywords: ["carrefour", "leclerc", "auchan", "lidl", "supermarche", "boulangerie", "restaurant"],
|
||||
parentId: null,
|
||||
},
|
||||
{
|
||||
id: "cat-2",
|
||||
name: "Transport",
|
||||
color: "#3b82f6",
|
||||
icon: "car",
|
||||
keywords: ["sncf", "ratp", "uber", "essence", "total", "parking", "peage"],
|
||||
parentId: null,
|
||||
},
|
||||
{
|
||||
id: "cat-3",
|
||||
name: "Logement",
|
||||
color: "#f59e0b",
|
||||
icon: "home",
|
||||
keywords: ["loyer", "edf", "engie", "eau", "assurance habitation"],
|
||||
parentId: null,
|
||||
},
|
||||
{
|
||||
id: "cat-4",
|
||||
name: "Loisirs",
|
||||
color: "#ec4899",
|
||||
icon: "gamepad",
|
||||
keywords: ["cinema", "netflix", "spotify", "fnac", "amazon"],
|
||||
parentId: null,
|
||||
},
|
||||
{
|
||||
id: "cat-5",
|
||||
name: "Santé",
|
||||
color: "#ef4444",
|
||||
icon: "heart",
|
||||
keywords: ["pharmacie", "medecin", "docteur", "hopital", "mutuelle"],
|
||||
parentId: null,
|
||||
},
|
||||
{
|
||||
id: "cat-6",
|
||||
name: "Revenus",
|
||||
color: "#10b981",
|
||||
icon: "wallet",
|
||||
keywords: ["salaire", "virement recu", "remboursement"],
|
||||
parentId: null,
|
||||
},
|
||||
{
|
||||
id: "cat-7",
|
||||
name: "Abonnements",
|
||||
color: "#8b5cf6",
|
||||
icon: "repeat",
|
||||
keywords: ["free", "orange", "sfr", "bouygues", "internet", "telephone"],
|
||||
parentId: null,
|
||||
},
|
||||
{
|
||||
id: "cat-8",
|
||||
name: "Shopping",
|
||||
color: "#06b6d4",
|
||||
icon: "bag",
|
||||
keywords: ["zara", "h&m", "decathlon", "ikea"],
|
||||
parentId: null,
|
||||
},
|
||||
]
|
||||
|
||||
const defaultData: BankingData = {
|
||||
accounts: [],
|
||||
transactions: [],
|
||||
folders: [{ id: "folder-root", name: "Mes Comptes", parentId: null, color: "#6366f1", icon: "folder" }],
|
||||
categories: defaultCategories,
|
||||
categoryRules: [],
|
||||
}
|
||||
|
||||
export function loadData(): BankingData {
|
||||
if (typeof window === "undefined") return defaultData
|
||||
|
||||
const stored = localStorage.getItem(STORAGE_KEY)
|
||||
if (!stored) {
|
||||
saveData(defaultData)
|
||||
return defaultData
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(stored)
|
||||
} catch {
|
||||
return defaultData
|
||||
}
|
||||
}
|
||||
|
||||
export function saveData(data: BankingData): void {
|
||||
if (typeof window === "undefined") return
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(data))
|
||||
}
|
||||
|
||||
export function addAccount(account: Account): BankingData {
|
||||
const data = loadData()
|
||||
data.accounts.push(account)
|
||||
saveData(data)
|
||||
return data
|
||||
}
|
||||
|
||||
export function updateAccount(account: Account): BankingData {
|
||||
const data = loadData()
|
||||
const index = data.accounts.findIndex((a) => a.id === account.id)
|
||||
if (index !== -1) {
|
||||
data.accounts[index] = account
|
||||
saveData(data)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
export function deleteAccount(accountId: string): BankingData {
|
||||
const data = loadData()
|
||||
data.accounts = data.accounts.filter((a) => a.id !== accountId)
|
||||
data.transactions = data.transactions.filter((t) => t.accountId !== accountId)
|
||||
saveData(data)
|
||||
return data
|
||||
}
|
||||
|
||||
export function addTransactions(transactions: Transaction[]): BankingData {
|
||||
const data = loadData()
|
||||
|
||||
// Filter out duplicates based on fitId
|
||||
const existingFitIds = new Set(data.transactions.map((t) => `${t.accountId}-${t.fitId}`))
|
||||
const newTransactions = transactions.filter((t) => !existingFitIds.has(`${t.accountId}-${t.fitId}`))
|
||||
|
||||
data.transactions.push(...newTransactions)
|
||||
saveData(data)
|
||||
return data
|
||||
}
|
||||
|
||||
export function updateTransaction(transaction: Transaction): BankingData {
|
||||
const data = loadData()
|
||||
const index = data.transactions.findIndex((t) => t.id === transaction.id)
|
||||
if (index !== -1) {
|
||||
data.transactions[index] = transaction
|
||||
saveData(data)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
export function addFolder(folder: Folder): BankingData {
|
||||
const data = loadData()
|
||||
data.folders.push(folder)
|
||||
saveData(data)
|
||||
return data
|
||||
}
|
||||
|
||||
export function updateFolder(folder: Folder): BankingData {
|
||||
const data = loadData()
|
||||
const index = data.folders.findIndex((f) => f.id === folder.id)
|
||||
if (index !== -1) {
|
||||
data.folders[index] = folder
|
||||
saveData(data)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
export function deleteFolder(folderId: string): BankingData {
|
||||
const data = loadData()
|
||||
// Move accounts to root
|
||||
data.accounts = data.accounts.map((a) => (a.folderId === folderId ? { ...a, folderId: "folder-root" } : a))
|
||||
// Move subfolders to parent
|
||||
const folder = data.folders.find((f) => f.id === folderId)
|
||||
if (folder) {
|
||||
data.folders = data.folders.map((f) => (f.parentId === folderId ? { ...f, parentId: folder.parentId } : f))
|
||||
}
|
||||
data.folders = data.folders.filter((f) => f.id !== folderId)
|
||||
saveData(data)
|
||||
return data
|
||||
}
|
||||
|
||||
export function addCategory(category: Category): BankingData {
|
||||
const data = loadData()
|
||||
data.categories.push(category)
|
||||
saveData(data)
|
||||
return data
|
||||
}
|
||||
|
||||
export function updateCategory(category: Category): BankingData {
|
||||
const data = loadData()
|
||||
const index = data.categories.findIndex((c) => c.id === category.id)
|
||||
if (index !== -1) {
|
||||
data.categories[index] = category
|
||||
saveData(data)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
export function deleteCategory(categoryId: string): BankingData {
|
||||
const data = loadData()
|
||||
data.categories = data.categories.filter((c) => c.id !== categoryId)
|
||||
// Remove category from transactions
|
||||
data.transactions = data.transactions.map((t) => (t.categoryId === categoryId ? { ...t, categoryId: null } : t))
|
||||
saveData(data)
|
||||
return data
|
||||
}
|
||||
|
||||
// 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) {
|
||||
if (lowerDesc.includes(keyword.toLowerCase())) {
|
||||
return category.id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
export function generateId(): string {
|
||||
return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
|
||||
}
|
||||
Reference in New Issue
Block a user