feat: Add fresh database setup script and media handling improvements

- Introduced a new script for setting up a fresh database with ordered migration tasks.
- Added a utility function to find media by filename, improving media handling in various scripts.
- Updated preload scripts to utilize the new media fetching utility.
- Refactored datenschutz, impressum, and mitglied-werden fields to use stable IDs and anchor IDs.
- Enhanced home and network pages to accommodate new field structures.
- Added new preload script for global CMS settings.
- Improved code readability and organization across multiple files.
This commit is contained in:
syntaxbullet
2026-06-22 17:20:45 +02:00
parent 09a43062a0
commit 9545f2513d
30 changed files with 359 additions and 171 deletions

View File

@@ -29,6 +29,9 @@ export type LegalPageContent = {
}
type LegalPageCms = Partial<LegalPageContent>
type LegalSectionCms = LegalSectionContent & {
anchorId?: string
}
const fallbackText = (value: unknown, fallback: string) => (typeof value === 'string' && value.length > 0 ? value : fallback)
@@ -42,7 +45,10 @@ export default function LegalPage({ content, cmsKey }: { content: LegalPageConte
const cms = (useCmsRoute()?.doc?.[cmsKey] || {}) as LegalPageCms
const hero = { ...content.hero, ...(cms.hero || {}) }
const navigation = { ...content.navigation, ...(cms.navigation || {}) }
const sections = fallbackArray<LegalSectionContent>(cms.sections, content.sections)
const sections = fallbackArray<LegalSectionCms>(cms.sections, content.sections).map((section) => ({
...section,
id: section.anchorId || section.id,
}))
return (
<div style={{ background: CREAM, minHeight: '100vh' }}>

View File

@@ -90,7 +90,7 @@ export const homeContent = {
headline: 'DIE JURY BEWERTET GERADE.',
body:
'Die Anmeldephase 2026 ist geschlossen. Unsere unabhängige Expertenjury aus Wissenschaft und Praxis sichtet und bewertet derzeit alle Einreichungen.',
cta: null,
cta: {},
accent: '#4A8FC9',
bg: '#060D1C',
glow: 'rgba(74,143,201,0.12)',

View File

@@ -596,7 +596,7 @@ function StatusSlider({ data }: { data?: HomeCms }) {
const phases = fallbackArray(data?.phases, homeContent.status.phases).map((phase, i) => {
const phaseRecord = phase as StatusPhase
const fallbackPhase = homeContent.status.phases[i]
const fallbackCta = fallbackPhase?.cta
const fallbackCta = fallbackPhase?.cta?.label
? { label: fallbackPhase.cta.label, to: fallbackPhase.cta.url }
: null
const cta = phaseRecord?.cta?.label

View File

@@ -30,7 +30,7 @@ type NetzwerkCms = Partial<typeof netzwerkContent> & {
type PatronPerson = (typeof netzwerkContent.patronage.people)[number] & { imageUpload?: unknown }
type JuryMember = (typeof netzwerkContent.jury.members)[number] & { imageUpload?: unknown }
type Partner = (typeof netzwerkContent.partners.items)[number] & { tier: 1 | 2 | 3; heroImg?: string; linkedin?: string; logoSubtext?: string }
type Partner = (typeof netzwerkContent.partners.items)[number] & { stableId?: string; tier: 1 | 2 | 3; heroImg?: string; linkedin?: string; logoSubtext?: string }
type PartnerTier = (typeof netzwerkContent.partners.tiers)[number]
type ExpertiseRow = (typeof netzwerkContent.expertise.rows)[number]
type StatItem = (typeof netzwerkContent.juryIntro.stats)[number]
@@ -458,6 +458,7 @@ const Netzwerk: React.FC = () => {
const defaultLogoColor = fallbackText(partnerSection.defaultLogoColor, netzwerkContent.partners.defaultLogoColor);
const partners = fallbackArray<Partner>(partnerSection.items, netzwerkContent.partners.items as Partner[]).map((partner) => ({
...partner,
id: partner.stableId || partner.id,
logoColor: fallbackText(partner.logoColor, defaultLogoColor),
}));
const partnerTiers = fallbackArray<PartnerTier>(partnerSection.tiers, netzwerkContent.partners.tiers);