81 lines
3.0 KiB
TypeScript
81 lines
3.0 KiB
TypeScript
import { Link } from 'react-router-dom';
|
|
import type { HeroSectionPayload } from '@homaroma/types';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { getLocalizedField } from '../utils/localization';
|
|
|
|
interface DynamicHeroProps {
|
|
payload: HeroSectionPayload;
|
|
}
|
|
|
|
export default function DynamicHero({ payload }: DynamicHeroProps) {
|
|
const { t, i18n } = useTranslation();
|
|
const lang = i18n.language;
|
|
const { imageUrl, buttonLink } = payload;
|
|
const tagline = getLocalizedField(payload.tagline, lang);
|
|
const title = getLocalizedField(payload.title, lang);
|
|
const description = getLocalizedField(payload.description, lang);
|
|
const buttonText = getLocalizedField(payload.buttonText, lang);
|
|
const focalPoint = typeof payload.focalPoint === 'object' && payload.focalPoint ? (payload.focalPoint as { x: string, y: string }) : undefined;
|
|
|
|
const renderTitle = (text: string) => {
|
|
if (!text) return null;
|
|
return text.split('[').map((part, i) => {
|
|
if (part.includes(']')) {
|
|
const [accent, rest] = part.split(']');
|
|
return (
|
|
<span key={i}>
|
|
<span className="text-pop-pink font-medium italic">
|
|
{accent}
|
|
</span>
|
|
{rest}
|
|
</span>
|
|
);
|
|
}
|
|
return <span key={i}>{part}</span>;
|
|
});
|
|
};
|
|
|
|
return (
|
|
<section className="relative w-full flex flex-col md:block md:h-[90vh] md:aspect-[21/9] bg-[#EBE7E0] overflow-hidden">
|
|
<div className="relative w-full h-[50vh] min-h-[400px] md:absolute md:inset-0 md:h-full md:z-0">
|
|
<img
|
|
src={imageUrl || `${import.meta.env.VITE_API_URL.replace('/api', '')}/assets/hero.png`}
|
|
className="w-full h-full object-cover"
|
|
alt="Hero Background"
|
|
style={{ objectPosition: focalPoint ? `${focalPoint.x} ${focalPoint.y}` : undefined }}
|
|
onError={(e) => {
|
|
(e.target as HTMLImageElement).style.display = 'none';
|
|
}}
|
|
/>
|
|
</div>
|
|
|
|
<div className="relative z-10 mx-auto py-12 w-full max-w-4xl space-y-6 px-8 text-center md:py-0 md:h-full md:flex md:flex-col md:justify-center md:items-center animate-fade-in">
|
|
<p className="text-pop-black/70 font-semibold tracking-[0.3em] text-xs md:text-sm uppercase drop-shadow-md">
|
|
{tagline || t('hero.defaultTagline')}
|
|
</p>
|
|
<h1 className="ui-hero-title">
|
|
{renderTitle(title) || renderTitle(t('hero.defaultTitle'))}
|
|
</h1>
|
|
<p className="ui-hero-copy">
|
|
{description}
|
|
</p>
|
|
<div className="flex flex-col sm:flex-row gap-6 items-center justify-center">
|
|
<Link
|
|
to={buttonLink || "/shop"}
|
|
className="ui-button-secondary"
|
|
>
|
|
{buttonText || t('hero.exploreCollection')}
|
|
</Link>
|
|
<a
|
|
href="#categories"
|
|
className="ui-dark-link group"
|
|
>
|
|
{t('hero.learnMore')}
|
|
<span className="group-hover:translate-x-1 transition-transform">→</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|