Initial commit
This commit is contained in:
328
services/phaseTemplateService.ts
Normal file
328
services/phaseTemplateService.ts
Normal file
@@ -0,0 +1,328 @@
|
||||
/**
|
||||
* Service pour la gestion des templates de phases BTP via l'API backend
|
||||
* Remplace l'utilisation des données statiques par des appels API
|
||||
*/
|
||||
|
||||
import { TypeChantier, PhaseTemplate, ChantierTemplate, TYPE_CHANTIER_LABELS, CATEGORIES_CHANTIER } from '../types/chantier-templates';
|
||||
import { PhaseChantier } from '../types/btp-extended';
|
||||
|
||||
class PhaseTemplateService {
|
||||
|
||||
private apiBaseUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8080/api/v1';
|
||||
|
||||
/**
|
||||
* Récupérer la liste des types de chantiers disponibles depuis l'API
|
||||
*/
|
||||
async getAvailableChantierTypes(): Promise<{ value: TypeChantier; label: string; categorie: string }[]> {
|
||||
try {
|
||||
const response = await fetch(`${this.apiBaseUrl}/phase-templates/types-chantier`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem('token')}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Erreur lors de la récupération des types de chantiers');
|
||||
}
|
||||
|
||||
const typesFromAPI = await response.json();
|
||||
|
||||
// Mapper les types de l'API vers le format attendu par le frontend
|
||||
const mappedTypes = typesFromAPI.map((type: any) => {
|
||||
// Trouver la catégorie correspondante
|
||||
let categorie = 'Autre';
|
||||
for (const [cat, config] of Object.entries(CATEGORIES_CHANTIER)) {
|
||||
if (config.types.includes(type as TypeChantier)) {
|
||||
categorie = config.label;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
value: type as TypeChantier,
|
||||
label: TYPE_CHANTIER_LABELS[type as TypeChantier] || type,
|
||||
categorie: categorie
|
||||
};
|
||||
});
|
||||
|
||||
return mappedTypes;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur lors de la récupération des types de chantiers:', error);
|
||||
// Fallback vers les données locales si l'API est indisponible
|
||||
return this.getLocalChantierTypes();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupérer les templates de phases pour un type de chantier
|
||||
*/
|
||||
async getTemplatesByType(typeChantier: TypeChantier): Promise<PhaseTemplate[]> {
|
||||
try {
|
||||
const response = await fetch(`${this.apiBaseUrl}/phase-templates/by-type/${typeChantier}`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem('token')}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Erreur lors de la récupération des templates');
|
||||
}
|
||||
|
||||
const templates = await response.json();
|
||||
return templates;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur lors de la récupération des templates:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupérer un template par son ID avec ses sous-phases
|
||||
*/
|
||||
async getTemplateById(id: string): Promise<PhaseTemplate | null> {
|
||||
try {
|
||||
const response = await fetch(`${this.apiBaseUrl}/phase-templates/${id}`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem('token')}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (response.status === 404) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Erreur lors de la récupération du template');
|
||||
}
|
||||
|
||||
const template = await response.json();
|
||||
return template;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur lors de la récupération du template:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prévisualiser les phases qui seraient générées pour un type de chantier
|
||||
*/
|
||||
async previewPhases(typeChantier: TypeChantier): Promise<PhaseTemplate[]> {
|
||||
try {
|
||||
const response = await fetch(`${this.apiBaseUrl}/phase-templates/previsualisation/${typeChantier}`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem('token')}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Erreur lors de la prévisualisation des phases');
|
||||
}
|
||||
|
||||
const phases = await response.json();
|
||||
return phases;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur lors de la prévisualisation des phases:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculer la durée totale estimée pour un type de chantier
|
||||
*/
|
||||
async calculateDureeTotale(typeChantier: TypeChantier): Promise<number> {
|
||||
try {
|
||||
const response = await fetch(`${this.apiBaseUrl}/phase-templates/duree-estimee/${typeChantier}`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem('token')}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Erreur lors du calcul de la durée');
|
||||
}
|
||||
|
||||
const duree = await response.json();
|
||||
return duree;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur lors du calcul de la durée:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyser la complexité d'un type de chantier
|
||||
*/
|
||||
async analyzeComplexity(typeChantier: TypeChantier): Promise<{
|
||||
typeChantier: TypeChantier;
|
||||
nombrePhases: number;
|
||||
nombrePhasesCritiques: number;
|
||||
dureeTotal: number;
|
||||
niveauComplexite: string;
|
||||
}> {
|
||||
try {
|
||||
const response = await fetch(`${this.apiBaseUrl}/phase-templates/complexite/${typeChantier}`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem('token')}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Erreur lors de l\'analyse de complexité');
|
||||
}
|
||||
|
||||
const complexite = await response.json();
|
||||
return complexite;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur lors de l\'analyse de complexité:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Générer automatiquement les phases pour un chantier
|
||||
*/
|
||||
async generatePhases(
|
||||
chantierId: string,
|
||||
dateDebutChantier: Date,
|
||||
inclureSousPhases: boolean = true
|
||||
): Promise<PhaseChantier[]> {
|
||||
try {
|
||||
const response = await fetch(`${this.apiBaseUrl}/phase-templates/generer-phases`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem('token')}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
chantierId: chantierId,
|
||||
dateDebutChantier: dateDebutChantier.toISOString().split('T')[0],
|
||||
inclureSousPhases: inclureSousPhases
|
||||
})
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.text();
|
||||
throw new Error(error || 'Erreur lors de la génération des phases');
|
||||
}
|
||||
|
||||
const phasesGenerees = await response.json();
|
||||
return phasesGenerees;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur lors de la génération des phases:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Créer un nouveau template de phase
|
||||
*/
|
||||
async createTemplate(template: Partial<PhaseTemplate>): Promise<PhaseTemplate> {
|
||||
try {
|
||||
const response = await fetch(`${this.apiBaseUrl}/phase-templates`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem('token')}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(template)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.text();
|
||||
throw new Error(error || 'Erreur lors de la création du template');
|
||||
}
|
||||
|
||||
const nouveauTemplate = await response.json();
|
||||
return nouveauTemplate;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur lors de la création du template:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mettre à jour un template de phase
|
||||
*/
|
||||
async updateTemplate(id: string, template: Partial<PhaseTemplate>): Promise<PhaseTemplate> {
|
||||
try {
|
||||
const response = await fetch(`${this.apiBaseUrl}/phase-templates/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem('token')}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(template)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.text();
|
||||
throw new Error(error || 'Erreur lors de la mise à jour du template');
|
||||
}
|
||||
|
||||
const templateMisAJour = await response.json();
|
||||
return templateMisAJour;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur lors de la mise à jour du template:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Supprimer (désactiver) un template de phase
|
||||
*/
|
||||
async deleteTemplate(id: string): Promise<void> {
|
||||
try {
|
||||
const response = await fetch(`${this.apiBaseUrl}/phase-templates/${id}`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem('token')}`
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.text();
|
||||
throw new Error(error || 'Erreur lors de la suppression du template');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur lors de la suppression du template:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback: Récupérer les types de chantiers depuis les données locales
|
||||
*/
|
||||
private getLocalChantierTypes(): { value: TypeChantier; label: string; categorie: string }[] {
|
||||
const types: { value: TypeChantier; label: string; categorie: string }[] = [];
|
||||
|
||||
for (const [categorie, config] of Object.entries(CATEGORIES_CHANTIER)) {
|
||||
for (const type of config.types) {
|
||||
types.push({
|
||||
value: type,
|
||||
label: TYPE_CHANTIER_LABELS[type],
|
||||
categorie: config.label
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return types;
|
||||
}
|
||||
}
|
||||
|
||||
export default new PhaseTemplateService();
|
||||
Reference in New Issue
Block a user