rushiljain's picture
Upload 29 files
691cdd0 verified
import React, { useEffect, useRef, useState } from 'react';
import { Link } from 'react-router-dom';
import MagneticButton from './MagneticButton.jsx';
import ImageFlex from './ImageFlex.jsx';
export default function Hero() {
const mediaRef = useRef(null);
const videoRef = useRef(null);
const [mounted, setMounted] = useState(false);
const [videoLoaded, setVideoLoaded] = useState(false);
useEffect(() => {
setMounted(true);
// Check if video loads successfully
if (videoRef.current) {
const handleLoadedData = () => setVideoLoaded(true);
const handleError = () => setVideoLoaded(false);
videoRef.current.addEventListener('loadeddata', handleLoadedData);
videoRef.current.addEventListener('error', handleError);
return () => {
if (videoRef.current) {
videoRef.current.removeEventListener('loadeddata', handleLoadedData);
videoRef.current.removeEventListener('error', handleError);
}
};
}
}, []);
useEffect(() => {
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
const onScroll = () => {
const y = window.scrollY;
const el = videoLoaded ? videoRef.current : mediaRef.current;
if (!el) return;
// Subtle parallax translate
el.style.transform = `translateY(${Math.min(40, y * 0.15)}px) scale(1.05)`;
};
window.addEventListener('scroll', onScroll, { passive: true });
return () => window.removeEventListener('scroll', onScroll);
}, [videoLoaded]);
return (
<section
className="relative flex min-h-screen items-end overflow-hidden bg-slate-900 text-white mb-0"
aria-label="Hero"
style={{ zIndex: 1 }}
>
{/* Video background with image fallback */}
<video
ref={videoRef}
autoPlay
loop
muted
playsInline
className={`absolute inset-0 h-full w-full object-cover will-change-transform ${
videoLoaded ? 'opacity-100' : 'opacity-0'
}`}
style={{
transform: mounted ? 'scale(1.05)' : undefined,
filter: 'brightness(1.12) contrast(1.06)'
}}
aria-hidden="true"
>
<source src="/assets/hero-video.mp4" type="video/mp4" />
{/* TODO: replace with actual video path */}
</video>
<ImageFlex
base="/assets/hero" /* TODO: replace */
alt=""
className={`absolute inset-0 h-full w-full object-cover will-change-transform ${
videoLoaded ? 'opacity-0' : 'opacity-100'
}`}
style={{
transform: mounted ? 'scale(1.05)' : undefined,
filter: 'brightness(1.12) contrast(1.06)'
}}
ref={mediaRef}
/>
<div className="absolute inset-0 bg-slate-900/40" aria-hidden="true"></div>
{/* Overlay logo at top-right */}
<div className="absolute right-0 top-0 z-10">
<div className="rounded-bl-xl bg-white/30 px-3 py-2 shadow-lg backdrop-blur-md ring-1 ring-white/20 md:px-4 md:py-3">
<ImageFlex
base="/assets/logo"
alt="Jade Infra"
className="h-14 w-auto md:h-18 lg:h-22"
/>
</div>
</div>
{/* Heading with equal left and bottom margins regardless of media aspect */}
<div className="absolute left-6 bottom-6 z-10 md:left-10 md:bottom-10 lg:left-16 lg:bottom-16">
<div className="max-w-3xl">
<h1 className="h1 text-white">Building Tomorrow with Quality and Trust</h1>
</div>
</div>
</section>
);
}