first test commit
Deploy GISE landing page / build-and-deploy (push) Successful in 17s
Deploy GISE landing page test / build-and-deploy (push) Successful in 16s

This commit is contained in:
LathanDevers
2026-07-28 11:10:36 +02:00
parent 599c5d5526
commit f83eb53cf4
14 changed files with 996 additions and 467 deletions
+302
View File
@@ -0,0 +1,302 @@
import React, { useState, useEffect } from 'react';
import { Shield, Server, Lock, ChevronRight, Activity, Network, Briefcase, Stethoscope, FileText, CheckCircle, Moon, Sun } from 'lucide-react';
import { Link } from 'react-router-dom';
import { useTheme } from '../hooks/useTheme';
export default function GiseLandingPage() {
const [cookieConsent, setCookieConsent] = useState<boolean | null>(null);
const [formStatus, setFormStatus] = useState<'idle' | 'submitting' | 'success'>('idle');
// --- GESTION DU MODE CLAIR/SOMBRE ---
const { isDark, toggleTheme } = useTheme();
// -------------------------------------
// --- LOGIQUE DES COOKIES ---
useEffect(() => {
const getCookie = (name: string) => {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop()?.split(';').shift();
return null;
};
const existingConsent = getCookie('gise_cookie_consent');
if (existingConsent === 'true') setCookieConsent(true);
else if (existingConsent === 'false') setCookieConsent(false);
}, []);
const handleAcceptCookies = () => {
const date = new Date();
date.setTime(date.getTime() + (365 * 24 * 60 * 60 * 1000));
document.cookie = `gise_cookie_consent=true;expires=${date.toUTCString()};path=/;Secure;SameSite=Strict`;
setCookieConsent(true);
};
const handleRefuseCookies = () => {
const date = new Date();
date.setTime(date.getTime() + (365 * 24 * 60 * 60 * 1000));
document.cookie = `gise_cookie_consent=false;expires=${date.toUTCString()};path=/;Secure;SameSite=Strict`;
setCookieConsent(false);
};
const handleResetCookies = () => {
document.cookie = "gise_cookie_consent=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
setCookieConsent(null);
};
// ---------------------------
const handleContactSubmit = (e: React.SubmitEvent) => {
e.preventDefault();
setFormStatus('submitting');
setTimeout(() => setFormStatus('success'), 1500);
};
return (
<div className="min-h-screen font-sans selection:bg-gise-accent selection:text-white transition-colors duration-300">
{/* NAVIGATION */}
<nav className="fixed w-full z-40 bg-white/90 dark:bg-slate-950/90 backdrop-blur-md border-b border-slate-200 dark:border-slate-800 transition-colors duration-300">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between items-center h-20">
<div className="flex items-center gap-2">
<Shield className="h-8 w-8 text-gise-accent" />
<span className="text-2xl font-bold tracking-wider text-slate-900 dark:text-white">GISE</span>
</div>
<div className="hidden md:flex space-x-8 text-sm font-medium text-slate-600 dark:text-slate-300">
<a href="#expertise" className="hover:text-gise-accent dark:hover:text-white transition-colors">Expertise</a>
<a href="#solutions" className="hover:text-gise-accent dark:hover:text-white transition-colors">Solutions</a>
<a href="#industries" className="hover:text-gise-accent dark:hover:text-white transition-colors">Secteurs</a>
<a href="#contact" className="hover:text-gise-accent dark:hover:text-white transition-colors">Contact</a>
</div>
<div className="flex items-center gap-4">
{/* BOUTON TOGGLE THEME */}
<button
onClick={toggleTheme}
className="p-2 rounded-full bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-400 hover:text-gise-accent dark:hover:text-white transition-colors"
aria-label="Basculer le thème"
>
{isDark ? <Sun className="w-5 h-5" /> : <Moon className="w-5 h-5" />}
</button>
<a href="#contact" className="hidden md:inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-gise-accent hover:bg-gise-accentHover transition-colors">
Réponse à Incident
</a>
</div>
</div>
</div>
</nav>
{/* HERO SECTION */}
<section className="pt-32 pb-20 px-4 sm:px-6 lg:px-8 max-w-7xl mx-auto flex flex-col items-center text-center">
<div className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-slate-200 dark:bg-slate-800/50 border border-slate-300 dark:border-slate-700 text-sm text-slate-700 dark:text-slate-300 mb-8 transition-colors">
<Lock className="w-4 h-4 text-emerald-600 dark:text-emerald-400" />
<span>Cabinet d'Expertise en Cybersécurité B2B</span>
</div>
<h1 className="text-5xl md:text-7xl font-extrabold text-slate-900 dark:text-white tracking-tight mb-6 transition-colors">
Protégez votre patrimoine numérique <br className="hidden md:block"/> avec une exigence <span className="text-transparent bg-clip-text bg-linear-to-r from-blue-600 to-gise-accent dark:from-blue-400 dark:to-gise-accent">absolue.</span>
</h1>
<p className="mt-4 text-xl text-slate-600 dark:text-slate-400 max-w-3xl mb-10 transition-colors">
Nous concevons, infogérons et sécurisons les infrastructures informatiques des cabinets d'avocats, cliniques privées et fiduciaires. Hébergement souverain et confidentialité totale de vos données.
</p>
<div className="flex flex-col sm:flex-row gap-4">
<a href="#contact" className="px-8 py-4 text-base font-bold rounded-md text-white bg-gise-accent hover:bg-gise-accentHover transition-all flex items-center justify-center gap-2">
Demander un Audit <ChevronRight className="w-5 h-5" />
</a>
<a href="#solutions" className="px-8 py-4 text-base font-medium rounded-md text-slate-700 dark:text-slate-300 bg-white dark:bg-slate-800 border border-slate-300 dark:border-slate-700 hover:bg-slate-50 dark:hover:bg-slate-700 transition-all flex items-center justify-center">
Découvrir nos Solutions
</a>
</div>
</section>
{/* EXPERTISE */}
<section id="expertise" className="py-20 bg-slate-100 dark:bg-slate-900 border-t border-slate-200 dark:border-slate-800 transition-colors">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-16">
<h2 className="text-3xl font-bold text-slate-900 dark:text-white mb-4">Notre Expertise Fondamentale</h2>
<p className="text-slate-600 dark:text-slate-400">Le socle de votre tranquillité d'esprit numérique.</p>
</div>
<div className="grid md:grid-cols-3 gap-8">
{[
{ icon: Activity, title: "Audit & Cartographie", desc: "Diagnostic approfondi de votre architecture, analyse des vulnérabilités de surface et rapport d'impact stratégique." },
{ icon: Server, title: "Refonte Cloud Privé", desc: "Migration de vos serveurs vétustes vers nos hyperviseurs Bare-Metal souverains, infogérés en circuit fermé." },
{ icon: Lock, title: "Infogérance & Monitoring", desc: "Supervision 24/7 de vos nœuds de calcul, support premium et réponse aux incidents en temps réel." }
].map((item, i) => (
<div key={i} className="bg-white dark:bg-slate-800 p-8 rounded-xl border border-slate-200 dark:border-slate-700 hover:border-gise-accent dark:hover:border-gise-accent transition-colors">
<item.icon className="h-10 w-10 text-gise-accent mb-6" />
<h3 className="text-xl font-bold text-slate-900 dark:text-white mb-3">{item.title}</h3>
<p className="text-slate-600 dark:text-slate-400 leading-relaxed">{item.desc}</p>
</div>
))}
</div>
</div>
</section>
{/* SOLUTIONS */}
<section id="solutions" className="py-24 bg-white dark:bg-slate-950 relative overflow-hidden transition-colors">
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-200 h-200 bg-gise-accent/10 blur-[120px] rounded-full pointer-events-none"></div>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
<div className="mb-16">
<h2 className="text-3xl font-bold text-slate-900 dark:text-white mb-4">Des Solutions Technologiques Sur-Mesure</h2>
<p className="text-slate-600 dark:text-slate-400 max-w-2xl">Au-delà du conseil, nous déployons pour vous des environnements numériques ultra-sécurisés, vous garantissant un contrôle absolu sur vos données et vos communications.</p>
</div>
<div className="grid lg:grid-cols-2 gap-12">
{/* Portail VIP */}
<div className="bg-linear-to-br from-slate-200 dark:from-slate-800 to-slate-100 dark:to-slate-900 p-1 rounded-2xl">
<div className="bg-white dark:bg-slate-900 h-full p-8 md:p-12 rounded-xl transition-colors">
<div className="flex items-center gap-3 mb-6">
<Shield className="h-8 w-8 text-emerald-500 dark:text-emerald-400" />
<h3 className="text-3xl font-bold text-slate-900 dark:text-white">Espace Client & Coffre-Fort</h3>
</div>
<p className="text-lg text-slate-700 dark:text-slate-300 mb-8">Un portail privé dédié à la réassurance et à la gestion de vos actifs les plus sensibles.</p>
<ul className="space-y-4 text-slate-600 dark:text-slate-400">
<li className="flex items-start gap-3"><CheckCircle className="h-5 w-5 text-emerald-500 dark:text-emerald-400 shrink-0 mt-0.5" /> <span>Tableau de bord de suivi en temps réel de la santé de vos serveurs (Uptime, Charge).</span></li>
<li className="flex items-start gap-3"><CheckCircle className="h-5 w-5 text-emerald-500 dark:text-emerald-400 shrink-0 mt-0.5" /> <span>Stockage chiffré de bout en bout pour vos mots de passe et documents confidentiels.</span></li>
<li className="flex items-start gap-3"><CheckCircle className="h-5 w-5 text-emerald-500 dark:text-emerald-400 shrink-0 mt-0.5" /> <span>Canal de communication direct et hermétique avec votre ingénieur dédié.</span></li>
</ul>
</div>
</div>
{/* Réseau */}
<div className="bg-linear-to-br from-slate-200 dark:from-slate-800 to-slate-100 dark:to-slate-900 p-1 rounded-2xl">
<div className="bg-white dark:bg-slate-900 h-full p-8 md:p-12 rounded-xl transition-colors">
<div className="flex items-center gap-3 mb-6">
<Network className="h-8 w-8 text-blue-500 dark:text-blue-400" />
<h3 className="text-3xl font-bold text-slate-900 dark:text-white">Architecture Réseau Zero-Trust</h3>
</div>
<p className="text-lg text-slate-700 dark:text-slate-300 mb-8">L'interconnexion inviolable de vos différentes succursales et infrastructures.</p>
<ul className="space-y-4 text-slate-600 dark:text-slate-400">
<li className="flex items-start gap-3"><CheckCircle className="h-5 w-5 text-blue-500 dark:text-blue-400 shrink-0 mt-0.5" /> <span>Réseau segmenté interdisant par défaut toute connexion non authentifiée (Zero-Trust).</span></li>
<li className="flex items-start gap-3"><CheckCircle className="h-5 w-5 text-blue-500 dark:text-blue-400 shrink-0 mt-0.5" /> <span>Tunnels VPN privés (WireGuard) rendant vos flux invisibles sur internet.</span></li>
<li className="flex items-start gap-3"><CheckCircle className="h-5 w-5 text-blue-500 dark:text-blue-400 shrink-0 mt-0.5" /> <span>Filtrage de flux applicatif et pare-feu d'entreprise de dernière génération.</span></li>
</ul>
</div>
</div>
</div>
</div>
</section>
{/* INDUSTRIES */}
<section id="industries" className="py-20 bg-slate-50 dark:bg-slate-900 border-t border-slate-200 dark:border-slate-800 transition-colors">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<h2 className="text-3xl font-bold text-center text-slate-900 dark:text-white mb-16">Des solutions pensées pour les données critiques</h2>
<div className="grid md:grid-cols-3 gap-6 text-center">
<div className="p-6">
<Briefcase className="w-12 h-12 text-slate-400 dark:text-slate-500 mx-auto mb-4" />
<h4 className="text-xl font-bold text-slate-900 dark:text-white mb-2">Cabinets d'Avocats</h4>
<p className="text-slate-600 dark:text-slate-400 text-sm">Secret professionnel garanti par des environnements de stockage étanches.</p>
</div>
<div className="p-6">
<Stethoscope className="w-12 h-12 text-slate-400 dark:text-slate-500 mx-auto mb-4" />
<h4 className="text-xl font-bold text-slate-900 dark:text-white mb-2">Cliniques Privées</h4>
<p className="text-slate-600 dark:text-slate-400 text-sm">Protection absolue et souveraineté des données de santé à caractère personnel.</p>
</div>
<div className="p-6">
<FileText className="w-12 h-12 text-slate-400 dark:text-slate-500 mx-auto mb-4" />
<h4 className="text-xl font-bold text-slate-900 dark:text-white mb-2">Fiduciaires & Comptables</h4>
<p className="text-slate-600 dark:text-slate-400 text-sm">Continuité de service et intégrité totale des flux financiers de vos clients.</p>
</div>
</div>
</div>
</section>
{/* CONTACT */}
<section id="contact" className="py-24 bg-white dark:bg-slate-950 transition-colors">
<div className="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-12">
<h2 className="text-3xl font-bold text-slate-900 dark:text-white mb-4">Entrons en contact</h2>
<p className="text-slate-600 dark:text-slate-400">Pour un audit de sécurité ou une urgence, notre équipe vous répond sous 2 heures.</p>
</div>
{formStatus === 'success' ? (
<div className="bg-emerald-100 dark:bg-emerald-900/30 border border-emerald-300 dark:border-emerald-500/50 p-8 rounded-xl text-center">
<CheckCircle className="w-16 h-16 text-emerald-500 dark:text-emerald-400 mx-auto mb-4" />
<h3 className="text-2xl font-bold text-slate-900 dark:text-white mb-2">Message Envoyé</h3>
<p className="text-emerald-800 dark:text-emerald-200">Nos experts ont bien reçu votre demande et vous recontacteront dans les plus brefs délais.</p>
<button onClick={() => setFormStatus('idle')} className="mt-6 text-sm text-emerald-600 dark:text-emerald-400 hover:underline">Envoyer un autre message</button>
</div>
) : (
<form onSubmit={handleContactSubmit} className="space-y-6">
<div className="grid md:grid-cols-2 gap-6">
<div>
<label htmlFor="name" className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Nom complet</label>
<input required type="text" id="name" className="w-full bg-slate-50 dark:bg-slate-900 border border-slate-300 dark:border-slate-700 rounded-md px-4 py-3 text-slate-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-gise-accent" placeholder="Jean Dupont" />
</div>
<div>
<label htmlFor="company" className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Entreprise / Cabinet</label>
<input required type="text" id="company" className="w-full bg-slate-50 dark:bg-slate-900 border border-slate-300 dark:border-slate-700 rounded-md px-4 py-3 text-slate-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-gise-accent" placeholder="Cabinet Dupont & Associés" />
</div>
</div>
<div>
<label htmlFor="email" className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Email professionnel</label>
<input required type="email" id="email" className="w-full bg-slate-50 dark:bg-slate-900 border border-slate-300 dark:border-slate-700 rounded-md px-4 py-3 text-slate-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-gise-accent" placeholder="jean@cabinet-dupont.fr" />
</div>
<div>
<label htmlFor="message" className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Votre besoin</label>
<textarea required id="message" rows={4} className="w-full bg-slate-50 dark:bg-slate-900 border border-slate-300 dark:border-slate-700 rounded-md px-4 py-3 text-slate-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-gise-accent resize-none" placeholder="Décrivez brièvement votre infrastructure ou l'incident en cours..."></textarea>
</div>
<button disabled={formStatus === 'submitting'} type="submit" className="w-full bg-gise-accent hover:bg-gise-accentHover text-white font-bold py-4 rounded-md transition-colors flex items-center justify-center gap-2 disabled:opacity-70">
{formStatus === 'submitting' ? 'Envoi en cours...' : 'Envoyer la demande'}
</button>
</form>
)}
</div>
</section>
{/* FOOTER */}
<footer className="bg-slate-100 dark:bg-slate-950 border-t border-slate-200 dark:border-slate-900 py-12 mt-12 transition-colors">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex flex-col md:flex-row justify-between items-center md:items-start gap-8 mb-8">
<div className="flex items-center gap-2 shrink-0">
<Shield className="h-8 w-8 text-slate-400 dark:text-slate-700" />
<span className="text-2xl font-bold tracking-wider text-slate-400 dark:text-slate-700">GISE</span>
</div>
<div className="flex flex-wrap justify-center md:justify-end gap-x-8 gap-y-4 text-sm font-medium text-slate-500 dark:text-slate-400">
<Link to="/mentions-legales" className="hover:text-slate-900 dark:hover:text-white transition-colors">Mentions Légales</Link>
<Link to="/politique-confidentialite" className="hover:text-slate-900 dark:hover:text-white transition-colors">Politique de Confidentialité</Link>
<Link to="/politique-cookies" className="hover:text-slate-900 dark:hover:text-white transition-colors">Politique des Cookies</Link>
<button onClick={handleResetCookies} className="hover:text-slate-900 dark:hover:text-white transition-colors text-left underline decoration-slate-400 dark:decoration-slate-600 underline-offset-4">Gérer mes cookies</button>
<Link to="/cgs" className="hover:text-slate-900 dark:hover:text-white transition-colors">Conditions Générales (CGS)</Link>
</div>
</div>
<div className="pt-8 border-t border-slate-200 dark:border-slate-900/50 flex flex-col md:flex-row justify-between items-center gap-4 text-xs text-slate-500 dark:text-slate-600">
<p className="flex items-center gap-1">
<Server className="w-3 h-3" />
Infrastructure souveraine hébergée en Belgique (UE).
</p>
<p>© {new Date().getFullYear()} GISE Cybersecurity. Tous droits réservés.</p>
</div>
</div>
</footer>
{/* COOKIE BANNER */}
{cookieConsent === null && (
<div className="fixed bottom-0 left-0 right-0 p-4 z-50 animate-in slide-in-from-bottom-10 fade-in duration-500">
<div className="max-w-5xl mx-auto bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 shadow-2xl rounded-lg p-6 flex flex-col sm:flex-row items-center justify-between gap-6 transition-colors">
<div className="flex-1">
<h4 className="text-slate-900 dark:text-white font-bold mb-2">Gestion de vos données (RGPD)</h4>
<p className="text-sm text-slate-600 dark:text-slate-400">
GISE utilise uniquement des cookies strictement nécessaires au fonctionnement du site et à la sécurité de votre navigation. Aucun traceur publicitaire ou de revente de données n'est déployé sur nos environnements.
<Link to="/politique-cookies" className="text-gise-accent hover:text-blue-600 dark:hover:text-blue-400 hover:underline ml-2 transition-colors">
Lire notre politique
</Link>.
</p>
</div>
<div className="flex gap-3 shrink-0">
<button onClick={handleRefuseCookies} className="px-6 py-2 text-sm font-medium text-slate-600 dark:text-slate-300 hover:text-slate-900 dark:hover:text-white border border-slate-300 dark:border-slate-600 rounded hover:bg-slate-50 dark:hover:bg-slate-700 transition-colors">
Refuser
</button>
<button onClick={handleAcceptCookies} className="px-6 py-2 text-sm font-medium text-white bg-gise-accent hover:bg-gise-accentHover rounded transition-colors">
Accepter
</button>
</div>
</div>
</div>
)}
</div>
);
}