feat: adding teams in PG

This commit is contained in:
Julien Froidefond
2025-08-21 09:44:29 +02:00
parent 4e82a6d860
commit 345ff5baa0
8 changed files with 478 additions and 14 deletions

View File

@@ -1,4 +1,4 @@
import { UserEvaluation, UserProfile, SkillLevel } from "../lib/types";
import { UserEvaluation, UserProfile, SkillLevel, Team } from "../lib/types";
export class ApiClient {
private baseUrl: string;
@@ -168,6 +168,159 @@ export class ApiClient {
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;
}
}
}
// Instance singleton

View File

@@ -8,5 +8,8 @@ export { getPool, closePool } from "./database";
// Evaluation services (server-only)
export { EvaluationService, evaluationService } from "./evaluation-service";
// Teams services (server-only)
export { TeamsService } from "./teams-service";
// API client (can be used client-side)
export { ApiClient, apiClient } from "./api-client";

171
services/teams-service.ts Normal file
View File

@@ -0,0 +1,171 @@
import { getPool } from "./database";
import { Team } from "@/lib/types";
export class TeamsService {
/**
* Get all teams
*/
static async getTeams(): Promise<Team[]> {
const pool = getPool();
const query = `
SELECT id, name, direction
FROM teams
ORDER BY direction, name
`;
try {
const result = await pool.query(query);
return result.rows;
} catch (error) {
console.error("Error fetching teams:", error);
throw new Error("Failed to fetch teams");
}
}
/**
* Get teams by direction
*/
static async getTeamsByDirection(direction: string): Promise<Team[]> {
const pool = getPool();
const query = `
SELECT id, name, direction
FROM teams
WHERE direction = $1
ORDER BY name
`;
try {
const result = await pool.query(query, [direction]);
return result.rows;
} catch (error) {
console.error("Error fetching teams by direction:", error);
throw new Error("Failed to fetch teams by direction");
}
}
/**
* Get team by ID
*/
static async getTeamById(id: string): Promise<Team | null> {
const pool = getPool();
const query = `
SELECT id, name, direction
FROM teams
WHERE id = $1
`;
try {
const result = await pool.query(query, [id]);
return result.rows[0] || null;
} catch (error) {
console.error("Error fetching team by ID:", error);
throw new Error("Failed to fetch team");
}
}
/**
* Create a new team
*/
static async createTeam(
team: Omit<Team, "created_at" | "updated_at">
): Promise<Team> {
const pool = getPool();
const query = `
INSERT INTO teams (id, name, direction)
VALUES ($1, $2, $3)
RETURNING id, name, direction
`;
try {
const result = await pool.query(query, [
team.id,
team.name,
team.direction,
]);
return result.rows[0];
} catch (error) {
console.error("Error creating team:", error);
throw new Error("Failed to create team");
}
}
/**
* Update a team
*/
static async updateTeam(
id: string,
updates: Partial<Omit<Team, "id">>
): Promise<Team | null> {
const pool = getPool();
const fields = [];
const values = [];
let paramIndex = 1;
if (updates.name !== undefined) {
fields.push(`name = $${paramIndex++}`);
values.push(updates.name);
}
if (updates.direction !== undefined) {
fields.push(`direction = $${paramIndex++}`);
values.push(updates.direction);
}
if (fields.length === 0) {
return this.getTeamById(id);
}
values.push(id);
const query = `
UPDATE teams
SET ${fields.join(", ")}
WHERE id = $${paramIndex}
RETURNING id, name, direction
`;
try {
const result = await pool.query(query, values);
return result.rows[0] || null;
} catch (error) {
console.error("Error updating team:", error);
throw new Error("Failed to update team");
}
}
/**
* Delete a team
*/
static async deleteTeam(id: string): Promise<boolean> {
const pool = getPool();
const query = `DELETE FROM teams WHERE id = $1`;
try {
const result = await pool.query(query, [id]);
return (result.rowCount ?? 0) > 0;
} catch (error) {
console.error("Error deleting team:", error);
throw new Error("Failed to delete team");
}
}
/**
* Get all directions
*/
static async getDirections(): Promise<string[]> {
const pool = getPool();
const query = `
SELECT DISTINCT direction
FROM teams
ORDER BY direction
`;
try {
const result = await pool.query(query);
return result.rows.map((row) => row.direction);
} catch (error) {
console.error("Error fetching directions:", error);
throw new Error("Failed to fetch directions");
}
}
}