fix: dynamic attire buttons in ScrollOverlays + mobile touch support

This commit is contained in:
Najjar\NajjarV02 2026-04-20 15:13:34 +04:00
parent 320b77b32b
commit b2a484f402

View File

@ -1,7 +1,7 @@
'use client'; 'use client';
import { useScroll, useTransform, motion } from 'framer-motion'; import { useScroll, useTransform, motion } from 'framer-motion';
import { ReactNode } from 'react'; import { ReactNode, useEffect, useState } from 'react';
import Link from 'next/link'; import Link from 'next/link';
interface SectionProps { interface SectionProps {
@ -132,6 +132,33 @@ const SECTION_CONFIGS = [
export function ScrollOverlays() { export function ScrollOverlays() {
const { scrollYProgress } = useScroll(); const { scrollYProgress } = useScroll();
// Dynamically load personas from the pricing API so any admin-added attire shows here
const [attireItems, setAttireItems] = useState<{ label: string; id: string }[]>([
{ label: 'Kandura', id: 'emarati-kandura' },
{ label: 'Vest', id: 'industrial-vest' },
{ label: 'Suit', id: 'business-suit' },
]);
useEffect(() => {
fetch('/api/admin/pricing/')
.then((r) => r.json())
.then((data) => {
const excluded = new Set(['base', 'custom-color', 'emarati-kandura', 'industrial-vest', 'business-suit']);
const extras: { label: string; id: string }[] = (data.items ?? [])
.filter((item: { id: string; label: string; modelPath?: string | null }) =>
!excluded.has(item.id) && item.modelPath
)
.map((item: { id: string; label: string }) => ({ label: item.label, id: item.id }));
setAttireItems([
{ label: 'Kandura', id: 'emarati-kandura' },
{ label: 'Vest', id: 'industrial-vest' },
{ label: 'Suit', id: 'business-suit' },
...extras,
]);
})
.catch(() => {});
}, []);
return ( return (
<div <div
style={{ style={{
@ -207,14 +234,15 @@ export function ScrollOverlays() {
<p style={{ fontSize: '0.95rem', color: '#475569', lineHeight: 1.6, margin: 0, fontWeight: 300 }}> <p style={{ fontSize: '0.95rem', color: '#475569', lineHeight: 1.6, margin: 0, fontWeight: 300 }}>
From traditional Emarati Kandura to industrial safety gear and professional business attire. Configure every detail to match your brand. From traditional Emarati Kandura to industrial safety gear and professional business attire. Configure every detail to match your brand.
</p> </p>
<div style={{ display: 'flex', gap: '1rem', marginTop: '2rem' }}> <div style={{ display: 'flex', gap: '1rem', marginTop: '2rem', flexWrap: 'wrap' }}>
{[ {attireItems.map((item) => (
{ label: 'Kandura', id: 'emarati-kandura' },
{ label: 'Vest', id: 'industrial-vest' },
{ label: 'Suit', id: 'business-suit' }
].map((item) => (
<div <div
key={item.id} key={item.id}
onClick={() => {
import('@/store/useConfigStore').then(({ configStore }) => {
configStore.getState().setPersonaAttire(item.id);
});
}}
onMouseEnter={() => { onMouseEnter={() => {
import('@/store/useConfigStore').then(({ configStore }) => { import('@/store/useConfigStore').then(({ configStore }) => {
configStore.getState().setPersonaAttire(item.id); configStore.getState().setPersonaAttire(item.id);
@ -231,7 +259,10 @@ export function ScrollOverlays() {
fontWeight: 600, fontWeight: 600,
cursor: 'pointer', cursor: 'pointer',
transition: 'all 0.3s ease', transition: 'all 0.3s ease',
boxShadow: '0 4px 12px rgba(0,0,0,0.05)' boxShadow: '0 4px 12px rgba(0,0,0,0.05)',
pointerEvents: 'auto',
userSelect: 'none',
WebkitTapHighlightColor: 'transparent',
}} }}
onMouseOver={(e) => { onMouseOver={(e) => {
e.currentTarget.style.background = 'var(--color-gold)'; e.currentTarget.style.background = 'var(--color-gold)';