Refactor: Implement DashboardLayout, fix mobile nav, and resolve scroll issues

This commit is contained in:
ren
2026-01-29 14:41:46 +01:00
parent 0a04e0817d
commit 811c78ffa5
171 changed files with 1678 additions and 23983 deletions

39
lib/otp.ts Normal file
View File

@@ -0,0 +1,39 @@
import fs from 'fs';
import path from 'path';
const OTP_FILE = path.join(process.cwd(), 'auth-otp.json');
interface OTPData {
code: string;
expiresAt: number;
}
export function generateOTP(): string {
return Math.floor(100000 + Math.random() * 900000).toString();
}
export function saveOTP(code: string) {
const data: OTPData = {
code,
expiresAt: Date.now() + 5 * 60 * 1000 // 5 minutes
};
try {
fs.writeFileSync(OTP_FILE, JSON.stringify(data));
} catch (err) {
console.error("Error saving OTP:", err);
}
}
export function verifyOTP(code: string): boolean {
if (!fs.existsSync(OTP_FILE)) return false;
try {
const data: OTPData = JSON.parse(fs.readFileSync(OTP_FILE, 'utf8'));
if (Date.now() > data.expiresAt) return false;
// Simple check
return String(data.code).trim() === String(code).trim();
} catch (e) {
console.error("Error verifying OTP:", e);
return false;
}
}

39
lib/server-db.ts Normal file
View File

@@ -0,0 +1,39 @@
import fs from 'fs';
import path from 'path';
import { AppState } from './types';
const DB_FILE = path.join(process.cwd(), 'data', 'db.json');
const defaultState: AppState = {
fixedDebts: [],
variableDebts: [],
creditCards: [],
cardPayments: [],
incomes: [],
monthlyBudgets: [],
serviceBills: [],
alerts: [],
currentMonth: new Date().getMonth(),
currentYear: new Date().getFullYear(),
};
export function getDatabase(): AppState {
if (!fs.existsSync(DB_FILE)) {
saveDatabase(defaultState);
return defaultState;
}
try {
return JSON.parse(fs.readFileSync(DB_FILE, 'utf8'));
} catch (error) {
console.error('Database read error:', error);
return defaultState;
}
}
export function saveDatabase(data: AppState) {
try {
fs.writeFileSync(DB_FILE, JSON.stringify(data, null, 2));
} catch (error) {
console.error('Database write error:', error);
}
}

View File

@@ -5,12 +5,13 @@ import { createDebtsSlice, DebtsSlice } from './store/slices/debtsSlice'
import { createCardsSlice, CardsSlice } from './store/slices/cardsSlice'
import { createBudgetSlice, BudgetSlice } from './store/slices/budgetSlice'
import { createAlertsSlice, AlertsSlice } from './store/slices/alertsSlice'
import { createIncomesSlice, IncomesSlice } from './store/slices/incomesSlice'
import { createServicesSlice, ServicesSlice } from './store/slices/servicesSlice'
// Combined State Interface
// Note: We extend the individual slices to create the full store interface
export interface FinanzasState extends DebtsSlice, CardsSlice, BudgetSlice, AlertsSlice, ServicesSlice { }
export interface FinanzasState extends DebtsSlice, CardsSlice, BudgetSlice, AlertsSlice, ServicesSlice, IncomesSlice { }
export const useFinanzasStore = create<FinanzasState>()(
persist(
@@ -20,6 +21,7 @@ export const useFinanzasStore = create<FinanzasState>()(
...createBudgetSlice(...a),
...createAlertsSlice(...a),
...createServicesSlice(...a),
...createIncomesSlice(...a),
}),
{
name: 'finanzas-storage',

View File

@@ -0,0 +1,33 @@
import { StateCreator } from 'zustand'
import { Income, AppState } from '@/lib/types'
import { v4 as uuidv4 } from 'uuid'
export interface IncomesSlice {
incomes: Income[]
addIncome: (income: Omit<Income, 'id'>) => void
removeIncome: (id: string) => void
updateIncome: (id: string, income: Partial<Income>) => void
}
export const createIncomesSlice: StateCreator<
AppState & IncomesSlice,
[],
[],
IncomesSlice
> = (set) => ({
incomes: [],
addIncome: (income) =>
set((state) => ({
incomes: [...(state.incomes || []), { ...income, id: uuidv4() }],
})),
removeIncome: (id) =>
set((state) => ({
incomes: state.incomes.filter((i) => i.id !== id),
})),
updateIncome: (id, updatedIncome) =>
set((state) => ({
incomes: state.incomes.map((i) =>
i.id === id ? { ...i, ...updatedIncome } : i
),
})),
})

View File

@@ -74,11 +74,20 @@ export interface ServiceBill {
notes?: string
}
export interface Income {
id: string
amount: number
description: string
date: string
category: 'salary' | 'freelance' | 'business' | 'gift' | 'other'
}
export interface AppState {
fixedDebts: FixedDebt[]
variableDebts: VariableDebt[]
creditCards: CreditCard[]
cardPayments: CardPayment[]
incomes: Income[] // Added incomes
monthlyBudgets: MonthlyBudget[]
serviceBills: ServiceBill[]
alerts: Alert[]