import { useState } from "react";
const patterns = [
{
id: 1, category: "Créationnel", name: "Singleton",
role: "Une seule instance, accessible globalement.",
code: `public class DatabaseConnection {
private static DatabaseConnection instance;
private DatabaseConnection() {
// constructeur privé
}
public static DatabaseConnection getInstance() {
if (instance == null) {
instance = new DatabaseConnection();
}
return instance;
}
public void query(String sql) {
[Link]("Exécution : " + sql);
}
}
// Utilisation
DatabaseConnection db = [Link]();
[Link]("SELECT * FROM clients");`
},
{
id: 2, category: "Créationnel", name: "Factory Method",
role: "Sous-classe décide quel objet créer.",
code: `// Interface commune
interface Vehicule {
void conduire();
}
class Voiture implements Vehicule {
public void conduire() { [Link](" Conduite voiture"); }
}
class Velo implements Vehicule {
public void conduire() { [Link](" Conduite vélo"); }
}
// Factory abstraite
abstract class Transport {
public abstract Vehicule creerVehicule();
public void utiliser() {
Vehicule v = creerVehicule();
[Link]();
}
}
class TransportVoiture extends Transport {
public Vehicule creerVehicule() { return new Voiture(); }
}
class TransportVelo extends Transport {
public Vehicule creerVehicule() { return new Velo(); }
}
// Utilisation
Transport t = new TransportVoiture();
[Link](); // Conduite voiture`
},
{
id: 3, category: "Créationnel", name: "Abstract Factory",
role: "Crée des familles d'objets compatibles.",
code: `interface Bouton { void afficher(); }
interface Checkbox { void cocher(); }
// Famille Sombre
class BoutonSombre implements Bouton {
public void afficher() { [Link](" Bouton sombre"); }
}
class CheckboxSombre implements Checkbox {
public void cocher() { [Link](" Checkbox sombre"); }
}
// Factory abstraite
interface ThemeFactory {
Bouton creerBouton();
Checkbox creerCheckbox();
}
class ThemeSombreFactory implements ThemeFactory {
public Bouton creerBouton() { return new BoutonSombre(); }
public Checkbox creerCheckbox() { return new CheckboxSombre(); }
}
// Utilisation
ThemeFactory factory = new ThemeSombreFactory();
Bouton btn = [Link]();
[Link](); // Bouton sombre`
},
{
id: 4, category: "Créationnel", name: "Builder",
role: "Construit un objet complexe étape par étape.",
code: `class Burger {
private String pain, viande, sauce;
private boolean fromage;
private Burger() {}
public static class Builder {
private Burger burger = new Burger();
public Builder pain(String pain) {
[Link] = pain; return this;
}
public Builder viande(String viande) {
[Link] = viande; return this;
}
public Builder sauce(String sauce) {
[Link] = sauce; return this;
}
public Builder avecFromage() {
[Link] = true; return this;
}
public Burger build() { return burger; }
}
public String toString() {
return pain + " + " + viande + " + " + sauce
+ (fromage ? " + fromage" : "");
}
}
// Utilisation
Burger b = new [Link]()
.pain("Brioche")
.viande("Bœuf")
.sauce("BBQ")
.avecFromage()
.build();
[Link](b); // Brioche + Bœuf + BBQ + fromage`
},
{
id: 5, category: "Créationnel", name: "Prototype",
role: "Clone un objet existant.",
code: `class Ennemi implements Cloneable {
private String nom;
private int vie;
private String arme;
public Ennemi(String nom, int vie, String arme) {
[Link] = nom;
[Link] = vie;
[Link] = arme;
}
@Override
public Ennemi clone() {
try {
return (Ennemi) [Link]();
} catch (CloneNotSupportedException e) {
return null;
}
}
public String toString() {
return nom + " | vie=" + vie + " | arme=" + arme;
}
}
// Utilisation
Ennemi original = new Ennemi("Gobelin", 100, "Épée");
Ennemi copie = [Link]();
[Link](copie); // Gobelin | vie=100 | arme=Épée`
},
{
id: 6, category: "Structurel", name: "Adapter",
role: "Fait collaborer deux interfaces incompatibles.",
code: `// Interface attendue par notre code
interface PriseEuropeenne {
void brancher220V();
}
// Classe externe incompatible
class PriseAmericaine {
public void brancher110V() {
[Link](" Branché en 110V");
}
}
// Adaptateur
class AdaptateurPrise implements PriseEuropeenne {
private PriseAmericaine priseUS;
public AdaptateurPrise(PriseAmericaine prise) {
[Link] = prise;
}
@Override
public void brancher220V() {
[Link](" Conversion 220V → 110V");
priseUS.brancher110V();
}
}
// Utilisation
PriseEuropeenne prise = new AdaptateurPrise(new PriseAmericaine());
prise.brancher220V();
// Conversion 220V → 110V
// Branché en 110V`
},
{
id: 7, category: "Structurel", name: "Bridge",
role: "Sépare abstraction et implémentation.",
code: `// Implémentation
interface Appareil {
void allumer();
void eteindre();
}
class TV implements Appareil {
public void allumer() { [Link](" TV allumée"); }
public void eteindre() { [Link](" TV éteinte"); }
}
// Abstraction
abstract class Telecommande {
protected Appareil appareil;
public Telecommande(Appareil a) { [Link] = a; }
public abstract void boutonPower();
}
class TelecommandeSimple extends Telecommande {
public TelecommandeSimple(Appareil a) { super(a); }
public void boutonPower() {
[Link]("Appui sur POWER...");
[Link]();
}
}
// Utilisation
Telecommande t = new TelecommandeSimple(new TV());
[Link](); // Appui sur POWER... / TV allumée`
},
{
id: 8, category: "Structurel", name: "Composite",
role: "Traite un objet et un groupe de la même façon.",
code: `interface Composant {
void afficher(String indent);
}
class Fichier implements Composant {
private String nom;
public Fichier(String nom) { [Link] = nom; }
public void afficher(String indent) {
[Link](indent + " " + nom);
}
}
class Dossier implements Composant {
private String nom;
private List<Composant> enfants = new ArrayList<>();
public Dossier(String nom) { [Link] = nom; }
public void ajouter(Composant c) { [Link](c); }
public void afficher(String indent) {
[Link](indent + " " + nom);
for (Composant c : enfants)
[Link](indent + " ");
}
}
// Utilisation
Dossier racine = new Dossier("Projets");
[Link](new Fichier("[Link]"));
Dossier src = new Dossier("src");
[Link](new Fichier("[Link]"));
[Link](src);
[Link]("");
// Projets
// [Link]
// src
// [Link]`
},
{
id: 9, category: "Structurel", name: "Decorator",
role: "Ajoute des fonctionnalités dynamiquement.",
code: `interface Cafe {
String getDescription();
double getPrix();
}
class CafeSimple implements Cafe {
public String getDescription() { return "Café"; }
public double getPrix() { return 1.0; }
}
// Décorateur de base
abstract class DecoratorCafe implements Cafe {
protected Cafe cafe;
public DecoratorCafe(Cafe c) { [Link] = c; }
}
class AvecLait extends DecoratorCafe {
public AvecLait(Cafe c) { super(c); }
public String getDescription() { return [Link]() + " + Lait"; }
public double getPrix() { return [Link]() + 0.3; }
}
class AvecSucre extends DecoratorCafe {
public AvecSucre(Cafe c) { super(c); }
public String getDescription() { return [Link]() + " + Sucre"; }
public double getPrix() { return [Link]() + 0.1; }
}
// Utilisation
Cafe commande = new AvecSucre(new AvecLait(new CafeSimple()));
[Link]([Link]()); // Café + Lait + Sucre
[Link]([Link]()); // 1.4`
},
{
id: 10, category: "Structurel", name: "Facade",
role: "Interface simplifiée pour un système complexe.",
code: `// Sous-systèmes complexes
class Batterie {
public void verifier() { [Link](" Batterie OK"); }
}
class Moteur {
public void demarrer() { [Link](" Moteur démarré"); }
}
class Injection {
public void activer() { [Link](" Injection activée"); }
}
// Façade
class Voiture {
private Batterie batterie = new Batterie();
private Moteur moteur = new Moteur();
private Injection injection = new Injection();
public void demarrer() {
[Link](" Démarrage...");
[Link]();
[Link]();
[Link]();
[Link](" Prêt à rouler !");
}
}
// Utilisation — l'utilisateur n'a qu'un bouton
Voiture voiture = new Voiture();
[Link]();`
},
{
id: 11, category: "Structurel", name: "Flyweight",
role: "Partage les données communes pour économiser la mémoire.",
code: `// Données PARTAGÉES (intrinsèques)
class TypeArbre {
private String texture;
private String couleur;
public TypeArbre(String texture, String couleur) {
[Link] = texture;
[Link] = couleur;
}
public void afficher(int x, int y) {
[Link](" " + couleur + " à (" + x + "," + y + ")");
}
}
// Factory Flyweight
class TypeArbreFactory {
private static Map<String, TypeArbre> cache = new HashMap<>();
public static TypeArbre obtenir(String texture, String couleur) {
String cle = texture + couleur;
[Link](cle, new TypeArbre(texture, couleur));
return [Link](cle);
}
}
// Objet avec données UNIQUES (extrinsèques)
class Arbre {
private int x, y;
private TypeArbre type;
public Arbre(int x, int y, String texture, String couleur) {
this.x = x; this.y = y;
[Link] = [Link](texture, couleur);
}
public void afficher() { [Link](x, y); }
}
// 1000 arbres, mais seulement quelques TypeArbre en mémoire`
},
{
id: 12, category: "Structurel", name: "Proxy",
role: "Contrôle l'accès à un objet via un intermédiaire.",
code: `interface Image {
void afficher();
}
// Objet réel (lourd à charger)
class ImageHaute implements Image {
private String fichier;
public ImageHaute(String fichier) {
[Link] = fichier;
charger(); // long !
}
private void charger() {
[Link](" Chargement de " + fichier);
}
public void afficher() {
[Link](" Affichage de " + fichier);
}
}
// Proxy (chargement paresseux)
class ProxyImage implements Image {
private String fichier;
private ImageHaute imageReelle;
public ProxyImage(String fichier) { [Link] = fichier; }
public void afficher() {
if (imageReelle == null) {
imageReelle = new ImageHaute(fichier); // chargé seulement ici
}
[Link]();
}
}
// Utilisation
Image img = new ProxyImage("[Link]"); // pas encore chargé
[Link](); // chargé puis affiché`
},
{
id: 13, category: "Comportemental", name: "Chain of Responsibility",
role: "Passe une requête le long d'une chaîne de handlers.",
code: `abstract class SupportHandler {
protected SupportHandler suivant;
public void setSuivant(SupportHandler s) { [Link] = s; }
public abstract void traiter(int niveau);
}
class NiveauUn extends SupportHandler {
public void traiter(int niveau) {
if (niveau == 1) [Link](" Niveau 1 traite");
else if (suivant != null) [Link](niveau);
}
}
class NiveauDeux extends SupportHandler {
public void traiter(int niveau) {
if (niveau == 2) [Link](" Niveau 2 traite");
else if (suivant != null) [Link](niveau);
}
}
class Manager extends SupportHandler {
public void traiter(int niveau) {
[Link](" Manager traite le niveau " + niveau);
}
}
// Utilisation
NiveauUn n1 = new NiveauUn();
NiveauDeux n2 = new NiveauDeux();
Manager mgr = new Manager();
[Link](n2);
[Link](mgr);
[Link](3); // Manager traite le niveau 3`
},
{
id: 14, category: "Comportemental", name: "Command",
role: "Encapsule une action dans un objet (undo/redo).",
code: `interface Command {
void execute();
void undo();
}
class TextEditor {
private StringBuilder texte = new StringBuilder();
public void ecrire(String mot) { [Link](mot); }
public void effacer(int nb) {
int len = [Link]();
[Link](len - nb, len);
}
public String getTexte() { return [Link](); }
}
class EcrireCommand implements Command {
private TextEditor editor;
private String mot;
public EcrireCommand(TextEditor e, String mot) {
[Link] = e; [Link] = mot;
}
public void execute() { [Link](mot); }
public void undo() { [Link]([Link]()); }
}
// Utilisation
TextEditor editor = new TextEditor();
Command cmd = new EcrireCommand(editor, "Bonjour");
[Link]();
[Link]([Link]()); // Bonjour
[Link]();
[Link]([Link]()); // (vide)`
},
{
id: 15, category: "Comportemental", name: "Iterator",
role: "Parcourt une collection sans exposer sa structure.",
code: `// En Java, l'Iterator est natif via Iterable<T>
class Panier implements Iterable<String> {
private List<String> articles = new ArrayList<>();
public void ajouter(String article) {
[Link](article);
}
@Override
public Iterator<String> iterator() {
return [Link]();
}
}
// Utilisation
Panier panier = new Panier();
[Link]("Robe 3 ans");
[Link]("Pantalon 5 ans");
[Link]("Veste 2 ans");
// Le for-each utilise l'Iterator en coulisse
for (String article : panier) {
[Link](" " + article);
}
// Robe 3 ans
// Pantalon 5 ans
// Veste 2 ans`
},
{
id: 16, category: "Comportemental", name: "Mediator",
role: "Centralise les communications entre objets.",
code: `// Médiateur
interface TourControle {
void autoriser(String avion, String action);
}
class TourDeControle implements TourControle {
public void autoriser(String avion, String action) {
[Link](" Tour → " + avion + " : " + action);
}
}
// Collègues
class Avion {
private String nom;
private TourControle tour;
public Avion(String nom, TourControle tour) {
[Link] = nom; [Link] = tour;
}
public void demanderAtterrissage() {
[Link](" " + nom + " demande à atterrir");
[Link](nom, "Autorisé piste 02");
}
public void demanderDecollage() {
[Link](" " + nom + " demande à décoller");
[Link](nom, "Autorisé décollage");
}
}
// Utilisation — les avions ne se parlent PAS entre eux
TourControle tour = new TourDeControle();
new Avion("AF123", tour).demanderAtterrissage();
new Avion("SN456", tour).demanderDecollage();`
},
{
id: 17, category: "Comportemental", name: "Memento",
role: "Sauvegarde et restaure l'état d'un objet.",
code: `// Memento — snapshot de l'état
class Memento {
private final int vie;
private final int niveau;
public Memento(int vie, int niveau) {
[Link] = vie; [Link] = niveau;
}
public int getVie() { return vie; }
public int getNiveau() { return niveau; }
}
// Objet dont on sauvegarde l'état
class Joueur {
private int vie = 100;
private int niveau = 1;
public void progresser() { niveau++; vie -= 30; }
public Memento sauvegarder() {
return new Memento(vie, niveau);
}
public void restaurer(Memento m) {
[Link] = [Link]();
[Link] = [Link]();
}
public String toString() {
return "Vie=" + vie + " Niveau=" + niveau;
}
}
// Utilisation
Joueur joueur = new Joueur();
Memento save = [Link](); // Sauvegarde
[Link]();
[Link](joueur); // Vie=70 Niveau=2
[Link](save);
[Link](joueur); // Vie=100 Niveau=1`
},
{
id: 18, category: "Comportemental", name: "Observer",
role: "Notifie automatiquement les abonnés d'un changement.",
code: `import [Link].*;
interface Observateur {
void notifier(String video);
}
class Chaine {
private List<Observateur> abonnes = new ArrayList<>();
public void abonner(Observateur o) { [Link](o); }
public void desabonner(Observateur o){ [Link](o); }
public void publierVideo(String titre) {
[Link](" Nouvelle vidéo : " + titre);
for (Observateur o : abonnes)
[Link](titre);
}
}
class Abonne implements Observateur {
private String nom;
public Abonne(String nom) { [Link] = nom; }
public void notifier(String video) {
[Link](" " + nom + " a reçu : " + video);
}
}
// Utilisation
Chaine chaine = new Chaine();
[Link](new Abonne("Alice"));
[Link](new Abonne("Bob"));
[Link]("Design Patterns en Java");
// Alice a reçu : Design Patterns en Java
// Bob a reçu : Design Patterns en Java`
},
{
id: 19, category: "Comportemental", name: "State",
role: "Change le comportement selon l'état interne.",
code: `interface EtatDistributeur {
void insererArgent();
void distribuer();
}
class SansArgent implements EtatDistributeur {
public void insererArgent() { [Link](" Argent inséré"); }
public void distribuer() { [Link](" Insérez de l'argent d'abord"); }
}
class AvecArgent implements EtatDistributeur {
public void insererArgent() { [Link](" Argent déjà inséré"); }
public void distribuer() { [Link](" Produit distribué !"); }
}
class Distributeur {
private EtatDistributeur etat;
public Distributeur() { [Link] = new SansArgent(); }
public void setEtat(EtatDistributeur e) { [Link] = e; }
public void insererArgent() {
[Link]();
setEtat(new AvecArgent()); // transition
}
public void distribuer() {
[Link]();
setEtat(new SansArgent()); // transition
}
}
// Utilisation
Distributeur d = new Distributeur();
[Link](); // Insérez de l'argent d'abord
[Link](); // Argent inséré
[Link](); // Produit distribué !`
},
{
id: 20, category: "Comportemental", name: "Strategy",
role: "Algorithmes interchangeables à la volée.",
code: `// Stratégies de paiement
interface Paiement {
void payer(double montant);
}
class PayPal implements Paiement {
public void payer(double montant) {
[Link](" PayPal : " + montant + " €");
}
}
class CarteBancaire implements Paiement {
public void payer(double montant) {
[Link](" Carte : " + montant + " €");
}
}
class Bitcoin implements Paiement {
public void payer(double montant) {
[Link]("₿ Bitcoin : " + montant + " €");
}
}
// Contexte
class Panier {
private Paiement strategie;
public void setStrategie(Paiement p) { [Link] = p; }
public void commander(double total) {
[Link](" Commande de " + total + " €");
[Link](total);
}
}
// Utilisation
Panier panier = new Panier();
[Link](new PayPal());
[Link](49.99); // PayPal : 49.99 €
[Link](new Bitcoin());
[Link](49.99); // ₿ Bitcoin : 49.99 €`
},
{
id: 21, category: "Comportemental", name: "Template Method",
role: "Squelette de l'algorithme défini dans la classe mère.",
code: `abstract class BoissonChaude {
// Template Method — squelette fixe
public final void preparer() {
chauffer();
infuser(); // étape variable
verser();
ajouter(); // étape optionnelle
}
private void chauffer() { [Link](" Eau chauffée"); }
private void verser() { [Link](" Versé dans la tasse"); }
protected abstract void infuser();
protected abstract void ajouter();
}
class The extends BoissonChaude {
protected void infuser() { [Link](" Infusion du thé"); }
protected void ajouter() { [Link](" Ajout de citron"); }
}
class Cafe extends BoissonChaude {
protected void infuser() { [Link](" Filtrage du café"); }
protected void ajouter() { [Link](" Ajout de lait"); }
}
// Utilisation
new The().preparer();
// Eau chauffée / Infusion du thé / Versé / Citron`
},
{
id: 22, category: "Comportemental", name: "Visitor",
role: "Ajoute des opérations sans modifier les classes.",
code: `// Visiteur
interface VisiteurTaxe {
void visiter(Livre livre);
void visiter(Electronique elec);
}
interface Produit {
void accepter(VisiteurTaxe v);
}
class Livre implements Produit {
public double prix;
public Livre(double p) { [Link] = p; }
public void accepter(VisiteurTaxe v) { [Link](this); }
}
class Electronique implements Produit {
public double prix;
public Electronique(double p) { [Link] = p; }
public void accepter(VisiteurTaxe v) { [Link](this); }
}
// Implémentation du visiteur (nouvelle opération)
class CalculateurTaxe implements VisiteurTaxe {
public void visiter(Livre l) {
[Link](" Taxe livre : " + [Link] * 0.05 + " €");
}
public void visiter(Electronique e) {
[Link](" Taxe élec : " + [Link] * 0.20 + " €");
}
}
// Utilisation
List<Produit> produits = [Link](new Livre(20), new Electronique(100));
VisiteurTaxe taxe = new CalculateurTaxe();
[Link](p -> [Link](taxe));`
},
{
id: 23, category: "Comportemental", name: "Interpreter",
role: "Interprète un langage ou des expressions.",
code: `// Interpréteur d'expressions booléennes simples
interface Expression {
boolean interpreter(Map<String, Boolean> contexte);
}
class Variable implements Expression {
private String nom;
public Variable(String nom) { [Link] = nom; }
public boolean interpreter(Map<String, Boolean> ctx) {
return [Link](nom, false);
}
}
class Et implements Expression {
private Expression gauche, droite;
public Et(Expression g, Expression d) {
gauche = g; droite = d;
}
public boolean interpreter(Map<String, Boolean> ctx) {
return [Link](ctx) && [Link](ctx);
}
}
class Ou implements Expression {
private Expression gauche, droite;
public Ou(Expression g, Expression d) {
gauche = g; droite = d;
}
public boolean interpreter(Map<String, Boolean> ctx) {
return [Link](ctx) || [Link](ctx);
}
}
// Expression : estMajeur ET (aCompte OU aParent)
Expression expr = new Et(
new Variable("estMajeur"),
new Ou(new Variable("aCompte"), new Variable("aParent"))
);
Map<String, Boolean> ctx = [Link](
"estMajeur", true, "aCompte", false, "aParent", true
);
[Link]([Link](ctx)); // true`
}
];
const categoryColors = {
"Créationnel": { bg: "#0f2a1a", accent: "#22c55e", border: "#16a34a", badge: "#14532d" }
"Structurel": { bg: "#0f1f3a", accent: "#60a5fa", border: "#2563eb", badge: "#1e3a5f" }
"Comportemental": { bg: "#2a0f2a", accent: "#c084fc", border: "#9333ea", badge: "#4a1065" }
};
export default function DesignPatterns() {
const [selected, setSelected] = useState(patterns[0]);
const [filter, setFilter] = useState("Tous");
const categories = ["Tous", "Créationnel", "Structurel", "Comportemental"];
const filtered = filter === "Tous" ? patterns : [Link](p => [Link] === filter)
const colors = categoryColors[[Link]];
return (
<div style={{
fontFamily: "'JetBrains Mono', 'Fira Code', monospace",
background: "#080b12",
minHeight: "100vh",
color: "#e2e8f0",
display: "flex",
flexDirection: "column",
}}>
{/* Header */}
<div style={{
padding: "24px 32px 16px",
borderBottom: "1px solid #1e293b",
background: "linear-gradient(180deg, #0d1117 0%, #080b12 100%)",
}}>
<div style={{ display: "flex", alignItems: "baseline", gap: 12 }}>
<span style={{ fontSize: 11, color: "#475569", letterSpacing: 3, textTransform: "up
<h1 style={{ margin: 0, fontSize: 22, fontWeight: 700, color: "#f8fafc", letterSpac
23 Design Patterns
</h1>
<span style={{ fontSize: 11, color: "#475569", letterSpacing: 2, textTransform: "up
</div>
{/* Filter tabs */}
<div style={{ display: "flex", gap: 8, marginTop: 16 }}>
{[Link](cat => {
const isActive = filter === cat;
const c = cat === "Tous" ? null : categoryColors[cat];
return (
<button key={cat} onClick={() => setFilter(cat)} style={{
padding: "5px 14px",
borderRadius: 20,
border: isActive
? `1px solid ${c ? [Link] : "#64748b"}`
: "1px solid #1e293b",
background: isActive
? (c ? [Link] : "#1e293b")
: "transparent",
color: isActive ? (c ? [Link] : "#94a3b8") : "#475569",
fontSize: 11,
cursor: "pointer",
letterSpacing: 0.5,
fontFamily: "inherit",
transition: "all 0.15s",
}}>
{cat}
</button>
);
})}
</div>
</div>
<div style={{ display: "flex", flex: 1, overflow: "hidden", minHeight: 0 }}>
{/* Sidebar */}
<div style={{
width: 220,
borderRight: "1px solid #1e293b",
overflowY: "auto",
flexShrink: 0,
padding: "8px 0",
}}>
{[Link](p => {
const isActive = [Link] === [Link];
const c = categoryColors[[Link]];
return (
<div key={[Link]} onClick={() => setSelected(p)} style={{
display: "flex",
alignItems: "center",
gap: 10,
padding: "9px 16px",
cursor: "pointer",
background: isActive ? [Link] : "transparent",
borderLeft: isActive ? `3px solid ${[Link]}` : "3px solid transparent",
transition: "all 0.12s",
}}>
<span style={{
fontSize: 10,
color: isActive ? [Link] : "#334155",
fontWeight: 700,
minWidth: 20,
}}>
{String([Link]).padStart(2, "0")}
</span>
<span style={{
fontSize: 12,
color: isActive ? "#f1f5f9" : "#64748b",
fontWeight: isActive ? 600 : 400,
}}>
{[Link]}
</span>
</div>
);
})}
</div>
{/* Main panel */}
<div style={{ flex: 1, overflowY: "auto", padding: "24px 28px" }}>
{/* Pattern header */}
<div style={{
display: "flex",
alignItems: "flex-start",
justifyContent: "space-between",
marginBottom: 20,
gap: 12,
}}>
<div>
<div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 6 }
<span style={{
fontSize: 10,
padding: "3px 10px",
borderRadius: 12,
background: [Link],
color: [Link],
border: `1px solid ${[Link]}`,
letterSpacing: 1,
textTransform: "uppercase",
fontWeight: 700,
}}>
{[Link]}
</span>
<span style={{ fontSize: 10, color: "#334155" }}>Pattern #{[Link]}</span
</div>
<h2 style={{ margin: 0, fontSize: 26, fontWeight: 800, color: "#f8fafc", letter
{[Link]}
</h2>
</div>
</div>
{/* Role */}
<div style={{
padding: "12px 16px",
background: [Link],
border: `1px solid ${[Link]}`,
borderRadius: 8,
marginBottom: 20,
fontSize: 13,
color: "#cbd5e1",
lineHeight: 1.6,
}}>
<span style={{ color: [Link], fontWeight: 700, marginRight: 8 }}>Rôle :</s
{[Link]}
</div>
{/* Code block */}
<div style={{
background: "#0d1117",
border: "1px solid #1e293b",
borderRadius: 10,
overflow: "hidden",
}}>
<div style={{
display: "flex",
alignItems: "center",
gap: 6,
padding: "10px 16px",
background: "#111827",
borderBottom: "1px solid #1e293b",
}}>
{["#ff5f57","#febc2e","#28c840"].map((c,i) => (
<div key={i} style={{ width: 10, height: 10, borderRadius: "50%", background:
))}
<span style={{ marginLeft: 8, fontSize: 11, color: "#475569" }}>
{[Link]}.java
</span>
</div>
<pre style={{
margin: 0,
padding: "20px",
fontSize: 12,
lineHeight: 1.7,
overflowX: "auto",
color: "#94a3b8",
tabSize: 4,
}}>
<code dangerouslySetInnerHTML={{
__html: [Link]
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
// keywords
.replace(/\b(public|private|protected|abstract|final|static|class|interface
'<span style="color:#c084fc">$1</span>')
// types
.replace(/\b(String|int|double|boolean|List|Map|ArrayList|HashMap|void)\b/g
'<span style="color:#60a5fa">$1</span>')
// strings
.replace(/"([^"]*?)"/g,
'<span style="color:#86efac">"$1"</span>')
// comments
.replace(/(\/\/[^\n]*)/g,
'<span style="color:#334155;font-style:italic">$1</span>')
// emojis — keep colored
.replace(/([\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{27BF}])/gu,
'<span style="color:#fbbf24">$1</span>')
// numbers
.replace(/\b(\d+\.?\d*)\b/g,
'<span style="color:#fb923c">$1</span>')
}} />
</pre>
</div>
{/* Nav arrows */}
<div style={{ display: "flex", justifyContent: "space-between", marginTop: 20 }}>
<button
onClick={() => { const i = [Link](p=>[Link]===[Link]); if(i>0) s
disabled={[Link] === 1}
style={{
padding: "8px 18px", borderRadius: 6, border: "1px solid #1e293b",
background: "transparent", color: [Link]===1 ? "#1e293b" : "#64748b",
cursor: [Link]===1 ? "default" : "pointer", fontSize: 12, fontFamily: "i
}}>
← Précédent
</button>
<span style={{ fontSize: 11, color: "#334155", alignSelf: "center" }}>
{[Link]} / 23
</span>
<button
onClick={() => { const i = [Link](p=>[Link]===[Link]); if(i<patt
disabled={[Link] === 23}
style={{
padding: "8px 18px", borderRadius: 6, border: "1px solid #1e293b",
background: "transparent", color: [Link]===23 ? "#1e293b" : "#64748b",
cursor: [Link]===23 ? "default" : "pointer", fontSize: 12, fontFamily: "
}}>
Suivant →
</button>
</div>
</div>
</div>
</div>
);
}