mirror of
https://github.com/escalante29/WealthySmart.git
synced 2026-05-19 10:28:48 +02:00
Add budget module: FastAPI backend + React frontend
Some checks failed
Deploy to VPS / deploy (push) Failing after 7s
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:
69
frontend/src/api.ts
Normal file
69
frontend/src/api.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import axios from 'axios';
|
||||
|
||||
const api = axios.create({
|
||||
baseURL: import.meta.env.VITE_API_URL || '/api/v1',
|
||||
});
|
||||
|
||||
api.interceptors.request.use((config) => {
|
||||
const token = localStorage.getItem('token');
|
||||
if (token) config.headers.Authorization = `Bearer ${token}`;
|
||||
return config;
|
||||
});
|
||||
|
||||
api.interceptors.response.use(
|
||||
(res) => res,
|
||||
(err) => {
|
||||
if (err.response?.status === 401) {
|
||||
localStorage.removeItem('token');
|
||||
window.location.href = '/login';
|
||||
}
|
||||
return Promise.reject(err);
|
||||
},
|
||||
);
|
||||
|
||||
export default api;
|
||||
|
||||
export async function login(username: string, password: string) {
|
||||
const form = new URLSearchParams();
|
||||
form.append('username', username);
|
||||
form.append('password', password);
|
||||
const { data } = await api.post('/auth/login', form);
|
||||
localStorage.setItem('token', data.access_token);
|
||||
return data;
|
||||
}
|
||||
|
||||
export interface Account {
|
||||
id: number;
|
||||
bank: string;
|
||||
currency: string;
|
||||
label: string;
|
||||
balance: number;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface Category {
|
||||
id: number;
|
||||
name: string;
|
||||
icon: string;
|
||||
auto_match_patterns: string | null;
|
||||
}
|
||||
|
||||
export interface Transaction {
|
||||
id: number;
|
||||
amount: number;
|
||||
currency: string;
|
||||
merchant: string;
|
||||
city: string | null;
|
||||
date: string;
|
||||
card_type: string | null;
|
||||
card_last4: string | null;
|
||||
authorization_code: string | null;
|
||||
reference: string | null;
|
||||
transaction_type: string;
|
||||
source: string;
|
||||
bank: string;
|
||||
notes: string | null;
|
||||
category_id: number | null;
|
||||
category: Category | null;
|
||||
created_at: string;
|
||||
}
|
||||
Reference in New Issue
Block a user