Initialize Next.js project with essential configurations and components
- Added .gitignore to exclude unnecessary files and directories. - Created next.config.js for Next.js configuration. - Set up package.json and package-lock.json with dependencies including Next.js, React, and TypeScript. - Implemented Tailwind CSS for styling with a dedicated tailwind.config.ts. - Developed core application structure including layout, pages, and components for header, footer, and various sections (Hero, Services, Pricing, etc.). - Integrated contact form functionality using nodemailer for email handling. - Established global styles in globals.css and added animations with Framer Motion. - Included README.md for project documentation and setup instructions.
This commit is contained in:
169
app/api/contact/route.ts
Normal file
169
app/api/contact/route.ts
Normal file
@@ -0,0 +1,169 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import nodemailer from 'nodemailer'
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
const body = await request.json()
|
||||
const { name, email, company, service, message } = body
|
||||
|
||||
// Validation des champs requis
|
||||
if (!name || !email || !service || !message) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Tous les champs requis doivent être remplis.' },
|
||||
{ status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
// Validation de l'email
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
||||
if (!emailRegex.test(email)) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Adresse email invalide.' },
|
||||
{ status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
// Configuration du transporteur SMTP OVH
|
||||
const transporter = nodemailer.createTransport({
|
||||
host: process.env.SMTP_HOST || 'ssl0.ovh.net',
|
||||
port: parseInt(process.env.SMTP_PORT || '465'),
|
||||
secure: true, // true pour le port 465, false pour les autres ports
|
||||
auth: {
|
||||
user: process.env.SMTP_USER, // L'email d'envoi OVH
|
||||
pass: process.env.SMTP_PASSWORD, // Le mot de passe de l'email OVH
|
||||
},
|
||||
})
|
||||
|
||||
// Configuration de l'email
|
||||
const mailOptions = {
|
||||
from: process.env.SMTP_FROM || process.env.SMTP_USER,
|
||||
to: 'contact@runlock.re',
|
||||
replyTo: email,
|
||||
subject: `[Runlock.re] Nouvelle demande de contact - ${service}`,
|
||||
html: `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.container {
|
||||
background-color: white;
|
||||
padding: 30px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
||||
}
|
||||
h1 {
|
||||
color: #00ff88;
|
||||
border-bottom: 2px solid #00ff88;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.info-row {
|
||||
margin: 15px 0;
|
||||
padding: 10px;
|
||||
background-color: #f9f9f9;
|
||||
border-left: 4px solid #00ff88;
|
||||
}
|
||||
.label {
|
||||
font-weight: bold;
|
||||
color: #666;
|
||||
display: inline-block;
|
||||
min-width: 120px;
|
||||
}
|
||||
.message-box {
|
||||
background-color: #f9f9f9;
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
margin-top: 20px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.footer {
|
||||
margin-top: 30px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #ddd;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Nouvelle demande de contact</h1>
|
||||
|
||||
<div class="info-row">
|
||||
<span class="label">Nom :</span>
|
||||
<span>${name}</span>
|
||||
</div>
|
||||
|
||||
<div class="info-row">
|
||||
<span class="label">Email :</span>
|
||||
<span><a href="mailto:${email}">${email}</a></span>
|
||||
</div>
|
||||
|
||||
${company ? `
|
||||
<div class="info-row">
|
||||
<span class="label">Entreprise :</span>
|
||||
<span>${company}</span>
|
||||
</div>
|
||||
` : ''}
|
||||
|
||||
<div class="info-row">
|
||||
<span class="label">Service :</span>
|
||||
<span>${service}</span>
|
||||
</div>
|
||||
|
||||
<div class="message-box">
|
||||
<strong>Message :</strong><br><br>
|
||||
${message.replace(/\n/g, '<br>')}
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<p>Cet email a été envoyé depuis le formulaire de contact de runlock.re</p>
|
||||
<p>Vous pouvez répondre directement à cet email pour contacter ${name}</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`,
|
||||
text: `
|
||||
Nouvelle demande de contact - Runlock.re
|
||||
|
||||
Nom: ${name}
|
||||
Email: ${email}
|
||||
${company ? `Entreprise: ${company}\n` : ''}
|
||||
Service: ${service}
|
||||
|
||||
Message:
|
||||
${message}
|
||||
|
||||
---
|
||||
Cet email a été envoyé depuis le formulaire de contact de runlock.re
|
||||
Vous pouvez répondre directement à cet email pour contacter ${name}
|
||||
`,
|
||||
}
|
||||
|
||||
// Envoi de l'email
|
||||
await transporter.sendMail(mailOptions)
|
||||
|
||||
return NextResponse.json(
|
||||
{ message: 'Votre message a été envoyé avec succès !' },
|
||||
{ status: 200 }
|
||||
)
|
||||
} catch (error) {
|
||||
console.error('Erreur lors de l\'envoi de l\'email:', error)
|
||||
return NextResponse.json(
|
||||
{ error: 'Une erreur est survenue lors de l\'envoi de votre message. Veuillez réessayer.' },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user