import React, { useState, useEffect, useMemo, useRef } from 'react'; import ReactDOM from 'react-dom/client'; import { HashRouter as Router, Routes, Route, Link, useLocation } from 'react-router-dom'; // --- TYPES & DATA --- enum Category { CINEMATIQUE = 'Cinématique', CHASE = 'Chase Cam', TECH = 'Photogrammétrie', COMMERCIAL = 'Publicité', ACTION = 'Sport & Action' } const PORTFOLIO_DATA = [ { id: '1', title: 'Les Sommets Silencieux', category: Category.CINEMATIQUE, thumbnail: 'https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?auto=format&fit=crop&w=1200&q=80', year: '2024', gear: 'CineLifter + Sony A7SIII' }, { id: '2', title: 'Urban Drift Chase', category: Category.CHASE, thumbnail: 'https://images.unsplash.com/photo-1511919884226-fd3cad34687c?auto=format&fit=crop&w=1200&q=80', year: '2023', gear: '5" Freestyle + GoPro 12' }, { id: '3', title: 'Mapping Industriel', category: Category.TECH, thumbnail: 'https://images.unsplash.com/photo-1581094794329-c8112a89af12?auto=format&fit=crop&w=1200&q=80', year: '2024', gear: 'DJI Mavic 3E + RTK' }, { id: '4', title: 'Villa de Luxe Tour', category: Category.COMMERCIAL, thumbnail: 'https://images.unsplash.com/photo-1613490493576-7fde63acd811?auto=format&fit=crop&w=1200&q=80', year: '2024', gear: 'CineWhoop 3.5"' }, { id: '5', title: 'Suivi Enduro', category: Category.ACTION, thumbnail: 'https://images.unsplash.com/photo-1558981403-c5f9899a28bc?auto=format&fit=crop&w=1200&q=80', year: '2023', gear: 'Long Range 7"' }, { id: '6', title: 'Horizon Côtier', category: Category.CINEMATIQUE, thumbnail: 'https://images.unsplash.com/photo-1501785888041-af3ef285b470?auto=format&fit=crop&w=1200&q=80', year: '2024', gear: '5" Cinematic' }, { id: '7', title: 'Flux de Nuit', category: Category.CINEMATIQUE, thumbnail: 'https://images.unsplash.com/photo-1449824913935-59a10b8d2000?auto=format&fit=crop&w=1200&q=80', year: '2023', gear: 'Whoop Naked GoPro' }, { id: '8', title: 'Inspection de Pont', category: Category.TECH, thumbnail: 'https://images.unsplash.com/photo-1433086966358-54859d0ed716?auto=format&fit=crop&w=1200&q=80', year: '2024', gear: 'Drone Industriel' }, { id: '9', title: 'Rallye Étape A1', category: Category.CHASE, thumbnail: 'https://images.unsplash.com/photo-1515276427842-f85802d514a2?auto=format&fit=crop&w=1200&q=80', year: '2024', gear: 'High Speed FPV' }, ]; const EXPERTISE = [ { label: 'Pilotage', val: 'Certification DGAC S1/S3' }, { label: 'Technique', val: 'BTS Géomètre Topographe' }, { label: 'Logiciels', val: 'Pix4D / DaVinci Resolve' }, { label: 'Vitesse', val: 'Max 160km/h' } ]; // --- HOOKS --- const useReveal = () => { useEffect(() => { const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) entry.target.classList.add('active'); }); }, { threshold: 0.1 }); document.querySelectorAll('.reveal').forEach(el => observer.observe(el)); return () => observer.disconnect(); }, []); }; // --- COMPONENTS --- const Navbar = () => { const [scrolled, setScrolled] = useState(false); const location = useLocation(); useEffect(() => { const handle = () => setScrolled(window.scrollY > 50); window.addEventListener('scroll', handle); return () => window.removeEventListener('scroll', handle); }, []); const navItems = [ { name: 'Portfolio', path: '/portfolio' }, { name: 'Prestations', path: '/prestations' }, { name: 'À Propos', path: '/a-propos' }, { name: 'Contact', path: '/contact' } ]; return ( ); }; const SectionHeader = ({ sub, title }: { sub: string, title: string }) => (
{sub}

