Set up initial frontend with Vite and integrated Docker for full-stack build

This commit is contained in:
alexandre grondin
2026-04-19 22:24:59 +02:00
commit ac63c4be99
37 changed files with 9796 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
// Centralized API client
// Injects Authorization + X-Budget-Id headers on every request
const BASE = '/api'
function getToken() {
return localStorage.getItem('budget-token')
}
function getActiveBudgetId() {
return localStorage.getItem('budget-active-id') || '1'
}
export async function apiFetch(method, path, body) {
const token = getToken()
const headers = { 'Content-Type': 'application/json' }
if (token) {
headers['Authorization'] = 'Bearer ' + token
}
// X-Budget-Id sera utilisé à l'étape 2 (middleware backend)
headers['X-Budget-Id'] = getActiveBudgetId()
const opts = { method, headers }
if (body !== undefined) opts.body = JSON.stringify(body)
const res = await fetch(BASE + path, opts)
if (res.status === 401) {
// Token expiré : vider la session
localStorage.removeItem('budget-token')
window.dispatchEvent(new Event('auth:expired'))
throw new Error('Session expirée')
}
if (!res.ok) {
const data = await res.json().catch(() => ({}))
throw new Error(data.error || 'Erreur serveur')
}
return res.json()
}
export const api = {
get: (path) => apiFetch('GET', path),
post: (path, body) => apiFetch('POST', path, body),
put: (path, body) => apiFetch('PUT', path, body),
delete: (path) => apiFetch('DELETE', path),
}