Checkpoint: Ajout du champ "Fonction" (Directeur, Chef de service, Autre) dans la fiche apprenant : mise à jour du schéma de base de données, ajout dans les formulaires d'inscription et de gestion des apprenants, affichage dans le tableau des apprenants, et intégration dans tous les exports (Excel, PDF, feuille de présence).
This commit is contained in:
@@ -5,6 +5,7 @@ import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, D
|
|||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||||
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
import { trpc } from "@/lib/trpc";
|
import { trpc } from "@/lib/trpc";
|
||||||
import { Plus, Pencil, Trash2, Search, SlidersHorizontal } from "lucide-react";
|
import { Plus, Pencil, Trash2, Search, SlidersHorizontal } from "lucide-react";
|
||||||
import { useState, useMemo } from "react";
|
import { useState, useMemo } from "react";
|
||||||
@@ -20,6 +21,7 @@ export default function AdminApprenants() {
|
|||||||
prenom: "",
|
prenom: "",
|
||||||
email: "",
|
email: "",
|
||||||
codeEtablissement: "",
|
codeEtablissement: "",
|
||||||
|
fonction: "autre" as "directeur" | "chef_service" | "autre",
|
||||||
});
|
});
|
||||||
|
|
||||||
const utils = trpc.useUtils();
|
const utils = trpc.useUtils();
|
||||||
@@ -60,7 +62,7 @@ export default function AdminApprenants() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const resetForm = () => {
|
const resetForm = () => {
|
||||||
setFormData({ nom: "", prenom: "", email: "", codeEtablissement: "" });
|
setFormData({ nom: "", prenom: "", email: "", codeEtablissement: "", fonction: "autre" });
|
||||||
setEditingId(null);
|
setEditingId(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -70,6 +72,7 @@ export default function AdminApprenants() {
|
|||||||
prenom: apprenant.prenom,
|
prenom: apprenant.prenom,
|
||||||
email: apprenant.email,
|
email: apprenant.email,
|
||||||
codeEtablissement: apprenant.codeEtablissement,
|
codeEtablissement: apprenant.codeEtablissement,
|
||||||
|
fonction: apprenant.fonction || "autre",
|
||||||
});
|
});
|
||||||
setEditingId(apprenant.id);
|
setEditingId(apprenant.id);
|
||||||
setOpen(true);
|
setOpen(true);
|
||||||
@@ -179,6 +182,19 @@ export default function AdminApprenants() {
|
|||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label htmlFor="fonction">Fonction *</Label>
|
||||||
|
<Select value={formData.fonction} onValueChange={(value: any) => setFormData({ ...formData, fonction: value })}>
|
||||||
|
<SelectTrigger id="fonction">
|
||||||
|
<SelectValue />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="directeur">Directeur</SelectItem>
|
||||||
|
<SelectItem value="chef_service">Chef de service</SelectItem>
|
||||||
|
<SelectItem value="autre">Autre</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<Button type="button" variant="outline" onClick={() => setOpen(false)}>
|
<Button type="button" variant="outline" onClick={() => setOpen(false)}>
|
||||||
@@ -245,6 +261,7 @@ export default function AdminApprenants() {
|
|||||||
<TableHead>Prénom</TableHead>
|
<TableHead>Prénom</TableHead>
|
||||||
<TableHead>Email</TableHead>
|
<TableHead>Email</TableHead>
|
||||||
<TableHead>Code établissement</TableHead>
|
<TableHead>Code établissement</TableHead>
|
||||||
|
<TableHead>Fonction</TableHead>
|
||||||
<TableHead className="text-right">Actions</TableHead>
|
<TableHead className="text-right">Actions</TableHead>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
@@ -255,6 +272,10 @@ export default function AdminApprenants() {
|
|||||||
<TableCell>{apprenant.prenom}</TableCell>
|
<TableCell>{apprenant.prenom}</TableCell>
|
||||||
<TableCell>{apprenant.email}</TableCell>
|
<TableCell>{apprenant.email}</TableCell>
|
||||||
<TableCell>{apprenant.codeEtablissement}</TableCell>
|
<TableCell>{apprenant.codeEtablissement}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
{apprenant.fonction === "directeur" ? "Directeur" :
|
||||||
|
apprenant.fonction === "chef_service" ? "Chef de service" : "Autre"}
|
||||||
|
</TableCell>
|
||||||
<TableCell className="text-right">
|
<TableCell className="text-right">
|
||||||
<div className="flex justify-end gap-2">
|
<div className="flex justify-end gap-2">
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { toast } from "sonner";
|
|||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
import { fr } from "date-fns/locale";
|
import { fr } from "date-fns/locale";
|
||||||
import { CheckCircle, XCircle, AlertCircle, Calendar, MapPin, Users } from "lucide-react";
|
import { CheckCircle, XCircle, AlertCircle, Calendar, MapPin, Users } from "lucide-react";
|
||||||
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
import { APP_LOGO, APP_TITLE } from "@/const";
|
import { APP_LOGO, APP_TITLE } from "@/const";
|
||||||
|
|
||||||
export default function Inscription() {
|
export default function Inscription() {
|
||||||
@@ -21,6 +22,7 @@ export default function Inscription() {
|
|||||||
prenom: "",
|
prenom: "",
|
||||||
email: "",
|
email: "",
|
||||||
codeEtablissement: "",
|
codeEtablissement: "",
|
||||||
|
fonction: "autre" as "directeur" | "chef_service" | "autre",
|
||||||
});
|
});
|
||||||
const [selectedSessionId, setSelectedSessionId] = useState<number | null>(null);
|
const [selectedSessionId, setSelectedSessionId] = useState<number | null>(null);
|
||||||
const [inscriptionSuccess, setInscriptionSuccess] = useState(false);
|
const [inscriptionSuccess, setInscriptionSuccess] = useState(false);
|
||||||
@@ -320,6 +322,19 @@ export default function Inscription() {
|
|||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label htmlFor="fonction">Fonction *</Label>
|
||||||
|
<Select value={formData.fonction} onValueChange={(value: any) => setFormData({ ...formData, fonction: value })}>
|
||||||
|
<SelectTrigger id="fonction">
|
||||||
|
<SelectValue />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="directeur">Directeur</SelectItem>
|
||||||
|
<SelectItem value="chef_service">Chef de service</SelectItem>
|
||||||
|
<SelectItem value="autre">Autre</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="bg-amber-50 border border-amber-200 rounded-lg p-4">
|
<div className="bg-amber-50 border border-amber-200 rounded-lg p-4">
|
||||||
<p className="text-sm text-amber-800">
|
<p className="text-sm text-amber-800">
|
||||||
|
|||||||
1
drizzle/0002_fuzzy_sugar_man.sql
Normal file
1
drizzle/0002_fuzzy_sugar_man.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE `apprenants` ADD `fonction` enum('directeur','chef_service','autre') NOT NULL;
|
||||||
480
drizzle/meta/0002_snapshot.json
Normal file
480
drizzle/meta/0002_snapshot.json
Normal file
@@ -0,0 +1,480 @@
|
|||||||
|
{
|
||||||
|
"version": "5",
|
||||||
|
"dialect": "mysql",
|
||||||
|
"id": "c625e855-6929-4091-a755-d300ea81b53a",
|
||||||
|
"prevId": "95d14d84-eb09-4770-af36-02daa58e4a5d",
|
||||||
|
"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": {}
|
||||||
|
},
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
"sessionId": {
|
||||||
|
"name": "sessionId",
|
||||||
|
"type": "int",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"statut": {
|
||||||
|
"name": "statut",
|
||||||
|
"type": "enum('confirmee','liste_attente','annulee')",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "'confirmee'"
|
||||||
|
},
|
||||||
|
"dateInscription": {
|
||||||
|
"name": "dateInscription",
|
||||||
|
"type": "timestamp",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "(now())"
|
||||||
|
},
|
||||||
|
"invitationEnvoyee": {
|
||||||
|
"name": "invitationEnvoyee",
|
||||||
|
"type": "boolean",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"emailConfirmationEnvoye": {
|
||||||
|
"name": "emailConfirmationEnvoye",
|
||||||
|
"type": "boolean",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"emailTeaserEnvoye": {
|
||||||
|
"name": "emailTeaserEnvoye",
|
||||||
|
"type": "boolean",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"emailRappelEnvoye": {
|
||||||
|
"name": "emailRappelEnvoye",
|
||||||
|
"type": "boolean",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": 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": {
|
||||||
|
"inscriptions_id": {
|
||||||
|
"name": "inscriptions_id",
|
||||||
|
"columns": [
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uniqueConstraints": {
|
||||||
|
"inscriptions_apprenantId_sessionId_unique": {
|
||||||
|
"name": "inscriptions_apprenantId_sessionId_unique",
|
||||||
|
"columns": [
|
||||||
|
"apprenantId",
|
||||||
|
"sessionId"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"checkConstraint": {}
|
||||||
|
},
|
||||||
|
"sessions": {
|
||||||
|
"name": "sessions",
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
"dateDebut": {
|
||||||
|
"name": "dateDebut",
|
||||||
|
"type": "datetime",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"dateFin": {
|
||||||
|
"name": "dateFin",
|
||||||
|
"type": "datetime",
|
||||||
|
"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": {
|
||||||
|
"sessions_id": {
|
||||||
|
"name": "sessions_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": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,6 +15,13 @@
|
|||||||
"when": 1762953926304,
|
"when": 1762953926304,
|
||||||
"tag": "0001_smooth_warbird",
|
"tag": "0001_smooth_warbird",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 2,
|
||||||
|
"version": "5",
|
||||||
|
"when": 1762957612797,
|
||||||
|
"tag": "0002_fuzzy_sugar_man",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -51,6 +51,7 @@ export const apprenants = mysqlTable("apprenants", {
|
|||||||
prenom: varchar("prenom", { length: 255 }).notNull(),
|
prenom: varchar("prenom", { length: 255 }).notNull(),
|
||||||
email: varchar("email", { length: 320 }).notNull().unique(),
|
email: varchar("email", { length: 320 }).notNull().unique(),
|
||||||
codeEtablissement: varchar("codeEtablissement", { length: 50 }).notNull(),
|
codeEtablissement: varchar("codeEtablissement", { length: 50 }).notNull(),
|
||||||
|
fonction: mysqlEnum("fonction", ["directeur", "chef_service", "autre"]).notNull(),
|
||||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||||
updatedAt: timestamp("updatedAt").defaultNow().onUpdateNow().notNull(),
|
updatedAt: timestamp("updatedAt").defaultNow().onUpdateNow().notNull(),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ interface InscriptionExport {
|
|||||||
prenom: string;
|
prenom: string;
|
||||||
email: string;
|
email: string;
|
||||||
codeEtablissement: string;
|
codeEtablissement: string;
|
||||||
|
fonction: string;
|
||||||
statut: string;
|
statut: string;
|
||||||
dateInscription: Date;
|
dateInscription: Date;
|
||||||
}
|
}
|
||||||
@@ -36,6 +37,7 @@ export function generateExcelExport(
|
|||||||
'Prénom': i.prenom,
|
'Prénom': i.prenom,
|
||||||
'Email': i.email,
|
'Email': i.email,
|
||||||
'Code établissement': i.codeEtablissement,
|
'Code établissement': i.codeEtablissement,
|
||||||
|
'Fonction': i.fonction === 'directeur' ? 'Directeur' : i.fonction === 'chef_service' ? 'Chef de service' : 'Autre',
|
||||||
'Statut': i.statut === 'confirmee' ? 'Confirmée' : i.statut === 'liste_attente' ? 'Liste d\'attente' : 'Annulée',
|
'Statut': i.statut === 'confirmee' ? 'Confirmée' : i.statut === 'liste_attente' ? 'Liste d\'attente' : 'Annulée',
|
||||||
'Date d\'inscription': i.dateInscription.toLocaleDateString('fr-FR'),
|
'Date d\'inscription': i.dateInscription.toLocaleDateString('fr-FR'),
|
||||||
}));
|
}));
|
||||||
@@ -122,12 +124,13 @@ export function generatePDFExport(
|
|||||||
i.prenom,
|
i.prenom,
|
||||||
i.email,
|
i.email,
|
||||||
i.codeEtablissement,
|
i.codeEtablissement,
|
||||||
|
i.fonction === 'directeur' ? 'Directeur' : i.fonction === 'chef_service' ? 'Chef de service' : 'Autre',
|
||||||
i.statut === 'confirmee' ? 'Confirmée' : i.statut === 'liste_attente' ? 'Liste d\'attente' : 'Annulée',
|
i.statut === 'confirmee' ? 'Confirmée' : i.statut === 'liste_attente' ? 'Liste d\'attente' : 'Annulée',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
autoTable(doc, {
|
autoTable(doc, {
|
||||||
startY: yPos + 10,
|
startY: yPos + 10,
|
||||||
head: [['Nom', 'Prénom', 'Email', 'Code étab.', 'Statut']],
|
head: [['Nom', 'Prénom', 'Email', 'Code étab.', 'Fonction', 'Statut']],
|
||||||
body: tableData,
|
body: tableData,
|
||||||
styles: { fontSize: 9 },
|
styles: { fontSize: 9 },
|
||||||
headStyles: { fillColor: [37, 99, 235] },
|
headStyles: { fillColor: [37, 99, 235] },
|
||||||
@@ -173,17 +176,18 @@ export function generateFeuillePresence(
|
|||||||
i.nom,
|
i.nom,
|
||||||
i.prenom,
|
i.prenom,
|
||||||
i.codeEtablissement,
|
i.codeEtablissement,
|
||||||
|
i.fonction === 'directeur' ? 'Directeur' : i.fonction === 'chef_service' ? 'Chef de service' : 'Autre',
|
||||||
'', // Colonne signature
|
'', // Colonne signature
|
||||||
]);
|
]);
|
||||||
|
|
||||||
autoTable(doc, {
|
autoTable(doc, {
|
||||||
startY: yPos + 10,
|
startY: yPos + 10,
|
||||||
head: [['Nom', 'Prénom', 'Code établissement', 'Signature']],
|
head: [['Nom', 'Prénom', 'Code établissement', 'Fonction', 'Signature']],
|
||||||
body: tableData,
|
body: tableData,
|
||||||
styles: { fontSize: 10, cellPadding: 5 },
|
styles: { fontSize: 10, cellPadding: 5 },
|
||||||
headStyles: { fillColor: [37, 99, 235] },
|
headStyles: { fillColor: [37, 99, 235] },
|
||||||
columnStyles: {
|
columnStyles: {
|
||||||
3: { cellWidth: 40 }, // Largeur pour la colonne signature
|
4: { cellWidth: 40 }, // Largeur pour la colonne signature
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ export const appRouter = router({
|
|||||||
prenom: z.string().min(1),
|
prenom: z.string().min(1),
|
||||||
email: z.string().email(),
|
email: z.string().email(),
|
||||||
codeEtablissement: z.string().min(1),
|
codeEtablissement: z.string().min(1),
|
||||||
|
fonction: z.enum(["directeur", "chef_service", "autre"]),
|
||||||
})).mutation(async ({ input }) => {
|
})).mutation(async ({ input }) => {
|
||||||
await db.createApprenant(input);
|
await db.createApprenant(input);
|
||||||
return { success: true };
|
return { success: true };
|
||||||
@@ -101,6 +102,7 @@ export const appRouter = router({
|
|||||||
prenom: z.string().min(1).optional(),
|
prenom: z.string().min(1).optional(),
|
||||||
email: z.string().email().optional(),
|
email: z.string().email().optional(),
|
||||||
codeEtablissement: z.string().min(1).optional(),
|
codeEtablissement: z.string().min(1).optional(),
|
||||||
|
fonction: z.enum(["directeur", "chef_service", "autre"]).optional(),
|
||||||
})).mutation(async ({ input }) => {
|
})).mutation(async ({ input }) => {
|
||||||
const { id, ...data } = input;
|
const { id, ...data } = input;
|
||||||
await db.updateApprenant(id, data);
|
await db.updateApprenant(id, data);
|
||||||
@@ -342,6 +344,7 @@ export const appRouter = router({
|
|||||||
prenom: i.apprenant!.prenom,
|
prenom: i.apprenant!.prenom,
|
||||||
email: i.apprenant!.email,
|
email: i.apprenant!.email,
|
||||||
codeEtablissement: i.apprenant!.codeEtablissement,
|
codeEtablissement: i.apprenant!.codeEtablissement,
|
||||||
|
fonction: i.apprenant!.fonction,
|
||||||
statut: i.inscription.statut,
|
statut: i.inscription.statut,
|
||||||
dateInscription: new Date(i.inscription.dateInscription),
|
dateInscription: new Date(i.inscription.dateInscription),
|
||||||
}));
|
}));
|
||||||
@@ -375,6 +378,7 @@ export const appRouter = router({
|
|||||||
prenom: i.apprenant!.prenom,
|
prenom: i.apprenant!.prenom,
|
||||||
email: i.apprenant!.email,
|
email: i.apprenant!.email,
|
||||||
codeEtablissement: i.apprenant!.codeEtablissement,
|
codeEtablissement: i.apprenant!.codeEtablissement,
|
||||||
|
fonction: i.apprenant!.fonction,
|
||||||
statut: i.inscription.statut,
|
statut: i.inscription.statut,
|
||||||
dateInscription: new Date(i.inscription.dateInscription),
|
dateInscription: new Date(i.inscription.dateInscription),
|
||||||
}));
|
}));
|
||||||
@@ -408,6 +412,7 @@ export const appRouter = router({
|
|||||||
prenom: i.apprenant!.prenom,
|
prenom: i.apprenant!.prenom,
|
||||||
email: i.apprenant!.email,
|
email: i.apprenant!.email,
|
||||||
codeEtablissement: i.apprenant!.codeEtablissement,
|
codeEtablissement: i.apprenant!.codeEtablissement,
|
||||||
|
fonction: i.apprenant!.fonction,
|
||||||
statut: i.inscription.statut,
|
statut: i.inscription.statut,
|
||||||
dateInscription: new Date(i.inscription.dateInscription),
|
dateInscription: new Date(i.inscription.dateInscription),
|
||||||
}));
|
}));
|
||||||
|
|||||||
5
todo.md
5
todo.md
@@ -69,3 +69,8 @@
|
|||||||
- [x] Ajouter des filtres de recherche sur la page des apprenants
|
- [x] Ajouter des filtres de recherche sur la page des apprenants
|
||||||
|
|
||||||
- [x] Ajouter des filtres complets sur la page de gestion des inscrits (recherche, statut, établissement, tri par date)
|
- [x] Ajouter des filtres complets sur la page de gestion des inscrits (recherche, statut, établissement, tri par date)
|
||||||
|
|
||||||
|
- [x] Ajouter le champ "Fonction" (Directeur, Chef de service, Autre) dans la fiche apprenant
|
||||||
|
- [x] Mettre à jour le schéma de base de données
|
||||||
|
- [x] Mettre à jour les formulaires d'inscription et de gestion
|
||||||
|
- [x] Ajouter la fonction dans les exports PDF/Excel
|
||||||
|
|||||||
Reference in New Issue
Block a user