mirror of
https://github.com/complexcaresolutions/frontend.blogwoman.de.git
synced 2026-03-17 16:14:00 +00:00
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>
81 lines
2 KiB
TypeScript
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>
|
|
)
|
|
}
|