Add budget module: FastAPI backend + React frontend
Some checks failed
Deploy to VPS / deploy (push) Failing after 7s

Backend: FastAPI + PostgreSQL with models for accounts, transactions,
and categories. Auto-categorization from merchant patterns, token auth,
CRUD endpoints, and seed data for 16 categories and 4 bank accounts.

Frontend: Login, Dashboard (account balances + recent charges),
Transactions (full CRUD table with search/filter), Cash & Transfers
view. Dark theme with emerald/cyan accents, responsive layout.

Infrastructure: Updated docker-compose for backend + db services,
nginx proxy config for API routing, deploy workflow with secrets.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Carlos Escalante
2026-03-21 11:33:38 -06:00
parent cfd2eba849
commit 13161b8e49
34 changed files with 1855 additions and 112 deletions

View File

@@ -0,0 +1,36 @@
import { createContext, useContext, useState, useEffect, type ReactNode } from 'react';
interface AuthCtx {
isAuthenticated: boolean;
logout: () => void;
setAuthenticated: (v: boolean) => void;
}
const AuthContext = createContext<AuthCtx>({
isAuthenticated: false,
logout: () => {},
setAuthenticated: () => {},
});
export function AuthProvider({ children }: { children: ReactNode }) {
const [isAuthenticated, setAuthenticated] = useState(!!localStorage.getItem('token'));
useEffect(() => {
const check = () => setAuthenticated(!!localStorage.getItem('token'));
window.addEventListener('storage', check);
return () => window.removeEventListener('storage', check);
}, []);
const logout = () => {
localStorage.removeItem('token');
setAuthenticated(false);
};
return (
<AuthContext.Provider value={{ isAuthenticated, logout, setAuthenticated }}>
{children}
</AuthContext.Provider>
);
}
export const useAuth = () => useContext(AuthContext);