const express = require('express');
const cors = require('cors');
const nodemailer = require('nodemailer');
const axios = require('axios');
const path = require('path');
require('dotenv').config();
const app = express();
const PORT = process.env.PORT || 3000;
// Middleware
app.use(cors());
app.use(express.json());
app.use(express.static(path.join(__dirname, '../dist/florale-emotion')));
// Email configuration
const transporter = nodemailer.createTransport({
host: 'smtp.mailbox.org',
port: 587,
secure: false,
auth: {
user: process.env.EMAIL_USER || 'info@florale-emotion.de',
pass: process.env.EMAIL_PASS || 'your-email-password'
}
});
// Gitea configuration
const GITEA_CONFIG = {
url: process.env.GITEA_URL || 'https://your-gitea-instance.com',
token: process.env.GITEA_TOKEN || 'your-gitea-token',
owner: 'florale-emotion',
repo: 'tickets'
};
// Email templates
const getCustomerEmailTemplate = (formData) => {
const eventTypes = {
'wedding': 'Hochzeit',
'funeral': 'Beerdigung',
'corporate': 'Firmenevent',
'birthday': 'Geburtstag',
'anniversary': 'Jubiläum',
'other': 'Sonstiges'
};
return `
Liebe/r ${formData.firstName} ${formData.lastName},
vielen Dank für Ihr Interesse an unseren floralen Services für Ihr/e ${eventTypes[formData.eventType] || formData.eventType}!
Wir haben Ihre Anfrage erhalten und werden uns schnellstmöglich bei Ihnen melden. In der Regel antworten wir innerhalb von 24 Stunden.
Ihre Anfrage im Überblick:
- Event-Art: ${eventTypes[formData.eventType] || formData.eventType}
${formData.eventDate ? `- Gewünschtes Datum: ${new Date(formData.eventDate).toLocaleDateString('de-DE')}
` : ''}
${formData.guestCount ? `- Anzahl Gäste: ${formData.guestCount}
` : ''}
${formData.budget ? `- Budget: ${formData.budget}
` : ''}
Falls Sie noch Fragen haben oder zusätzliche Informationen benötigen, zögern Sie nicht, uns zu kontaktieren.
Mit floralen Grüßen,
Ihr Team von Florale Emotion
Veronika & Corinna
`;
};
const getInternalEmailTemplate = (formData) => {
const eventTypes = {
'wedding': 'Hochzeit',
'funeral': 'Beerdigung',
'corporate': 'Firmenevent',
'birthday': 'Geburtstag',
'anniversary': 'Jubiläum',
'other': 'Sonstiges'
};
return `
Kundeninformationen
Name: ${formData.firstName} ${formData.lastName}
E-Mail: ${formData.email}
Telefon: ${formData.phone || 'Nicht angegeben'}
Event-Details
Art des Events: ${eventTypes[formData.eventType] || formData.eventType}
Gewünschtes Datum: ${formData.eventDate ? new Date(formData.eventDate).toLocaleDateString('de-DE') : 'Nicht angegeben'}
Anzahl Gäste: ${formData.guestCount || 'Nicht angegeben'}
Budget: ${formData.budget || 'Nicht angegeben'}
Nachricht
${formData.message.replace(/\n/g, '
')}
Eingegangen am: ${new Date().toLocaleString('de-DE')}
`;
};
// Create Gitea ticket
async function createGiteaTicket(formData) {
try {
const eventTypes = {
'wedding': 'Hochzeit',
'funeral': 'Beerdigung',
'corporate': 'Corporate Event',
'birthday': 'Geburtstag',
'anniversary': 'Jubiläum',
'other': 'Sonstiges'
};
const title = `Neue Anfrage: ${eventTypes[formData.eventType] || formData.eventType} - ${formData.firstName} ${formData.lastName}`;
const body = `## Kundeninformationen
- **Name:** ${formData.firstName} ${formData.lastName}
- **E-Mail:** ${formData.email}
- **Telefon:** ${formData.phone || 'Nicht angegeben'}
## Event-Details
- **Art des Events:** ${eventTypes[formData.eventType] || formData.eventType}
- **Gewünschtes Datum:** ${formData.eventDate || 'Nicht angegeben'}
- **Anzahl Gäste:** ${formData.guestCount || 'Nicht angegeben'}
- **Budget:** ${formData.budget || 'Nicht angegeben'}
## Nachricht
${formData.message}
---
*Automatisch erstellt am ${new Date().toLocaleString('de-DE')}*`;
const issue = {
title,
body,
labels: ['kunde-anfrage', eventTypes[formData.eventType]?.toLowerCase().replace(' ', '-') || 'sonstiges'],
assignees: ['veronika', 'corinna']
};
const response = await axios.post(
`${GITEA_CONFIG.url}/api/v1/repos/${GITEA_CONFIG.owner}/${GITEA_CONFIG.repo}/issues`,
issue,
{
headers: {
'Authorization': `token ${GITEA_CONFIG.token}`,
'Content-Type': 'application/json'
}
}
);
return response.data;
} catch (error) {
console.error('Error creating Gitea ticket:', error.response?.data || error.message);
throw error;
}
}
// Routes
app.post('/api/contact', async (req, res) => {
try {
const formData = req.body;
// Send confirmation email to customer
const customerMailOptions = {
from: process.env.EMAIL_USER || 'info@florale-emotion.de',
to: formData.email,
subject: 'Bestätigung Ihrer Anfrage - Florale Emotion',
html: getCustomerEmailTemplate(formData)
};
// Send notification email to team
const teamMailOptions = {
from: process.env.EMAIL_USER || 'info@florale-emotion.de',
to: [
'veronika@florale-emotion.de',
'corinna@florale-emotion.de',
'info@florale-emotion.de'
],
subject: `Neue Kundenanfrage: ${formData.firstName} ${formData.lastName}`,
html: getInternalEmailTemplate(formData)
};
// Send emails
await Promise.all([
transporter.sendMail(customerMailOptions),
transporter.sendMail(teamMailOptions)
]);
// Create Gitea ticket
let ticketId = null;
try {
const ticket = await createGiteaTicket(formData);
ticketId = ticket.number;
} catch (ticketError) {
console.error('Failed to create Gitea ticket:', ticketError);
// Continue even if ticket creation fails
}
res.json({
success: true,
message: 'Anfrage erfolgreich gesendet',
ticketId
});
} catch (error) {
console.error('Error processing contact form:', error);
res.status(500).json({
success: false,
message: 'Fehler beim Senden der Anfrage'
});
}
});
app.post('/api/newsletter', async (req, res) => {
try {
const { email } = req.body;
const mailOptions = {
from: process.env.EMAIL_USER || 'info@florale-emotion.de',
to: email,
subject: 'Willkommen bei Florale Emotion Newsletter',
html: `
Vielen Dank für Ihr Interesse an Florale Emotion.
Sie erhalten ab sofort Updates über neue Projekte, Tipps und besondere Angebote.
`
};
await transporter.sendMail(mailOptions);
res.json({
success: true,
message: 'Newsletter-Anmeldung erfolgreich'
});
} catch (error) {
console.error('Error processing newsletter signup:', error);
res.status(500).json({
success: false,
message: 'Fehler bei der Newsletter-Anmeldung'
});
}
});
// Health check
app.get('/api/health', (req, res) => {
res.json({ status: 'OK', timestamp: new Date().toISOString() });
});
// Serve Angular app
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, '../dist/florale-emotion/index.html'));
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});