Descarga de archivos implementada

This commit is contained in:
2026-02-10 13:39:39 -07:00
parent e766e5b747
commit a8e7af87dc
11 changed files with 832 additions and 449 deletions

View File

@@ -9,14 +9,14 @@ interface RequestOptions extends RequestInit {
async function request<T>(endpoint: string, options: RequestOptions = {}): Promise<T> {
const { params, ...init } = options;
let url = `${API_BASE}${endpoint}`;
if (params) {
// Filtrar parámetros undefined y null
const filteredParams = Object.entries(params)
.filter(([key, value]) => value !== undefined && value !== null && value !== '')
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {});
if (Object.keys(filteredParams).length > 0) {
const searchParams = new URLSearchParams(filteredParams);
url += `?${searchParams.toString()}`;
@@ -42,9 +42,9 @@ async function request<T>(endpoint: string, options: RequestOptions = {}): Promi
if (response.status === 401) {
// Token expired or invalid
if (typeof window !== 'undefined') {
localStorage.removeItem('internal_auth_token');
localStorage.removeItem('internal_auth_user');
window.location.href = '/login';
localStorage.removeItem('internal_auth_token');
localStorage.removeItem('internal_auth_user');
window.location.href = '/login';
}
throw new Error('Unauthorized');
}
@@ -56,25 +56,68 @@ async function request<T>(endpoint: string, options: RequestOptions = {}): Promi
// Handle empty responses (like 204 No Content)
if (response.status === 204) {
return {} as T;
return {} as T;
}
return response.json();
}
async function downloadFile(endpoint: string, filename: string): Promise<void> {
const authState = get(auth);
const token = authState.token || (typeof window !== 'undefined' ? localStorage.getItem('internal_auth_token') : null);
const headers = new Headers();
if (token) {
headers.set('Authorization', `Bearer ${token}`);
}
const response = await fetch(`${API_BASE}${endpoint}`, {
method: 'GET',
headers
});
if (response.status === 401) {
if (typeof window !== 'undefined') {
localStorage.removeItem('internal_auth_token');
localStorage.removeItem('internal_auth_user');
window.location.href = '/login';
}
throw new Error('Unauthorized');
}
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.detail || `Download error: ${response.statusText}`);
}
// Crear blob y descargar
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}
export const api = {
get: <T>(endpoint: string, params?: Record<string, string>) =>
get: <T>(endpoint: string, params?: Record<string, string>) =>
request<T>(endpoint, { method: 'GET', params }),
post: <T>(endpoint: string, body: any) =>
post: <T>(endpoint: string, body: any) =>
request<T>(endpoint, { method: 'POST', body: JSON.stringify(body) }),
put: <T>(endpoint: string, body: any) =>
put: <T>(endpoint: string, body: any) =>
request<T>(endpoint, { method: 'PUT', body: JSON.stringify(body) }),
patch: <T>(endpoint: string, body: any) =>
patch: <T>(endpoint: string, body: any) =>
request<T>(endpoint, { method: 'PATCH', body: JSON.stringify(body) }),
delete: <T>(endpoint: string) =>
request<T>(endpoint, { method: 'DELETE' })
delete: <T>(endpoint: string) =>
request<T>(endpoint, { method: 'DELETE' }),
downloadFile: (endpoint: string, filename: string) =>
downloadFile(endpoint, filename)
};