diff --git a/client/src/pages/AdminFormations.tsx b/client/src/pages/AdminFormations.tsx index 14a5c27..8291174 100644 --- a/client/src/pages/AdminFormations.tsx +++ b/client/src/pages/AdminFormations.tsx @@ -22,6 +22,7 @@ export default function AdminFormations() { const [formData, setFormData] = useState({ nom: "", description: "", + publicCible: "autre" as "directeur" | "chef_service" | "autre", lienUnique: "", actif: true, }); @@ -63,7 +64,7 @@ export default function AdminFormations() { }); const resetForm = () => { - setFormData({ nom: "", description: "", lienUnique: "", actif: true }); + setFormData({ nom: "", description: "", publicCible: "autre" as "directeur" | "chef_service" | "autre", lienUnique: "", actif: true }); setEditingId(null); }; @@ -71,6 +72,7 @@ export default function AdminFormations() { setFormData({ nom: formation.nom, description: formation.description || "", + publicCible: formation.publicCible || "autre", lienUnique: formation.lienUnique, actif: formation.actif, }); @@ -167,6 +169,22 @@ export default function AdminFormations() { rows={3} /> +
+ + +
Nom Description + Public cible Lien d'inscription Statut Actions - {filteredFormations.map((formation) => ( + {filteredFormations.map((formation) => { + const publicCibleLabel = formation.publicCible === "directeur" ? "Directeur" : formation.publicCible === "chef_service" ? "Chef de service" : "Autre"; + return ( {formation.nom} {formation.description || "-"} + {publicCibleLabel} - ))} + ); + })} ) : ( diff --git a/client/src/pages/Inscription.tsx b/client/src/pages/Inscription.tsx index 62bafa7..118ebae 100644 --- a/client/src/pages/Inscription.tsx +++ b/client/src/pages/Inscription.tsx @@ -230,6 +230,10 @@ export default function Inscription() { {formation.description}

)} +
+ + Public cible : {formation.publicCible === "directeur" ? "Directeurs" : formation.publicCible === "chef_service" ? "Chefs de service" : "Autre"} +
{/* Sessions disponibles */} diff --git a/drizzle/0004_futuristic_malice.sql b/drizzle/0004_futuristic_malice.sql new file mode 100644 index 0000000..cfd18c7 --- /dev/null +++ b/drizzle/0004_futuristic_malice.sql @@ -0,0 +1 @@ +ALTER TABLE `formations` ADD `publicCible` enum('directeur','chef_service','autre') NOT NULL; \ No newline at end of file diff --git a/drizzle/meta/0004_snapshot.json b/drizzle/meta/0004_snapshot.json new file mode 100644 index 0000000..bea7ba2 --- /dev/null +++ b/drizzle/meta/0004_snapshot.json @@ -0,0 +1,492 @@ +{ + "version": "5", + "dialect": "mysql", + "id": "9dc05bf2-d92e-4abf-be1e-7357b388c9a5", + "prevId": "0352a8eb-52dd-4dee-814f-96378a8fce64", + "tables": { + "apprenants": { + "name": "apprenants", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "nom": { + "name": "nom", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "prenom": { + "name": "prenom", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "codeEtablissement": { + "name": "codeEtablissement", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "fonction": { + "name": "fonction", + "type": "enum('directeur','chef_service','autre')", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(now())" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "onUpdate": true, + "default": "(now())" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "apprenants_id": { + "name": "apprenants_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "apprenants_email_unique": { + "name": "apprenants_email_unique", + "columns": [ + "email" + ] + } + }, + "checkConstraint": {} + }, + "datesFormation": { + "name": "datesFormation", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "sequenceId": { + "name": "sequenceId", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "dateDebut": { + "name": "dateDebut", + "type": "datetime", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "dateFin": { + "name": "dateFin", + "type": "datetime", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ordre": { + "name": "ordre", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(now())" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "datesFormation_id": { + "name": "datesFormation_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "formations": { + "name": "formations", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "nom": { + "name": "nom", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "publicCible": { + "name": "publicCible", + "type": "enum('directeur','chef_service','autre')", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "lienUnique": { + "name": "lienUnique", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "actif": { + "name": "actif", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(now())" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "onUpdate": true, + "default": "(now())" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "formations_id": { + "name": "formations_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "formations_lienUnique_unique": { + "name": "formations_lienUnique_unique", + "columns": [ + "lienUnique" + ] + } + }, + "checkConstraint": {} + }, + "inscriptions": { + "name": "inscriptions", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "apprenantId": { + "name": "apprenantId", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "sequenceId": { + "name": "sequenceId", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "statut": { + "name": "statut", + "type": "enum('confirmee','liste_attente','annulee')", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "dateInscription": { + "name": "dateInscription", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(now())" + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(now())" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "onUpdate": true, + "default": "(now())" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "inscriptions_id": { + "name": "inscriptions_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "sequences": { + "name": "sequences", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "formationId": { + "name": "formationId", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "nom": { + "name": "nom", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "lieu": { + "name": "lieu", + "type": "varchar(500)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "capaciteMax": { + "name": "capaciteMax", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 12 + }, + "dateBlocage": { + "name": "dateBlocage", + "type": "datetime", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "statut": { + "name": "statut", + "type": "enum('ouverte','bloquee','terminee')", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'ouverte'" + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(now())" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "onUpdate": true, + "default": "(now())" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "sequences_id": { + "name": "sequences_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "users": { + "name": "users", + "columns": { + "id": { + "name": "id", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": true + }, + "openId": { + "name": "openId", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "varchar(320)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "loginMethod": { + "name": "loginMethod", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "role": { + "name": "role", + "type": "enum('user','admin')", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'user'" + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(now())" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "onUpdate": true, + "default": "(now())" + }, + "lastSignedIn": { + "name": "lastSignedIn", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(now())" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "users_id": { + "name": "users_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "users_openId_unique": { + "name": "users_openId_unique", + "columns": [ + "openId" + ] + } + }, + "checkConstraint": {} + } + }, + "views": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "tables": {}, + "indexes": {} + } +} \ No newline at end of file diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index 58852a1..aa3420e 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -29,6 +29,13 @@ "when": 1762958719297, "tag": "0003_steady_mystique", "breakpoints": true + }, + { + "idx": 4, + "version": "5", + "when": 1763047968048, + "tag": "0004_futuristic_malice", + "breakpoints": true } ] } \ No newline at end of file diff --git a/drizzle/schema.ts b/drizzle/schema.ts index 6e00a80..c06cea2 100644 --- a/drizzle/schema.ts +++ b/drizzle/schema.ts @@ -32,6 +32,8 @@ export const formations = mysqlTable("formations", { id: int("id").autoincrement().primaryKey(), nom: varchar("nom", { length: 255 }).notNull(), description: text("description"), + /** Public cible de la formation (Directeur, Chef de service, Autre) */ + publicCible: mysqlEnum("publicCible", ["directeur", "chef_service", "autre"]).notNull(), /** Lien unique pour l'inscription à cette formation */ lienUnique: varchar("lienUnique", { length: 100 }).notNull().unique(), actif: boolean("actif").default(true).notNull(), diff --git a/server/routers.ts b/server/routers.ts index eb15e31..c77598f 100644 --- a/server/routers.ts +++ b/server/routers.ts @@ -47,6 +47,7 @@ export const appRouter = router({ create: adminProcedure.input(z.object({ nom: z.string().min(1), description: z.string().optional(), + publicCible: z.enum(["directeur", "chef_service", "autre"]), lienUnique: z.string().min(1), actif: z.boolean().optional(), })).mutation(async ({ input }) => { @@ -58,6 +59,7 @@ export const appRouter = router({ id: z.number(), nom: z.string().min(1).optional(), description: z.string().optional(), + publicCible: z.enum(["directeur", "chef_service", "autre"]).optional(), lienUnique: z.string().min(1).optional(), actif: z.boolean().optional(), })).mutation(async ({ input }) => { diff --git a/todo.md b/todo.md index 3da69e3..1fdeff0 100644 --- a/todo.md +++ b/todo.md @@ -117,3 +117,8 @@ - [x] Corriger le décalage horaire persistant dans parseLocalDateTime (09:48 envoyé devient 10:48 en base) - [x] Corriger l'erreur "toISOString is not a function" lors de la modification de séquences + +- [x] Ajouter le champ "Public cible" dans la fiche formation avec liste déroulante (Directeur, Chef de service, Autre) +- [x] Mettre à jour le schéma de base de données pour les formations +- [x] Mettre à jour les formulaires de gestion des formations +- [x] Afficher le public cible dans les listes et exports