dev du parc

This commit is contained in:
2026-04-21 18:39:01 +02:00
parent 9e421b1d08
commit 31940e48ba
17 changed files with 1124 additions and 17 deletions

View File

@@ -20,6 +20,7 @@ const COLLECTION_MAP = {
articles_mag: "/api/mags",
"pro-programmer": "/api/pro-programmer",
"parametres": "/api/parametres",
instruments: "/api/parc-instruments",
}
export default defineEventHandler(async (event) => {

View File

@@ -0,0 +1,72 @@
import { createError, readBody } from "h3"
import { getMysqlPool } from "~~/server/utils/mysql"
import { sendParcDemandEmails } from "~~/server/utils/mailer"
function normalizeValue(value) {
return typeof value === "string" ? value.trim() : ""
}
function isValidEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
}
export default defineEventHandler(async (event) => {
const body = await readBody(event)
const payload = {
requestType: normalizeValue(body?.requestType),
name: normalizeValue(body?.name),
email: normalizeValue(body?.email),
phone: normalizeValue(body?.phone),
organization: normalizeValue(body?.organization),
message: normalizeValue(body?.message),
}
if (!payload.requestType || !payload.name || !payload.email || !payload.phone || !payload.organization || !payload.message) {
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 (payload.message.length > 5000) {
throw createError({
statusCode: 400,
statusMessage: "Le message est trop long.",
})
}
const db = getMysqlPool()
try {
const [result] = await db.execute(
`
INSERT INTO parc_demandes (type_demande, nom, email, telephone, organisme, message)
VALUES (?, ?, ?, ?, ?, ?)
`,
[payload.requestType, payload.name, payload.email, payload.phone, payload.organization, payload.message]
)
const emailsSent = await sendParcDemandEmails(payload)
return {
ok: true,
id: result.insertId,
emailsSent,
}
} catch (error) {
console.error("Erreur API parc-demandes:", error)
throw createError({
statusCode: 500,
statusMessage: "Impossible denregistrer la demande pour le moment.",
})
}
})

98
server/utils/mailer.js Normal file
View File

@@ -0,0 +1,98 @@
import nodemailer from "nodemailer"
let transporter
function isSmtpConfigured(config) {
return Boolean(
config.smtpHost &&
config.smtpPort &&
config.smtpUser &&
config.smtpPassword &&
config.smtpFromEmail
)
}
function getTransporter() {
if (transporter) {
return transporter
}
const config = useRuntimeConfig()
if (!isSmtpConfigured(config)) {
return null
}
transporter = nodemailer.createTransport({
host: config.smtpHost,
port: Number(config.smtpPort),
secure: String(config.smtpSecure).toLowerCase() === "true",
auth: {
user: config.smtpUser,
pass: config.smtpPassword,
},
})
return transporter
}
export async function sendParcDemandEmails(payload) {
const config = useRuntimeConfig()
const mailer = getTransporter()
if (!mailer || !config.parcRequestRecipientEmail) {
return false
}
const from = config.smtpFromName
? `"${config.smtpFromName}" <${config.smtpFromEmail}>`
: config.smtpFromEmail
const adminSubject = `WONDIF - Formulaire de demande Parc instrumental - ${payload.name}`
const adminText = [
"Une nouvelle demande a été envoyée depuis le formulaire du Parc instrumental.",
"",
`Type de demande : ${payload.requestType}`,
`Nom : ${payload.name}`,
`Email : ${payload.email}`,
`Telephone : ${payload.phone}`,
`Structure : ${payload.organization}`,
"",
"Message :",
payload.message,
].join("\n")
const userSubject = "ONDIF - Confirmation de votre demande - Parc instrumental"
const userText = [
`Bonjour ${payload.name},`,
"",
"Votre demande a bien été transmise à l'équipe du Parc instrumental.",
"Nous reviendrons vers vous dans les meilleurs delais.",
"",
"Recapitulatif :",
`Type de demande : ${payload.requestType}`,
`Structure : ${payload.organization}`,
`Telephone : ${payload.phone}`,
"",
"Votre message :",
payload.message,
].join("\n")
await Promise.all([
mailer.sendMail({
from,
to: config.parcRequestRecipientEmail,
replyTo: payload.email,
subject: adminSubject,
text: adminText,
}),
mailer.sendMail({
from,
to: payload.email,
subject: userSubject,
text: userText,
}),
])
return true
}

25
server/utils/mysql.js Normal file
View File

@@ -0,0 +1,25 @@
import mysql from "mysql2/promise"
let pool
export function getMysqlPool() {
if (pool) {
return pool
}
const config = useRuntimeConfig()
pool = mysql.createPool({
host: config.mysqlHost,
port: Number(config.mysqlPort || 3306),
database: config.mysqlDatabase,
user: config.mysqlUser,
password: config.mysqlPassword,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0,
charset: "utf8mb4",
})
return pool
}