130 lines
4.1 KiB
TypeScript
130 lines
4.1 KiB
TypeScript
'use client';
|
|
|
|
import { useRef, useState, useEffect } from 'react';
|
|
import { useRouter } from 'next/navigation';
|
|
import { gsap } from 'gsap';
|
|
import PageLayout from './components/PageLayout';
|
|
import Crosshair from './components/Crosshair';
|
|
import Waves from './components/background/waves';
|
|
import SplitText from './components/SplitText';
|
|
|
|
export default function HomePage() {
|
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
const [isHover, setIsHover] = useState(false);
|
|
const [isMobile, setIsMobile] = useState(() => {
|
|
if (typeof window === 'undefined') return false;
|
|
return window.matchMedia('(max-width: 768px)').matches;
|
|
});
|
|
const router = useRouter();
|
|
|
|
// Mobile: instantly redirect to login
|
|
useEffect(() => {
|
|
if (!isMobile) return;
|
|
router.replace('/login');
|
|
}, [isMobile, router]);
|
|
|
|
// Keep breakpoint updated (resize/orientation)
|
|
useEffect(() => {
|
|
const mq = window.matchMedia('(max-width: 768px)');
|
|
const apply = () => setIsMobile(mq.matches);
|
|
mq.addEventListener?.('change', apply);
|
|
window.addEventListener('resize', apply, { passive: true });
|
|
return () => {
|
|
mq.removeEventListener?.('change', apply);
|
|
window.removeEventListener('resize', apply);
|
|
};
|
|
}, []);
|
|
|
|
const handleLoginClick = () => {
|
|
// Mobile: no page fade animation
|
|
if (isMobile || !containerRef.current) {
|
|
router.push('/login');
|
|
return;
|
|
}
|
|
|
|
gsap.to(containerRef.current, {
|
|
opacity: 0,
|
|
duration: 0.6,
|
|
ease: 'power2.out',
|
|
onComplete: () => router.push('/login'),
|
|
});
|
|
};
|
|
|
|
// Ensure LOGIN never stays stuck after scrolling / wheel (desktop only)
|
|
useEffect(() => {
|
|
if (isMobile) return;
|
|
const resetHover = () => setIsHover(false);
|
|
window.addEventListener('wheel', resetHover, { passive: true });
|
|
window.addEventListener('scroll', resetHover, { passive: true });
|
|
return () => {
|
|
window.removeEventListener('wheel', resetHover);
|
|
window.removeEventListener('scroll', resetHover);
|
|
};
|
|
}, [isMobile]);
|
|
|
|
// Prevent any home UI flash on mobile
|
|
if (isMobile) return null;
|
|
|
|
return (
|
|
<PageLayout>
|
|
<div
|
|
ref={containerRef}
|
|
className="min-h-screen flex items-center justify-center relative overflow-hidden bg-black text-white"
|
|
>
|
|
{/* Waves background */}
|
|
<Waves
|
|
className="pointer-events-none"
|
|
lineColor="#0f172a"
|
|
backgroundColor="rgba(245, 245, 240, 1)"
|
|
waveSpeedX={0.02}
|
|
waveSpeedY={0.01}
|
|
waveAmpX={40}
|
|
waveAmpY={20}
|
|
friction={0.9}
|
|
tension={0.01}
|
|
maxCursorMove={120}
|
|
xGap={12}
|
|
yGap={36}
|
|
animate={!isMobile}
|
|
interactive={!isMobile}
|
|
/>
|
|
|
|
<h1 className="z-10">
|
|
<a
|
|
onClick={handleLoginClick}
|
|
onMouseEnter={isMobile ? undefined : () => setIsHover(true)}
|
|
onMouseLeave={isMobile ? undefined : () => setIsHover(false)}
|
|
className="cursor-pointer"
|
|
>
|
|
{isMobile ? (
|
|
<span className="block text-5xl sm:text-6xl font-bold text-gray-500 text-center px-4">
|
|
PROFIT PLANET
|
|
</span>
|
|
) : (
|
|
<SplitText
|
|
key={isHover ? 'login' : 'profit-planet'}
|
|
text={isHover ? 'LOGIN' : 'PROFIT PLANET'}
|
|
tag="span"
|
|
className={`text-7xl sm:text-8xl md:text-9xl font-bold transition-colors duration-300 ${
|
|
isHover ? 'text-black' : 'text-gray-500'
|
|
}`}
|
|
delay={100}
|
|
duration={0.6}
|
|
ease="power3.out"
|
|
splitType="chars"
|
|
from={{ opacity: 0, y: 40 }}
|
|
to={{ opacity: 1, y: 0 }}
|
|
threshold={0.1}
|
|
rootMargin="-100px"
|
|
textAlign="center"
|
|
/>
|
|
)}
|
|
</a>
|
|
</h1>
|
|
|
|
{/* No parallax/crosshair on mobile */}
|
|
{!isMobile && <Crosshair containerRef={containerRef} color="#0f172a" />}
|
|
</div>
|
|
</PageLayout>
|
|
);
|
|
} |