Abmacode12's picture
🎯 Objectif
89085d9 verified
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Espace Codage - IA Interactive</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
<aside class="sidebar">
<h2>Espace Codage</h2>
<ul>
<li><a href="#">Accueil</a></li>
<li><a href="#">Projets</a></li>
<li><a href="#">Tâches</a></li>
</ul>
</aside>
<main class="main-content">
<h1>Mes Tâches</h1>
<p>Gérez les tâches de développement ici.</p>
<ul>
<li>Configurer IA</li>
<li>Créer interface</li>
<li>Générer vidéo depuis code</li>
</ul>
</main>
<section class="ia-panel">
<h3>IA Génératrice (Rosalinda)</h3>
<div class="ia-output" id="output">
<p>L’aperçu apparaîtra ici...</p>
</div>
<textarea id="codeInput" placeholder="Écris ton code ici..."></textarea>
<button onclick="sendCode()">Envoyer à l’IA</button>
</section>
</div>
<script src="script.js"></script>
</body>
</html>
<head>
<meta charset="UTF-8" />
<title>Espace Codage – Modèle Constructeur (Builder Pattern)</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Tailwind CSS CDN -->
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: {
DEFAULT: '#4f46e5', // indigo-600
fg: '#ffffff',
soft: 'rgba(79,70,229,0.2)',
},
secondary: {
DEFAULT: '#64748b', // slate-500
fg: '#ffffff',
soft: 'rgba(100,116,139,0.2)',
},
accent: {
DEFAULT: '#22d3ee', // cyan-400
soft: 'rgba(34,211,238,0.2)',
},
success: '#22c55e',
danger: '#ef4444',
warning: '#f59e0b',
surface: {
DEFAULT: '#0b1020',
soft: '#0f172a',
},
card: {
DEFAULT: '#0f172a',
soft: '#111827',
},
code: '#0b132b',
grid: 'rgba(255,255,255,0.06)',
border: 'rgba(255,255,255,0.12)',
},
boxShadow: {
soft: '0 18px 45px rgba(0,0,0,0.6)',
},
borderRadius: {
xl: '1rem',
'2xl': '1.25rem',
},
fontFamily: {
mono: ['JetBrains Mono','ui-monospace','SFMono-Regular','Menlo','Monaco','Consolas','Liberation Mono','Courier New','monospace'],
display: ['Inter','ui-sans-serif','system-ui','-apple-system','BlinkMacSystemFont','Segoe UI','Roboto','Helvetica Neue','Arial','Noto Sans','sans-serif','Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol','Noto Color Emoji'],
},
},
},
darkMode: 'class',
}
</script>
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&family=JetBrains+Mono:wght@400;600&display=swap" rel="stylesheet">
<style>
:root { color-scheme: dark; }
body { background-color: #050714; }
/* subtle grid background */
.grid-bg {
background-image:
linear-gradient(to bottom, var(--tw-colors-grid) 1px, transparent 1px),
linear-gradient(to right, var(--tw-colors-grid) 1px, transparent 1px);
background-size: 40px 40px, 40px 40px;
}
</style>
</head>
<body class="bg-surface text-slate-100 font-display antialiased selection:bg-primary/30 selection:text-white">
<main class="max-w-7xl mx-auto px-5 py-8 md:px-8 md:py-10">
<!-- Header -->
<header class="relative overflow-hidden rounded-2xl border border-border bg-gradient-to-br from-card to-surface shadow-soft p-5 md:p-7" data-animate="1">
<div class="absolute inset-0 pointer-events-none opacity-30">
<div class="absolute -top-24 -left-20 w-72 h-72 rounded-full bg-primary/20 blur-3xl"></div>
<div class="absolute -bottom-24 -right-20 w-72 h-72 rounded-full bg-accent/20 blur-3xl"></div>
</div>
<div class="relative flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
<div class="flex items-center gap-3">
<div class="w-10 h-10 rounded-full bg-gradient-to-br from-primary to-accent animate-spin-slow"></div>
<div>
<div class="text-xs uppercase tracking-[0.2em] text-slate-400">Espace Codage</div>
<h1 class="text-xl md:text-2xl font-bold tracking-wide">Modèle Constructeur · Builder Pattern</h1>
</div>
</div>
<p class="text-sm text-slate-400 max-w-2xl">
Visualisation de l'espace de codage et implémentation du pattern
<span class="text-white font-semibold">Builder</span> pour créer un
<span class="text-white font-semibold">ProjetEspaceCodage</span> étape par étape.
</p>
</div>
</header>
<div class="mt-6 grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Diagramme Espace Codage -->
<section class="relative rounded-2xl border border-border bg-gradient-to-br from-card to-surface shadow-soft p-5" data-animate="2" aria-label="Schéma Espace Codage">
<div class="flex items-center justify-between mb-3">
<div>
<h2 class="text-sm uppercase tracking-[0.2em] text-accent">Espace Codage</h2>
<p class="text-xs text-slate-400">Vue conceptuelle des outils : éditeur, terminal, build, tests, déploiement…</p>
</div>
<span class="text-[10px] uppercase tracking-[0.25em] text-slate-500">SCHEMA</span>
</div>
<div class="relative grid-bg rounded-xl border border-border p-4 md:p-5 min-h-[420px]">
<!-- Overlay SVG pour les flèches -->
<svg class="absolute inset-0 w-full h-full pointer-events-none" id="arrowLayer" style="z-index: 0;"></svg>
<div class="relative grid grid-rows-[auto,1fr,auto] gap-4 h-full" id="schemaRoot" style="z-index: 1;">
<!-- Ligne du haut : Documentation -->
<div class="flex justify-center">
<button class="node-btn" data-id="documentation" data-name="Documentation" title="Documentation">
Documentation
</button>
</div>
<!-- Ligne centrale -->
<div class="grid grid-cols-3 gap-3 md:gap-4 items-center">
<!-- Version Control (gauche) -->
<div class="flex justify-center">
<button class="node-btn" data-id="version" data-name="Version Control" title="Version Control">
Version Control
</button>
</div>
<!-- Colonne centrale -->
<div class="flex flex-col items-center gap-3">
<!-- Code Editor (centre principal) -->
<button class="node-btn node-main" data-id="editor" data-name="Code Editor" title="Code Editor">
Code Editor
</button>
<!-- Terminal + Debugger -->
<div class="flex gap-3">
<button class="node-btn" data-id="terminal" data-name="Terminal" title="Terminal">
Terminal
</button>
<button class="node-btn" data-id="debugger" data-name="Debugger" title="Debugger">
Debugger
</button>
</div>
<!-- Testing Framework -->
<button class="node-btn" data-id="testing" data-name="Testing Framework" title="Testing Framework">
Testing Framework
</button>
</div>
<!-- Build System (droite) -->
<div class="flex justify-center">
<button class="node-btn" data-id="build" data-name="Build System" title="Build System">
Build System
</button>
</div>
</div>
<!-- Ligne du bas : Deployment -->
<div class="flex justify-center">
<button class="node-btn" data-id="deploy" data-name="Deployment" title="Deployment">
Deployment
</button>
</div>
</div>
</div>
<div class="mt-4 text-xs text-slate-400">
Cliquez sur un nœud pour voir une info rapide. Utilisez les boutons de démonstration ci-dessous pour simuler la construction.
</div>
</section>
<!-- Code + Démonstration Builder -->
<section class="rounded-2xl border border-border bg-gradient-to-br from-card to-surface shadow-soft p-5" data-animate="3" aria-label="Code Builder Pattern">
<div class="flex items-start justify-between gap-3">
<div>
<h2 class="text-sm uppercase tracking-[0.2em] text-primary">Code · Builder Pattern</h2>
<p class="text-xs text-slate-400">
Implémentation en <strong class="text-white">Python</strong> du pattern
<strong class="text-white">Builder</strong> pour un <em>ProjetEspaceCodage</em> complexe.
</p>
<div class="mt-2 flex flex-wrap gap-2">
<span class="badge">Builder Pattern</span>
<span class="badge">Objet complexe</span>
<span class="badge">Python</span>
<span class="badge">Espace Codage</span>
</div>
</div>
<span class="text-[10px] uppercase tracking-[0.25em] text-slate-500">BUILDER</span>
</div>
<!-- Editeur simulé -->
<div class="mt-4 rounded-xl border border-border bg-code shadow-soft overflow-hidden">
<div class="flex items-center justify-between px-3 py-2 border-b border-border bg-slate-900/50">
<div class="flex items-center gap-1.5">
<span class="w-2.5 h-2.5 rounded-full bg-danger"></span>
<span class="w-2.5 h-2.5 rounded-full bg-warning"></span>
<span class="w-2.5 h-2.5 rounded-full bg-success"></span>
</div>
<div class="flex items-center gap-2 text-[10px] uppercase tracking-[0.18em] text-slate-400">
espace_codage_builder.py · Python
</div>
<div></div>
</div>
<pre class="font-mono text-[11px] leading-5 p-3 md:p-4 overflow-auto max-h-[420px]"><code><span class="text-slate-400"># === ESPACE CODAGE · MODÈLE CONSTRUCTEUR (BUILDER) ===</span>
<span class="text-slate-400"># Situation :</span>
<span class="text-slate-400"># - on veut créer un "objet complexe" ProjetEspaceCodage</span>
<span class="text-slate-400"># indépendamment de la manière dont chaque partie est construite.</span>
<span class="text-slate-400"># - différents Builders produisent différentes représentations</span>
<span class="text-slate-400"># (projet minimal, projet full‑stack, etc.).</span>
<span class="text-primary">from</span> abc <span class="text-primary">import</span> ABC, abstractmethod
<span class="text-primary">from</span> typing <span class="text-primary">import</span> List, Dict
<span class="text-accent">class</span> <span class="text-white">ProjetEspaceCodage</span>:
<span class="text-slate-400">"""Produit complexe : représente l'espace de codage complet."""</span>
<span class="text-primary">def</span> <span class="text-accent">__init__</span>(<span class="text-white">self</span>, <span class="text-white">nom</span>: <span class="text-secondary">str</span> = <span class="text-warning">"Nouveau Projet"</span>) -> <span class="text-primary">None</span>:
<span class="text-white">self</span>.nom = nom
<span class="text-white">self</span>.composants: List[str] = []
<span class="text-white">self</span>.configurations: Dict[str, str] = {}
<span class="text-white">self</span>.etapes: List[str] = []
<span class="text-primary">def</span> <span class="text-accent">ajouter_composant</span>(<span class="text-white">self</span>, <span class="text-white">description</span>: <span class="text-secondary">str</span>) -> <span class="text-primary">None</span>:
<span class="text-white">self</span>.composants.append(description)
<span class="text-primary">def</span> <span class="text-accent">ajouter_configuration</span>(<span class="text-white">self</span>, <span class="text-white">cle</span>: <span class="text-secondary">str</span>, <span class="text-white">valeur</span>: <span class="text-secondary">str</span>) -> <span class="text-primary">None</span>:
<span class="text-white">self</span>.configurations[cle] = valeur
<span class="text-primary">def</span> <span class="text-accent">ajouter_etape</span>(<span class="text-white">self</span>, <span class="text-white">etape</span>: <span class="text-secondary">str</span>) -> <span class="text-primary">None</span>:
<span class="text-white">self</span>.etapes.append(etape)
<span class="text-primary">def</span> <span class="text-accent">decrire</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
<span class="text-primary">print</span>(<span class="text-warning">f"</span><span class="text-warning">=== ESPACE CODAGE : {</span><span class="text-white">self</span>.nom<span class="text-warning">} ==="</span>)
<span class="text-primary">print</span>(<span class="text-warning">"Composants :"</span>)
<span class="text-primary">for</span> i, comp <span class="text-primary">in</span> <span class="text-primary">enumerate</span>(<span class="text-white">self</span>.composants, <span class="text-warning">1</span>):
<span class="text-primary">print</span>(<span class="text-warning">f"</span><span class="text-warning"> {i}. {comp}"</span>)
<span class="text-primary">if</span> <span class="text-white">self</span>.configurations:
<span class="text-primary">print</span>(<span class="text-warning">"</span><span class="text-warning">Configurations :"</span>)
<span class="text-primary">for</span> cle, val <span class="text-primary">in</span> <span class="text-white">self</span>.configurations.items():
<span class="text-primary">print</span>(<span class="text-warning">f"</span><span class="text-warning"> • {cle}: {val}"</span>)
<span class="text-primary">if</span> <span class="text-white">self</span>.etapes:
<span class="text-primary">print</span>(<span class="text-warning">"</span><span class="text-warning">Étapes de construction :"</span>)
<span class="text-primary">for</span> etape <span class="text-primary">in</span> <span class="text-white">self</span>.etapes:
<span class="text-primary">print</span>(<span class="text-warning">f"</span><span class="text-warning"> → {etape}"</span>)
<span class="text-accent">class</span> <span class="text-white">ConstructeurEspaceCodage</span>(ABC):
<span class="text-slate-400">"""Interface d'assemblage & construction."""</span>
<span class="text-primary">def</span> <span class="text-accent">__init__</span>(<span class="text-white">self</span>, <span class="text-white">nom_projet</span>: <span class="text-secondary">str</span>) -> <span class="text-primary">None</span>:
<span class="text-white">self</span>.projet = ProjetEspaceCodage(nom_projet)
@abstractmethod
<span class="text-primary">def</span> <span class="text-accent">configurer_documentation</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>: <span class="text-primary">pass</span>
@abstractmethod
<span class="text-primary">def</span> <span class="text-accent">configurer_editeur</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>: <span class="text-primary">pass</span>
@abstractmethod
<span class="text-primary">def</span> <span class="text-accent">configurer_terminal_debugger</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>: <span class="text-primary">pass</span>
@abstractmethod
<span class="text-primary">def</span> <span class="text-accent">configurer_build_system</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>: <span class="text-primary">pass</span>
@abstractmethod
<span class="text-primary">def</span> <span class="text-accent">configurer_tests</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>: <span class="text-primary">pass</span>
@abstractmethod
<span class="text-primary">def</span> <span class="text-accent">configurer_deploiement</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>: <span class="text-primary">pass</span>
<span class="text-primary">def</span> <span class="text-accent">obtenir_projet</span>(<span class="text-white">self</span>) -> ProjetEspaceCodage:
<span class="text-primary">return</span> <span class="text-white">self</span>.projet
<span class="text-primary">def</span> <span class="text-accent">operation_optionnelle</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>: <span class="text-primary">pass</span>
<span class="text-accent">class</span> <span class="text-white">ConstructeurMinimal</span>(ConstructeurEspaceCodage):
<span class="text-primary">def</span> <span class="text-accent">configurer_documentation</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Documentation : README.md simple"</span>)
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Documentation minimale configurée"</span>)
<span class="text-primary">def</span> <span class="text-accent">configurer_editeur</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Code Editor : VS Code avec thème par défaut"</span>)
<span class="text-white">self</span>.projet.ajouter_configuration(<span class="text-warning">"editor.theme"</span>, <span class="text-warning">"default-dark"</span>)
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Éditeur de code configuré"</span>)
<span class="text-primary">def</span> <span class="text-accent">configurer_terminal_debugger</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Terminal intégré + debug minimal (print)"</span>)
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Terminal et debugger basique configurés"</span>)
<span class="text-primary">def</span> <span class="text-accent">configurer_build_system</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Build System : exécution directe du script"</span>)
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Système de build minimal configuré"</span>)
<span class="text-primary">def</span> <span class="text-accent">configurer_tests</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Tests : quelques tests manuels"</span>)
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Tests manuels configurés"</span>)
<span class="text-primary">def</span> <span class="text-accent">configurer_deploiement</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Déploiement : exécution locale seulement"</span>)
<span class="text-white">self</span>.projet.ajouter_configuration(<span class="text-warning">"deployment.target"</span>, <span class="text-warning">"local"</span>)
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Déploiement local configuré"</span>)
<span class="text-accent">class</span> <span class="text-white">ConstructeurFullStack</span>(ConstructeurEspaceCodage):
<span class="text-primary">def</span> <span class="text-accent">configurer_documentation</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Documentation : wiki, UML, API complète"</span>)
<span class="text-white">self</span>.projet.ajouter_configuration(<span class="text-warning">"docs.format"</span>, <span class="text-warning">"OpenAPI + Markdown"</span>)
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Documentation complète configurée"</span>)
<span class="text-primary">def</span> <span class="text-accent">configurer_editeur</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Code Editor : IDE complet + plugins"</span>)
<span class="text-white">self</span>.projet.ajouter_configuration(<span class="text-warning">"editor.plugins"</span>, <span class="text-warning">"lint, format, refactor, git, ..."</span>)
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Éditeur avancé configuré"</span>)
<span class="text-primary">def</span> <span class="text-accent">configurer_terminal_debugger</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Terminal multi‑onglets + debugger graphique"</span>)
<span class="text-white">self</span>.projet.ajouter_configuration(<span class="text-warning">"debugger.features"</span>, <span class="text-warning">"breakpoints, watch, stack, step-by-step"</span>)
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Terminal et debugger avancés configurés"</span>)
<span class="text-primary">def</span> <span class="text-accent">configurer_build_system</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Build System : pipeline CI/CD automatisé"</span>)
<span class="text-white">self</span>.projet.ajouter_configuration(<span class="text-warning">"build.pipeline"</span>, <span class="text-warning">"tests → build → packaging → deployment"</span>)
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Système de build avancé configuré"</span>)
<span class="text-primary">def</span> <span class="text-accent">configurer_tests</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Testing Framework : unitaires, intégration, e2e"</span>)
<span class="text-white">self</span>.projet.ajouter_configuration(<span class="text-warning">"testing.coverage"</span>, <span class="text-warning">">= 90%"</span>)
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Framework de tests complet configuré"</span>)
<span class="text-primary">def</span> <span class="text-accent">configurer_deploiement</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Déploiement : CI/CD vers staging/production (cloud)"</span>)
<span class="text-white">self</span>.projet.ajouter_configuration(<span class="text-warning">"deployment.providers"</span>, <span class="text-warning">"AWS, Docker, Kubernetes"</span>)
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Déploiement cloud configuré"</span>)
<span class="text-primary">def</span> <span class="text-accent">operation_optionnelle</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Analyse statique + métriques + revues automatisées"</span>)
<span class="text-white">self</span>.projet.ajouter_configuration(<span class="text-warning">"quality.metrics"</span>, <span class="text-warning">"complexité, dette technique, vulnérabilités"</span>)
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Analyses avancées configurées (optionnel)"</span>)
<span class="text-accent">class</span> <span class="text-white">DirecteurEspaceCodage</span>:
<span class="text-slate-400">"""Le Directeur orchestre les étapes de construction."""</span>
<span class="text-primary">def</span> <span class="text-accent">__init__</span>(<span class="text-white">self</span>, <span class="text-white">builder</span>: ConstructeurEspaceCodage) -> <span class="text-primary">None</span>:
<span class="text-white">self</span>._builder = builder
<span class="text-primary">def</span> <span class="text-accent">construire_espace_codage</span>(<span class="text-white">self</span>) -> ProjetEspaceCodage:
<span class="text-white">self</span>._builder.configurer_documentation()
<span class="text-white">self</span>._builder.configurer_editeur()
<span class="text-white">self</span>._builder.configurer_terminal_debugger()
<span class="text-white">self</span>._builder.configurer_build_system()
<span class="text-white">self</span>._builder.configurer_tests()
<span class="text-white">self</span>._builder.configurer_deploiement()
<span class="text-white">self</span>._builder.operation_optionnelle()
<span class="text-primary">return</span> <span class="text-white">self</span>._builder.obtenir_projet()
<span class="text-primary">if</span> __name__ == <span class="text-warning">"__main__"</span>:
<span class="text-primary">print</span>(<span class="text-warning">"=== ESPACE CODAGE · PROJET MINIMAL ==="</span>)
directeur = DirecteurEspaceCodage(ConstructeurMinimal(<span class="text-warning">"Script Python Simple"</span>))
projet_min = directeur.construire_espace_codage()
projet_min.decrire()
<span class="text-primary">print</span>(<span class="text-warning">"</span><span class="text-warning">=== ESPACE CODAGE · PROJET FULL‑STACK ==="</span>)
directeur = DirecteurEspaceCodage(ConstructeurFullStack(<span class="text-warning">"Application Web Avancée"</span>))
projet_full = directeur.construire_espace_codage()
projet_full.decrire()
</code></pre>
</div>
<!-- Démonstration Builder -->
<div class="mt-5 rounded-xl border border-border bg-slate-900/40 p-4">
<div class="flex items-center justify-between">
<h3 class="text-xs uppercase tracking-[0.2em] text-accent">Démonstration du Builder Pattern</h3>
<div class="text-[10px] uppercase tracking-[0.2em] text-slate-500">DEMO</div>
</div>
<div class="mt-3 flex flex-wrap gap-2">
<button class="btn-primary" id="btn-minimal">Construire Projet Minimal</button>
<button class="btn-secondary" id="btn-fullstack">Construire Projet Full‑Stack</button>
<button class="btn-ghost" id="btn-reset">Réinitialiser</button>
</div>
<div id="demoOutput" class="mt-4 rounded-lg border border-border bg-black/40 p-3 font-mono text-[12px] leading-5 max-h-56 overflow-auto text-accent">
<div>Prêt à construire un espace de codage…</div>
</div>
</div>
<div class="mt-4 text-xs text-slate-400">
<strong class="text-white">Note :</strong> Le <strong>modèle Constructeur</strong> se concentre sur un seul
<em>objet complexe</em> (ProjetEspaceCodage) construit étape par étape. Une
<strong>Abstract Factory</strong> fournirait plusieurs familles d’objets (éditeur, terminal, debugger, …)
sans orchestrer le processus de construction comme le fait le <code>DirecteurEspaceCodage</code>.
</div>
</section>
</div>
</main>
<!-- Tooltip flottant -->
<div id="nodeTooltip" class="hidden absolute z-50 max-w-[240px] rounded-lg border border-primary/40 bg-slate-900/95 px-3 py-2 text-[11px] leading-5 shadow-xl backdrop-blur">
<div class="text-primary font-semibold" id="nodeTitle"></div>
<div class="text-slate-300" id="nodeDesc"></div>
</div>
<script>
// Animation helpers
const animateItems = document.querySelectorAll('[data-animate]');
animateItems.forEach(el => {
el.style.opacity = '0';
el.style.transform = 'translateY(10px)';
setTimeout(() => {
el.style.transition = 'all .6s cubic-bezier(.2,.7,.2,1)';
el.style.opacity = '1';
el.style.transform = 'translateY(0)';
}, 120);
});
// Node definitions and info
const nodeInfo = {
documentation: {
title: 'Documentation',
desc: 'Système de documentation intégré avec recherche et exemples (wiki, API, UML).'
},
editor: {
title: 'Code Editor',
desc: 'Éditeur de code avec coloration syntaxique, auto-complétion, refactorisations.'
},
terminal: {
title: 'Terminal',
desc: 'Terminal intégré multi‑onglets avec support de plusieurs shells et historique.'
},
debugger: {
title: 'Debugger',
desc: 'Debugger graphique avec breakpoints, inspection, watch, step‑by‑step.'
},
version: {
title: 'Version Control',
desc: 'Contrôle de version (Git) avec interface graphique, branches et historial.'
},
testing: {
title: 'Testing Framework',
desc: 'Tests unitaires, d’intégration et end‑to‑end. Couverture de code et rapports.'
},
build: {
title: 'Build System',
desc: 'Pipeline de build et CI/CD : compilation, packaging et déploiement automatisés.'
},
deploy: {
title: 'Deployment',
desc: 'Déploiement vers staging/production (cloud), rollback et monitoring.'
},
};
// Connections for arrows (visual only)
const connections = [
{ from: 'documentation', to: 'editor', label: 'docs' },
{ from: 'editor', to: 'terminal', label: 'exec' },
{ from: 'editor', to: 'debugger', label: 'debug' },
{ from: 'editor', to: 'build', label: 'build' },
{ from: 'version', to: 'editor', label: 'vcs' },
{ from: 'terminal', to: 'testing', label: 'test' },
{ from: 'debugger', to: 'testing', label: 'verify' },
{ from: 'testing', to: 'deploy', label: 'deploy' },
{ from: 'build', to: 'deploy', label: 'package' },
{ from: 'deploy', to: 'version', label: 'release' },
];
// Build arrows
function drawArrows() {
const svg = document.getElementById('arrowLayer');
if (!svg) return;
svg.innerHTML = '';
const root = document.getElementById('schemaRoot');
const rootRect = root.getBoundingClientRect();
function centerOf(id) {
const el = root.querySelector(`[data-id="${id}"]`);
if (!el) return { x: 0, y: 0 };
const r = el.getBoundingClientRect();
return {
x: r.left - rootRect.left + r.width / 2,
y: r.top - rootRect.top + r.height / 2
};
}
connections.forEach((c, idx) => {
const from = centerOf(c.from);
const to = centerOf(c.to);
// Curved path
const dx = to.x - from.x;
const dy = to.y - from.y;
const dist = Math.hypot(dx, dy);
const curve = Math.min(80, Math.max(30, dist * 0.25));
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
const d = `M ${from.x} ${from.y}
C ${from.x + curve} ${from.y}
${to.x - curve} ${to.y}
${to.x} ${to.y}`;
path.setAttribute('d', d);
path.setAttribute('fill', 'none');
path.setAttribute('stroke', 'rgba(148,163,184,0.55)');
path.setAttribute('stroke-width', '1.25');
path.setAttribute('marker-end', 'url(#arrowHead)');
svg.appendChild(path);
});
// Marker
let defs = svg.querySelector('defs');
if (!defs) {
defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
svg.appendChild(defs);
}
let marker = svg.querySelector('#arrowHead');
if (!marker) {
marker = document.createElementNS('http://www.w3.org/2000/svg', 'marker');
marker.setAttribute('id', 'arrowHead');
marker.setAttribute('viewBox', '0 0 10 10');
marker.setAttribute('refX', '8');
marker.setAttribute('refY', '5');
marker.setAttribute('markerWidth', '6');
marker.setAttribute('markerHeight', '6');
marker.setAttribute('orient', 'auto-start-reverse');
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.setAttribute('d', 'M 0 0 L 10 5 L 0 10 z');
path.setAttribute('fill', 'rgba(148,163,184,0.9)');
marker.appendChild(path);
defs.appendChild(marker);
}
}
// Node interactions + tooltip
function setupNodes() {
const tooltip = document.getElementById('nodeTooltip');
const title = document.getElementById('nodeTitle');
const desc = document.getElementById('nodeDesc');
document.querySelectorAll('.node-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
const id = btn.dataset.id;
const info = nodeInfo[id];
if (!info) return;
// Visual pulse
btn.classList.add('ring-2', 'ring-primary/60');
setTimeout(() => btn.classList.remove('ring-2', 'ring-primary/60'), 600);
// Tooltip content
title.textContent = info.title;
desc.textContent = info.desc;
tooltip.classList.remove('hidden');
// Position near button
const r = btn.getBoundingClientRect();
tooltip.style.left = `${Math.min(window.innerWidth - 260, r.right + 10)}px`;
tooltip.style.top = `${r.top + window.scrollY}px`;
setTimeout(() => tooltip.classList.add('hidden'), 2800);
});
});
document.addEventListener('click', (e) => {
if (!e.target.closest('.node-btn')) {
tooltip.classList.add('hidden');
}
});
}
// Builder demo logic
function setupBuilderDemo() {
const output = document.getElementById('demoOutput');
const btnMinimal = document.getElementById('btn-minimal');
const btnFullstack = document.getElementById('btn-fullstack');
const btnReset = document.getElementById('btn-reset');
function clearOutput() {
output.innerHTML = '<div>Prêt à construire un espace de codage…</div>';
}
function addLine(text, kind = 'info') {
const line = document.createElement('div');
line.className = 'mb-1';
if (kind === 'ok') line.classList.add('text-success');
if (kind === 'warn') line.classList.add('text-warning');
line.textContent = text;
output.appendChild(line);
output.scrollTop = output.scrollHeight;
}
function highlightNode(id) {
const node = document.querySelector(`[data-id="${id}"]`);
if (!node) return;
node.classList.add('ring-2', 'ring-accent/70');
setTimeout(() => node.classList.remove('ring-2', 'ring-accent/70'), 900);
}
const minimalSteps = [
{ id: 'documentation', msg: 'Configuration de la documentation simple (README).' },
{ id: 'editor', msg: 'Configuration de l’éditeur VS Code (thème par défaut).' },
{ id: 'terminal', msg: 'Configuration du terminal intégré et du debug minimal.' },
{ id: 'build', msg: 'Configuration du système de build minimal (exécution directe).' },
{ id: 'testing', msg: 'Configuration des tests manuels.' },
{ id: 'deploy', msg: 'Configuration du déploiement local.' },
];
const fullstackSteps = [
{ id: 'documentation', msg: 'Configuration de la documentation complète (wiki, UML, API).' },
{ id: 'editor', msg: 'Configuration de l’IDE avancé et des plugins.' },
{ id: 'terminal', msg: 'Configuration du terminal multi‑onglets et debugger graphique.' },
{ id: 'build', msg: 'Configuration du pipeline CI/CD automatisé.' },
{ id: 'testing', msg: 'Configuration du framework de tests complet (unitaires, intégration, e2e).' },
{ id: 'deploy', msg: 'Configuration du déploiement cloud (AWS, Docker, Kubernetes).' },
];
function runDemo(type) {
clearOutput();
const steps = type === 'minimal' ? minimalSteps : fullstackSteps;
let delay = 0;
steps.forEach((s, i) => {
setTimeout(() => {
addLine(`→ ${s.msg}`);
highlightNode(s.id);
}, delay);
delay += 650;
});
// Completion
setTimeout(() => {
addLine('✅ Projet ' + (type === 'minimal' ? 'minimal' : 'full‑stack') + ' construit avec succès.', 'ok');
}, delay + 200);
}
btnMinimal.addEventListener('click', () => runDemo('minimal'));
btnFullstack.addEventListener('click', () => runDemo('fullstack'));
btnReset.addEventListener('click', () => clearOutput());
}
// Initial draw
window.addEventListener('load', () => {
drawArrows();
setupNodes();
setupBuilderDemo();
});
window.addEventListener('resize', () => {
// Throttle redraw
clearTimeout(window.__arrowTimer);
window.__arrowTimer = setTimeout(drawArrows, 120);
});
</script>
<!-- Tailwind utilities via @apply -->
<style type="text/tailwindcss">
@layer utilities {
.animate-spin-slow {
animation: spin 8s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.node-btn {
@apply inline-flex items-center justify-center px-4 py-2 text-[11px] tracking-[0.18em] uppercase rounded-full border border-border bg-slate-900/60 hover:bg-slate-800/70 transition;
}
.node-main {
@apply border-primary/70 bg-gradient-to-br from-primary/15 to-accent/10 text-white;
}
.btn-primary {
@apply inline-flex items-center gap-2 px-4 py-2 rounded-full border border-primary/60 bg-primary/15 hover:bg-primary/25 text-primary transition;
}
.btn-secondary {
@apply inline-flex items-center gap-2 px-4 py-2 rounded-full border border-secondary/60 bg-secondary/15 hover:bg-secondary/25 text-secondary transition;
}
.btn-ghost {
@apply inline-flex items-center gap-2 px-4 py-2 rounded-full border border-border bg-transparent hover:bg-slate-800/50 text-slate-300 transition;
}
.badge {
@apply text-[10px] uppercase tracking-[0.18em] rounded-full border border-border px-2 py-0.5 text-slate-300;
}
}
</style>
<script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
</body>
</html>