import fs from 'fs'; import path from 'path'; import { detectDeviceType } from './deviceDetect'; export interface UIComponent { id: string; // Eindeutige ID (z.B. uuid / timestamp) slotId: string; // Platz-ID (z.B. 'hero-badge-slot', 'hero-actions-slot', 'bento-slot-1') orderIndex?: number; // Position / Reihenfolge auf dem Platz type: 'button' | 'badge' | 'text' | 'card' | 'accordion' | 'stat-box' | 'testimonial' | 'cta-box'; content: string; link?: string; animation0?: string; // e.g. 'spring-fade', 'hover-bounce', 'pulse-glow' style?: 'primary' | 'secondary' | 'outline' | 'glass'; } export interface SectionConfig { id: string; type: 'hero' | 'bento' | 'contact' | 'custom'; title?: string; subtitle?: string; badge?: string; animation?: string; elements?: UIComponent[]; } export interface SiteConfig { siteName: string; metaDescription: string; header?: { brandName?: string; brandHighlight?: string; ctaText?: string; ctaLink?: string; showThemeToggle?: boolean; glassEffect?: boolean; }; footer?: { brandDescription?: string; copyrightText?: string; showLegalLinks?: boolean; }; hero: { badge: string; title: string; subtitle: string; ctaPrimaryText: string; ctaPrimaryLink: string; ctaSecondaryText: string; ctaSecondaryLink: string; animation?: string; elements?: UIComponent[]; }; bento: { sectionTitle: string; sectionSubtitle: string; animation?: string; cards: Array<{ id: string; title: string; description: string; colSpan?: number; badge?: string; icon?: string; animation?: string; }>; }; contact: { title: string; subtitle: string; recipientEmail: string; phone?: string; address?: string; }; sectionsOrder: string[]; sectionsDetails?: SectionConfig[]; } export interface ThemeConfig { activePreset: string; glassBlur?: string; // 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' glassOpacity?: number; // 0.1 to 0.9 glassBorderRadius?: string; // 'rounded-lg' | 'rounded-xl' | 'rounded-2xl' customColors?: { bg?: string; accent?: string; }; } export interface SmtpConfig { host: string; port: number; secure: boolean; user: string; pass: string; fromName: string; fromEmail: string; isConfigured: boolean; } export const FALLBACK_SITE_CONFIG: SiteConfig = { siteName: 'N&D IT Solutions', metaDescription: 'High-Performance Webdesign & Digital Solutions - 100% DSGVO-konform.', header: { brandName: 'N&D', brandHighlight: 'i-t SOLUTIONS', ctaText: 'Erstgespräch buchen', ctaLink: '#contact', showThemeToggle: true, glassEffect: true }, footer: { brandDescription: 'Ihr Partner für professionelles Webdesign, Website-Entwicklung und lokale SEO für Kleinbetriebe & KMU.', copyrightText: 'N&D i-t SOLUTIONS. Alle Rechte vorbehalten.', showLegalLinks: true }, hero: { badge: 'š Waas Enterprise Baukastensystem', title: 'Maßgeschneiderte Webseiten. Digital im Griff.', subtitle: 'Wir entwickeln blitzschnelle, DSGVO-konforme High-End Webseiten für Ihr Unternehmen zum monatlichen Festpreis – inklusive Wartung & Hosting.', ctaPrimaryText: 'Projekt anfragen', ctaPrimaryLink: '#contact', ctaSecondaryText: 'Mehr erfahren', ctaSecondaryLink: '#services', elements: [ { id: 'el-1', slotId: 'hero-badge-slot', type: 'badge', content: 'WaaS Engine' }, { id: 'el-2', slotId: 'hero-actions-slot', type: 'button', content: 'Neuer Button', link: '#contact', animation0: 'spring-fade', style: 'primary' } ] }, bento: { sectionTitle: 'High-End Features & Leistung', sectionSubtitle: 'Modernste Technologie & Höchster Datenschutz vereint.', cards: [ { id: 'card-1', title: 'Ultra Fast SSR', description: 'Sub-100ms Ladezeiten dank Astro Hybrid SSR Architecture. Google Core Web Vitals > 95%.', colSpan: 2, badge: 'Performance', icon: 'zap' }, { id: 'card-2', title: '100% DSGVO-Sicher', description: 'Keine Cookies, keine Tracking-Skripte, Zero Third-Party Requests.', colSpan: 1, badge: 'Datenschutz', icon: 'shield' }, { id: 'card-3', title: 'Liquid Glass UI', description: 'Moderne Ästhetik mit matte Boxen, Aurora Glows und physikalischen Kanten-Effekten.', colSpan: 1, badge: 'Design', icon: 'layers' }, { id: 'card-4', title: 'Sorgenfrei-Paket', description: 'Hosting, SSL, Wartung und regelmäßige Inhalts-Updates komplett inklusive.', colSpan: 2, badge: 'Full-Service', icon: 'check' } ] }, contact: { title: 'Bereit für Ihr Projekt?', subtitle: 'Schreiben Sie uns direkt. Wir antworten innerhalb von 24 Stunden persönlich.', recipientEmail: 'kontakt@ndsolutions.de', phone: '+49 (0) 123 456789', address: 'Deutschland' }, sectionsOrder: ['hero', 'bento', 'contact'], sectionsDetails: [ { id: 'hero', type: 'hero', title: 'Hero Sektion', elements: [ { id: 'el-1', slotId: 'hero-badge-slot', type: 'badge', content: 'WaaS Engine' } ] }, { id: 'bento', type: 'bento', title: 'Bento Grid', elements: [] }, { id: 'contact', type: 'contact', title: 'Contact Section', elements: [] } ], site_info: { title: 'N&D IT Solutions', homepage_id: 'page_home' }, pages: [ { id: 'page_home', slug: '/', title: 'Startseite (Hauptseite)', is_published: true, sections: [ { id: 'hero', type: 'HeroSection', settings: {} }, { id: 'bento', type: 'BentoGrid', settings: {} }, { id: 'contact', type: 'ContactSection', settings: {} } ] }, { id: 'page_templates', slug: '/templates', title: 'Templates & Design-Muster', is_published: true, sections: [ { id: 'hero_templates', type: 'HeroSection', settings: { title: 'Templates', subtitle: 'Unsere fertigen Design-Vorlagen' } } ] }, { id: 'page_privacy', slug: '/datenschutz', title: 'Datenschutzerklärung', is_published: true, sections: [ { id: 'privacy_content', type: 'HeroSection', settings: { title: 'Datenschutz', subtitle: '100% DSGVO-konforme Datenverarbeitung.' } } ] } ] }; export const FALLBACK_THEME_CONFIG: ThemeConfig = { activePreset: 'corporateDark' }; export const FALLBACK_SMTP_CONFIG: SmtpConfig = { host: 'smtp.placeholder.local', port: 587, secure: false, user: 'placeholder@domain.de', pass: '****', fromName: 'N&D IT Solutions System', fromEmail: 'noreply@ndsolutions.de', isConfigured: false }; function readJsonFile(filePath: string, fallback: T): T { try { if (!fs.existsSync(filePath)) { return fallback; } const content = fs.readFileSync(filePath, 'utf-8'); if (!content.trim()) { return fallback; } const parsed = JSON.parse(content); return { ...fallback, ...parsed }; } catch (error) { console.warn(`[WaaS ConfigLoader] Warning loading ${filePath}, using fallback defaults.`, error); return fallback; } } export function loadWaasConfigs(userAgent: string = '', isDraft: boolean = false) { const dataDir = process.env.DATA_DIR || path.join(process.cwd(), 'app', 'data'); const device = detectDeviceType(userAgent); const draftSitePath = path.join(dataDir, 'site.config.draft.json'); const deviceSitePath = path.join(dataDir, `site.${device}.config.json`); const genericSitePath = path.join(dataDir, 'site.config.json'); let sitePath = genericSitePath; if (isDraft && fs.existsSync(draftSitePath)) { sitePath = draftSitePath; } else if (fs.existsSync(deviceSitePath)) { sitePath = deviceSitePath; } const deviceThemePath = path.join(dataDir, `theme.${device}.config.json`); const genericThemePath = path.join(dataDir, 'theme.config.json'); const themePath = fs.existsSync(deviceThemePath) ? deviceThemePath : genericThemePath; const deviceSmtpPath = path.join(dataDir, `smtp.${device}.config.json`); const genericSmtpPath = path.join(dataDir, 'smtp.config.json'); const smtpPath = fs.existsSync(deviceSmtpPath) ? deviceSmtpPath : genericSmtpPath; const rawSite = readJsonFile>(sitePath, FALLBACK_SITE_CONFIG); const siteConfig: SiteConfig = { ...FALLBACK_SITE_CONFIG, ...rawSite, hero: { ...FALLBACK_SITE_CONFIG.hero, ...(rawSite.hero || {}) }, bento: { ...FALLBACK_SITE_CONFIG.bento, ...(rawSite.bento || {}) }, contact: { ...FALLBACK_SITE_CONFIG.contact, ...(rawSite.contact || {}) }, pages: (rawSite as any).pages && (rawSite as any).pages.length > 0 ? (rawSite as any).pages : (FALLBACK_SITE_CONFIG as any).pages, site_info: { ...(FALLBACK_SITE_CONFIG as any).site_info, ...((rawSite as any).site_info || {}) } }; const themeConfig = readJsonFile(themePath, FALLBACK_THEME_CONFIG); const smtpConfig = readJsonFile(smtpPath, FALLBACK_SMTP_CONFIG); return { siteConfig, themeConfig, smtpConfig }; } export function getSiteConfig(isDraft: boolean = false) { return loadWaasConfigs('', isDraft).siteConfig; }