"use client"; import { useEffect, useRef, useCallback, useState } from "react"; import { Button } from "@/components/ui/Button"; import { FloatingHearts } from "@/components/ui/FloatingHearts"; import { HeroLogo } from "@/components/ui/HeroLogo"; import type { SiteContent } from "@/types/content"; const DEFAULT_VIDEOS = ["/video/ira.mp4", "/video/nadezda.mp4", "/video/nastya-2.mp4"]; interface HeroProps { data: SiteContent["hero"]; } export function Hero({ data: hero }: HeroProps) { const sectionRef = useRef(null); const scrolledRef = useRef(false); const overlayRef = useRef(null); const readyCount = useRef(0); const [mounted, setMounted] = useState(false); const videos = hero.videos?.length ? hero.videos : DEFAULT_VIDEOS; const centerVideo = videos[Math.floor(videos.length / 2)] || videos[0]; const totalVideos = videos.slice(0, 3).length + 1; // desktop (3) + mobile (1) useEffect(() => { setMounted(true); }, []); const handleVideoReady = useCallback(() => { readyCount.current += 1; if (readyCount.current >= totalVideos && overlayRef.current) { overlayRef.current.style.opacity = "0"; } }, [totalVideos]); const scrollToNext = useCallback(() => { const el = sectionRef.current; if (!el) return; let next = el.nextElementSibling; while (next && next.tagName !== "SECTION") { next = next.nextElementSibling; } next?.scrollIntoView({ behavior: "smooth" }); }, []); useEffect(() => { const el = sectionRef.current; if (!el) return; function handleWheel(e: WheelEvent) { if (e.deltaY <= 0 || scrolledRef.current) return; if (window.scrollY > 10) return; scrolledRef.current = true; scrollToNext(); setTimeout(() => { scrolledRef.current = false; }, 1000); } function handleTouchStart(e: TouchEvent) { (el as HTMLElement).dataset.touchY = String(e.touches[0].clientY); } function handleTouchEnd(e: TouchEvent) { const startY = Number((el as HTMLElement).dataset.touchY); const endY = e.changedTouches[0].clientY; if (startY - endY > 50 && !scrolledRef.current && window.scrollY < 10) { scrolledRef.current = true; scrollToNext(); setTimeout(() => { scrolledRef.current = false; }, 1000); } } el.addEventListener("wheel", handleWheel, { passive: true }); el.addEventListener("touchstart", handleTouchStart, { passive: true }); el.addEventListener("touchend", handleTouchEnd, { passive: true }); return () => { el.removeEventListener("wheel", handleWheel); el.removeEventListener("touchstart", handleTouchStart); el.removeEventListener("touchend", handleTouchEnd); }; }, [scrollToNext]); return (
{/* Videos render only after hydration to avoid SSR mismatch */} {mounted && ( <> {/* Mobile: single centered video */}
{/* Desktop: diagonal split with all videos */}
{videos.slice(0, 3).map((src, i) => { const positions = [ { left: "0%", width: "38%" }, { left: "31%", width: "38%" }, { left: "62%", width: "38%" }, ]; const clips = [ "polygon(0 0, 100% 0, 86% 100%, 0 100%)", "polygon(14% 0, 100% 0, 86% 100%, 0 100%)", "polygon(14% 0, 100% 0, 100% 100%, 0 100%)", ]; return (
); })} {/* Gold diagonal lines between panels */}
)} {/* Loading overlay — covers videos but not content */}
{/* Floating hearts */} {/* Content */}

{hero.headline}

{hero.subheadline}

); }