Implementiere Impressum/Datenschutz-System und bereinige URL-Konfiguration
- Neues Impressum/Datenschutz-Tab mit konfigurierbaren rechtlichen Daten - Konfigurationsdatei legal-config.ts für alle rechtlichen Informationen - RPC-Endpoint legal.getConfig() für rechtliche Daten - Schöne Tab-Navigation zwischen Impressum und Datenschutz - Responsive Design mit Loading-States und Fehlerbehandlung - Alle rechtlichen Daten über Umgebungsvariablen konfigurierbar - FRONTEND_URL entfernt - nur noch DOMAIN wird verwendet - Hilfsfunktion generateUrl() für konsistente URL-Generierung - Code-Duplikation in bookings.ts eliminiert - .env.example aktualisiert mit allen neuen Variablen - README.md dokumentiert neue rechtliche Konfiguration - DSGVO- und TMG-konforme Inhalte implementiert
This commit is contained in:
76
src/server/lib/legal-config.ts
Normal file
76
src/server/lib/legal-config.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
// Legal configuration for Impressum and Datenschutz
|
||||
export interface LegalConfig {
|
||||
// Impressum data
|
||||
companyName: string;
|
||||
ownerName: string;
|
||||
address: {
|
||||
street: string;
|
||||
city: string;
|
||||
postalCode: string;
|
||||
country: string;
|
||||
};
|
||||
contact: {
|
||||
phone: string;
|
||||
email: string;
|
||||
website: string;
|
||||
};
|
||||
businessDetails: {
|
||||
taxId?: string;
|
||||
vatId?: string;
|
||||
commercialRegister?: string;
|
||||
responsibleForContent: string;
|
||||
};
|
||||
|
||||
// Datenschutz data
|
||||
dataProtection: {
|
||||
responsiblePerson: string;
|
||||
email: string;
|
||||
purpose: string;
|
||||
legalBasis: string;
|
||||
dataRetention: string;
|
||||
rights: string;
|
||||
cookies: string;
|
||||
thirdPartyServices: string[];
|
||||
dataSecurity: string;
|
||||
contactDataProtection: string;
|
||||
};
|
||||
}
|
||||
|
||||
// Default configuration - should be overridden by environment variables
|
||||
export const defaultLegalConfig: LegalConfig = {
|
||||
companyName: process.env.COMPANY_NAME || "Stargirlnails Kiel",
|
||||
ownerName: process.env.OWNER_NAME || "Inhaber Name",
|
||||
address: {
|
||||
street: process.env.ADDRESS_STREET || "Musterstraße 123",
|
||||
city: process.env.ADDRESS_CITY || "Kiel",
|
||||
postalCode: process.env.ADDRESS_POSTAL_CODE || "24103",
|
||||
country: process.env.ADDRESS_COUNTRY || "Deutschland",
|
||||
},
|
||||
contact: {
|
||||
phone: process.env.CONTACT_PHONE || "+49 431 123456",
|
||||
email: process.env.CONTACT_EMAIL || "info@stargirlnails.de",
|
||||
website: process.env.DOMAIN || "stargirlnails.de",
|
||||
},
|
||||
businessDetails: {
|
||||
taxId: process.env.TAX_ID || "",
|
||||
vatId: process.env.VAT_ID || "",
|
||||
commercialRegister: process.env.COMMERCIAL_REGISTER || "",
|
||||
responsibleForContent: process.env.RESPONSIBLE_FOR_CONTENT || "Inhaber Name",
|
||||
},
|
||||
dataProtection: {
|
||||
responsiblePerson: process.env.DATA_PROTECTION_RESPONSIBLE || "Inhaber Name",
|
||||
email: process.env.DATA_PROTECTION_EMAIL || "datenschutz@stargirlnails.de",
|
||||
purpose: process.env.DATA_PROTECTION_PURPOSE || "Terminbuchung und Kundenbetreuung",
|
||||
legalBasis: process.env.DATA_PROTECTION_LEGAL_BASIS || "Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) und Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse)",
|
||||
dataRetention: process.env.DATA_PROTECTION_RETENTION || "Buchungsdaten werden 3 Jahre nach Vertragsende gespeichert",
|
||||
rights: process.env.DATA_PROTECTION_RIGHTS || "Auskunft, Berichtigung, Löschung, Einschränkung, Widerspruch, Beschwerde bei der Aufsichtsbehörde",
|
||||
cookies: process.env.DATA_PROTECTION_COOKIES || "Wir verwenden technisch notwendige Cookies für die Funktionalität der Website",
|
||||
thirdPartyServices: process.env.THIRD_PARTY_SERVICES ? process.env.THIRD_PARTY_SERVICES.split(',') : ["Resend (E-Mail-Versand)"],
|
||||
dataSecurity: process.env.DATA_PROTECTION_SECURITY || "SSL-Verschlüsselung, sichere Server, regelmäßige Updates",
|
||||
contactDataProtection: process.env.DATA_PROTECTION_CONTACT || "Bei Fragen zum Datenschutz wenden Sie sich an: datenschutz@stargirlnails.de",
|
||||
},
|
||||
};
|
||||
|
||||
export function getLegalConfig(): LegalConfig {
|
||||
return defaultLegalConfig;
|
||||
}
|
@@ -19,6 +19,13 @@ function formatDateGerman(dateString: string): string {
|
||||
return `${day}.${month}.${year}`;
|
||||
}
|
||||
|
||||
// Helper function to generate URLs from DOMAIN environment variable
|
||||
function generateUrl(path: string = ''): string {
|
||||
const domain = process.env.DOMAIN || 'localhost:5173';
|
||||
const protocol = domain.includes('localhost') ? 'http' : 'https';
|
||||
return `${protocol}://${domain}${path}`;
|
||||
}
|
||||
|
||||
const BookingSchema = z.object({
|
||||
id: z.string(),
|
||||
treatmentId: z.string(),
|
||||
@@ -119,9 +126,7 @@ const create = os
|
||||
// Notify customer: request received (pending)
|
||||
void (async () => {
|
||||
const formattedDate = formatDateGerman(input.appointmentDate);
|
||||
const domain = process.env.DOMAIN || 'localhost:5173';
|
||||
const protocol = domain.includes('localhost') ? 'http' : 'https';
|
||||
const homepageUrl = `${protocol}://${domain}`;
|
||||
const homepageUrl = generateUrl();
|
||||
const html = await renderBookingPendingHTML({ name: input.customerName, date: input.appointmentDate, time: input.appointmentTime });
|
||||
await sendEmail({
|
||||
to: input.customerEmail,
|
||||
@@ -150,9 +155,7 @@ const create = os
|
||||
hasInspirationPhoto: !!input.inspirationPhoto
|
||||
});
|
||||
|
||||
const domain = process.env.DOMAIN || 'localhost:5173';
|
||||
const protocol = domain.includes('localhost') ? 'http' : 'https';
|
||||
const homepageUrl = `${protocol}://${domain}`;
|
||||
const homepageUrl = generateUrl();
|
||||
|
||||
const adminText = `Neue Buchungsanfrage eingegangen:\n\n` +
|
||||
`Name: ${input.customerName}\n` +
|
||||
@@ -260,7 +263,8 @@ const updateStatus = os
|
||||
const cancellationToken = await queryClient.cancellation.createToken({ bookingId: booking.id });
|
||||
|
||||
const formattedDate = formatDateGerman(booking.appointmentDate);
|
||||
const cancellationUrl = `${process.env.FRONTEND_URL || 'http://localhost:5173'}/cancel/${cancellationToken.token}`;
|
||||
const cancellationUrl = generateUrl(`/cancel/${cancellationToken.token}`);
|
||||
const homepageUrl = generateUrl();
|
||||
|
||||
const html = await renderBookingConfirmedHTML({
|
||||
name: booking.customerName,
|
||||
@@ -269,10 +273,6 @@ const updateStatus = os
|
||||
cancellationUrl
|
||||
});
|
||||
|
||||
const domain = process.env.DOMAIN || 'localhost:5173';
|
||||
const protocol = domain.includes('localhost') ? 'http' : 'https';
|
||||
const homepageUrl = `${protocol}://${domain}`;
|
||||
|
||||
await sendEmailWithAGB({
|
||||
to: booking.customerEmail,
|
||||
subject: "Dein Termin wurde bestätigt - AGB im Anhang",
|
||||
@@ -282,9 +282,7 @@ const updateStatus = os
|
||||
});
|
||||
} else if (input.status === "cancelled") {
|
||||
const formattedDate = formatDateGerman(booking.appointmentDate);
|
||||
const domain = process.env.DOMAIN || 'localhost:5173';
|
||||
const protocol = domain.includes('localhost') ? 'http' : 'https';
|
||||
const homepageUrl = `${protocol}://${domain}`;
|
||||
const homepageUrl = generateUrl();
|
||||
const html = await renderBookingCancelledHTML({ name: booking.customerName, date: booking.appointmentDate, time: booking.appointmentTime });
|
||||
await sendEmail({
|
||||
to: booking.customerEmail,
|
||||
|
@@ -4,6 +4,7 @@ import { router as bookings } from "./bookings";
|
||||
import { router as auth } from "./auth";
|
||||
import { router as availability } from "./availability";
|
||||
import { router as cancellation } from "./cancellation";
|
||||
import { router as legal } from "./legal";
|
||||
|
||||
export const router = {
|
||||
demo,
|
||||
@@ -12,4 +13,5 @@ export const router = {
|
||||
auth,
|
||||
availability,
|
||||
cancellation,
|
||||
legal,
|
||||
};
|
||||
|
8
src/server/rpc/legal.ts
Normal file
8
src/server/rpc/legal.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { os } from "@orpc/server";
|
||||
import { getLegalConfig } from "@/server/lib/legal-config";
|
||||
|
||||
export const router = {
|
||||
getConfig: os.handler(async () => {
|
||||
return getLegalConfig();
|
||||
}),
|
||||
};
|
Reference in New Issue
Block a user