feat(admin): add global header and footer configuration fields in admin dashboard

This commit is contained in:
Daniel S
2026-08-09 22:58:54 +02:00
parent 591eba43c1
commit 30b407d2e8
2 changed files with 65 additions and 1 deletions

View File

@@ -100,8 +100,55 @@ const presets = Object.values(THEME_PRESETS);
<input type="text" id="infoAddress" value={(siteConfig as any).site_info?.address || ''} class="w-full glass-panel bg-slate-950/60 rounded-xl p-3 text-xs text-white focus:outline-none focus:border-sky-400" />
</div>
</div>
<!-- Global Header Config -->
<h3 class="text-xs font-bold text-slate-400 uppercase tracking-wider pt-4 border-t border-white/10">Globaler Header / Navigation Bar</h3>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label class="block text-xs font-semibold text-slate-400 mb-1">Brand Name (z.B. N&D)</label>
<input type="text" id="headerBrandName" value={siteConfig.header?.brandName || 'N&D'} class="w-full glass-panel bg-slate-950/60 rounded-xl p-3 text-xs text-white focus:outline-none focus:border-sky-400" />
</div>
<div>
<label class="block text-xs font-semibold text-slate-400 mb-1">Brand Highlight (z.B. i-t SOLUTIONS)</label>
<input type="text" id="headerBrandHighlight" value={siteConfig.header?.brandHighlight || 'i-t SOLUTIONS'} class="w-full glass-panel bg-slate-950/60 rounded-xl p-3 text-xs text-white focus:outline-none focus:border-sky-400" />
</div>
<div>
<label class="block text-xs font-semibold text-slate-400 mb-1">CTA Button Text</label>
<input type="text" id="headerCtaText" value={siteConfig.header?.ctaText || 'Erstgespräch buchen'} class="w-full glass-panel bg-slate-950/60 rounded-xl p-3 text-xs text-white focus:outline-none focus:border-sky-400" />
</div>
<div>
<label class="block text-xs font-semibold text-slate-400 mb-1">CTA Button Link</label>
<input type="text" id="headerCtaLink" value={siteConfig.header?.ctaLink || '#contact'} class="w-full glass-panel bg-slate-950/60 rounded-xl p-3 text-xs text-white focus:outline-none focus:border-sky-400" />
</div>
<label class="flex items-center gap-2 cursor-pointer sm:col-span-2">
<input type="checkbox" id="headerShowThemeToggle" checked={siteConfig.header?.showThemeToggle !== false} class="rounded text-sky-400 focus:ring-0" />
<span class="text-xs text-slate-300 font-semibold">Theme-Toggle Button (☀️/🌙) anzeigen</span>
</label>
<label class="flex items-center gap-2 cursor-pointer sm:col-span-2">
<input type="checkbox" id="headerGlassEffect" checked={siteConfig.header?.glassEffect !== false} class="rounded text-sky-400 focus:ring-0" />
<span class="text-xs text-slate-300 font-semibold">Liquid Glassmorphism Effekt aktivieren</span>
</label>
</div>
<!-- Global Footer Config -->
<h3 class="text-xs font-bold text-slate-400 uppercase tracking-wider pt-4 border-t border-white/10">Globaler Footer</h3>
<div class="space-y-4">
<div>
<label class="block text-xs font-semibold text-slate-400 mb-1">Footer Beschreibungstext</label>
<textarea id="footerBrandDescription" rows="2" class="w-full glass-panel bg-slate-950/60 rounded-xl p-3 text-xs text-white focus:outline-none focus:border-sky-400 resize-none">{siteConfig.footer?.brandDescription || ''}</textarea>
</div>
<div>
<label class="block text-xs font-semibold text-slate-400 mb-1">Copyright Text</label>
<input type="text" id="footerCopyrightText" value={siteConfig.footer?.copyrightText || ''} class="w-full glass-panel bg-slate-950/60 rounded-xl p-3 text-xs text-white focus:outline-none focus:border-sky-400" />
</div>
<label class="flex items-center gap-2 cursor-pointer">
<input type="checkbox" id="footerShowLegalLinks" checked={siteConfig.footer?.showLegalLinks !== false} class="rounded text-sky-400 focus:ring-0" />
<span class="text-xs text-slate-300 font-semibold">Rechtliche Links (Datenschutz & Impressum) im Footer anzeigen</span>
</label>
</div>
</div>
</div>
<!-- Sidebar Column -->
@@ -193,9 +240,23 @@ const presets = Object.values(THEME_PRESETS);
email: getVal('infoEmail'),
phone: getVal('infoPhone'),
address: getVal('infoAddress')
},
header: {
brandName: getVal('headerBrandName'),
brandHighlight: getVal('headerBrandHighlight'),
ctaText: getVal('headerCtaText'),
ctaLink: getVal('headerCtaLink'),
showThemeToggle: getBool('headerShowThemeToggle'),
glassEffect: getBool('headerGlassEffect')
},
footer: {
brandDescription: getVal('footerBrandDescription'),
copyrightText: getVal('footerCopyrightText'),
showLegalLinks: getBool('footerShowLegalLinks')
}
},
themeConfig: {
activePreset: selectedPreset
},

View File

@@ -20,8 +20,11 @@ export const POST: APIRoute = async ({ request }) => {
...currentSite,
...body.siteConfig,
hero: { ...(currentSite.hero || {}), ...(body.siteConfig.hero || {}) },
site_info: { ...((currentSite as any).site_info || {}), ...(body.siteConfig.site_info || {}) }
site_info: { ...((currentSite as any).site_info || {}), ...(body.siteConfig.site_info || {}) },
header: { ...(currentSite.header || {}), ...(body.siteConfig.header || {}) },
footer: { ...(currentSite.footer || {}), ...(body.siteConfig.footer || {}) }
};
const sitePath = path.join(dataDir, 'site.config.json');
const draftPath = path.join(dataDir, 'site.config.draft.json');
fs.writeFileSync(sitePath, JSON.stringify(newSite, null, 2), 'utf8');