generated from gitea_admin/default
ajout de bouton réserver et ajout du formulaire lycée
This commit is contained in:
163
server/api/projet-lycee.post.js
Normal file
163
server/api/projet-lycee.post.js
Normal 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: "L’adresse email n’est pas valide.",
|
||||
})
|
||||
}
|
||||
|
||||
if (!/^\d{2}$/.test(payload.department)) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: "Le département n’est 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 d’enregistrer la candidature pour le moment.",
|
||||
})
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user