Files
ndsolutionswebsite/src/utils/configLoader.ts

294 lines
9.1 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<T>(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<Partial<SiteConfig>>(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<ThemeConfig>(themePath, FALLBACK_THEME_CONFIG);
const smtpConfig = readJsonFile<SmtpConfig>(smtpPath, FALLBACK_SMTP_CONFIG);
return { siteConfig, themeConfig, smtpConfig };
}
export function getSiteConfig(isDraft: boolean = false) {
return loadWaasConfigs('', isDraft).siteConfig;
}