feat(admin): add global header and footer configuration fields in admin dashboard
This commit is contained in:
@@ -100,7 +100,54 @@ 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>
|
||||
|
||||
@@ -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
|
||||
},
|
||||
|
||||
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user