Merge remote-tracking branch 'origin/main'
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions

This commit is contained in:
Vadym Samoilenko 2026-06-01 21:36:07 +01:00
commit 00a3ae163a

View file

@ -231,6 +231,12 @@ export function DinoWheel({ dinos, galleryImages }: DinoWheelProps) {
}
}, [manualNav])
function handleSelect(i: number) {
if (timerRef.current) clearInterval(timerRef.current)
goTo(i)
setTimeout(startTimer, 8000)
}
const current = items[active]!
const band = geom.outer - geom.inner
const midband = (geom.inner + geom.outer) / 2
@ -564,6 +570,110 @@ export function DinoWheel({ dinos, galleryImages }: DinoWheelProps) {
</div>
))}
</div>
{/* ── Prev / dots / Next ── */}
<div className="relative flex items-center justify-center gap-4 py-4">
<button
onClick={() => handleSelect((active - 1 + n) % n)}
className="flex h-9 w-9 items-center justify-center rounded-full transition-colors"
style={{ border: '1px solid rgba(255,255,255,0.25)', color: '#fff' }}
aria-label="Попередній динозавр"
>
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" aria-hidden="true">
<path
d="M9 2.5L4.5 7L9 11.5"
stroke="white"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</button>
<div className="flex flex-wrap justify-center gap-1.5">
{items.map((_, i) => (
<button
key={i}
onClick={() => handleSelect(i)}
aria-label={items[i]!.name}
aria-current={i === active ? true : undefined}
style={{
width: i === active ? 20 : 7,
height: 7,
borderRadius: 4,
background: i === active ? '#fdcf54' : 'rgba(255,255,255,0.25)',
border: 'none',
padding: 0,
cursor: 'pointer',
transition: 'width 0.3s ease, background 0.3s ease',
}}
/>
))}
</div>
<button
onClick={() => handleSelect((active + 1) % n)}
className="flex h-9 w-9 items-center justify-center rounded-full transition-colors"
style={{ border: '1px solid rgba(255,255,255,0.25)', color: '#fff' }}
aria-label="Наступний динозавр"
>
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" aria-hidden="true">
<path
d="M5 2.5L9.5 7L5 11.5"
stroke="white"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</button>
</div>
{/* ── Photo gallery row ── */}
<div className="relative mx-auto grid max-w-[1204px] grid-cols-3 gap-3 px-4 pb-12 lg:gap-5 lg:pb-16">
{GALLERY_PHOTOS.map((photo, i) => (
<div
key={i}
className="overflow-hidden"
style={{
borderRadius: 20,
border: '3px solid #f28b4a',
aspectRatio: '3 / 4',
boxShadow: '0 8px 32px rgba(0,0,0,0.35)',
}}
>
<img
src={photo.src}
alt={photo.alt}
className="h-full w-full object-cover transition-transform duration-500 hover:scale-105"
loading="lazy"
/>
</div>
))}
</div>
{/* ── Mobile name list ── */}
<div className="relative mx-auto grid max-w-[1204px] grid-cols-2 gap-2 px-4 pb-6 sm:grid-cols-3 lg:hidden">
{items.map((dino, i) => (
<button
key={i}
onClick={() => handleSelect(i)}
className="flex items-center gap-2 rounded-[10px] px-3 py-2 text-left text-[11px] font-semibold transition-all"
style={{
background: i === active ? 'rgba(253,207,84,0.18)' : 'rgba(255,255,255,0.06)',
color: i === active ? '#fdcf54' : 'rgba(255,255,255,0.6)',
border: i === active ? '1px solid rgba(253,207,84,0.6)' : '1px solid transparent',
...FONT_MONT,
}}
aria-current={i === active ? true : undefined}
>
<span aria-hidden="true" style={{ fontSize: 13 }}>
{DINO_EMOJIS[i % DINO_EMOJIS.length]}
</span>
<span className="truncate">{dino.name}</span>
</button>
))}
</div>
</section>
)
}