feat: initial commit - finanzas app

Complete personal finance management application with:
- Dashboard with financial metrics and alerts
- Credit card management and payments
- Fixed and variable debt tracking
- Monthly budget planning
- Intelligent alert system
- Responsive design with Tailwind CSS

Tech stack: Next.js 14, TypeScript, Zustand, Recharts

🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
renato97
2026-01-29 00:00:32 +00:00
commit 712b06f118
65 changed files with 8556 additions and 0 deletions

View File

@@ -0,0 +1,45 @@
import { StateCreator } from 'zustand'
import { v4 as uuidv4 } from 'uuid'
import { Alert } from '@/lib/types'
export interface AlertsSlice {
alerts: Alert[]
addAlert: (alert: Omit<Alert, 'id' | 'date'>) => void
markAlertAsRead: (id: string) => void
deleteAlert: (id: string) => void
clearAllAlerts: () => void
}
export const createAlertsSlice: StateCreator<AlertsSlice> = (set) => ({
alerts: [],
addAlert: (alert) =>
set((state) => ({
alerts: [
...state.alerts,
{
...alert,
id: uuidv4(),
date: new Date().toISOString(),
},
],
})),
markAlertAsRead: (id) =>
set((state) => ({
alerts: state.alerts.map((a) =>
a.id === id ? { ...a, isRead: true } : a
),
})),
deleteAlert: (id) =>
set((state) => ({
alerts: state.alerts.filter((a) => a.id !== id),
})),
clearAllAlerts: () =>
set(() => ({
alerts: [],
})),
})

View File

@@ -0,0 +1,39 @@
import { StateCreator } from 'zustand'
import { MonthlyBudget } from '@/lib/types'
const now = new Date()
export interface BudgetSlice {
monthlyBudgets: MonthlyBudget[]
currentMonth: number
currentYear: number
setMonthlyBudget: (budget: MonthlyBudget) => void
updateMonthlyBudget: (month: number, year: number, updates: Partial<MonthlyBudget>) => void
}
export const createBudgetSlice: StateCreator<BudgetSlice> = (set) => ({
monthlyBudgets: [],
currentMonth: now.getMonth() + 1,
currentYear: now.getFullYear(),
setMonthlyBudget: (budget) =>
set((state) => {
const existingIndex = state.monthlyBudgets.findIndex(
(b) => b.month === budget.month && b.year === budget.year
)
if (existingIndex >= 0) {
const newBudgets = [...state.monthlyBudgets]
newBudgets[existingIndex] = budget
return { monthlyBudgets: newBudgets }
}
return { monthlyBudgets: [...state.monthlyBudgets, budget] }
}),
updateMonthlyBudget: (month, year, updates) =>
set((state) => ({
monthlyBudgets: state.monthlyBudgets.map((b) =>
b.month === month && b.year === year ? { ...b, ...updates } : b
),
})),
})

View File

@@ -0,0 +1,47 @@
import { StateCreator } from 'zustand'
import { v4 as uuidv4 } from 'uuid'
import { CreditCard, CardPayment } from '@/lib/types'
export interface CardsSlice {
creditCards: CreditCard[]
cardPayments: CardPayment[]
addCreditCard: (card: Omit<CreditCard, 'id'>) => void
updateCreditCard: (id: string, card: Partial<CreditCard>) => void
deleteCreditCard: (id: string) => void
addCardPayment: (payment: Omit<CardPayment, 'id'>) => void
deleteCardPayment: (id: string) => void
}
export const createCardsSlice: StateCreator<CardsSlice> = (set) => ({
creditCards: [],
cardPayments: [],
addCreditCard: (card) =>
set((state) => ({
creditCards: [...state.creditCards, { ...card, id: uuidv4() }],
})),
updateCreditCard: (id, card) =>
set((state) => ({
creditCards: state.creditCards.map((c) =>
c.id === id ? { ...c, ...card } : c
),
})),
deleteCreditCard: (id) =>
set((state) => ({
creditCards: state.creditCards.filter((c) => c.id !== id),
})),
addCardPayment: (payment) =>
set((state) => ({
cardPayments: [...state.cardPayments, { ...payment, id: uuidv4() }],
})),
deleteCardPayment: (id) =>
set((state) => ({
cardPayments: state.cardPayments.filter((p) => p.id !== id),
})),
})

View File

@@ -0,0 +1,73 @@
import { StateCreator } from 'zustand'
import { v4 as uuidv4 } from 'uuid'
import { FixedDebt, VariableDebt } from '@/lib/types'
export interface DebtsSlice {
fixedDebts: FixedDebt[]
variableDebts: VariableDebt[]
// Actions Fixed
addFixedDebt: (debt: Omit<FixedDebt, 'id'>) => void
updateFixedDebt: (id: string, debt: Partial<FixedDebt>) => void
deleteFixedDebt: (id: string) => void
toggleFixedDebtPaid: (id: string) => void
// Actions Variable
addVariableDebt: (debt: Omit<VariableDebt, 'id'>) => void
updateVariableDebt: (id: string, debt: Partial<VariableDebt>) => void
deleteVariableDebt: (id: string) => void
toggleVariableDebtPaid: (id: string) => void
}
export const createDebtsSlice: StateCreator<DebtsSlice> = (set) => ({
fixedDebts: [],
variableDebts: [],
addFixedDebt: (debt) =>
set((state) => ({
fixedDebts: [...state.fixedDebts, { ...debt, id: uuidv4() }],
})),
updateFixedDebt: (id, debt) =>
set((state) => ({
fixedDebts: state.fixedDebts.map((d) =>
d.id === id ? { ...d, ...debt } : d
),
})),
deleteFixedDebt: (id) =>
set((state) => ({
fixedDebts: state.fixedDebts.filter((d) => d.id !== id),
})),
toggleFixedDebtPaid: (id) =>
set((state) => ({
fixedDebts: state.fixedDebts.map((d) =>
d.id === id ? { ...d, isPaid: !d.isPaid } : d
),
})),
addVariableDebt: (debt) =>
set((state) => ({
variableDebts: [...state.variableDebts, { ...debt, id: uuidv4() }],
})),
updateVariableDebt: (id, debt) =>
set((state) => ({
variableDebts: state.variableDebts.map((d) =>
d.id === id ? { ...d, ...debt } : d
),
})),
deleteVariableDebt: (id) =>
set((state) => ({
variableDebts: state.variableDebts.filter((d) => d.id !== id),
})),
toggleVariableDebtPaid: (id) =>
set((state) => ({
variableDebts: state.variableDebts.map((d) =>
d.id === id ? { ...d, isPaid: !d.isPaid } : d
),
})),
})