Files
homaroma/apps/spa/src/components/DynamicHero.tsx
T
2026-07-12 00:46:25 -04:00

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">&rarr;</span>
</a>
</div>
</div>
</section>
);
}