x
This commit is contained in:
1 parent
b641acbeb7
commit
e349ef5b84
14 files changed
+720
-558
No files matched your search
@@ -2,6 +2,7 @@ import { Link } from 'react-router-dom';
|
||||
import type { BannerSectionPayload } from '@homaroma/types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getLocalizedField } from '../utils/localization';
|
||||
import { getHeroPositionClasses } from './DynamicHero';
|
||||
|
||||
interface DynamicBannerProps {
|
||||
payload: BannerSectionPayload;
|
||||
@@ -17,71 +18,53 @@ export default function DynamicBanner({ payload }: DynamicBannerProps) {
|
||||
const focalPoint = typeof payload.focalPoint === 'object' && payload.focalPoint ? payload.focalPoint : undefined;
|
||||
const imageStyle = focalPoint ? { objectPosition: `${focalPoint.x} ${focalPoint.y}` } : undefined;
|
||||
|
||||
const desktopPosition = payload.buttonPosition || 'center-left';
|
||||
const mobilePosition = payload.mobileButtonPosition || desktopPosition;
|
||||
const { wrapperClasses, contentClasses, actionsClasses } = getHeroPositionClasses(mobilePosition, desktopPosition);
|
||||
|
||||
const bannerInner = (
|
||||
<>
|
||||
<div className="absolute inset-0 z-0">
|
||||
<img
|
||||
src={imageUrl}
|
||||
className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-[1.03]"
|
||||
alt={title || "Banner"}
|
||||
style={imageStyle}
|
||||
/>
|
||||
<div className="ui-banner-overlay"></div>
|
||||
</div>
|
||||
|
||||
<div className={`ui-banner-content flex flex-col ${contentClasses}`}>
|
||||
{title && (
|
||||
<h3 className="font-serif text-3xl font-light leading-tight text-pop-pink md:text-5xl">
|
||||
{title}
|
||||
</h3>
|
||||
)}
|
||||
{description && (
|
||||
<p className="font-light text-base text-pop-bg/95 md:text-lg">
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
{buttonText && (
|
||||
<div className={`pt-4 flex ${actionsClasses}`}>
|
||||
<span className="ui-button-secondary">
|
||||
{buttonText}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<section className="ui-section-band bg-pop-bg relative overflow-hidden">
|
||||
{linkUrl ? (
|
||||
<Link to={linkUrl} className="ui-banner-shell group block cursor-pointer">
|
||||
<div className="absolute inset-0 z-0">
|
||||
<img
|
||||
src={imageUrl}
|
||||
className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-[1.03]"
|
||||
alt={title || "Banner"}
|
||||
style={imageStyle}
|
||||
/>
|
||||
<div className="ui-banner-overlay"></div>
|
||||
</div>
|
||||
|
||||
<div className="ui-banner-content">
|
||||
{title && (
|
||||
<h3 className="font-serif text-3xl font-light leading-tight text-pop-pink md:text-5xl">
|
||||
{title}
|
||||
</h3>
|
||||
)}
|
||||
{description && (
|
||||
<p className="font-light text-base text-pop-bg/95 md:text-lg">
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
{buttonText && (
|
||||
<div className="pt-4">
|
||||
<span className="ui-button-secondary">
|
||||
{buttonText}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<Link to={linkUrl} className={`ui-banner-shell group flex flex-col ${wrapperClasses} cursor-pointer`}>
|
||||
{bannerInner}
|
||||
</Link>
|
||||
) : (
|
||||
<div className="ui-banner-shell group block cursor-default">
|
||||
<div className="absolute inset-0 z-0">
|
||||
<img
|
||||
src={imageUrl}
|
||||
className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-[1.03]"
|
||||
alt={title || "Banner"}
|
||||
style={imageStyle}
|
||||
/>
|
||||
<div className="ui-banner-overlay"></div>
|
||||
</div>
|
||||
|
||||
<div className="ui-banner-content">
|
||||
{title && (
|
||||
<h3 className="font-serif text-3xl font-light leading-tight text-pop-pink md:text-5xl">
|
||||
{title}
|
||||
</h3>
|
||||
)}
|
||||
{description && (
|
||||
<p className="font-light text-base text-pop-bg/95 md:text-lg">
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
{buttonText && (
|
||||
<div className="pt-4">
|
||||
<span className="ui-button-secondary">
|
||||
{buttonText}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className={`ui-banner-shell group flex flex-col ${wrapperClasses} cursor-default`}>
|
||||
{bannerInner}
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
|
||||
@@ -7,6 +7,138 @@ interface DynamicHeroProps {
|
||||
payload: HeroSectionPayload;
|
||||
}
|
||||
|
||||
// Map 9-box grid position to mobile flex classes
|
||||
export const getHeroMobilePositionClasses = (pos: string) => {
|
||||
switch (pos) {
|
||||
case 'top-left':
|
||||
return {
|
||||
wrapper: 'justify-start items-start text-left pt-20 pb-12 pl-6 pr-6',
|
||||
content: 'items-start text-left',
|
||||
actions: 'items-start justify-start'
|
||||
};
|
||||
case 'top-center':
|
||||
return {
|
||||
wrapper: 'justify-start items-center text-center pt-20 pb-12 px-6',
|
||||
content: 'items-center text-center',
|
||||
actions: 'items-center justify-center'
|
||||
};
|
||||
case 'top-right':
|
||||
return {
|
||||
wrapper: 'justify-start items-end text-right pt-20 pb-12 pr-6 pl-6',
|
||||
content: 'items-end text-right',
|
||||
actions: 'items-end justify-end'
|
||||
};
|
||||
case 'center-left':
|
||||
return {
|
||||
wrapper: 'justify-center items-start text-left py-16 pl-6 pr-6',
|
||||
content: 'items-start text-left',
|
||||
actions: 'items-start justify-start'
|
||||
};
|
||||
case 'center-right':
|
||||
return {
|
||||
wrapper: 'justify-center items-end text-right py-16 pr-6 pl-6',
|
||||
content: 'items-end text-right',
|
||||
actions: 'items-end justify-end'
|
||||
};
|
||||
case 'bottom-left':
|
||||
return {
|
||||
wrapper: 'justify-end items-start text-left pt-12 pb-16 pl-6 pr-6',
|
||||
content: 'items-start text-left',
|
||||
actions: 'items-start justify-start'
|
||||
};
|
||||
case 'bottom-center':
|
||||
return {
|
||||
wrapper: 'justify-end items-center text-center pt-12 pb-16 px-6',
|
||||
content: 'items-center text-center',
|
||||
actions: 'items-center justify-center'
|
||||
};
|
||||
case 'bottom-right':
|
||||
return {
|
||||
wrapper: 'justify-end items-end text-right pt-12 pb-16 pr-6 pl-6',
|
||||
content: 'items-end text-right',
|
||||
actions: 'items-end justify-end'
|
||||
};
|
||||
case 'center':
|
||||
default:
|
||||
return {
|
||||
wrapper: 'justify-center items-center text-center py-16 px-6',
|
||||
content: 'items-center text-center',
|
||||
actions: 'items-center justify-center'
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// Map 9-box grid position to desktop (md:) flex classes
|
||||
export const getHeroDesktopPositionClasses = (pos: string) => {
|
||||
switch (pos) {
|
||||
case 'top-left':
|
||||
return {
|
||||
wrapper: 'md:justify-start md:items-start md:text-left md:pt-28 md:pb-12 md:pl-16 md:pr-6',
|
||||
content: 'md:items-start md:text-left',
|
||||
actions: 'md:items-start md:justify-start'
|
||||
};
|
||||
case 'top-center':
|
||||
return {
|
||||
wrapper: 'md:justify-start md:items-center md:text-center md:pt-28 md:pb-12 md:px-6',
|
||||
content: 'md:items-center md:text-center',
|
||||
actions: 'md:items-center md:justify-center'
|
||||
};
|
||||
case 'top-right':
|
||||
return {
|
||||
wrapper: 'md:justify-start md:items-end md:text-right md:pt-28 md:pb-12 md:pr-16 md:pl-6',
|
||||
content: 'md:items-end md:text-right',
|
||||
actions: 'md:items-end md:justify-end'
|
||||
};
|
||||
case 'center-left':
|
||||
return {
|
||||
wrapper: 'md:justify-center md:items-start md:text-left md:py-16 md:pl-16 md:pr-6',
|
||||
content: 'md:items-start md:text-left',
|
||||
actions: 'md:items-start md:justify-start'
|
||||
};
|
||||
case 'center-right':
|
||||
return {
|
||||
wrapper: 'md:justify-center md:items-end md:text-right md:py-16 md:pr-16 md:pl-6',
|
||||
content: 'md:items-end md:text-right',
|
||||
actions: 'md:items-end md:justify-end'
|
||||
};
|
||||
case 'bottom-left':
|
||||
return {
|
||||
wrapper: 'md:justify-end md:items-start md:text-left md:pt-12 md:pb-24 md:pl-16 md:pr-6',
|
||||
content: 'md:items-start md:text-left',
|
||||
actions: 'md:items-start md:justify-start'
|
||||
};
|
||||
case 'bottom-center':
|
||||
return {
|
||||
wrapper: 'md:justify-end md:items-center md:text-center md:pt-12 md:pb-24 md:px-6',
|
||||
content: 'md:items-center md:text-center',
|
||||
actions: 'md:items-center md:justify-center'
|
||||
};
|
||||
case 'bottom-right':
|
||||
return {
|
||||
wrapper: 'md:justify-end md:items-end md:text-right md:pt-12 md:pb-24 md:pr-16 md:pl-6',
|
||||
content: 'md:items-end md:text-right',
|
||||
actions: 'md:items-end md:justify-end'
|
||||
};
|
||||
case 'center':
|
||||
default:
|
||||
return {
|
||||
wrapper: 'md:justify-center md:items-center md:text-center md:py-16 md:px-6',
|
||||
content: 'md:items-center md:text-center',
|
||||
actions: 'md:items-center md:justify-center'
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export function getHeroPositionClasses(mobilePos: string, desktopPos: string) {
|
||||
const mClasses = getHeroMobilePositionClasses(mobilePos);
|
||||
const dClasses = getHeroDesktopPositionClasses(desktopPos);
|
||||
return {
|
||||
wrapperClasses: `${mClasses.wrapper} ${dClasses.wrapper}`,
|
||||
contentClasses: `${mClasses.content} ${dClasses.content}`,
|
||||
actionsClasses: `${mClasses.actions} ${dClasses.actions}`,
|
||||
};
|
||||
}
|
||||
|
||||
export default function DynamicHero({ payload }: DynamicHeroProps) {
|
||||
const { t, i18n } = useTranslation();
|
||||
const lang = i18n.language;
|
||||
@@ -53,134 +185,7 @@ export default function DynamicHero({ payload }: DynamicHeroProps) {
|
||||
});
|
||||
};
|
||||
|
||||
// Map 9-box grid position to mobile flex classes
|
||||
const getMobilePositionClasses = (pos: string) => {
|
||||
switch (pos) {
|
||||
case 'top-left':
|
||||
return {
|
||||
wrapper: 'justify-start items-start text-left pt-20 pb-12 pl-6 pr-6',
|
||||
content: 'items-start text-left',
|
||||
actions: 'items-start justify-start'
|
||||
};
|
||||
case 'top-center':
|
||||
return {
|
||||
wrapper: 'justify-start items-center text-center pt-20 pb-12 px-6',
|
||||
content: 'items-center text-center',
|
||||
actions: 'items-center justify-center'
|
||||
};
|
||||
case 'top-right':
|
||||
return {
|
||||
wrapper: 'justify-start items-end text-right pt-20 pb-12 pr-6 pl-6',
|
||||
content: 'items-end text-right',
|
||||
actions: 'items-end justify-end'
|
||||
};
|
||||
case 'center-left':
|
||||
return {
|
||||
wrapper: 'justify-center items-start text-left py-16 pl-6 pr-6',
|
||||
content: 'items-start text-left',
|
||||
actions: 'items-start justify-start'
|
||||
};
|
||||
case 'center-right':
|
||||
return {
|
||||
wrapper: 'justify-center items-end text-right py-16 pr-6 pl-6',
|
||||
content: 'items-end text-right',
|
||||
actions: 'items-end justify-end'
|
||||
};
|
||||
case 'bottom-left':
|
||||
return {
|
||||
wrapper: 'justify-end items-start text-left pt-12 pb-16 pl-6 pr-6',
|
||||
content: 'items-start text-left',
|
||||
actions: 'items-start justify-start'
|
||||
};
|
||||
case 'bottom-center':
|
||||
return {
|
||||
wrapper: 'justify-end items-center text-center pt-12 pb-16 px-6',
|
||||
content: 'items-center text-center',
|
||||
actions: 'items-center justify-center'
|
||||
};
|
||||
case 'bottom-right':
|
||||
return {
|
||||
wrapper: 'justify-end items-end text-right pt-12 pb-16 pr-6 pl-6',
|
||||
content: 'items-end text-right',
|
||||
actions: 'items-end justify-end'
|
||||
};
|
||||
case 'center':
|
||||
default:
|
||||
return {
|
||||
wrapper: 'justify-center items-center text-center py-16 px-6',
|
||||
content: 'items-center text-center',
|
||||
actions: 'items-center justify-center'
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// Map 9-box grid position to desktop (md:) flex classes
|
||||
const getDesktopPositionClasses = (pos: string) => {
|
||||
switch (pos) {
|
||||
case 'top-left':
|
||||
return {
|
||||
wrapper: 'md:justify-start md:items-start md:text-left md:pt-28 md:pb-12 md:pl-16 md:pr-6',
|
||||
content: 'md:items-start md:text-left',
|
||||
actions: 'md:items-start md:justify-start'
|
||||
};
|
||||
case 'top-center':
|
||||
return {
|
||||
wrapper: 'md:justify-start md:items-center md:text-center md:pt-28 md:pb-12 md:px-6',
|
||||
content: 'md:items-center md:text-center',
|
||||
actions: 'md:items-center md:justify-center'
|
||||
};
|
||||
case 'top-right':
|
||||
return {
|
||||
wrapper: 'md:justify-start md:items-end md:text-right md:pt-28 md:pb-12 md:pr-16 md:pl-6',
|
||||
content: 'md:items-end md:text-right',
|
||||
actions: 'md:items-end md:justify-end'
|
||||
};
|
||||
case 'center-left':
|
||||
return {
|
||||
wrapper: 'md:justify-center md:items-start md:text-left md:py-16 md:pl-16 md:pr-6',
|
||||
content: 'md:items-start md:text-left',
|
||||
actions: 'md:items-start md:justify-start'
|
||||
};
|
||||
case 'center-right':
|
||||
return {
|
||||
wrapper: 'md:justify-center md:items-end md:text-right md:py-16 md:pr-16 md:pl-6',
|
||||
content: 'md:items-end md:text-right',
|
||||
actions: 'md:items-end md:justify-end'
|
||||
};
|
||||
case 'bottom-left':
|
||||
return {
|
||||
wrapper: 'md:justify-end md:items-start md:text-left md:pt-12 md:pb-24 md:pl-16 md:pr-6',
|
||||
content: 'md:items-start md:text-left',
|
||||
actions: 'md:items-start md:justify-start'
|
||||
};
|
||||
case 'bottom-center':
|
||||
return {
|
||||
wrapper: 'md:justify-end md:items-center md:text-center md:pt-12 md:pb-24 md:px-6',
|
||||
content: 'md:items-center md:text-center',
|
||||
actions: 'md:items-center md:justify-center'
|
||||
};
|
||||
case 'bottom-right':
|
||||
return {
|
||||
wrapper: 'md:justify-end md:items-end md:text-right md:pt-12 md:pb-24 md:pr-16 md:pl-6',
|
||||
content: 'md:items-end md:text-right',
|
||||
actions: 'md:items-end md:justify-end'
|
||||
};
|
||||
case 'center':
|
||||
default:
|
||||
return {
|
||||
wrapper: 'md:justify-center md:items-center md:text-center md:py-16 md:px-6',
|
||||
content: 'md:items-center md:text-center',
|
||||
actions: 'md:items-center md:justify-center'
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const mClasses = getMobilePositionClasses(mobilePosition);
|
||||
const dClasses = getDesktopPositionClasses(desktopPosition);
|
||||
|
||||
const wrapperClasses = `${mClasses.wrapper} ${dClasses.wrapper}`;
|
||||
const contentClasses = `${mClasses.content} ${dClasses.content}`;
|
||||
const actionsClasses = `${mClasses.actions} ${dClasses.actions}`;
|
||||
const { wrapperClasses, contentClasses, actionsClasses } = getHeroPositionClasses(mobilePosition, desktopPosition);
|
||||
|
||||
const overlayStyle = (payload as any).overlayStyle || 'gradient';
|
||||
const overlayOpacity = (payload as any).overlayOpacity !== undefined ? (payload as any).overlayOpacity : 45;
|
||||
@@ -245,7 +250,7 @@ export default function DynamicHero({ payload }: DynamicHeroProps) {
|
||||
</h1>
|
||||
)}
|
||||
{description && (
|
||||
<p className="ui-hero-copy !text-white/90 drop-shadow-md !pb-2">
|
||||
<p className={`ui-hero-copy !text-white/90 drop-shadow-md !pb-2 ${contentClasses.includes('text-left') ? '!mx-0' : contentClasses.includes('text-right') ? '!ml-auto !mr-0' : '!mx-auto'}`}>
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Link } from 'react-router-dom';
|
||||
import type { HeroCarouselSectionPayload } from '@homaroma/types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getLocalizedField } from '../utils/localization';
|
||||
import { getHeroPositionClasses } from './DynamicHero';
|
||||
|
||||
// Import Swiper styles
|
||||
import 'swiper/css';
|
||||
@@ -115,27 +116,35 @@ export default function DynamicHeroCarousel({ payload }: DynamicHeroCarouselProp
|
||||
/>
|
||||
|
||||
{/* Text Overlay */}
|
||||
{(slide.title || slide.subtitle || slide.buttonText) && (
|
||||
<div className="absolute inset-0 z-10 bg-gradient-to-t from-black/70 via-black/20 to-transparent flex flex-col justify-end p-6 md:p-10">
|
||||
<div className="max-w-xl space-y-1.5 md:space-y-2">
|
||||
{slide.subtitle && (
|
||||
<p className="text-[10px] md:text-xs uppercase font-bold tracking-widest text-pop-yellow drop-shadow-md">
|
||||
{slide.subtitle}
|
||||
</p>
|
||||
)}
|
||||
{slide.title && (
|
||||
<h3 className="text-lg md:text-3xl font-bold text-white drop-shadow-md leading-tight">
|
||||
{renderTitle(slide.title)}
|
||||
</h3>
|
||||
)}
|
||||
{slide.buttonText && (
|
||||
<span className="inline-block mt-2 px-4 py-1.5 bg-pop-pink text-white text-xs font-bold rounded-full shadow-lg hover:bg-pop-red transition-all">
|
||||
{slide.buttonText}
|
||||
</span>
|
||||
)}
|
||||
{(slide.title || slide.subtitle || slide.buttonText) && (() => {
|
||||
const slideDesktopPos = (slide as any).buttonPosition || 'bottom-left';
|
||||
const slideMobilePos = (slide as any).mobileButtonPosition || slideDesktopPos;
|
||||
const { wrapperClasses, contentClasses, actionsClasses } = getHeroPositionClasses(slideMobilePos, slideDesktopPos);
|
||||
|
||||
return (
|
||||
<div className={`absolute inset-0 z-10 bg-gradient-to-t from-black/70 via-black/20 to-transparent flex flex-col p-6 md:p-10 ${wrapperClasses}`}>
|
||||
<div className={`max-w-xl space-y-1.5 md:space-y-2 flex flex-col ${contentClasses}`}>
|
||||
{slide.subtitle && (
|
||||
<p className="text-[10px] md:text-xs uppercase font-bold tracking-widest text-pop-yellow drop-shadow-md">
|
||||
{slide.subtitle}
|
||||
</p>
|
||||
)}
|
||||
{slide.title && (
|
||||
<h3 className="text-lg md:text-3xl font-bold text-white drop-shadow-md leading-tight">
|
||||
{renderTitle(slide.title)}
|
||||
</h3>
|
||||
)}
|
||||
{slide.buttonText && (
|
||||
<div className={`flex ${actionsClasses} pt-1`}>
|
||||
<span className="inline-block mt-2 px-4 py-1.5 bg-pop-pink text-white text-xs font-bold rounded-full shadow-lg hover:bg-pop-red transition-all">
|
||||
{slide.buttonText}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
);
|
||||
})()}
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Link } from 'react-router-dom';
|
||||
import type { HeroVideoSectionPayload } from '@homaroma/types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getLocalizedField } from '../utils/localization';
|
||||
import { getHeroPositionClasses } from './DynamicHero';
|
||||
|
||||
interface DynamicHeroVideoProps {
|
||||
payload: HeroVideoSectionPayload;
|
||||
@@ -97,46 +98,56 @@ export default function DynamicHeroVideo({ payload }: DynamicHeroVideoProps) {
|
||||
></div>
|
||||
|
||||
{/* Overlay Typography Content */}
|
||||
<div className="relative z-20 mx-auto px-6 py-16 w-full max-w-5xl text-center space-y-6 flex flex-col items-center justify-center animate-fade-in">
|
||||
{tagline && (
|
||||
<p className="text-xs md:text-sm font-semibold uppercase tracking-[0.35em] text-pop-pink/90 drop-shadow-md">
|
||||
{tagline}
|
||||
</p>
|
||||
)}
|
||||
{(() => {
|
||||
const desktopPosition = (payload as any).buttonPosition || 'center';
|
||||
const mobilePosition = (payload as any).mobileButtonPosition || desktopPosition;
|
||||
const { wrapperClasses, contentClasses, actionsClasses } = getHeroPositionClasses(mobilePosition, desktopPosition);
|
||||
|
||||
<h1 className="font-serif text-4xl md:text-6xl lg:text-7xl font-light leading-tight tracking-wide drop-shadow-lg text-white">
|
||||
{renderTitle(title) || renderTitle(t('hero.defaultTitle'))}
|
||||
</h1>
|
||||
return (
|
||||
<div className={`relative z-20 mx-auto px-6 py-16 w-full max-w-5xl h-full flex flex-col animate-fade-in ${wrapperClasses}`}>
|
||||
<div className={`flex flex-col space-y-6 max-w-3xl ${contentClasses}`}>
|
||||
{tagline && (
|
||||
<p className="text-xs md:text-sm font-semibold uppercase tracking-[0.35em] text-pop-pink/90 drop-shadow-md">
|
||||
{tagline}
|
||||
</p>
|
||||
)}
|
||||
|
||||
{description && (
|
||||
<p className="max-w-2xl text-sm md:text-lg font-light leading-relaxed opacity-90 drop-shadow">
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
<h1 className="font-serif text-4xl md:text-6xl lg:text-7xl font-light leading-tight tracking-wide drop-shadow-lg text-white">
|
||||
{renderTitle(title) || renderTitle(t('hero.defaultTitle'))}
|
||||
</h1>
|
||||
|
||||
{/* Dual Action Buttons */}
|
||||
{(buttonText || secondaryButtonText) && (
|
||||
<div className="flex flex-wrap items-center justify-center gap-4 pt-4">
|
||||
{buttonText && payload.buttonLink && (
|
||||
<Link
|
||||
to={payload.buttonLink}
|
||||
className="px-8 py-3.5 bg-white text-neutral-900 font-medium text-xs uppercase tracking-widest hover:bg-pop-pink hover:text-white transition-all shadow-lg rounded-sm"
|
||||
>
|
||||
{buttonText}
|
||||
</Link>
|
||||
)}
|
||||
{description && (
|
||||
<p className="max-w-2xl text-sm md:text-lg font-light leading-relaxed opacity-90 drop-shadow">
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
|
||||
{secondaryButtonText && payload.secondaryButtonLink && (
|
||||
<Link
|
||||
to={payload.secondaryButtonLink}
|
||||
className="px-8 py-3.5 bg-transparent border border-white/40 text-white font-medium text-xs uppercase tracking-widest hover:bg-white/10 hover:border-white transition-all rounded-sm backdrop-blur-sm"
|
||||
>
|
||||
{secondaryButtonText}
|
||||
</Link>
|
||||
)}
|
||||
{/* Dual Action Buttons */}
|
||||
{(buttonText || secondaryButtonText) && (
|
||||
<div className={`flex flex-wrap gap-4 pt-4 ${actionsClasses}`}>
|
||||
{buttonText && payload.buttonLink && (
|
||||
<Link
|
||||
to={payload.buttonLink}
|
||||
className="px-8 py-3.5 bg-white text-neutral-900 font-medium text-xs uppercase tracking-widest hover:bg-pop-pink hover:text-white transition-all shadow-lg rounded-sm"
|
||||
>
|
||||
{buttonText}
|
||||
</Link>
|
||||
)}
|
||||
|
||||
{secondaryButtonText && payload.secondaryButtonLink && (
|
||||
<Link
|
||||
to={payload.secondaryButtonLink}
|
||||
className="px-8 py-3.5 bg-transparent border border-white/40 text-white font-medium text-xs uppercase tracking-widest hover:bg-white/10 hover:border-white transition-all rounded-sm backdrop-blur-sm"
|
||||
>
|
||||
{secondaryButtonText}
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})()}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user