Implementiere Stornierungssystem und E-Mail-Links zur Hauptseite
- Neues Stornierungssystem mit sicheren Token-basierten Links - Stornierungsfrist konfigurierbar über MIN_STORNO_TIMESPAN (24h Standard) - Stornierungs-Seite mit Buchungsdetails und Ein-Klick-Stornierung - Automatische Slot-Freigabe bei Stornierung - Stornierungs-Link in Bestätigungs-E-Mails integriert - Alle E-Mails enthalten jetzt Links zur Hauptseite (DOMAIN Variable) - Schöne HTML-Buttons und Text-Links in allen E-Mail-Templates - Vollständige Validierung: Vergangenheits-Check, Token-Ablauf, Stornierungsfrist - Responsive Stornierungs-Seite mit Loading-States und Fehlerbehandlung - Dokumentation in README.md aktualisiert
This commit is contained in:
@@ -27,6 +27,10 @@ async function getLogoDataUrl(): Promise<string | null> {
|
||||
|
||||
async function renderBrandedEmail(title: string, bodyHtml: string): Promise<string> {
|
||||
const logo = await getLogoDataUrl();
|
||||
const domain = process.env.DOMAIN || 'localhost:5173';
|
||||
const protocol = domain.includes('localhost') ? 'http' : 'https';
|
||||
const homepageUrl = `${protocol}://${domain}`;
|
||||
|
||||
return `
|
||||
<div style="font-family: Arial, sans-serif; color: #0f172a; background:#fdf2f8; padding:24px;">
|
||||
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="max-width:640px; margin:0 auto; background:#ffffff; border-radius:12px; overflow:hidden; box-shadow:0 1px 3px rgba(0,0,0,0.06)">
|
||||
@@ -42,6 +46,9 @@ async function renderBrandedEmail(title: string, bodyHtml: string): Promise<stri
|
||||
${bodyHtml}
|
||||
</div>
|
||||
<hr style="border:none; border-top:1px solid #f1f5f9; margin:24px 0" />
|
||||
<div style="text-align:center; margin-bottom:16px;">
|
||||
<a href="${homepageUrl}" style="display: inline-block; background-color: #db2777; color: white; padding: 12px 24px; text-decoration: none; border-radius: 6px; font-weight: 600; font-size: 14px;">Zur Website</a>
|
||||
</div>
|
||||
<div style="font-size:12px; color:#64748b; text-align:center;">
|
||||
© ${new Date().getFullYear()} Stargirlnails Kiel • Professional Nail Care
|
||||
</div>
|
||||
@@ -63,8 +70,8 @@ export async function renderBookingPendingHTML(params: { name: string; date: str
|
||||
return renderBrandedEmail("Deine Terminanfrage ist eingegangen", inner);
|
||||
}
|
||||
|
||||
export async function renderBookingConfirmedHTML(params: { name: string; date: string; time: string }) {
|
||||
const { name, date, time } = params;
|
||||
export async function renderBookingConfirmedHTML(params: { name: string; date: string; time: string; cancellationUrl?: string }) {
|
||||
const { name, date, time, cancellationUrl } = params;
|
||||
const formattedDate = formatDateGerman(date);
|
||||
const inner = `
|
||||
<p>Hallo ${name},</p>
|
||||
@@ -74,6 +81,13 @@ export async function renderBookingConfirmedHTML(params: { name: string; date: s
|
||||
<p style="margin: 0; font-weight: 600; color: #db2777;">📋 Wichtiger Hinweis:</p>
|
||||
<p style="margin: 8px 0 0 0; color: #475569;">Die Allgemeinen Geschäftsbedingungen (AGB) findest du im Anhang dieser E-Mail. Bitte lies sie vor deinem Termin durch.</p>
|
||||
</div>
|
||||
${cancellationUrl ? `
|
||||
<div style="background-color: #fef3f2; border-left: 4px solid #ef4444; padding: 16px; margin: 20px 0; border-radius: 4px;">
|
||||
<p style="margin: 0; font-weight: 600; color: #ef4444;">❌ Termin stornieren:</p>
|
||||
<p style="margin: 8px 0 12px 0; color: #475569;">Falls du den Termin stornieren möchtest, kannst du das hier tun:</p>
|
||||
<a href="${cancellationUrl}" style="display: inline-block; background-color: #ef4444; color: white; padding: 12px 24px; text-decoration: none; border-radius: 6px; font-weight: 600;">Termin stornieren</a>
|
||||
</div>
|
||||
` : ''}
|
||||
<p>Liebe Grüße,<br/>Stargirlnails Kiel</p>
|
||||
`;
|
||||
return renderBrandedEmail("Termin bestätigt", inner);
|
||||
|
Reference in New Issue
Block a user