feat: clean up Preistraeger detail structure by removing unused fields and updating related migrations
This commit is contained in:
@@ -275,9 +275,6 @@ export const Preistraeger: CollectionConfig = {
|
||||
{ name: 'category', type: 'text', defaultValue: preistraegerDetailContent.fallbackWinner.category },
|
||||
{ name: 'awardType', type: 'text', defaultValue: preistraegerDetailContent.fallbackWinner.awardType },
|
||||
{ name: 'longDesc', type: 'textarea', defaultValue: preistraegerDetailContent.fallbackWinner.longDesc },
|
||||
{ name: 'quote', type: 'textarea', defaultValue: preistraegerDetailContent.fallbackWinner.quote },
|
||||
{ name: 'quotePerson', type: 'text', defaultValue: preistraegerDetailContent.fallbackWinner.quotePerson },
|
||||
{ name: 'quoteRole', type: 'text', defaultValue: preistraegerDetailContent.fallbackWinner.quoteRole },
|
||||
{ name: 'location', type: 'text', defaultValue: preistraegerDetailContent.fallbackWinner.location },
|
||||
{ name: 'industry', type: 'text', defaultValue: preistraegerDetailContent.fallbackWinner.industry },
|
||||
],
|
||||
@@ -322,19 +319,6 @@ export const Preistraeger: CollectionConfig = {
|
||||
{ name: 'imageAlt', type: 'text', defaultValue: preistraegerDetailContent.sideImage.imageAlt },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'facts',
|
||||
label: 'Facts box labels',
|
||||
type: 'group',
|
||||
fields: [
|
||||
{ name: 'heading', type: 'text', defaultValue: preistraegerDetailContent.facts.heading },
|
||||
{ name: 'categoryLabel', type: 'text', defaultValue: preistraegerDetailContent.facts.categoryLabel },
|
||||
{ name: 'awardLabel', type: 'text', defaultValue: preistraegerDetailContent.facts.awardLabel },
|
||||
{ name: 'yearLabel', type: 'text', defaultValue: preistraegerDetailContent.facts.yearLabel },
|
||||
{ name: 'locationLabel', type: 'text', defaultValue: preistraegerDetailContent.facts.locationLabel },
|
||||
{ name: 'industryLabel', type: 'text', defaultValue: preistraegerDetailContent.facts.industryLabel },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'websiteCta',
|
||||
label: 'Website CTA',
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
import { type MigrateDownArgs, type MigrateUpArgs, sql } from '@payloadcms/db-sqlite'
|
||||
|
||||
type MigrationDB = MigrateUpArgs['db']
|
||||
|
||||
const ident = (value: string) => `\`${value.replace(/`/g, '``')}\``
|
||||
const literal = (value: string) => `'${value.replace(/'/g, "''")}'`
|
||||
|
||||
const factsColumns = [
|
||||
['heading', 'Auf einen Blick'],
|
||||
['category_label', 'Kategorie'],
|
||||
['award_label', 'Auszeichnung'],
|
||||
['year_label', 'Jahr'],
|
||||
['location_label', 'Standort'],
|
||||
['industry_label', 'Branche'],
|
||||
] as const
|
||||
|
||||
const fallbackQuoteColumns = [
|
||||
['quote', 'Diese Erfolgsgeschichte wird aktuell in Payload CMS gepflegt.'],
|
||||
['quote_person', 'BMP'],
|
||||
['quote_role', 'Preisträger'],
|
||||
] as const
|
||||
|
||||
async function tableExists(db: MigrationDB, tableName: string) {
|
||||
const rows = (await db.all(
|
||||
sql.raw(`SELECT name FROM sqlite_master WHERE type = 'table' AND name = ${literal(tableName)}`),
|
||||
)) as Array<{ name: string }>
|
||||
|
||||
return rows.length > 0
|
||||
}
|
||||
|
||||
async function columnExists(db: MigrationDB, tableName: string, columnName: string) {
|
||||
if (!(await tableExists(db, tableName))) return false
|
||||
|
||||
const columns = (await db.all(sql.raw(`PRAGMA table_info(${ident(tableName)})`))) as Array<{ name: string }>
|
||||
|
||||
return columns.some((column) => column.name === columnName)
|
||||
}
|
||||
|
||||
async function addColumn(db: MigrationDB, tableName: string, columnName: string, definition: string) {
|
||||
if (await columnExists(db, tableName, columnName)) return
|
||||
|
||||
await db.run(sql.raw(`ALTER TABLE ${ident(tableName)} ADD ${ident(columnName)} ${definition};`))
|
||||
}
|
||||
|
||||
async function dropColumn(db: MigrationDB, tableName: string, columnName: string) {
|
||||
if (!(await columnExists(db, tableName, columnName))) return
|
||||
|
||||
await db.run(sql.raw(`ALTER TABLE ${ident(tableName)} DROP COLUMN ${ident(columnName)};`))
|
||||
}
|
||||
|
||||
export async function up({ db, payload: _payload, req: _req }: MigrateUpArgs): Promise<void> {
|
||||
for (const [suffix] of factsColumns) {
|
||||
await dropColumn(db, 'preistraeger', `detail_page_facts_${suffix}`)
|
||||
await dropColumn(db, '_preistraeger_v', `version_detail_page_facts_${suffix}`)
|
||||
}
|
||||
|
||||
for (const [suffix] of fallbackQuoteColumns) {
|
||||
await dropColumn(db, 'preistraeger', `detail_page_fallback_winner_${suffix}`)
|
||||
await dropColumn(db, '_preistraeger_v', `version_detail_page_fallback_winner_${suffix}`)
|
||||
}
|
||||
}
|
||||
|
||||
export async function down({ db, payload: _payload, req: _req }: MigrateDownArgs): Promise<void> {
|
||||
for (const [suffix, defaultValue] of factsColumns) {
|
||||
await addColumn(db, 'preistraeger', `detail_page_facts_${suffix}`, `text DEFAULT ${literal(defaultValue)}`)
|
||||
await addColumn(db, '_preistraeger_v', `version_detail_page_facts_${suffix}`, `text DEFAULT ${literal(defaultValue)}`)
|
||||
}
|
||||
|
||||
for (const [suffix, defaultValue] of fallbackQuoteColumns) {
|
||||
await addColumn(db, 'preistraeger', `detail_page_fallback_winner_${suffix}`, `text DEFAULT ${literal(defaultValue)}`)
|
||||
await addColumn(db, '_preistraeger_v', `version_detail_page_fallback_winner_${suffix}`, `text DEFAULT ${literal(defaultValue)}`)
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import * as migration_20260713_155500_shared_application_form from './20260713_1
|
||||
import * as migration_20260713_163000_participation_supporting_awards_copy from './20260713_163000_participation_supporting_awards_copy';
|
||||
import * as migration_20260713_194500_contact_submissions from './20260713_194500_contact_submissions';
|
||||
import * as migration_20260713_213000_netzwerk_jury_selection from './20260713_213000_netzwerk_jury_selection';
|
||||
import * as migration_20260713_220000_preistraeger_detail_cleanup from './20260713_220000_preistraeger_detail_cleanup';
|
||||
|
||||
export const migrations = [
|
||||
{
|
||||
@@ -96,4 +97,9 @@ export const migrations = [
|
||||
down: migration_20260713_213000_netzwerk_jury_selection.down,
|
||||
name: '20260713_213000_netzwerk_jury_selection',
|
||||
},
|
||||
{
|
||||
up: migration_20260713_220000_preistraeger_detail_cleanup.up,
|
||||
down: migration_20260713_220000_preistraeger_detail_cleanup.down,
|
||||
name: '20260713_220000_preistraeger_detail_cleanup',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -2564,9 +2564,6 @@ export interface Preistraeger {
|
||||
category?: string | null;
|
||||
awardType?: string | null;
|
||||
longDesc?: string | null;
|
||||
quote?: string | null;
|
||||
quotePerson?: string | null;
|
||||
quoteRole?: string | null;
|
||||
location?: string | null;
|
||||
industry?: string | null;
|
||||
};
|
||||
@@ -2584,14 +2581,6 @@ export interface Preistraeger {
|
||||
image?: (number | null) | Media;
|
||||
imageAlt?: string | null;
|
||||
};
|
||||
facts?: {
|
||||
heading?: string | null;
|
||||
categoryLabel?: string | null;
|
||||
awardLabel?: string | null;
|
||||
yearLabel?: string | null;
|
||||
locationLabel?: string | null;
|
||||
industryLabel?: string | null;
|
||||
};
|
||||
websiteCta?: {
|
||||
label?: string | null;
|
||||
};
|
||||
@@ -4806,9 +4795,6 @@ export interface PreistraegerSelect<T extends boolean = true> {
|
||||
category?: T;
|
||||
awardType?: T;
|
||||
longDesc?: T;
|
||||
quote?: T;
|
||||
quotePerson?: T;
|
||||
quoteRole?: T;
|
||||
location?: T;
|
||||
industry?: T;
|
||||
};
|
||||
@@ -4827,16 +4813,6 @@ export interface PreistraegerSelect<T extends boolean = true> {
|
||||
image?: T;
|
||||
imageAlt?: T;
|
||||
};
|
||||
facts?:
|
||||
| T
|
||||
| {
|
||||
heading?: T;
|
||||
categoryLabel?: T;
|
||||
awardLabel?: T;
|
||||
yearLabel?: T;
|
||||
locationLabel?: T;
|
||||
industryLabel?: T;
|
||||
};
|
||||
websiteCta?:
|
||||
| T
|
||||
| {
|
||||
|
||||
@@ -784,13 +784,13 @@ const Netzwerk: React.FC = () => {
|
||||
|
||||
{/* ── 7. SPONSORING-FORM ───────────────────────────────────────────────── */}
|
||||
<section id="sponsoring" style={{
|
||||
background: NAVY, overflow: 'hidden', position: 'relative',
|
||||
minHeight: isMobile ? 'auto' : 'calc(100vh - 60px)',
|
||||
background: '#24366A', overflow: 'hidden', position: 'relative',
|
||||
height: isMobile ? 'auto' : 'calc(100vh - 60px)',
|
||||
display: 'flex', flexDirection: 'column',
|
||||
}}>
|
||||
<div style={{ flex: 1, position: 'relative', zIndex: 1, display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '4fr 1px 8fr', minHeight: 0, overflow: isMobile ? 'visible' : 'visible' }}>
|
||||
<div style={{ flex: 1, position: 'relative', zIndex: 1, display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '4fr 1px 8fr', minHeight: 0, overflow: 'hidden' }}>
|
||||
{/* Left – pitch */}
|
||||
<div style={{ padding: isMobile ? '32px 24px 24px' : '36px 36px 32px 52px', display: 'flex', flexDirection: 'column', justifyContent: 'center', overflow: 'visible' }}>
|
||||
<div style={{ padding: isMobile ? '32px 24px 24px' : '36px 36px 32px 52px', display: 'flex', flexDirection: 'column', justifyContent: 'center', overflow: 'hidden' }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, color: GOLD, display: 'block', marginBottom: 8 }}>{fallbackText(sponsoring.eyebrow, netzwerkContent.sponsoring.eyebrow)}</span>
|
||||
<h2 className="type-section-title text-role-inverse" style={{ textTransform: 'uppercase', margin: '0 0 12px' }}><Lines text={fallbackText(sponsoring.heading, netzwerkContent.sponsoring.heading)} /></h2>
|
||||
<div style={{ width: 36, height: 2, background: GOLD, margin: '0 0 14px', flexShrink: 0 }} />
|
||||
@@ -810,7 +810,7 @@ const Netzwerk: React.FC = () => {
|
||||
{/* Center divider */}
|
||||
{!isMobile && <div style={{ background: 'rgba(255,255,255,0.07)' }} />}
|
||||
{/* Right – gold form panel */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', overflow: 'visible', minHeight: 0, position: 'relative', background: 'linear-gradient(160deg,#DDB84A 0%,#C9A227 52%,#A87800 100%)' }}>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', overflow: 'hidden', minHeight: 0, position: 'relative', background: 'linear-gradient(160deg,#DDB84A 0%,#C9A227 52%,#A87800 100%)' }}>
|
||||
<svg style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none', zIndex: 0 }} aria-hidden="true">
|
||||
<defs>
|
||||
<pattern id="sponsoringCross" width="18" height="18" patternUnits="userSpaceOnUse">
|
||||
@@ -836,7 +836,7 @@ const Netzwerk: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div id="sponsoring-form" style={{ padding: isMobile ? '28px 20px' : '24px 48px 32px 40px', flex: 1, display: 'flex', flexDirection: 'column', minHeight: isMobile ? 560 : 0, position: 'relative', zIndex: 1, scrollMarginTop: 80 }}>
|
||||
<div id="sponsoring-form" style={{ padding: isMobile ? '32px 24px' : '24px 48px 32px 40px', flex: isMobile ? 'none' : 1, height: isMobile ? '82svh' : undefined, display: 'flex', flexDirection: 'column', minHeight: 0, position: 'relative', zIndex: 1, scrollMarginTop: 80 }}>
|
||||
<SponsoringForm theme="gold" content={cms.sponsoringForm} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -18,7 +18,8 @@ const BG_ALT = '#E4E2E3';
|
||||
const ARCHIVE_START_YEAR = 2007;
|
||||
const ARCHIVE_END_YEAR = 2023;
|
||||
const ARCHIVE_PERIOD = 'archive-2007-2023' as const;
|
||||
const ARCHIVE_LABEL = `${ARCHIVE_START_YEAR}–${ARCHIVE_END_YEAR}`;
|
||||
const ARCHIVE_RANGE_LABEL = `${ARCHIVE_START_YEAR}–${ARCHIVE_END_YEAR}`;
|
||||
const ARCHIVE_TAB_LABEL = 'Bis 2023';
|
||||
const GOLDENE_BAVARIA_GROUP = 'goldene-bavaria';
|
||||
const PREISTRAEGER_GROUP = 'preistraeger';
|
||||
|
||||
@@ -165,7 +166,7 @@ export default function Preistraeger() {
|
||||
const [activePeriod, setActivePeriod] = useState<WinnerPeriod | undefined>(undefined);
|
||||
const selectedPeriod = activePeriod ?? periods[0] ?? ARCHIVE_PERIOD;
|
||||
const isArchivePeriod = selectedPeriod === ARCHIVE_PERIOD;
|
||||
const selectedPeriodLabel = isArchivePeriod ? ARCHIVE_LABEL : String(selectedPeriod);
|
||||
const selectedPeriodLabel = isArchivePeriod ? ARCHIVE_RANGE_LABEL : String(selectedPeriod);
|
||||
|
||||
const filtered = useMemo(
|
||||
() => winners.filter((winner) => isArchivePeriod ? isArchiveWinner(winner) : winner.year === selectedPeriod),
|
||||
@@ -229,7 +230,7 @@ export default function Preistraeger() {
|
||||
transition: 'color 0.15s, border-color 0.15s',
|
||||
}}
|
||||
>
|
||||
{period === ARCHIVE_PERIOD ? ARCHIVE_LABEL : period}
|
||||
{period === ARCHIVE_PERIOD ? ARCHIVE_TAB_LABEL : period}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { Link, useParams, Navigate } from '@/spa/router';
|
||||
import { Trophy, ArrowLeft, MapPin, Building2, Globe, ChevronRight, Download, ChevronLeft, X } from 'lucide-react';
|
||||
import { ArrowLeft, Globe, ChevronRight, Download, ChevronLeft, X } from 'lucide-react';
|
||||
import { WINNERS } from '@/spa/data/winners';
|
||||
import { useCmsRoute } from '@/spa/cmsRoute';
|
||||
import { docImageUrl, mediaAlt, mediaUrl } from '@/spa/cmsMediaField';
|
||||
@@ -37,6 +37,7 @@ type PreistraegerGalleryCms = {
|
||||
}
|
||||
|
||||
const fallbackText = (value: unknown, fallback: string) => typeof value === 'string' && value.length > 0 ? value : fallback;
|
||||
const cmsText = (value: unknown) => typeof value === 'string' ? value.trim() : '';
|
||||
const optionalNumber = (value: unknown) => {
|
||||
if (value === null || value === undefined || value === '') return undefined;
|
||||
const parsed = Number(value);
|
||||
@@ -70,9 +71,9 @@ export default function PreistraegerDetail() {
|
||||
img: docImageUrl(cmsWinner, placeholderImage),
|
||||
shortDesc: String(cmsWinner.shortDesc || cmsWinner.description || cmsWinner.meta?.description || ''),
|
||||
longDesc: String(cmsWinner.longDesc || cmsWinner.description || cmsWinner.meta?.description || fallbackWinner.longDesc || preistraegerDetailContent.fallbackWinner.longDesc),
|
||||
quote: String(cmsWinner.quote || fallbackWinner.quote || preistraegerDetailContent.fallbackWinner.quote),
|
||||
quotePerson: String(cmsWinner.quotePerson || cmsWinner.title || fallbackWinner.quotePerson || preistraegerDetailContent.fallbackWinner.quotePerson),
|
||||
quoteRole: String(cmsWinner.quoteRole || fallbackWinner.quoteRole || preistraegerDetailContent.fallbackWinner.quoteRole),
|
||||
quote: cmsText(cmsWinner.quote),
|
||||
quotePerson: cmsText(cmsWinner.quotePerson),
|
||||
quoteRole: cmsText(cmsWinner.quoteRole),
|
||||
location: String(cmsWinner.location || fallbackWinner.location || preistraegerDetailContent.fallbackWinner.location),
|
||||
industry: String(cmsWinner.industry || fallbackWinner.industry || preistraegerDetailContent.fallbackWinner.industry),
|
||||
website: String(cmsWinner.website || '#'),
|
||||
@@ -85,9 +86,12 @@ export default function PreistraegerDetail() {
|
||||
const breadcrumb = { ...preistraegerDetailContent.breadcrumb, ...(detail.breadcrumb || {}) };
|
||||
const sections = { ...preistraegerDetailContent.sections, ...(detail.sections || {}) };
|
||||
const sideImage = { ...preistraegerDetailContent.sideImage, ...(detail.sideImage || {}) };
|
||||
const facts = { ...preistraegerDetailContent.facts, ...(detail.facts || {}) };
|
||||
const websiteCta = { ...preistraegerDetailContent.websiteCta, ...(detail.websiteCta || {}) };
|
||||
const backLink = { ...preistraegerDetailContent.backLink, ...(detail.backLink || {}) };
|
||||
const juryTextBeforeName = cmsText(sections.juryTextBeforeName);
|
||||
const juryTextAfterNameBeforeCategory = cmsText(sections.juryTextAfterNameBeforeCategory);
|
||||
const juryTextAfterCategory = cmsText(sections.juryTextAfterCategory);
|
||||
const showJuryText = Boolean(juryTextBeforeName || juryTextAfterNameBeforeCategory || juryTextAfterCategory);
|
||||
const downloadHref = mediaUrl(cmsWinner?.downloadZip, '');
|
||||
const downloadFilename = mediaFilename(cmsWinner?.downloadZip);
|
||||
const downloadLabel = fallbackText(cmsWinner?.downloadLabel, 'Pressepaket herunterladen');
|
||||
@@ -170,51 +174,42 @@ export default function PreistraegerDetail() {
|
||||
<h2 className="type-subtitle text-role-heading" style={{ textTransform: 'uppercase', marginBottom: 20 }}>
|
||||
{fallbackText(sections.juryHeading, preistraegerDetailContent.sections.juryHeading)}
|
||||
</h2>
|
||||
<p className="type-body text-role-body" style={{ marginBottom: 40 }}>
|
||||
{fallbackText(sections.juryTextBeforeName, preistraegerDetailContent.sections.juryTextBeforeName)} {winner.name} {fallbackText(sections.juryTextAfterNameBeforeCategory, preistraegerDetailContent.sections.juryTextAfterNameBeforeCategory)} <strong>{winner.category}</strong>. {fallbackText(sections.juryTextAfterCategory, preistraegerDetailContent.sections.juryTextAfterCategory)}
|
||||
</p>
|
||||
{showJuryText ? (
|
||||
<p className="type-body text-role-body" style={{ marginBottom: 40 }}>
|
||||
{juryTextBeforeName}
|
||||
{juryTextAfterNameBeforeCategory ? (
|
||||
<>{juryTextBeforeName ? ' ' : null}{winner.name} {juryTextAfterNameBeforeCategory} <strong>{winner.category}</strong>.</>
|
||||
) : null}
|
||||
{juryTextAfterCategory ? <>{juryTextBeforeName || juryTextAfterNameBeforeCategory ? ' ' : null}{juryTextAfterCategory}</> : null}
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
{/* Quote */}
|
||||
<div style={{ borderLeft: `4px solid ${GOLD}`, paddingLeft: 24, marginBottom: 40 }}>
|
||||
<p className="type-body text-role-heading" style={{ fontStyle: 'italic', marginBottom: 12 }}>
|
||||
<span style={{ color: GOLD, fontSize: 28, lineHeight: 1, marginRight: 4, fontFamily: '"IBM Plex Sans"' }}>“</span>
|
||||
{winner.quote}
|
||||
<span style={{ color: GOLD, fontSize: 28, lineHeight: 1, marginLeft: 2, fontFamily: '"IBM Plex Sans"' }}>”</span>
|
||||
</p>
|
||||
<p className="type-small text-role-secondary" style={{ fontWeight: 700, margin: 0, textTransform: 'uppercase', letterSpacing: '0.08em' }}>
|
||||
– {winner.quotePerson}, {winner.quoteRole}
|
||||
</p>
|
||||
</div>
|
||||
{winner.quote ? (
|
||||
<div style={{ borderLeft: `4px solid ${GOLD}`, paddingLeft: 24, marginBottom: 40 }}>
|
||||
<p className="type-body text-role-heading" style={{ fontStyle: 'italic', marginBottom: winner.quotePerson || winner.quoteRole ? 12 : 0 }}>
|
||||
<span style={{ color: GOLD, fontSize: 28, lineHeight: 1, marginRight: 4, fontFamily: '"IBM Plex Sans"' }}>“</span>
|
||||
{winner.quote}
|
||||
<span style={{ color: GOLD, fontSize: 28, lineHeight: 1, marginLeft: 2, fontFamily: '"IBM Plex Sans"' }}>”</span>
|
||||
</p>
|
||||
{winner.quotePerson || winner.quoteRole ? (
|
||||
<p className="type-small text-role-secondary" style={{ fontWeight: 700, margin: 0, textTransform: 'uppercase', letterSpacing: '0.08em' }}>
|
||||
{winner.quotePerson ? <>– {winner.quotePerson}</> : null}
|
||||
{winner.quotePerson && winner.quoteRole ? ', ' : null}
|
||||
{winner.quoteRole}
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
{/* Right: Photo + Info box */}
|
||||
{/* Right: Photo + actions */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 32 }}>
|
||||
{/* Photo */}
|
||||
<div style={{ borderRadius: 0, overflow: 'hidden', aspectRatio: '4/3' }}>
|
||||
<Image unoptimized src={mediaUrl(sideImage.image, `/${preistraegerDetailContent.sideImage.imageFilename}`)} alt={mediaAlt(sideImage.image, fallbackText(sideImage.imageAlt, preistraegerDetailContent.sideImage.imageAlt))} style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block', filter: 'brightness(0.95)' }} />
|
||||
</div>
|
||||
|
||||
{/* Kenndaten */}
|
||||
<div style={{ background: BG_ALT, borderLeft: `3px solid ${GOLD}`, padding: '20px 24px' }}>
|
||||
<h3 className="type-small text-role-secondary" style={{ fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.1em', marginBottom: 20 }}>
|
||||
{fallbackText(facts.heading, preistraegerDetailContent.facts.heading)}
|
||||
</h3>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
|
||||
{[
|
||||
{ label: fallbackText(facts.categoryLabel, preistraegerDetailContent.facts.categoryLabel), value: winner.category, icon: <Trophy size={14} style={{ color: GOLD }} /> },
|
||||
{ label: fallbackText(facts.awardLabel, preistraegerDetailContent.facts.awardLabel), value: winner.type, icon: <Trophy size={14} style={{ color: GOLD }} /> },
|
||||
...(typeof winner.year === 'number' ? [{ label: fallbackText(facts.yearLabel, preistraegerDetailContent.facts.yearLabel), value: String(winner.year), icon: null }] : []),
|
||||
{ label: fallbackText(facts.locationLabel, preistraegerDetailContent.facts.locationLabel), value: winner.location, icon: <MapPin size={14} style={{ color: GOLD }} /> },
|
||||
{ label: fallbackText(facts.industryLabel, preistraegerDetailContent.facts.industryLabel), value: winner.industry, icon: <Building2 size={14} style={{ color: GOLD }} /> },
|
||||
].map(row => (
|
||||
<div key={row.label} style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 11, color: GRAY, textTransform: 'uppercase', letterSpacing: '0.08em' }}>{row.label}</span>
|
||||
<span style={{ fontFamily: FF, fontSize: 17, fontWeight: 700, color: '#101828', overflowWrap: 'anywhere' }}>{row.value}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Website button */}
|
||||
<a
|
||||
href={`https://${winner.website}`}
|
||||
|
||||
@@ -10,9 +10,6 @@ export const preistraegerDetailContent = {
|
||||
category: 'Preisträger',
|
||||
awardType: 'Auszeichnung',
|
||||
longDesc: 'Dieser Preisträger wird aus Payload CMS geladen.',
|
||||
quote: 'Diese Erfolgsgeschichte wird aktuell in Payload CMS gepflegt.',
|
||||
quotePerson: 'BMP',
|
||||
quoteRole: 'Preisträger',
|
||||
location: 'Bayern',
|
||||
industry: 'Mittelstand',
|
||||
},
|
||||
@@ -28,14 +25,6 @@ export const preistraegerDetailContent = {
|
||||
imageFilename: 'gala-preistraeger.jpg',
|
||||
imageAlt: 'Gala Preisverleihung',
|
||||
},
|
||||
facts: {
|
||||
heading: 'Auf einen Blick',
|
||||
categoryLabel: 'Kategorie',
|
||||
awardLabel: 'Auszeichnung',
|
||||
yearLabel: 'Jahr',
|
||||
locationLabel: 'Standort',
|
||||
industryLabel: 'Branche',
|
||||
},
|
||||
websiteCta: {
|
||||
label: 'Website besuchen ↗',
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user