ente_nazionale_frontend/lib/api.ts
Linas cb0c8dc140 Add missing lib/ (API client, auth, models) and logo asset
lib/ was never committed despite every page importing from it - a
fresh clone couldn't build. public/logo-encap.jpg was likewise
missing even though app/login/page.tsx already references it.
Also gitignore .idea/, which shouldn't be tracked.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017hQcuUQFue2bFvrYw2UQhK
2026-08-24 17:20:22 +03:00

175 lines
4.5 KiB
TypeScript

const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL ?? 'http://localhost:8080/api';
import { LoginResponse, User, Association } from "./models";
// Store token in localStorage (we'll improve this later)
export function setAuthToken(token: string) {
localStorage.setItem('auth_token', token);
}
export function getAuthToken(): string | null {
return localStorage.getItem('auth_token');
}
export function removeAuthToken() {
localStorage.removeItem('auth_token');
}
// Helper to add Authorization header
function getHeaders(): HeadersInit {
const headers: HeadersInit = {
'Content-Type': 'application/json',
};
const token = getAuthToken();
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
return headers;
}
export async function login(email: string, password: string): Promise<LoginResponse> {
const response = await fetch(`${API_BASE_URL}/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password }),
});
if (!response.ok) {
throw new Error('Invalid credentials');
}
const data: LoginResponse = await response.json();
setAuthToken(data.token); // Store token
return data;
}
export async function getAssociation(id: string): Promise<Association> {
const response = await fetch(`${API_BASE_URL}/associations/${id}`, {
headers: getHeaders(),
});
if (!response.ok) {
if (response.status === 401 || response.status === 403) {
removeAuthToken();
throw new Error('Unauthorized');
}
throw new Error('Failed to fetch association');
}
return response.json();
}
export async function getAssociations(): Promise<Association[]> {
const response = await fetch(`${API_BASE_URL}/associations`, {
headers: getHeaders(),
});
if (!response.ok) {
if (response.status === 401 || response.status === 403) {
removeAuthToken();
throw new Error('Unauthorized');
}
throw new Error('Failed to fetch associations');
}
return response.json();
}
export async function createAssociation(association: Omit<Association, 'id' | 'created' | 'translit'>): Promise<Association> {
const response = await fetch(`${API_BASE_URL}/associations`, {
method: 'POST',
headers: getHeaders(),
body: JSON.stringify(association),
});
if (!response.ok) {
throw new Error('Failed to create association');
}
return response.json();
}
export async function updateAssociation(id: string, association: Association): Promise<Association> {
const response = await fetch(`${API_BASE_URL}/associations/${id}`, {
method: 'PUT',
headers: getHeaders(),
body: JSON.stringify(association),
});
if (!response.ok) {
if (response.status === 401 || response.status === 403) {
removeAuthToken();
throw new Error('Unauthorized');
}
throw new Error('Failed to update association');
}
return response.json();
}
export async function downloadAttestato(id: string, associationName: string): Promise<void> {
const response = await fetch(`${API_BASE_URL}/associations/${id}/attestato`, {
headers: getHeaders(),
});
if (!response.ok) {
if (response.status === 401 || response.status === 403) {
removeAuthToken();
throw new Error('Unauthorized');
}
throw new Error('Failed to generate attestato');
}
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = `attestato-${associationName}.pdf`;
document.body.appendChild(link);
link.click();
link.remove();
window.URL.revokeObjectURL(url);
}
export async function deleteAssociation(id: string): Promise<void> {
const response = await fetch(`${API_BASE_URL}/associations/${id}`, {
method: 'DELETE',
headers: getHeaders(),
});
if (!response.ok) {
if (response.status === 401 || response.status === 403) {
removeAuthToken();
throw new Error('Unauthorized');
}
throw new Error('Failed to delete association');
}
}
export function logout() {
removeAuthToken();
}
export async function verifyToken(): Promise<boolean> {
try {
const token = getAuthToken();
if (!token) return false;
const response = await fetch(`${API_BASE_URL}/associations`, {
headers: getHeaders(),
});
if (response.status === 401 || response.status === 403) {
removeAuthToken();
return false;
}
return response.ok;
} catch (error) {
console.error("verifyToken error:", error);
return false;
}
}