summaryrefslogtreecommitdiff
path: root/src/components/layout
diff options
context:
space:
mode:
authorertopogo <erwin.t.pombett@gmail.com>2026-02-19 11:34:16 +0100
committerertopogo <erwin.t.pombett@gmail.com>2026-02-19 11:34:16 +0100
commita21bd6a6710d123ef3bfc3c9aab37fc0c276f9c5 (patch)
treee2cc828607ea91e5c90ae0ea98c6b7d11324eaf1 /src/components/layout
feat: initial project setup - Next.js 16, Payload CMS v3, palette Mapuche
Next.js 16 App Router + TypeScript + Tailwind CSS v4. Payload CMS v3 with PostgreSQL adapter. Mapuche Corporate palette. Public pages, Docker Compose + Caddy, security middleware. Co-authored-by: Cursor <cursoragent@cursor.com>
Diffstat (limited to 'src/components/layout')
-rw-r--r--src/components/layout/Footer.tsx113
-rw-r--r--src/components/layout/Header.tsx93
2 files changed, 206 insertions, 0 deletions
diff --git a/src/components/layout/Footer.tsx b/src/components/layout/Footer.tsx
new file mode 100644
index 0000000..472e029
--- /dev/null
+++ b/src/components/layout/Footer.tsx
@@ -0,0 +1,113 @@
+import Link from "next/link";
+import { Shield, Mail, Linkedin, Github } from "lucide-react";
+
+const footerLinks = {
+ services: [
+ { name: "Audit IAM", href: "/services#audit" },
+ { name: "Intégration OIDC", href: "/services#oidc" },
+ { name: "Migration Zero Trust", href: "/services#zero-trust" },
+ { name: "Sécurisation AD / Entra", href: "/services#ad-entra" },
+ ],
+ resources: [
+ { name: "Articles", href: "/articles" },
+ { name: "Démo OIDC", href: "/demos/oidc-flow" },
+ { name: "Démo OAuth", href: "/demos/oauth-playground" },
+ { name: "Démo Zero Trust", href: "/demos/zero-trust" },
+ ],
+};
+
+export function Footer() {
+ return (
+ <footer className="bg-cosmos-950 border-t border-cosmos-800">
+ <div className="mx-auto max-w-7xl px-6 py-12 lg:px-8">
+ <div className="grid grid-cols-1 md:grid-cols-4 gap-8">
+ <div className="md:col-span-1">
+ <Link href="/" className="flex items-center gap-3">
+ <div className="w-9 h-9 rounded-lg bg-araucaria-500 flex items-center justify-center">
+ <Shield className="w-5 h-5 text-cosmos-950" />
+ </div>
+ <span className="text-lg font-bold text-nieve">Der-topogo</span>
+ </Link>
+ <p className="mt-4 text-sm text-cosmos-400 leading-relaxed">
+ Consulting senior en Identity & Access Management et sécurité
+ informatique. Expert OIDC, OAuth, Zero Trust, AD, Entra ID.
+ </p>
+ </div>
+
+ <div>
+ <h3 className="text-sm font-semibold text-araucaria-400 uppercase tracking-wider">
+ Services
+ </h3>
+ <ul className="mt-4 space-y-3">
+ {footerLinks.services.map((link) => (
+ <li key={link.name}>
+ <Link
+ href={link.href}
+ className="text-sm text-cosmos-300 hover:text-nieve transition-colors"
+ >
+ {link.name}
+ </Link>
+ </li>
+ ))}
+ </ul>
+ </div>
+
+ <div>
+ <h3 className="text-sm font-semibold text-araucaria-400 uppercase tracking-wider">
+ Ressources
+ </h3>
+ <ul className="mt-4 space-y-3">
+ {footerLinks.resources.map((link) => (
+ <li key={link.name}>
+ <Link
+ href={link.href}
+ className="text-sm text-cosmos-300 hover:text-nieve transition-colors"
+ >
+ {link.name}
+ </Link>
+ </li>
+ ))}
+ </ul>
+ </div>
+
+ <div>
+ <h3 className="text-sm font-semibold text-araucaria-400 uppercase tracking-wider">
+ Contact
+ </h3>
+ <div className="mt-4 space-y-3">
+ <a
+ href="mailto:contact@your-domain.com"
+ className="flex items-center gap-2 text-sm text-cosmos-300 hover:text-nieve transition-colors"
+ >
+ <Mail className="w-4 h-4" />
+ contact@your-domain.com
+ </a>
+ <div className="flex gap-4 pt-2">
+ <a
+ href="#"
+ className="text-cosmos-400 hover:text-nieve transition-colors"
+ aria-label="LinkedIn"
+ >
+ <Linkedin className="w-5 h-5" />
+ </a>
+ <a
+ href="#"
+ className="text-cosmos-400 hover:text-nieve transition-colors"
+ aria-label="GitHub"
+ >
+ <Github className="w-5 h-5" />
+ </a>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div className="mt-12 pt-8 border-t border-cosmos-800">
+ <p className="text-xs text-cosmos-500 text-center">
+ &copy; {new Date().getFullYear()} Der-topogo. Tous droits réservés.
+ </p>
+ </div>
+ </div>
+ </footer>
+ );
+}
diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx
new file mode 100644
index 0000000..01cc271
--- /dev/null
+++ b/src/components/layout/Header.tsx
@@ -0,0 +1,93 @@
+"use client";
+
+import { useState } from "react";
+import Link from "next/link";
+import { Menu, X, Shield } from "lucide-react";
+import { cn } from "@/lib/utils";
+
+const navigation = [
+ { name: "Accueil", href: "/" },
+ { name: "Services", href: "/services" },
+ { name: "Articles", href: "/articles" },
+ { name: "Démos", href: "/demos" },
+ { name: "À propos", href: "/about" },
+];
+
+export function Header() {
+ const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
+
+ return (
+ <header className="sticky top-0 z-50 bg-cosmos-900/95 backdrop-blur-sm border-b border-cosmos-800">
+ <nav className="mx-auto max-w-7xl px-6 lg:px-8" aria-label="Navigation principale">
+ <div className="flex h-16 items-center justify-between">
+ <Link href="/" className="flex items-center gap-3 group">
+ <div className="w-9 h-9 rounded-lg bg-araucaria-500 flex items-center justify-center group-hover:bg-araucaria-400 transition-colors">
+ <Shield className="w-5 h-5 text-cosmos-950" />
+ </div>
+ <span className="text-lg font-bold text-nieve tracking-tight">
+ Der-topogo
+ </span>
+ </Link>
+
+ <div className="hidden md:flex md:items-center md:gap-1">
+ {navigation.map((item) => (
+ <Link
+ key={item.name}
+ href={item.href}
+ className="px-4 py-2 text-sm font-medium text-cosmos-200 hover:text-nieve hover:bg-cosmos-800 rounded-lg transition-colors"
+ >
+ {item.name}
+ </Link>
+ ))}
+ <Link
+ href="/contact"
+ className="ml-4 px-5 py-2 text-sm font-semibold bg-kultrun-700 text-nieve rounded-lg hover:bg-kultrun-600 transition-colors"
+ >
+ Contact
+ </Link>
+ </div>
+
+ <button
+ type="button"
+ className="md:hidden p-2 text-cosmos-200 hover:text-nieve"
+ onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
+ >
+ <span className="sr-only">Ouvrir le menu</span>
+ {mobileMenuOpen ? (
+ <X className="h-6 w-6" />
+ ) : (
+ <Menu className="h-6 w-6" />
+ )}
+ </button>
+ </div>
+
+ <div
+ className={cn(
+ "md:hidden overflow-hidden transition-all duration-300",
+ mobileMenuOpen ? "max-h-96 pb-4" : "max-h-0"
+ )}
+ >
+ <div className="space-y-1 pt-2">
+ {navigation.map((item) => (
+ <Link
+ key={item.name}
+ href={item.href}
+ className="block px-4 py-3 text-base font-medium text-cosmos-200 hover:text-nieve hover:bg-cosmos-800 rounded-lg transition-colors"
+ onClick={() => setMobileMenuOpen(false)}
+ >
+ {item.name}
+ </Link>
+ ))}
+ <Link
+ href="/contact"
+ className="block px-4 py-3 text-base font-semibold text-kultrun-300 hover:text-kultrun-200 hover:bg-cosmos-800 rounded-lg transition-colors"
+ onClick={() => setMobileMenuOpen(false)}
+ >
+ Contact
+ </Link>
+ </div>
+ </div>
+ </nav>
+ </header>
+ );
+}