Files
motovaultpro/frontend/src/pages/HomePage.tsx
2026-02-14 21:56:24 -06:00

299 lines
12 KiB
TypeScript

import { useState, useEffect } from 'react';
import { useAuth0 } from '@auth0/auth0-react';
import { useNavigate } from 'react-router-dom';
import { HeroCarousel } from './HomePage/HeroCarousel';
import { FeaturesGrid } from './HomePage/FeaturesGrid';
import { motion } from 'framer-motion';
export const HomePage = () => {
const { loginWithRedirect, isAuthenticated, logout } = useAuth0();
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const [isScrolled, setIsScrolled] = useState(false);
const [sessionCleared, setSessionCleared] = useState(false);
const navigate = useNavigate();
useEffect(() => {
const handleScroll = () => {
setIsScrolled(window.scrollY > 100);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
const handleAuthAction = () => {
if (isAuthenticated) {
navigate('/garage');
return;
}
// Check if user has a pending email verification (signed up but not verified)
const pendingVerificationEmail = localStorage.getItem('pendingVerificationEmail');
if (pendingVerificationEmail) {
// Redirect to verify-email page with the stored email
navigate('/verify-email', { state: { email: pendingVerificationEmail } });
return;
}
loginWithRedirect({ appState: { returnTo: '/garage' } });
};
const handleSignup = () => {
navigate('/signup');
};
const handleClearSession = async () => {
try {
const { indexedDBStorage } = await import('../core/utils/indexeddb-storage');
await indexedDBStorage.clearAll();
Object.keys(localStorage).forEach(key => {
if (key.startsWith('@@auth0')) localStorage.removeItem(key);
});
logout({ openUrl: false });
setSessionCleared(true);
setTimeout(() => setSessionCleared(false), 3000);
} catch (error) {
console.error('[HomePage] Failed to clear session:', error);
window.location.reload();
}
};
return (
<div className="min-h-screen bg-nero text-avus">
{/* Navigation Bar */}
<nav className={`fixed top-0 left-0 right-0 z-50 transition-colors duration-300 ${isScrolled ? 'bg-nero/95 backdrop-blur-sm' : 'bg-transparent'}`}>
<div className="w-full px-4 md:px-8 lg:px-12">
<div className="flex justify-between items-center h-16">
{/* Logo */}
<div className="flex-shrink-0">
<a href="#home" className="flex items-center">
<img
src="/images/logos/motovaultpro-title-slogan.png"
alt="MotoVaultPro - Precision Vehicle Management"
className="h-8 md:h-10 w-auto"
/>
</a>
</div>
{/* Desktop Menu */}
<div className="hidden md:flex items-center space-x-8">
<a href="#home" className="text-white/75 hover:text-white transition-colors">
Home
</a>
<a
href="#features"
className="text-white/75 hover:text-white transition-colors"
>
Features
</a>
<a href="#about" className="text-white/75 hover:text-white transition-colors">
About
</a>
<button
onClick={handleSignup}
className="border border-primary-500/90 text-primary-500 hover:bg-primary-500/10 hover:border-primary-500 font-semibold py-2 px-6 rounded-lg transition-colors duration-300 focus:outline-none focus:ring-2 focus:ring-primary-500/50"
>
Sign Up
</button>
<button
onClick={handleAuthAction}
className="bg-primary-500 hover:bg-primary-600 text-white font-semibold py-2 px-6 rounded-lg transition-colors duration-300 shadow-lg shadow-black/30 focus:outline-none focus:ring-2 focus:ring-primary-500/50"
>
Login
</button>
<button
onClick={handleClearSession}
className="text-white/40 hover:text-white/70 text-xs transition-colors min-h-[44px] min-w-[44px] flex items-center"
>
{sessionCleared ? 'Session cleared' : 'Trouble logging in?'}
</button>
</div>
{/* Mobile Menu Button */}
<div className="md:hidden">
<button
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
className="text-white/80 hover:text-white focus:outline-none"
>
<svg
className="h-6 w-6"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
viewBox="0 0 24 24"
stroke="currentColor"
>
{mobileMenuOpen ? (
<path d="M6 18L18 6M6 6l12 12" />
) : (
<path d="M4 6h16M4 12h16M4 18h16" />
)}
</svg>
</button>
</div>
</div>
{/* Mobile Menu */}
{mobileMenuOpen && (
<motion.div
initial={{ opacity: 0, height: 0 }}
animate={{ opacity: 1, height: 'auto' }}
exit={{ opacity: 0, height: 0 }}
className="md:hidden py-4 space-y-3 bg-nero/95 backdrop-blur-sm border-t border-white/10"
>
<a
href="#home"
className="block text-white/75 hover:text-white transition-colors py-2"
>
Home
</a>
<a
href="#features"
className="block text-white/75 hover:text-white transition-colors py-2"
>
Features
</a>
<a
href="#about"
className="block text-white/75 hover:text-white transition-colors py-2"
>
About
</a>
<button
onClick={handleSignup}
className="w-full border border-primary-500/90 text-primary-500 hover:bg-primary-500/10 font-semibold py-2 px-6 rounded-lg transition-colors duration-300 focus:outline-none focus:ring-2 focus:ring-primary-500/50"
>
Sign Up
</button>
<button
onClick={handleAuthAction}
className="w-full bg-primary-500 hover:bg-primary-600 text-white font-semibold py-2 px-6 rounded-lg transition-colors duration-300 focus:outline-none focus:ring-2 focus:ring-primary-500/50"
>
Login
</button>
<button
onClick={handleClearSession}
className="w-full text-white/40 hover:text-white/70 text-xs py-2 min-h-[44px] transition-colors"
>
{sessionCleared ? 'Session cleared' : 'Trouble logging in?'}
</button>
</motion.div>
)}
</div>
</nav>
{/* Hero Carousel */}
<section id="home">
<HeroCarousel onGetStarted={handleAuthAction} />
</section>
{/* Welcome Section */}
<section className="py-16 px-4 md:px-8 bg-[#1D1A18] border-t border-white/5">
<div className="max-w-4xl mx-auto text-center">
{/* Full Logo */}
<div className="mb-8">
<img
src="/images/logos/motovaultpro-logo-title.png"
alt="MotoVaultPro - Precision Vehicle Management"
className="w-[280px] sm:w-[380px] md:w-[520px] lg:w-[620px] max-w-[90vw] h-auto mx-auto"
loading="eager"
/>
</div>
<p className="text-lg text-titanio leading-relaxed mb-8">
Your collection deserves better than a spreadsheet.
Track every drive, lap time, and modification across your entire stable.
From maintenance histories and fuel logs to document storage and performance analytics, our platform gives you complete visibility into each car's story.
Whether it's one daily-driven sports car or a varied collection of different makes and models, we'll help you spend less time on paperwork and more time behind the wheel.
Let's build a system that matches your passion.
</p>
<p className="text-lg text-titanio leading-relaxed mb-8">
Do not hesitate to reach out for assistance in creating a custom workflow that best fits
your needs.
</p>
<button
onClick={handleAuthAction}
className="bg-primary-500 hover:bg-primary-600 text-white font-semibold py-3 px-8 rounded-lg transition-colors duration-300 shadow-lg shadow-black/30 focus:outline-none focus:ring-2 focus:ring-primary-500/50"
>
Get Started
</button>
</div>
</section>
{/* About Section */}
<section id="about" className="py-16 px-4 md:px-8 bg-nero border-t border-white/5">
<div className="max-w-6xl mx-auto">
<div className="grid md:grid-cols-2 gap-12 items-center">
<div>
<h3 className="text-sm font-semibold text-primary-500 uppercase tracking-wide mb-4">
About Us
</h3>
<h2 className="text-3xl md:text-4xl font-bold text-avus mb-6">
Built by enthusiasts. Made for your collection.
</h2>
<p className="text-lg text-titanio leading-relaxed mb-6">
We're car people, just like you. We built this because we wanted a community where enthusiasts could connect. That's where community verified Premium 93 started.
But we were also tired of juggling spreadsheets, receipts, and service records across our own collections.
Just getting started? Reach out and we'll help.
</p>
<p className="text-lg text-titanio leading-relaxed">
We are proud to use the finest technology and best practices to provide quality and
satisfaction for our users.
</p>
</div>
<div className="flex justify-center">
<div className="w-64 h-64 bg-primary-500 rounded-lg border border-white/10 flex items-center justify-center shadow-lg shadow-black/30">
<div className="text-center text-white p-8">
<svg
className="w-32 h-32 mx-auto mb-4"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M9 2a1 1 0 000 2h2a1 1 0 100-2H9z" />
<path
fillRule="evenodd"
d="M4 5a2 2 0 012-2 3 3 0 003 3h2a3 3 0 003-3 2 2 0 012 2v11a2 2 0 01-2 2H6a2 2 0 01-2-2V5zm3 4a1 1 0 000 2h.01a1 1 0 100-2H7zm3 0a1 1 0 000 2h3a1 1 0 100-2h-3zm-3 4a1 1 0 100 2h.01a1 1 0 100-2H7zm3 0a1 1 0 100 2h3a1 1 0 100-2h-3z"
clipRule="evenodd"
/>
</svg>
<p className="text-xl font-bold">Trusted Platform</p>
</div>
</div>
</div>
</div>
</div>
</section>
{/* Features Grid */}
<section id="features">
<FeaturesGrid />
</section>
{/* Bottom CTA */}
<section className="py-16 px-4 md:px-8 bg-gradient-to-r from-primary-700 via-primary-500 to-primary-700 text-white border-t border-white/10">
<div className="max-w-4xl mx-auto text-center">
<h2 className="text-2xl md:text-3xl font-bold mb-6">
We are a cloud-based platform accessible anywhere, anytime.
</h2>
<button
onClick={handleAuthAction}
className="bg-white/95 text-primary-500 hover:bg-white font-semibold py-3 px-8 rounded-lg transition-colors duration-300 shadow-lg shadow-black/30 focus:outline-none focus:ring-2 focus:ring-white/50"
>
Get Started
</button>
</div>
</section>
{/* Footer */}
<footer className="bg-black text-white py-8 px-4 md:px-8 border-t border-white/10">
<div className="max-w-7xl mx-auto text-center">
<p className="text-white/50">
&copy; {new Date().getFullYear()} FB Technologies LLC. All rights reserved.
</p>
</div>
</footer>
</div>
);
};