x
This commit is contained in:
1 parent
b641acbeb7
commit
e349ef5b84
14 files changed
+720
-558
No files matched your search
@@ -97,6 +97,136 @@ function AnnouncementBar({ payload, lang }: { payload: Record<string, unknown>,
|
||||
)
|
||||
}
|
||||
|
||||
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'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getDesktopPositionClasses = (pos: string) => {
|
||||
switch (pos) {
|
||||
case 'top-left':
|
||||
return {
|
||||
wrapper: 'md:justify-start md:items-start md:text-left md:pt-32 md:pb-12 md:pl-20 md:pr-8',
|
||||
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-32 md:pb-12 md:px-8',
|
||||
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-32 md:pb-12 md:pr-20 md:pl-8',
|
||||
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-20 md:pr-8',
|
||||
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-20 md:pl-8',
|
||||
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-20 md:pr-8',
|
||||
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-8',
|
||||
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-20 md:pl-8',
|
||||
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-8',
|
||||
content: 'md:items-center md:text-center',
|
||||
actions: 'md:items-center md:justify-center'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getHeroPositionClasses(mobilePos: string, desktopPos: string) {
|
||||
const mClasses = getMobilePositionClasses(mobilePos)
|
||||
const dClasses = getDesktopPositionClasses(desktopPos)
|
||||
return {
|
||||
wrapperClasses: `${mClasses.wrapper} ${dClasses.wrapper}`,
|
||||
contentClasses: `${mClasses.content} ${dClasses.content}`,
|
||||
actionsClasses: `${mClasses.actions} ${dClasses.actions}`,
|
||||
}
|
||||
}
|
||||
|
||||
function HeroSection({ payload, lang }: { payload: Record<string, unknown>, lang: string }) {
|
||||
const { t } = useTranslation()
|
||||
const i18nLang = useLang()
|
||||
@@ -125,132 +255,7 @@ function HeroSection({ payload, lang }: { payload: Record<string, unknown>, lang
|
||||
? rawButtonText.trim()
|
||||
: 'Explore Collection'
|
||||
|
||||
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'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getDesktopPositionClasses = (pos: string) => {
|
||||
switch (pos) {
|
||||
case 'top-left':
|
||||
return {
|
||||
wrapper: 'md:justify-start md:items-start md:text-left md:pt-32 md:pb-12 md:pl-20 md:pr-8',
|
||||
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-32 md:pb-12 md:px-8',
|
||||
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-32 md:pb-12 md:pr-20 md:pl-8',
|
||||
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-20 md:pr-8',
|
||||
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-20 md:pl-8',
|
||||
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-20 md:pr-8',
|
||||
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-8',
|
||||
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-20 md:pl-8',
|
||||
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-8',
|
||||
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 = typeof payload.overlayStyle === 'string' ? payload.overlayStyle : 'gradient'
|
||||
const overlayOpacity = typeof payload.overlayOpacity === 'number' ? payload.overlayOpacity : 45
|
||||
@@ -313,7 +318,7 @@ function HeroSection({ payload, lang }: { payload: Record<string, unknown>, lang
|
||||
</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>
|
||||
)}
|
||||
@@ -430,19 +435,26 @@ function HeroCarouselSection({ payload, lang }: { payload: Record<string, unknow
|
||||
</div>
|
||||
|
||||
{/* Optional Text Overlay */}
|
||||
{(title || subtitle || 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">
|
||||
{subtitle && <p className="text-[10px] md:text-xs uppercase font-bold tracking-widest text-brand-accent drop-shadow-md">{subtitle}</p>}
|
||||
{title && <h3 className="text-lg md:text-3xl font-bold text-white drop-shadow-md leading-tight">{renderAccentTitle(title)}</h3>}
|
||||
{buttonText && (
|
||||
<span className="inline-block mt-2 px-4 py-1.5 bg-brand-primary text-white text-xs font-bold rounded-full shadow-lg hover:bg-brand-primary-hover transition-all">
|
||||
{buttonText}
|
||||
</span>
|
||||
)}
|
||||
{(title || subtitle || buttonText) && (() => {
|
||||
const slideDesktopPos = typeof slide.buttonPosition === 'string' ? slide.buttonPosition : 'bottom-left'
|
||||
const slideMobilePos = typeof slide.mobileButtonPosition === 'string' ? slide.mobileButtonPosition : slideDesktopPos
|
||||
const { wrapperClasses: sWrap, contentClasses: sContent, actionsClasses: sActions } = 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 ${sWrap}`}>
|
||||
<div className={`max-w-xl space-y-1.5 md:space-y-2 flex flex-col ${sContent}`}>
|
||||
{subtitle && <p className="text-[10px] md:text-xs uppercase font-bold tracking-widest text-brand-accent drop-shadow-md">{subtitle}</p>}
|
||||
{title && <h3 className="text-lg md:text-3xl font-bold text-white drop-shadow-md leading-tight">{renderAccentTitle(title)}</h3>}
|
||||
{buttonText && (
|
||||
<div className={`flex ${sActions}`}>
|
||||
<span className="inline-block mt-2 px-4 py-1.5 bg-brand-primary text-white text-xs font-bold rounded-full shadow-lg hover:bg-brand-primary-hover transition-all">
|
||||
{buttonText}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
)
|
||||
})()}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -491,8 +503,12 @@ function HeroVideoSection({ payload, lang }: { payload: Record<string, unknown>,
|
||||
}
|
||||
}
|
||||
|
||||
const desktopPosition = typeof payload.buttonPosition === 'string' ? payload.buttonPosition : 'center'
|
||||
const mobilePosition = typeof payload.mobileButtonPosition === 'string' ? payload.mobileButtonPosition : desktopPosition
|
||||
const { wrapperClasses, contentClasses, actionsClasses } = getHeroPositionClasses(mobilePosition, desktopPosition)
|
||||
|
||||
return (
|
||||
<section className={`relative w-full ${getHeightClass(height)} overflow-hidden flex items-center justify-center bg-[#0B0F17] text-white`}>
|
||||
<section className={`relative w-full ${getHeightClass(height)} overflow-hidden flex bg-[#0B0F17] text-white`}>
|
||||
{videoUrl ? (
|
||||
<video
|
||||
autoPlay={payload.autoplay !== false}
|
||||
@@ -529,42 +545,44 @@ function HeroVideoSection({ payload, lang }: { payload: Record<string, unknown>,
|
||||
|
||||
<div className="absolute inset-0 z-10 bg-black transition-opacity" style={{ opacity: overlayOpacity / 100 }}></div>
|
||||
|
||||
<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">
|
||||
{tagline && (
|
||||
<p className="text-xs md:text-sm font-semibold uppercase tracking-[0.35em] text-brand-accent drop-shadow-md">
|
||||
{tagline}
|
||||
</p>
|
||||
)}
|
||||
{title && (
|
||||
<h1 className="font-serif text-4xl md:text-6xl lg:text-7xl font-light leading-tight tracking-wide drop-shadow-lg text-white">
|
||||
{renderAccentTitle(title)}
|
||||
</h1>
|
||||
)}
|
||||
{description && (
|
||||
<p className="max-w-2xl text-sm md:text-lg font-light leading-relaxed opacity-90 drop-shadow">
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
{(buttonText || secondaryButtonText) && (
|
||||
<div className="flex flex-wrap items-center justify-center gap-4 pt-4">
|
||||
{buttonText && buttonLink && (
|
||||
<Link
|
||||
href={buttonLink}
|
||||
className="px-8 py-3.5 bg-white text-neutral-900 font-medium text-xs uppercase tracking-widest hover:bg-brand-primary hover:text-white transition-all shadow-lg rounded-sm"
|
||||
>
|
||||
{buttonText}
|
||||
</Link>
|
||||
)}
|
||||
{secondaryButtonText && secondaryButtonLink && (
|
||||
<Link
|
||||
href={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 className={`relative z-20 mx-auto px-6 py-16 w-full max-w-5xl h-full flex flex-col ${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-brand-accent drop-shadow-md">
|
||||
{tagline}
|
||||
</p>
|
||||
)}
|
||||
{title && (
|
||||
<h1 className="font-serif text-4xl md:text-6xl lg:text-7xl font-light leading-tight tracking-wide drop-shadow-lg text-white">
|
||||
{renderAccentTitle(title)}
|
||||
</h1>
|
||||
)}
|
||||
{description && (
|
||||
<p className="max-w-2xl text-sm md:text-lg font-light leading-relaxed opacity-90 drop-shadow">
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
{(buttonText || secondaryButtonText) && (
|
||||
<div className={`flex flex-wrap gap-4 pt-4 ${actionsClasses}`}>
|
||||
{buttonText && buttonLink && (
|
||||
<Link
|
||||
href={buttonLink}
|
||||
className="px-8 py-3.5 bg-white text-neutral-900 font-medium text-xs uppercase tracking-widest hover:bg-brand-primary hover:text-white transition-all shadow-lg rounded-sm"
|
||||
>
|
||||
{buttonText}
|
||||
</Link>
|
||||
)}
|
||||
{secondaryButtonText && secondaryButtonLink && (
|
||||
<Link
|
||||
href={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>
|
||||
</section>
|
||||
)
|
||||
@@ -1103,8 +1121,12 @@ function BannerSection({ payload, lang }: { payload: Record<string, unknown>, la
|
||||
const linkUrl = typeof payload.linkUrl === 'string' ? payload.linkUrl : ''
|
||||
const focalPoint = typeof payload.focalPoint === 'object' && payload.focalPoint ? (payload.focalPoint as { x: string, y: string }) : undefined
|
||||
|
||||
const desktopPosition = typeof payload.buttonPosition === 'string' ? payload.buttonPosition : 'center-left'
|
||||
const mobilePosition = typeof payload.mobileButtonPosition === 'string' ? payload.mobileButtonPosition : desktopPosition
|
||||
const { wrapperClasses: bWrap, contentClasses: bContent, actionsClasses: bActions } = getHeroPositionClasses(mobilePosition, desktopPosition)
|
||||
|
||||
const content = (
|
||||
<div className="ui-banner-shell">
|
||||
<div className={`ui-banner-shell flex flex-col ${bWrap}`}>
|
||||
<Image
|
||||
src={imageUrl}
|
||||
alt={title || 'Banner'}
|
||||
@@ -1114,10 +1136,14 @@ function BannerSection({ payload, lang }: { payload: Record<string, unknown>, la
|
||||
style={{ objectPosition: focalPoint ? `${focalPoint.x} ${focalPoint.y}` : undefined }}
|
||||
/>
|
||||
<div className="ui-banner-overlay" />
|
||||
<div className="ui-banner-content">
|
||||
<div className={`ui-banner-content flex flex-col space-y-4 max-w-2xl ${bContent}`}>
|
||||
{title && <h2 className="text-3xl font-semibold text-brand-primary drop-shadow-md md:text-5xl">{title}</h2>}
|
||||
{description && <p className="text-surface-page/90 drop-shadow-sm">{description}</p>}
|
||||
{buttonText && <span className="inline-flex cursor-pointer rounded-full bg-surface-card px-6 py-3 font-semibold text-text-main transition-colors hover:bg-brand-primary hover:text-surface-card">{buttonText}</span>}
|
||||
{buttonText && (
|
||||
<div className={`flex ${bActions}`}>
|
||||
<span className="inline-flex cursor-pointer rounded-full bg-surface-card px-6 py-3 font-semibold text-text-main transition-colors hover:bg-brand-primary hover:text-surface-card">{buttonText}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user