- Changed migration commands in DATABASE_SETUP.md to use `pnpm run sync-skills` and `pnpm run sync-teams`. - Removed the skills migration API endpoint in route.ts, streamlining the migration process. - Updated MIGRATION_UUID.md to reflect changes in migration steps and removed the old skills migration script. - Added new sync scripts for skills and teams in package.json. - Cleaned up init.sql by removing old teams data insertion and adjusted comments for clarity.
445 lines
10 KiB
TypeScript
445 lines
10 KiB
TypeScript
import {
|
|
UserEvaluation,
|
|
UserProfile,
|
|
SkillLevel,
|
|
Team,
|
|
SkillCategory,
|
|
Skill,
|
|
} from "../lib/types";
|
|
|
|
export class ApiClient {
|
|
private baseUrl: string;
|
|
|
|
constructor() {
|
|
this.baseUrl = process.env.NEXT_PUBLIC_API_URL || "";
|
|
}
|
|
|
|
/**
|
|
* Charge une évaluation utilisateur depuis l'API
|
|
* Si profile est fourni, utilise les paramètres (mode compatibilité)
|
|
* Sinon, utilise l'authentification par cookie
|
|
*/
|
|
async loadUserEvaluation(
|
|
profile?: UserProfile
|
|
): Promise<UserEvaluation | null> {
|
|
try {
|
|
let url = `${this.baseUrl}/api/evaluations`;
|
|
|
|
// Mode compatibilité avec profile en paramètres
|
|
if (profile) {
|
|
const params = new URLSearchParams({
|
|
firstName: profile.firstName,
|
|
lastName: profile.lastName,
|
|
teamId: profile.teamId,
|
|
});
|
|
url += `?${params}`;
|
|
}
|
|
|
|
const response = await fetch(url, {
|
|
credentials: "same-origin", // Pour inclure les cookies
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error("Erreur lors du chargement de l'évaluation");
|
|
}
|
|
|
|
const data = await response.json();
|
|
return data.evaluation;
|
|
} catch (error) {
|
|
console.error("Erreur lors du chargement de l'évaluation:", error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sauvegarde une évaluation utilisateur via l'API
|
|
*/
|
|
async saveUserEvaluation(evaluation: UserEvaluation): Promise<void> {
|
|
try {
|
|
const response = await fetch(`${this.baseUrl}/api/evaluations`, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({ evaluation }),
|
|
credentials: "same-origin",
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error("Erreur lors de la sauvegarde de l'évaluation");
|
|
}
|
|
} catch (error) {
|
|
console.error("Erreur lors de la sauvegarde de l'évaluation:", error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Met à jour le niveau d'une skill
|
|
*/
|
|
async updateSkillLevel(
|
|
profile: UserProfile,
|
|
category: string,
|
|
skillId: string,
|
|
level: SkillLevel
|
|
): Promise<void> {
|
|
await this.updateSkill(profile, category, skillId, {
|
|
action: "updateLevel",
|
|
level,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Met à jour le statut de mentorat d'une skill
|
|
*/
|
|
async updateSkillMentorStatus(
|
|
profile: UserProfile,
|
|
category: string,
|
|
skillId: string,
|
|
canMentor: boolean
|
|
): Promise<void> {
|
|
await this.updateSkill(profile, category, skillId, {
|
|
action: "updateMentorStatus",
|
|
canMentor,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Met à jour le statut d'apprentissage d'une skill
|
|
*/
|
|
async updateSkillLearningStatus(
|
|
profile: UserProfile,
|
|
category: string,
|
|
skillId: string,
|
|
wantsToLearn: boolean
|
|
): Promise<void> {
|
|
await this.updateSkill(profile, category, skillId, {
|
|
action: "updateLearningStatus",
|
|
wantsToLearn,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Ajoute une skill à l'évaluation
|
|
*/
|
|
async addSkillToEvaluation(
|
|
profile: UserProfile,
|
|
category: string,
|
|
skillId: string
|
|
): Promise<void> {
|
|
await this.updateSkill(profile, category, skillId, {
|
|
action: "addSkill",
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Supprime une skill de l'évaluation
|
|
*/
|
|
async removeSkillFromEvaluation(
|
|
profile: UserProfile,
|
|
category: string,
|
|
skillId: string
|
|
): Promise<void> {
|
|
await this.updateSkill(profile, category, skillId, {
|
|
action: "removeSkill",
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Méthode utilitaire pour mettre à jour une skill
|
|
*/
|
|
private async updateSkill(
|
|
profile: UserProfile,
|
|
category: string,
|
|
skillId: string,
|
|
options: {
|
|
action:
|
|
| "updateLevel"
|
|
| "updateMentorStatus"
|
|
| "updateLearningStatus"
|
|
| "addSkill"
|
|
| "removeSkill";
|
|
level?: SkillLevel;
|
|
canMentor?: boolean;
|
|
wantsToLearn?: boolean;
|
|
}
|
|
): Promise<void> {
|
|
try {
|
|
const response = await fetch(`${this.baseUrl}/api/evaluations/skills`, {
|
|
method: "PUT",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
profile,
|
|
category,
|
|
skillId,
|
|
...options,
|
|
}),
|
|
credentials: "same-origin",
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error("Erreur lors de la mise à jour de la skill");
|
|
}
|
|
} catch (error) {
|
|
console.error("Erreur lors de la mise à jour de la skill:", error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Charge toutes les équipes
|
|
*/
|
|
async loadTeams(): Promise<Team[]> {
|
|
try {
|
|
const response = await fetch(`${this.baseUrl}/api/teams`);
|
|
|
|
if (!response.ok) {
|
|
throw new Error("Erreur lors du chargement des équipes");
|
|
}
|
|
|
|
return await response.json();
|
|
} catch (error) {
|
|
console.error("Erreur lors du chargement des équipes:", error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Charge une équipe par ID
|
|
*/
|
|
async loadTeamById(teamId: string): Promise<Team | null> {
|
|
try {
|
|
const response = await fetch(`${this.baseUrl}/api/teams/${teamId}`);
|
|
|
|
if (!response.ok) {
|
|
if (response.status === 404) {
|
|
return null;
|
|
}
|
|
throw new Error("Erreur lors du chargement de l'équipe");
|
|
}
|
|
|
|
return await response.json();
|
|
} catch (error) {
|
|
console.error("Erreur lors du chargement de l'équipe:", error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Charge les équipes par direction
|
|
*/
|
|
async loadTeamsByDirection(direction: string): Promise<Team[]> {
|
|
try {
|
|
const response = await fetch(
|
|
`${this.baseUrl}/api/teams/direction/${direction}`
|
|
);
|
|
|
|
if (!response.ok) {
|
|
throw new Error("Erreur lors du chargement des équipes par direction");
|
|
}
|
|
|
|
return await response.json();
|
|
} catch (error) {
|
|
console.error(
|
|
"Erreur lors du chargement des équipes par direction:",
|
|
error
|
|
);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Charge toutes les directions
|
|
*/
|
|
async loadDirections(): Promise<string[]> {
|
|
try {
|
|
const response = await fetch(`${this.baseUrl}/api/teams/directions`);
|
|
|
|
if (!response.ok) {
|
|
throw new Error("Erreur lors du chargement des directions");
|
|
}
|
|
|
|
return await response.json();
|
|
} catch (error) {
|
|
console.error("Erreur lors du chargement des directions:", error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Crée une nouvelle équipe
|
|
*/
|
|
async createTeam(
|
|
team: Omit<Team, "created_at" | "updated_at">
|
|
): Promise<Team | null> {
|
|
try {
|
|
const response = await fetch(`${this.baseUrl}/api/teams`, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(team),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error("Erreur lors de la création de l'équipe");
|
|
}
|
|
|
|
return await response.json();
|
|
} catch (error) {
|
|
console.error("Erreur lors de la création de l'équipe:", error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Met à jour une équipe
|
|
*/
|
|
async updateTeam(
|
|
teamId: string,
|
|
updates: Partial<Omit<Team, "id">>
|
|
): Promise<Team | null> {
|
|
try {
|
|
const response = await fetch(`${this.baseUrl}/api/teams/${teamId}`, {
|
|
method: "PUT",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(updates),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error("Erreur lors de la mise à jour de l'équipe");
|
|
}
|
|
|
|
return await response.json();
|
|
} catch (error) {
|
|
console.error("Erreur lors de la mise à jour de l'équipe:", error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Supprime une équipe
|
|
*/
|
|
async deleteTeam(teamId: string): Promise<boolean> {
|
|
try {
|
|
const response = await fetch(`${this.baseUrl}/api/teams/${teamId}`, {
|
|
method: "DELETE",
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error("Erreur lors de la suppression de l'équipe");
|
|
}
|
|
|
|
return true;
|
|
} catch (error) {
|
|
console.error("Erreur lors de la suppression de l'équipe:", error);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Charge toutes les catégories de skills
|
|
*/
|
|
async loadSkillCategories(): Promise<SkillCategory[]> {
|
|
try {
|
|
const response = await fetch(`${this.baseUrl}/api/skills`);
|
|
|
|
if (!response.ok) {
|
|
throw new Error("Erreur lors du chargement des catégories de skills");
|
|
}
|
|
|
|
return await response.json();
|
|
} catch (error) {
|
|
console.error(
|
|
"Erreur lors du chargement des catégories de skills:",
|
|
error
|
|
);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Charge les skills d'une catégorie
|
|
*/
|
|
async loadSkillsByCategory(categoryId: string): Promise<Skill[]> {
|
|
try {
|
|
const response = await fetch(`${this.baseUrl}/api/skills/${categoryId}`);
|
|
|
|
if (!response.ok) {
|
|
throw new Error("Erreur lors du chargement des skills par catégorie");
|
|
}
|
|
|
|
return await response.json();
|
|
} catch (error) {
|
|
console.error(
|
|
"Erreur lors du chargement des skills par catégorie:",
|
|
error
|
|
);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Crée une nouvelle catégorie de skill
|
|
*/
|
|
async createSkillCategory(category: {
|
|
id: string;
|
|
name: string;
|
|
icon: string;
|
|
}): Promise<boolean> {
|
|
try {
|
|
const response = await fetch(`${this.baseUrl}/api/skills`, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(category),
|
|
});
|
|
|
|
return response.ok;
|
|
} catch (error) {
|
|
console.error(
|
|
"Erreur lors de la création de la catégorie de skill:",
|
|
error
|
|
);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Crée une nouvelle skill
|
|
*/
|
|
async createSkill(
|
|
categoryId: string,
|
|
skill: {
|
|
id: string;
|
|
name: string;
|
|
description: string;
|
|
icon?: string;
|
|
links: string[];
|
|
}
|
|
): Promise<boolean> {
|
|
try {
|
|
const response = await fetch(`${this.baseUrl}/api/skills/${categoryId}`, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(skill),
|
|
});
|
|
|
|
return response.ok;
|
|
} catch (error) {
|
|
console.error("Erreur lors de la création de la skill:", error);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Instance singleton
|
|
export const apiClient = new ApiClient();
|