diff --git a/apps/admin/src/components/page-builder/AccordionForm.tsx b/apps/admin/src/components/page-builder/AccordionForm.tsx index 4954849..087b474 100644 --- a/apps/admin/src/components/page-builder/AccordionForm.tsx +++ b/apps/admin/src/components/page-builder/AccordionForm.tsx @@ -34,13 +34,85 @@ export default function AccordionForm({ /> +
+
+ +
+ setEditingSection({ + ...editingSection, + payload: { ...(editingSection.payload || {}), backgroundColor: e.target.value } + })} + className="w-10 h-10 rounded cursor-pointer p-1 bg-night-900 border border-white/10" + /> + setEditingSection({ + ...editingSection, + payload: { ...(editingSection.payload || {}), backgroundColor: e.target.value } + })} + className="admin-input flex-1 font-mono text-xs" + /> +
+
+
+ +
+ setEditingSection({ + ...editingSection, + payload: { ...(editingSection.payload || {}), textColor: e.target.value } + })} + className="w-10 h-10 rounded cursor-pointer p-1 bg-night-900 border border-white/10" + /> + setEditingSection({ + ...editingSection, + payload: { ...(editingSection.payload || {}), textColor: e.target.value } + })} + className="admin-input flex-1 font-mono text-xs" + /> +
+
+
+ +
+ setEditingSection({ + ...editingSection, + payload: { ...(editingSection.payload || {}), iconColor: e.target.value } + })} + className="w-10 h-10 rounded cursor-pointer p-1 bg-night-900 border border-white/10" + /> + setEditingSection({ + ...editingSection, + payload: { ...(editingSection.payload || {}), iconColor: e.target.value } + })} + className="admin-input flex-1 font-mono text-xs" + /> +
+
+
+
@@ -60,7 +65,7 @@ export default function AccordionSection({ payload }: AccordionSectionProps) { isOpen ? 'max-h-96 pb-5 opacity-100' : 'max-h-0 opacity-0' }`} > -

+

{getLocalizedField(item.a, lang)}

diff --git a/apps/spa/src/index.css b/apps/spa/src/index.css index c45e5c1..8e868ee 100644 --- a/apps/spa/src/index.css +++ b/apps/spa/src/index.css @@ -119,7 +119,7 @@ } .ui-button-secondary { - @apply inline-flex items-center justify-center rounded-full bg-pop-bg px-6 py-3 text-xs font-bold uppercase tracking-widest text-pop-black transition-colors hover:bg-pop-black/5; + @apply inline-flex items-center justify-center rounded-full bg-pop-bg px-6 py-3 text-xs font-bold uppercase tracking-widest text-pop-black transition-colors hover:bg-pop-pink hover:text-pop-bg; } .ui-input-shell { diff --git a/apps/website/src/components/dynamic/DynamicPageRenderer.tsx b/apps/website/src/components/dynamic/DynamicPageRenderer.tsx index 6bd5647..9739b2f 100644 --- a/apps/website/src/components/dynamic/DynamicPageRenderer.tsx +++ b/apps/website/src/components/dynamic/DynamicPageRenderer.tsx @@ -290,9 +290,9 @@ function BannerSection({ payload, lang }: { payload: Record, la {title
- {title &&

{title}

} - {description &&

{description}

} - {buttonText && {buttonText}} + {title &&

{title}

} + {description &&

{description}

} + {buttonText && {buttonText}}
) @@ -399,56 +399,82 @@ function EditorialCarouselSection({ payload, lang }: { payload: Record(null) + const scrollBy = (offset: number) => { + if (scrollContainerRef.current) { + scrollContainerRef.current.scrollBy({ left: offset, behavior: 'smooth' }) + } + } + if (!slides.length) return null return ( -
+
{title && (
-

{renderAccentTitle(title)}

+

{renderAccentTitle(title)}

)} -
- {slides.map((slide, index) => { - const slideTitle = localizedFromRecord(slide, 'title', resolvedLang) - const description = localizedFromRecord(slide, 'description', resolvedLang) - const category = localizedFromRecord(slide, 'category', resolvedLang) - const buttonText = localizedFromRecord(slide, 'buttonText', resolvedLang) - const buttonLink = typeof slide.buttonLink === 'string' ? slide.buttonLink : '' - const imageUrl = typeof slide.imageUrl === 'string' ? slide.imageUrl : '' +
+ +
+ {slides.map((slide, index) => { + const slideTitle = localizedFromRecord(slide, 'title', resolvedLang) + const description = localizedFromRecord(slide, 'description', resolvedLang) + const category = localizedFromRecord(slide, 'category', resolvedLang) + const buttonText = localizedFromRecord(slide, 'buttonText', resolvedLang) + const buttonLink = typeof slide.buttonLink === 'string' ? slide.buttonLink : '' + const imageUrl = typeof slide.imageUrl === 'string' ? slide.imageUrl : '' - return ( -
- {imageUrl ? ( -
- {slideTitle -
- ) : null} -
-
- {category &&

{category}

} - {slideTitle &&

{renderAccentTitle(slideTitle)}

} - {description &&

{description}

} -
- {buttonText && buttonLink && ( -
- - {buttonText} → - + return ( +
+ {imageUrl ? ( +
+ {slideTitle
- )} -
-
- ) - })} + ) : null} +
+
+ {category && {category}} + {slideTitle &&

{renderAccentTitle(slideTitle)}

} + {description &&

{description}

} +
+ {buttonText && buttonLink && ( +
+ + {buttonText} → + +
+ )} +
+ + ) + })} +
+
@@ -560,9 +586,12 @@ function AccordionSection({ payload, lang }: { payload: Record, const categories = Array.isArray(payload.categories) ? payload.categories.map(toRecord) : [] if (!categories.length) return null const sectionTitle = localizedFromRecord(payload, 'title', resolvedLang) + const backgroundColor = typeof payload.backgroundColor === 'string' ? payload.backgroundColor : undefined + const textColor = typeof payload.textColor === 'string' ? payload.textColor : undefined + const iconColor = typeof payload.iconColor === 'string' ? payload.iconColor : undefined return ( -
+
{sectionTitle &&

{sectionTitle}

} {categories.map((category, categoryIndex) => { @@ -573,8 +602,8 @@ function AccordionSection({ payload, lang }: { payload: Record, return (
{name && ( -

- {icon && {icon}} +

+ {icon && {icon}} {name}

)} @@ -586,7 +615,7 @@ function AccordionSection({ payload, lang }: { payload: Record, return (
- + {question}

{answer}

diff --git a/fix-website-carousel.js b/fix-website-carousel.js new file mode 100644 index 0000000..a1d976b --- /dev/null +++ b/fix-website-carousel.js @@ -0,0 +1,9 @@ +const fs = require('fs'); +const path = 'apps/website/src/components/dynamic/DynamicPageRenderer.tsx'; +let content = fs.readFileSync(path, 'utf8'); + +content = content.replace(/className="ui-section-dark-card group/g, 'className="ui-card group'); +content = content.replace(/className="ui-section-dark-card-title mt-6 text-xl"/g, 'className="text-xl font-bold text-text-main mt-6"'); +content = content.replace(/className="ui-section-dark-card-copy mt-3 text-base"/g, 'className="text-base text-muted-text mt-3 whitespace-pre-wrap"'); + +fs.writeFileSync(path, content); diff --git a/packages/types/index.ts b/packages/types/index.ts index 968c009..bf42c70 100644 --- a/packages/types/index.ts +++ b/packages/types/index.ts @@ -462,18 +462,23 @@ export type ScentGuidePage = z.infer; export const AccordionSectionPayloadSchema = z.object({ title: LocalizedStringSchema.optional(), + backgroundColor: z.string().optional(), + textColor: z.string().optional(), + iconColor: z.string().optional(), categories: z.array( z.object({ + id: z.string().optional(), name: LocalizedStringSchema, icon: z.string().optional(), questions: z.array( z.object({ + id: z.string().optional(), q: LocalizedStringSchema, a: LocalizedStringSchema, }) - ).min(1), + ), }) - ).min(1), + ).optional(), }); export type AccordionSectionPayload = z.infer;