{title}

); const Home = () => { useReveal(); return (
Basty FPV Logo

MOUVEMENT PRÉCIS

Pilote FPV Cinématique & Ingénierie Créative

Portfolio Prestations
Scrollez pour découvrir
{EXPERTISE.map(ex => (

{ex.label}

{ex.val}

))}
); }; const Portfolio = () => { const [active, setActive] = useState('Tout'); const items = active === 'Tout' ? PORTFOLIO_DATA : PORTFOLIO_DATA.filter(p => p.category === active); useReveal(); return (
{['Tout', ...Object.values(Category)].map(f => ( ))}
{items.map((proj, idx) => (
{proj.title}
{proj.year}

{proj.category}

{proj.title}

{proj.gear}
))}
); }; const Services = () => { useReveal(); const list = [ { t: 'Mouvement Cinématique', d: 'Captation FPV immersive pour publicités, clips et films. Résolution jusqu\'à 6K ProRes.', i: '🎬' }, { t: 'Suivi Haute Vitesse', d: 'Suivi dynamique de véhicules et sportifs. Vitesse stable jusqu\'à 160km/h en conditions extrêmes.', i: '🏎️' }, { t: 'Expertise Technique', d: 'Photogrammétrie et relevés techniques précis. Expertise certifiée BTS Géomètre Topographe.', i: '📐' }, { t: 'Exploration Intérieure', d: 'Visites virtuelles CineWhoop pour l\'immobilier de luxe et les complexes industriels.', i: '🏛️' } ]; return (
{list.map(s => (
{s.i}

{s.t}

{s.d}

))}
); }; const About = () => { useReveal(); return (

Basé en Picardie, j'allie la rigueur technique du géomètre à la créativité du pilote FPV.

Ancien technicien géomètre, j'ai conservé le goût de la précision millimétrée. Mon pilotage n'est pas qu'une question de cascades, c'est une étude du mouvement, de la lumière et de l'espace.

Je travaille avec des marques et des productions qui cherchent une image "premium", propre et dynamique, tout en garantissant une sécurité totale sur le terrain (Certifié DGAC).

Logiciels

  • Pix4D Mapper
  • DaVinci Resolve Studio
  • Adobe Creative Suite

Flotte

  • CineLifter Sony A7SIII
  • 5" Freestyle Performance
  • CineWhoop 3.5" Intérieur
); }; const Contact = () => { const [status, setStatus] = useState<'idle' | 'sending' | 'sent'>('idle'); const [formData, setFormData] = useState({ name: '', email: '', mission: 'Cinématique FPV', message: '' }); useReveal(); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); setStatus('sending'); // Simuler un envoi et ouvrir le client mail par défaut avec mailto const subject = `Demande de projet - ${formData.mission}`; const body = `Nom: ${formData.name}%0D%0AEmail: ${formData.email}%0D%0AMission: ${formData.mission}%0D%0A%0D%0AMessage:%0D%0A${formData.message}`; setTimeout(() => { window.location.href = `mailto:belon.bastian@basty.fr?subject=${subject}&body=${body}`; setStatus('sent'); }, 1000); }; const handleChange = (e: React.ChangeEvent) => { setFormData({ ...formData, [e.target.name]: e.target.value }); }; return (

Missions en France et à l'international.

belon.bastian@basty.fr
); }; // --- APP ROOT --- const App = () => { const { pathname } = useLocation(); useEffect(() => { window.scrollTo(0, 0); document.body.classList.remove('loaded'); setTimeout(() => document.body.classList.add('loaded'), 800); }, [pathname]); return (
} /> } /> } /> } /> } />
); }; // --- RENDER --- const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); root.render( ); window.addEventListener('load', () => setTimeout(() => document.body.classList.add('loaded'), 1000));