149 lines
5.1 KiB
TypeScript
149 lines
5.1 KiB
TypeScript
'use client'
|
|
import React from 'react'
|
|
import { motion } from 'framer-motion'
|
|
import type { Page, Media } from '../../payload-types'
|
|
import Link from 'next/link'
|
|
import Image from 'next/image'
|
|
import { ImagePlaceholder } from '../../components/ImagePlaceholder'
|
|
|
|
type BaseProps = Extract<NonNullable<Page['layout']>[0], { blockType: 'hero' }>
|
|
type Props = BaseProps & { whatsappNumber?: string | null }
|
|
|
|
const customEase = [0.22, 1, 0.36, 1] as const
|
|
|
|
const containerVariants = {
|
|
hidden: {},
|
|
visible: {
|
|
transition: {
|
|
staggerChildren: 0.14,
|
|
delayChildren: 0.2
|
|
},
|
|
},
|
|
}
|
|
|
|
const itemVariants = {
|
|
hidden: { opacity: 0, y: 22 },
|
|
visible: {
|
|
opacity: 1,
|
|
y: 0,
|
|
transition: {
|
|
duration: 0.7,
|
|
ease: customEase,
|
|
},
|
|
},
|
|
}
|
|
|
|
export const HeroBlock: React.FC<Props> = ({
|
|
title,
|
|
titleAccent,
|
|
subtitle,
|
|
primaryCta,
|
|
secondaryCta,
|
|
image,
|
|
whatsappNumber,
|
|
}) => {
|
|
const whatsappLink = whatsappNumber ? `https://wa.me/${whatsappNumber}` : '#'
|
|
|
|
const heroMedia = typeof image === 'object' && image !== null ? (image as Media) : null
|
|
const imageUrl = heroMedia?.url
|
|
const imageAlt = heroMedia?.alt || 'Tło hero'
|
|
|
|
return (
|
|
<motion.section
|
|
initial="hidden"
|
|
animate="visible"
|
|
className="relative w-full min-h-[70vh] lg:min-h-[85vh] flex flex-col justify-end overflow-hidden"
|
|
>
|
|
{/* Background Layer */}
|
|
<div className="absolute inset-0 z-0">
|
|
{imageUrl ? (
|
|
<>
|
|
<Image
|
|
src={imageUrl}
|
|
alt={imageAlt}
|
|
fill
|
|
priority
|
|
sizes="100vw"
|
|
className="object-cover object-center"
|
|
/>
|
|
{/* Ciemny gradient pod spodem, by biały tekst był świetnie czytelny, a zdjęcie pozostało nasycone */}
|
|
<div className="absolute inset-0 bg-gradient-to-t from-black/80 via-black/40 to-transparent lg:bg-gradient-to-r lg:from-black/90 lg:via-black/40 lg:to-transparent" />
|
|
<div className="absolute inset-0 bg-black/20" />
|
|
</>
|
|
) : (
|
|
<div className="absolute inset-0 bg-card bg-paper-noise border-b border-border/50" />
|
|
)}
|
|
</div>
|
|
|
|
{/* Content Layer */}
|
|
<div className="container-premium relative z-10 w-full pb-16 lg:pb-24 pt-32">
|
|
<div className="flex flex-col lg:flex-row items-end justify-between gap-12">
|
|
|
|
{/* Main Content (Bottom Left) */}
|
|
<motion.div
|
|
variants={containerVariants}
|
|
className="w-full lg:max-w-3xl flex flex-col"
|
|
>
|
|
<motion.h1
|
|
variants={itemVariants}
|
|
className={`font-heading text-4xl sm:text-5xl md:text-6xl lg:text-[4.5rem] font-bold leading-[1.05] mb-6 text-balance break-words hyphens-auto ${imageUrl ? 'text-white drop-shadow-md' : 'text-foreground'}`}
|
|
>
|
|
<span className="block">{title}</span>
|
|
{titleAccent && (
|
|
<span className="block text-accent mt-2">
|
|
{titleAccent.split(/(po polsku)/i).map((part, i) =>
|
|
part.toLowerCase() === 'po polsku' ? <i key={i} className="italic font-medium">{part}</i> : part
|
|
)}
|
|
</span>
|
|
)}
|
|
</motion.h1>
|
|
|
|
<motion.p
|
|
variants={itemVariants}
|
|
className={`text-lg sm:text-xl md:text-2xl mb-10 leading-relaxed font-medium max-w-[55ch] ${imageUrl ? 'text-white/90 drop-shadow-md' : 'text-foreground/90'}`}
|
|
>
|
|
{subtitle}
|
|
</motion.p>
|
|
|
|
<motion.div
|
|
variants={itemVariants}
|
|
className="flex flex-col sm:flex-row items-start sm:items-center gap-6 sm:gap-8"
|
|
>
|
|
{whatsappNumber && (
|
|
<a
|
|
href={whatsappLink}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="px-8 py-4 bg-[#25D366] hover:bg-[#20bd5a] text-[#1C1B1A] font-bold text-base sm:text-lg transition-colors flex items-center justify-center rounded-none shadow-md cursor-pointer border border-[#1C1B1A]/10"
|
|
>
|
|
{primaryCta}
|
|
</a>
|
|
)}
|
|
{secondaryCta?.text && secondaryCta?.url && (
|
|
secondaryCta.url.startsWith('#') ? (
|
|
<a
|
|
href={secondaryCta.url}
|
|
className={`${imageUrl ? 'text-white drop-shadow-md' : 'text-foreground'} font-semibold text-lg hover:text-accent hover:underline underline-offset-4 transition-colors`}
|
|
>
|
|
{secondaryCta.text}
|
|
</a>
|
|
) : (
|
|
<Link
|
|
href={secondaryCta.url}
|
|
className={`${imageUrl ? 'text-white drop-shadow-md' : 'text-foreground'} font-semibold text-lg hover:text-accent hover:underline underline-offset-4 transition-colors`}
|
|
>
|
|
{secondaryCta.text}
|
|
</Link>
|
|
)
|
|
)}
|
|
</motion.div>
|
|
</motion.div>
|
|
|
|
|
|
|
|
</div>
|
|
</div>
|
|
</motion.section>
|
|
)
|
|
}
|