Initial commit: Lageplan v1.0 - Next.js 15.5, React 19
This commit is contained in:
75
src/app/api/contact/route.ts
Normal file
75
src/app/api/contact/route.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { prisma } from '@/lib/db'
|
||||
import { sendEmail, getSmtpConfig } from '@/lib/email'
|
||||
import { z } from 'zod'
|
||||
|
||||
const contactSchema = z.object({
|
||||
name: z.string().min(1).max(200),
|
||||
email: z.string().email(),
|
||||
message: z.string().min(1).max(5000),
|
||||
})
|
||||
|
||||
// Get contact email from SystemSettings, fallback to app@lageplan.ch
|
||||
async function getContactEmail(): Promise<string> {
|
||||
try {
|
||||
const setting = await (prisma as any).systemSetting.findUnique({
|
||||
where: { key: 'contact_email' },
|
||||
})
|
||||
return setting?.value || 'app@lageplan.ch'
|
||||
} catch {
|
||||
return 'app@lageplan.ch'
|
||||
}
|
||||
}
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
try {
|
||||
const body = await req.json()
|
||||
const data = contactSchema.parse(body)
|
||||
|
||||
const contactEmail = await getContactEmail()
|
||||
const smtpConfig = await getSmtpConfig()
|
||||
|
||||
if (smtpConfig) {
|
||||
// Send via SMTP
|
||||
const html = `
|
||||
<h2>Neue Kontaktanfrage — Lageplan</h2>
|
||||
<table style="border-collapse:collapse;width:100%;max-width:500px;">
|
||||
<tr><td style="padding:8px;font-weight:bold;border-bottom:1px solid #eee;">Name</td><td style="padding:8px;border-bottom:1px solid #eee;">${escapeHtml(data.name)}</td></tr>
|
||||
<tr><td style="padding:8px;font-weight:bold;border-bottom:1px solid #eee;">E-Mail</td><td style="padding:8px;border-bottom:1px solid #eee;"><a href="mailto:${escapeHtml(data.email)}">${escapeHtml(data.email)}</a></td></tr>
|
||||
</table>
|
||||
<h3 style="margin-top:20px;">Nachricht</h3>
|
||||
<div style="background:#f9f9f9;padding:16px;border-radius:8px;white-space:pre-wrap;">${escapeHtml(data.message)}</div>
|
||||
<p style="margin-top:20px;font-size:12px;color:#999;">Gesendet über das Kontaktformular auf lageplan.ch</p>
|
||||
`
|
||||
|
||||
await sendEmail(contactEmail, `Kontaktanfrage von ${data.name}`, html)
|
||||
} else {
|
||||
// No SMTP configured — store in SystemSettings as fallback log
|
||||
const logKey = `contact_msg_${Date.now()}`
|
||||
await (prisma as any).systemSetting.create({
|
||||
data: {
|
||||
key: logKey,
|
||||
value: JSON.stringify({ name: data.name, email: data.email, message: data.message, date: new Date().toISOString() }),
|
||||
isSecret: false,
|
||||
category: 'contact_messages',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return NextResponse.json({ success: true })
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
return NextResponse.json({ error: 'Bitte füllen Sie alle Felder korrekt aus.' }, { status: 400 })
|
||||
}
|
||||
console.error('Contact form error:', error)
|
||||
return NextResponse.json({ error: 'Senden fehlgeschlagen. Bitte versuchen Sie es später.' }, { status: 500 })
|
||||
}
|
||||
}
|
||||
|
||||
function escapeHtml(str: string): string {
|
||||
return str
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
}
|
||||
Reference in New Issue
Block a user