frontend.blogwoman.de/src/components/blocks/HeroBlock.tsx
CCS Admin 3a8693289f feat: migrate all types from local bridge pattern to @c2s/payload-contracts
Complete type migration removing all 33+ local interfaces and as-unknown-as
casts. All components now use contracts types directly with type-safe
relationship resolution via payload-helpers.ts.

Key changes:
- New payload-helpers.ts: resolveRelation, getMediaUrl, getMediaAlt, socialLinksToMap
- types.ts: thin re-export layer from contracts (backward-compatible aliases)
- api.ts: direct contracts types, no bridge casts, typed getSeoSettings
- All 17 block components: correct CMS field names (headline, subline, cta group, etc.)
- All route files: page.seo.metaTitle (not page.meta.title), getMediaUrl for unions
- structuredData.ts: proper types for all schema generators
- Footer: social links from separate collection via socialLinksToMap()
- Header/Footer: resolveMedia for logo

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 15:25:16 +00:00

81 lines
2 KiB
TypeScript

import Image from 'next/image'
import { Button } from '@/components/ui'
import { cn } from '@/lib/utils'
import { getMediaUrl, getMediaAlt } from '@/lib/payload-helpers'
import type { BlockByType } from '@c2s/payload-contracts/types'
type HeroBlockProps = Omit<BlockByType<'hero-block'>, 'blockType' | 'blockName'>
export function HeroBlock({
headline,
subline,
backgroundImage,
cta,
alignment = 'center',
overlay = true,
}: HeroBlockProps) {
const bgUrl = getMediaUrl(backgroundImage)
const alignmentClasses = {
left: 'text-left items-start',
center: 'text-center items-center',
right: 'text-right items-end',
}
return (
<section className="relative min-h-[60vh] md:min-h-[70vh] flex items-center">
{/* Background Image */}
{bgUrl && (
<div className="absolute inset-0">
<Image
src={bgUrl}
alt={getMediaAlt(backgroundImage)}
fill
className="object-cover"
priority
/>
{overlay && (
<div className="absolute inset-0 bg-espresso/50" />
)}
</div>
)}
{/* Content */}
<div className="container relative z-10">
<div
className={cn(
'flex flex-col max-w-3xl py-20',
alignmentClasses[alignment || 'center'],
(alignment || 'center') === 'center' && 'mx-auto'
)}
>
<h1
className={cn(
'mb-6',
bgUrl ? 'text-soft-white' : 'text-espresso'
)}
>
{headline}
</h1>
{subline && (
<p
className={cn(
'text-lg md:text-xl leading-relaxed mb-8',
bgUrl ? 'text-soft-white/90' : 'text-espresso'
)}
>
{subline}
</p>
)}
{cta?.text && cta?.link && (
<Button href={cta.link} size="lg">
{cta.text}
</Button>
)}
</div>
</div>
</section>
)
}