x
This commit is contained in:
1 parent
641cc4e42b
commit
46968782b6
17 files changed
+265
-30
No files matched your search
@@ -3,6 +3,7 @@ import type { BannerSectionPayload } from '@homaroma/types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getLocalizedField } from '../utils/localization';
|
||||
import { getHeroPositionClasses } from './DynamicHero';
|
||||
import { getSectionPaddingClasses } from '../utils/spacing';
|
||||
|
||||
interface DynamicBannerProps {
|
||||
payload: BannerSectionPayload;
|
||||
@@ -66,7 +67,7 @@ export default function DynamicBanner({ payload }: DynamicBannerProps) {
|
||||
);
|
||||
|
||||
return (
|
||||
<section className="ui-section-band bg-pop-bg relative overflow-hidden">
|
||||
<section className={`bg-pop-bg relative overflow-hidden ${getSectionPaddingClasses(payload)}`}>
|
||||
{linkUrl ? (
|
||||
<Link to={linkUrl} className={`ui-banner-shell group flex flex-col ${shellWidthClass} ${wrapperClasses} cursor-pointer`}>
|
||||
{bannerInner}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Link } from 'react-router-dom';
|
||||
import { getCategoryImage, resolveCategoryMediaUrl, type Category, type CategoriesSectionPayload } from '@homaroma/types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getLocalizedField } from '../utils/localization';
|
||||
import { getSectionPaddingClasses } from '../utils/spacing';
|
||||
|
||||
interface DynamicCategoriesProps {
|
||||
payload: CategoriesSectionPayload;
|
||||
@@ -26,7 +27,7 @@ export default function DynamicCategories({ payload, categories, loading }: Dyna
|
||||
}, [categories, categoryIds]);
|
||||
|
||||
return (
|
||||
<section id="categories" className="ui-section-band relative overflow-hidden bg-pop-bg">
|
||||
<section id="categories" className={`relative overflow-hidden bg-pop-bg ${getSectionPaddingClasses(payload)}`}>
|
||||
<div className="ui-section-inner space-y-16 relative z-10">
|
||||
<div className="space-y-4 text-center">
|
||||
<h2 className="text-4xl font-bold tracking-tight text-pop-black md:text-5xl">
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Link } from 'react-router-dom';
|
||||
import type { EditorialTileSectionPayload } from '@homaroma/types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getLocalizedField } from '../utils/localization';
|
||||
import { getSectionPaddingClasses } from '../utils/spacing';
|
||||
|
||||
interface DynamicEditorialTileProps {
|
||||
payload: EditorialTileSectionPayload;
|
||||
@@ -54,7 +55,7 @@ export default function DynamicEditorialTile({ payload }: DynamicEditorialTilePr
|
||||
|
||||
return (
|
||||
<section
|
||||
className="ui-section-band w-full overflow-hidden"
|
||||
className={`w-full overflow-hidden ${getSectionPaddingClasses(payload)}`}
|
||||
style={{ backgroundColor: payload.backgroundColor, color: payload.textColor }}
|
||||
>
|
||||
<div className="ui-section-inner grid grid-cols-1 items-center gap-12 md:grid-cols-2 md:gap-20">
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useRef } from 'react';
|
||||
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getLocalizedField } from '../utils/localization';
|
||||
import { getSectionPaddingClasses } from '../utils/spacing';
|
||||
|
||||
interface DynamicProductCarouselProps {
|
||||
payload: any;
|
||||
@@ -21,7 +22,7 @@ export default function DynamicProductCarousel({ payload }: DynamicProductCarous
|
||||
const scrollRight = () => carouselRef.current?.scrollBy({ left: 300, behavior: 'smooth' });
|
||||
|
||||
return (
|
||||
<section className="ui-section-band bg-pop-bg">
|
||||
<section className={`bg-pop-bg ${getSectionPaddingClasses(p)}`}>
|
||||
<div className="ui-section-inner">
|
||||
{(title || description) && (
|
||||
<div className="text-center mb-12">
|
||||
|
||||
@@ -5,6 +5,7 @@ import ProductCard from './ProductCard';
|
||||
import type { Category, Product, ProductsSectionPayload } from '@homaroma/types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getLocalizedField } from '../utils/localization';
|
||||
import { getSectionPaddingClasses } from '../utils/spacing';
|
||||
|
||||
interface DynamicProductsProps {
|
||||
payload: ProductsSectionPayload & { products?: Product[] };
|
||||
@@ -24,7 +25,7 @@ export default function DynamicProducts({ payload, categories = [] }: DynamicPro
|
||||
const scrollRight = () => carouselRef.current?.scrollBy({ left: 300, behavior: 'smooth' });
|
||||
|
||||
return (
|
||||
<section className="ui-section-band relative bg-pop-bg">
|
||||
<section className={`relative bg-pop-bg ${getSectionPaddingClasses(payload)}`}>
|
||||
<div className="ui-section-inner relative z-10 space-y-12">
|
||||
<div className="flex flex-col md:flex-row items-start md:items-end justify-between gap-6 border-b border-pop-black/10 pb-6">
|
||||
<div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { QuoteCalloutPayload } from '@homaroma/types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getLocalizedField } from '../utils/localization';
|
||||
import { getSectionPaddingClasses } from '../utils/spacing';
|
||||
|
||||
interface DynamicQuoteCalloutProps {
|
||||
payload: QuoteCalloutPayload & { role?: string };
|
||||
@@ -14,7 +15,7 @@ export default function DynamicQuoteCallout({ payload }: DynamicQuoteCalloutProp
|
||||
const role = getLocalizedField(payload.role, lang);
|
||||
|
||||
return (
|
||||
<section className="ui-section-band bg-pop-bg">
|
||||
<section className={`bg-pop-bg ${getSectionPaddingClasses(payload)}`}>
|
||||
<div className="ui-section-inner text-center">
|
||||
<div className="bg-pop-black/5 rounded-3xl p-8 max-w-4xl mx-auto">
|
||||
<svg className="w-12 h-12 mx-auto text-pop-black/40 mb-8" fill="currentColor" viewBox="0 0 24 24">
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { PageSection } from '@homaroma/types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getLocalizedField } from '../utils/localization';
|
||||
import { getSectionPaddingClasses } from '../utils/spacing';
|
||||
|
||||
interface DynamicRichTextProps {
|
||||
section: PageSection;
|
||||
@@ -17,7 +18,7 @@ export default function DynamicRichText({ section }: DynamicRichTextProps) {
|
||||
if (!content) return null;
|
||||
|
||||
return (
|
||||
<section className="ui-section-band bg-pop-bg relative">
|
||||
<section className={`bg-pop-bg relative ${getSectionPaddingClasses(payload)}`}>
|
||||
<div className="ui-section-inner space-y-6">
|
||||
{title && (
|
||||
<h2 className="font-serif text-3xl font-semibold text-pop-black md:text-4xl text-center">
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { ScentNotesBreakdownPayload } from '@homaroma/types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getLocalizedField } from '../utils/localization';
|
||||
import { getSectionPaddingClasses } from '../utils/spacing';
|
||||
|
||||
interface DynamicScentNotesBreakdownProps {
|
||||
payload: ScentNotesBreakdownPayload;
|
||||
@@ -28,7 +29,7 @@ export default function DynamicScentNotesBreakdown({ payload }: DynamicScentNote
|
||||
const baseNotes = notes(payload.baseNotes);
|
||||
|
||||
return (
|
||||
<section className="ui-section-band bg-pop-bg">
|
||||
<section className={`bg-pop-bg ${getSectionPaddingClasses(payload)}`}>
|
||||
<div className="ui-section-inner text-center">
|
||||
<h2 className="mb-6 font-serif text-3xl text-pop-black md:text-5xl">
|
||||
{title || 'Scent Notes'}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { TextSectionPayload } from '@homaroma/types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getLocalizedField } from '../utils/localization';
|
||||
import { getSectionPaddingClasses } from '../utils/spacing';
|
||||
|
||||
interface DynamicTextProps {
|
||||
payload: TextSectionPayload;
|
||||
@@ -20,7 +21,7 @@ export default function DynamicText({ payload }: DynamicTextProps) {
|
||||
}[textAlign] || 'text-left';
|
||||
|
||||
return (
|
||||
<section className="ui-section-band bg-pop-bg relative">
|
||||
<section className={`bg-pop-bg relative ${getSectionPaddingClasses(payload)}`}>
|
||||
<div className={`ui-section-inner space-y-6 ${alignClass}`}>
|
||||
{title && (
|
||||
<h2 className="font-serif text-3xl font-semibold text-pop-black md:text-4xl">
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { AccordionSectionPayload } from '@homaroma/types';
|
||||
import { ChevronDown, ChevronUp } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getLocalizedField } from '../../utils/localization';
|
||||
import { getSectionPaddingClasses } from '../../utils/spacing';
|
||||
|
||||
interface AccordionSectionProps {
|
||||
payload: AccordionSectionPayload & { title?: string };
|
||||
@@ -20,7 +21,7 @@ export default function AccordionSection({ payload }: AccordionSectionProps) {
|
||||
|
||||
return (
|
||||
<section
|
||||
className="ui-section-band w-full px-4 md:px-8"
|
||||
className={`w-full px-4 md:px-8 ${getSectionPaddingClasses(payload)}`}
|
||||
style={{ backgroundColor: payload.backgroundColor, color: payload.textColor }}
|
||||
>
|
||||
<div className="ui-section-inner">
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { ContactInfoSectionPayload } from '@homaroma/types';
|
||||
import { MapPin, Mail, MessageCircle, Clock } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getLocalizedField } from '../../utils/localization';
|
||||
import { getSectionPaddingClasses } from '../../utils/spacing';
|
||||
|
||||
interface ContactInfoSectionProps {
|
||||
payload: ContactInfoSectionPayload & { title?: string };
|
||||
@@ -30,7 +31,7 @@ export default function ContactInfoSection({ payload }: ContactInfoSectionProps)
|
||||
] as const;
|
||||
|
||||
return (
|
||||
<section className="ui-section-band w-full bg-pop-bg px-4 md:px-8">
|
||||
<section className={`w-full bg-pop-bg px-4 md:px-8 ${getSectionPaddingClasses(payload)}`}>
|
||||
<div className="ui-section-inner">
|
||||
{title && (
|
||||
<div className="mb-10 text-center">
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
export function getSectionPaddingClasses(
|
||||
payload?: Record<string, any>,
|
||||
fallback: 'normal' | 'none' | 'compact' | 'spacious' = 'normal',
|
||||
): string {
|
||||
const padTop = payload?.paddingTop || payload?.sectionPadding || fallback;
|
||||
const padBottom = payload?.paddingBottom || payload?.sectionPadding || fallback;
|
||||
|
||||
const getPt = (p: string) => {
|
||||
switch (p) {
|
||||
case 'none':
|
||||
return 'pt-0';
|
||||
case 'compact':
|
||||
return 'pt-6 md:pt-10';
|
||||
case 'spacious':
|
||||
return 'pt-20 md:pt-28';
|
||||
case 'normal':
|
||||
default:
|
||||
return 'pt-10 md:pt-16';
|
||||
}
|
||||
};
|
||||
|
||||
const getPb = (p: string) => {
|
||||
switch (p) {
|
||||
case 'none':
|
||||
return 'pb-0';
|
||||
case 'compact':
|
||||
return 'pb-6 md:pb-10';
|
||||
case 'spacious':
|
||||
return 'pb-20 md:pb-28';
|
||||
case 'normal':
|
||||
default:
|
||||
return 'pb-10 md:pb-16';
|
||||
}
|
||||
};
|
||||
|
||||
return `${getPt(padTop)} ${getPb(padBottom)}`;
|
||||
}
|
||||
Reference in new issue
Block a user