Files
Elecciones-2025/Elecciones-Web/frontend-admin/src/services/apiService.ts

208 lines
6.8 KiB
TypeScript
Raw Normal View History

// src/services/apiService.ts
import axios from 'axios';
import { triggerLogout } from '../context/authUtils';
2025-10-20 14:38:10 -03:00
import type {
CandidatoOverride, AgrupacionPolitica,
UpdateAgrupacionData, Bancada, LogoAgrupacionCategoria,
2025-10-20 14:38:10 -03:00
MunicipioSimple, BancaPrevia, ProvinciaSimple
} from '../types';
2025-09-03 18:49:55 -03:00
/**
* URL base para las llamadas a la API.
*/
const API_URL_BASE = import.meta.env.DEV
? 'http://localhost:5217/api'
: 'https://elecciones2025.eldia.com/api';
/**
* URL completa para el endpoint de autenticación.
*/
export const AUTH_API_URL = `${API_URL_BASE}/auth`;
/**
* URL completa para los endpoints de administración.
*/
export const ADMIN_API_URL = `${API_URL_BASE}/admin`;
// Cliente de API para endpoints de administración (requiere token)
const adminApiClient = axios.create({
baseURL: ADMIN_API_URL,
});
// Cliente de API para endpoints públicos (no envía token)
const apiClient = axios.create({
2025-10-20 14:38:10 -03:00
baseURL: API_URL_BASE,
headers: { 'Content-Type': 'application/json' },
});
// --- INTERCEPTORES (Solo para el cliente de admin) ---
adminApiClient.interceptors.request.use(
(config) => {
const token = localStorage.getItem('admin-jwt-token');
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
adminApiClient.interceptors.response.use(
(response) => response,
(error) => {
if (axios.isAxiosError(error) && error.response?.status === 401) {
console.log("Token expirado o inválido. Deslogueando...");
triggerLogout();
}
return Promise.reject(error);
}
);
// --- INTERFACES PARA COMPOSICIÓN NACIONAL (NECESARIAS PARA EL NUEVO MÉTODO) ---
export interface PartidoComposicionNacional {
2025-10-20 14:38:10 -03:00
id: string;
nombre: string;
nombreCorto: string | null;
color: string | null;
bancasFijos: number;
bancasGanadas: number;
bancasTotales: number;
ordenDiputadosNacionales: number | null;
ordenSenadoresNacionales: number | null;
}
export interface CamaraComposicionNacional {
2025-10-20 14:38:10 -03:00
camaraNombre: string;
totalBancas: number;
bancasEnJuego: number;
partidos: PartidoComposicionNacional[];
presidenteBancada: { color: string | null; tipoBanca: 'ganada' | 'previa' | null } | null;
}
export interface ComposicionNacionalData {
2025-10-20 14:38:10 -03:00
diputados: CamaraComposicionNacional;
senadores: CamaraComposicionNacional;
}
// --- SERVICIOS DE API ---
// 1. Autenticación
export interface LoginCredentials { username: string; password: string; }
export const loginUser = async (credentials: LoginCredentials): Promise<string | null> => {
try {
const response = await axios.post(`${AUTH_API_URL}/login`, credentials);
return response.data.token;
} catch (error) {
console.error("Error during login request:", error);
throw error;
}
};
// 2. Agrupaciones
export const getAgrupaciones = async (): Promise<AgrupacionPolitica[]> => {
const response = await adminApiClient.get('/agrupaciones');
return response.data;
};
export const updateAgrupacion = async (id: string, data: UpdateAgrupacionData): Promise<void> => {
await adminApiClient.put(`/agrupaciones/${id}`, data);
};
// 3. Ordenamiento de Agrupaciones
export const updateOrden = async (camara: 'diputados' | 'senadores' | 'diputados-nacionales' | 'senadores-nacionales', ids: string[]): Promise<void> => {
2025-09-02 15:39:17 -03:00
await adminApiClient.put(`/agrupaciones/orden-${camara}`, ids);
};
// 4. Gestión de Bancas
export const getBancadas = async (camara: 'diputados' | 'senadores', eleccionId: number): Promise<Bancada[]> => {
const camaraId = (camara === 'diputados') ? 0 : 1;
const response = await adminApiClient.get(`/bancadas/${camaraId}?eleccionId=${eleccionId}`);
2025-09-02 15:39:17 -03:00
return response.data;
};
export interface UpdateBancadaData {
2025-09-02 15:39:17 -03:00
agrupacionPoliticaId: string | null;
nombreOcupante: string | null;
fotoUrl: string | null;
periodo: string | null;
}
export const updateBancada = async (bancadaId: number, data: UpdateBancadaData): Promise<void> => {
2025-09-02 15:39:17 -03:00
await adminApiClient.put(`/bancadas/${bancadaId}`, data);
};
// 5. Configuración General
export type ConfiguracionResponse = Record<string, string>;
export const getConfiguracion = async (): Promise<ConfiguracionResponse> => {
2025-09-02 15:39:17 -03:00
const response = await adminApiClient.get('/configuracion');
return response.data;
};
export const updateConfiguracion = async (data: Record<string, string>): Promise<void> => {
2025-09-02 15:39:17 -03:00
await adminApiClient.put('/configuracion', data);
2025-09-01 14:04:40 -03:00
};
// 6. Logos y Candidatos
export const getLogos = async (eleccionId: number): Promise<LogoAgrupacionCategoria[]> => {
const response = await adminApiClient.get(`/logos?eleccionId=${eleccionId}`);
2025-09-02 15:39:17 -03:00
return response.data;
2025-09-01 14:04:40 -03:00
};
export const updateLogos = async (data: LogoAgrupacionCategoria[]): Promise<void> => {
2025-09-02 15:39:17 -03:00
await adminApiClient.put('/logos', data);
};
export const getCandidatos = async (eleccionId: number): Promise<CandidatoOverride[]> => {
const response = await adminApiClient.get(`/candidatos?eleccionId=${eleccionId}`);
return response.data;
};
export const updateCandidatos = async (data: CandidatoOverride[]): Promise<void> => {
await adminApiClient.put('/candidatos', data);
};
2025-09-02 15:39:17 -03:00
// 7. Catálogos
2025-09-02 15:39:17 -03:00
export const getMunicipiosForAdmin = async (): Promise<MunicipioSimple[]> => {
const response = await adminApiClient.get('/catalogos/municipios');
return response.data;
};
// 8. Logging
export interface UpdateLoggingLevelData { level: string; }
export const updateLoggingLevel = async (data: UpdateLoggingLevelData): Promise<void> => {
await adminApiClient.put(`/logging-level`, data);
};
// 9. Bancas Previas
export const getBancasPrevias = async (eleccionId: number): Promise<BancaPrevia[]> => {
2025-10-20 14:38:10 -03:00
const response = await adminApiClient.get(`/bancas-previas/${eleccionId}`);
return response.data;
};
export const updateBancasPrevias = async (eleccionId: number, data: BancaPrevia[]): Promise<void> => {
2025-10-20 14:38:10 -03:00
await adminApiClient.put(`/bancas-previas/${eleccionId}`, data);
};
// 10. Obtener Composición Nacional (Endpoint Público)
export const getComposicionNacional = async (eleccionId: number): Promise<ComposicionNacionalData> => {
2025-10-20 14:38:10 -03:00
// Este es un endpoint público, por lo que usamos el cliente sin token de admin.
const response = await apiClient.get(`/elecciones/${eleccionId}/composicion-nacional`);
return response.data;
};
// Obtenemos las provincias para el selector de ámbito
export const getProvinciasForAdmin = async (): Promise<ProvinciaSimple[]> => {
2025-10-20 14:38:10 -03:00
const response = await adminApiClient.get('/catalogos/provincias');
return response.data;
};
export interface CreateAgrupacionData {
nombre: string;
nombreCorto: string | null;
color: string | null;
}
// Servicio para crear una nueva agrupación
export const createAgrupacion = async (data: CreateAgrupacionData): Promise<AgrupacionPolitica> => {
const response = await adminApiClient.post('/agrupaciones', data);
return response.data;
};