ajout de bouton réserver et ajout du formulaire lycée

This commit is contained in:
2026-05-25 17:15:17 +02:00
parent 107093f7bb
commit c2a11f1b61
12 changed files with 929 additions and 26 deletions

View File

@@ -0,0 +1,163 @@
import { createError, readBody } from "h3"
import { getMysqlPool } from "~~/server/utils/mysql"
import { sendProjetLyceeEmails } from "~~/server/utils/mailer"
function normalizeValue(value) {
return typeof value === "string" ? value.trim() : ""
}
function normalizePositiveInteger(value) {
const number = Number(value)
return Number.isInteger(number) && number > 0 ? number : null
}
function normalizePriority(value) {
const normalized = normalizeValue(value)
if (!normalized) return null
const match = normalized.match(/_(\d)$/)
if (!match) return null
const priority = Number(match[1])
return priority >= 0 && priority <= 4 ? priority : null
}
function isValidEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
}
function withTimeout(promise, delay, message) {
return Promise.race([
promise,
new Promise((_, reject) => {
setTimeout(() => reject(new Error(message)), delay)
}),
])
}
export default defineEventHandler(async (event) => {
const body = await readBody(event)
const payload = {
schoolName: normalizeValue(body?.schoolName),
department: normalizeValue(body?.department),
city: normalizeValue(body?.city),
coordinatorName: normalizeValue(body?.coordinatorName),
email: normalizeValue(body?.email),
phone: normalizeValue(body?.phone),
discipline: normalizeValue(body?.discipline),
classLevel: normalizeValue(body?.classLevel),
studentCount: normalizePositiveInteger(body?.studentCount),
concertRencontrePriority: normalizePriority(body?.concertRencontrePriority),
immersionPriority: normalizePriority(body?.immersionPriority),
eacPriority: normalizePriority(body?.eacPriority),
concertCommentePriority: normalizePriority(body?.concertCommentePriority),
projectPeriod: normalizeValue(body?.projectPeriod),
}
if (
!payload.schoolName ||
!payload.department ||
!payload.city ||
!payload.coordinatorName ||
!payload.email ||
!payload.phone ||
!payload.discipline ||
!payload.classLevel ||
!payload.studentCount ||
!payload.projectPeriod
) {
throw createError({
statusCode: 400,
statusMessage: "Tous les champs obligatoires doivent être remplis.",
})
}
if (!isValidEmail(payload.email)) {
throw createError({
statusCode: 400,
statusMessage: "Ladresse email nest pas valide.",
})
}
if (!/^\d{2}$/.test(payload.department)) {
throw createError({
statusCode: 400,
statusMessage: "Le département nest pas valide.",
})
}
if (payload.projectPeriod.length > 5000) {
throw createError({
statusCode: 400,
statusMessage: "La période souhaitée est trop longue.",
})
}
const db = getMysqlPool()
try {
const [result] = await db.execute(
`
INSERT INTO projet_lycee_demandes (
nom_etablissement,
departement,
ville,
coordinateur_nom,
email,
telephone,
discipline,
niveau_classe,
nombre_eleves,
priorite_concert_rencontre,
priorite_immersion,
priorite_eac,
priorite_concert_commente,
periode_souhaitee
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`,
[
payload.schoolName,
payload.department,
payload.city,
payload.coordinatorName,
payload.email,
payload.phone,
payload.discipline,
payload.classLevel,
payload.studentCount,
payload.concertRencontrePriority,
payload.immersionPriority,
payload.eacPriority,
payload.concertCommentePriority,
payload.projectPeriod,
]
)
let emailsSent = false
try {
emailsSent = await withTimeout(
sendProjetLyceeEmails(payload),
15000,
"Délai dépassé pour l'envoi email projet-lycee."
)
} catch (mailError) {
console.error("Erreur envoi email projet-lycee:", mailError)
}
return {
ok: true,
id: result.insertId,
emailsSent,
}
} catch (error) {
console.error("Erreur API projet-lycee:", error)
throw createError({
statusCode: 500,
statusMessage: "Impossible denregistrer la candidature pour le moment.",
})
}
})