Initial commit: Lageplan v1.0 - Next.js 15.5, React 19

This commit is contained in:
Pepe Ziberi
2026-02-21 11:57:44 +01:00
commit adf3dc8c1d
167 changed files with 34265 additions and 0 deletions

View File

@@ -0,0 +1,156 @@
import { NextRequest, NextResponse } from 'next/server'
import { prisma } from '@/lib/db'
import { getSession, isServerAdmin } from '@/lib/auth'
import { getSmtpConfig, saveSmtpConfig, testSmtpConnection, sendEmail } from '@/lib/email'
import { getStripeConfig, saveStripeConfig } from '@/lib/stripe'
// GET SMTP settings (mask password)
export async function GET() {
try {
const user = await getSession()
if (!user || !isServerAdmin(user.role)) {
return NextResponse.json({ error: 'Nicht autorisiert' }, { status: 403 })
}
const smtp = await getSmtpConfig()
// Load contact email
let contactEmail = 'app@lageplan.ch'
try {
const setting = await (prisma as any).systemSetting.findUnique({ where: { key: 'contact_email' } })
if (setting) contactEmail = setting.value
} catch {}
// Load Stripe settings
const stripeConfig = await getStripeConfig()
// Load demo project ID
let demoProjectId = ''
try {
const demoSetting = await (prisma as any).systemSetting.findUnique({ where: { key: 'demo_project_id' } })
if (demoSetting) demoProjectId = demoSetting.value
} catch {}
// Load registration notification email
let notifyRegistrationEmail = ''
try {
const nrSetting = await (prisma as any).systemSetting.findUnique({ where: { key: 'notify_registration_email' } })
if (nrSetting) notifyRegistrationEmail = nrSetting.value
} catch {}
// Load default symbol scale
let defaultSymbolScale = '1.5'
try {
const scaleSetting = await (prisma as any).systemSetting.findUnique({ where: { key: 'default_symbol_scale' } })
if (scaleSetting) defaultSymbolScale = scaleSetting.value
} catch {}
return NextResponse.json({
smtp: smtp ? { ...smtp, pass: smtp.pass ? '••••••••' : '' } : null,
contactEmail,
notifyRegistrationEmail,
demoProjectId,
defaultSymbolScale,
stripe: stripeConfig ? {
publicKey: stripeConfig.publicKey || '',
secretKey: stripeConfig.secretKey ? '••••••••' : '',
webhookSecret: stripeConfig.webhookSecret ? '••••••••' : '',
} : null,
})
} catch (error) {
console.error('Error fetching settings:', error)
return NextResponse.json({ error: 'Interner Fehler' }, { status: 500 })
}
}
// Save SMTP settings
export async function PUT(req: NextRequest) {
try {
const user = await getSession()
if (!user || !isServerAdmin(user.role)) {
return NextResponse.json({ error: 'Nicht autorisiert' }, { status: 403 })
}
const body = await req.json()
const { action, smtp, testEmail } = body
if (action === 'save_smtp') {
// Don't overwrite password if masked
const config: any = { ...smtp }
if (config.pass === '••••••••') {
delete config.pass
}
await saveSmtpConfig(config)
return NextResponse.json({ success: true, message: 'SMTP-Einstellungen gespeichert' })
}
if (action === 'test_smtp') {
const result = await testSmtpConnection()
return NextResponse.json(result)
}
if (action === 'send_test_email') {
if (!testEmail) {
return NextResponse.json({ error: 'E-Mail-Adresse erforderlich' }, { status: 400 })
}
try {
await sendEmail(
testEmail,
'Lageplan - Test E-Mail',
`<h2>Test E-Mail</h2><p>Diese E-Mail wurde von der Lageplan-Applikation gesendet.</p><p>SMTP-Konfiguration funktioniert korrekt.</p><p><small>Gesendet am ${new Date().toLocaleString('de-CH')}</small></p>`
)
return NextResponse.json({ success: true, message: `Test-E-Mail an ${testEmail} gesendet` })
} catch (error) {
return NextResponse.json({ success: false, error: error instanceof Error ? error.message : 'Senden fehlgeschlagen' })
}
}
if (action === 'save_stripe') {
const { stripe: stripeData } = body
if (!stripeData) return NextResponse.json({ error: 'Stripe-Daten fehlen' }, { status: 400 })
await saveStripeConfig({
secretKey: stripeData.secretKey,
publicKey: stripeData.publicKey,
webhookSecret: stripeData.webhookSecret,
})
return NextResponse.json({ success: true, message: 'Stripe-Einstellungen gespeichert' })
}
if (action === 'save_demo_project') {
const { demoProjectId } = body
await (prisma as any).systemSetting.upsert({
where: { key: 'demo_project_id' },
update: { value: demoProjectId || '' },
create: { key: 'demo_project_id', value: demoProjectId || '', isSecret: false, category: 'general' },
})
return NextResponse.json({ success: true, message: 'Demo-Projekt gespeichert' })
}
if (action === 'save_contact_email') {
const { contactEmail } = body
if (!contactEmail) return NextResponse.json({ error: 'E-Mail erforderlich' }, { status: 400 })
await (prisma as any).systemSetting.upsert({
where: { key: 'contact_email' },
update: { value: contactEmail },
create: { key: 'contact_email', value: contactEmail, isSecret: false, category: 'general' },
})
return NextResponse.json({ success: true })
}
if (action === 'save_setting') {
const { key, value } = body
if (!key) return NextResponse.json({ error: 'Key erforderlich' }, { status: 400 })
await (prisma as any).systemSetting.upsert({
where: { key },
update: { value: value || '' },
create: { key, value: value || '', isSecret: false, category: 'general' },
})
return NextResponse.json({ success: true })
}
return NextResponse.json({ error: 'Unbekannte Aktion' }, { status: 400 })
} catch (error) {
console.error('Error updating settings:', error)
return NextResponse.json({ error: 'Interner Fehler' }, { status: 500 })
}
}