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