- Déplacement de la copie de team-static.html dans la section principale de copie - Déplacement de la copie de team-visualization-data.json dans la section principale - Suppression des copies dupliquées qui étaient mal placées - Maintenant les fichiers seront copiés correctement lors du build Ces fichiers étaient absents du déploiement, causant l'affichage du radar au lieu des visualisations équipe
558 lines
26 KiB
Docker
558 lines
26 KiB
Docker
# Utiliser une image Node.js légère
|
|
FROM node:20-alpine
|
|
|
|
# Build arguments pour invalider le cache si nécessaire
|
|
ARG BUILD_DATE=unknown
|
|
ARG BUILD_VERSION=unknown
|
|
ARG CACHE_BUST=1
|
|
LABEL build.date="${BUILD_DATE}" \
|
|
build.version="${BUILD_VERSION}" \
|
|
cache.bust="${CACHE_BUST}"
|
|
|
|
# Invalider le cache en utilisant CACHE_BUST dans une instruction RUN
|
|
# Cela force Docker à reconstruire à partir de cette ligne si CACHE_BUST change
|
|
# Utiliser CACHE_BUST dans une variable d'environnement pour forcer l'invalidation
|
|
RUN echo "Cache bust: ${CACHE_BUST}" && \
|
|
echo "Build date: ${BUILD_DATE}" && \
|
|
date && \
|
|
echo "${CACHE_BUST}" > /tmp/cache_bust.txt
|
|
|
|
WORKDIR /app
|
|
|
|
# Variables d'environnement à définir AVANT npm install
|
|
ENV HUSKY=0
|
|
ENV HUSKY_SKIP_INSTALL=1
|
|
ENV NODE_PATH=/app/node_modules
|
|
ENV NODE_ENV=production
|
|
|
|
# Installation des dépendances système
|
|
RUN apk add --no-cache git python3
|
|
|
|
# Copie des fichiers de dépendances
|
|
COPY package.json package-lock.json* ./
|
|
|
|
# Installation des dépendances Node
|
|
RUN npm install --legacy-peer-deps --ignore-scripts
|
|
|
|
# Patch du package aoe_technology_radar pour inclure gray-matter dans les dépendances runtime
|
|
RUN node -e "const fs=require('fs');const pkgPath='./node_modules/aoe_technology_radar/package.json';const pkg=JSON.parse(fs.readFileSync(pkgPath,'utf8'));pkg.dependencies=pkg.dependencies||{};pkg.dependencies['gray-matter']='^4.0.3';pkg.dependencies['postcss']='^8.4.47';pkg.scripts=pkg.scripts||{};pkg.scripts.prepare='';fs.writeFileSync(pkgPath,JSON.stringify(pkg,null,2));"
|
|
|
|
# Copie du reste du projet
|
|
COPY . .
|
|
RUN chmod +x scripts/start-business.sh
|
|
|
|
# Préparer .techradar une fois pour toutes (évite les réinstallations au runtime)
|
|
# Le script techradar.js crée automatiquement .techradar lors de l'exécution
|
|
# Création manuelle de .techradar en copiant depuis node_modules
|
|
RUN mkdir -p .techradar && \
|
|
cp -r node_modules/aoe_technology_radar/* .techradar/
|
|
# Créer le fichier hash pour éviter la recréation (calculé séparément pour éviter les problèmes d'échappement)
|
|
RUN node -e "const crypto=require('crypto');const fs=require('fs');const hash=crypto.createHash('sha256').update(fs.readFileSync('package.json')).digest('hex');fs.writeFileSync('.techradar/hash',hash);"
|
|
RUN node -e "const fs=require('fs');const p='.techradar/package.json';if(!fs.existsSync(p)){console.error('.techradar/package.json not found');process.exit(1);}const pkg=JSON.parse(fs.readFileSync(p,'utf8'));pkg.scripts=pkg.scripts||{};pkg.scripts.prepare='';fs.writeFileSync(p,JSON.stringify(pkg,null,2));"
|
|
# Installer les dépendances dans .techradar (y compris devDependencies pour tsx nécessaire à build:data)
|
|
RUN cd .techradar && npm install --legacy-peer-deps --include=dev
|
|
RUN cd .techradar && npm run build:icons
|
|
|
|
# --- CONFIGURATION BUSINESS ---
|
|
# Application de la logique Business (remplacement de la config et des données)
|
|
# Préserver la structure de dossiers par date pour que le framework puisse parser les dates
|
|
RUN cp radar-business/config-business.json config.json && \
|
|
rm -rf radar/* && \
|
|
mkdir -p radar/2025-01-15 && \
|
|
cp -r radar-business/2025-01-15/* radar/2025-01-15/
|
|
|
|
# Générer les données de visualisation équipe si nécessaire
|
|
RUN if [ ! -f "public/team-visualization-data.json" ]; then \
|
|
echo "⚠️ team-visualization-data.json non trouvé, génération..." && \
|
|
node scripts/generate-team-visualization-data.js && \
|
|
echo "✅ Données de visualisation équipe générées"; \
|
|
else \
|
|
echo "✅ team-visualization-data.json existe déjà"; \
|
|
fi && \
|
|
echo "🔍 Vérification contenu team-visualization-data.json:" && \
|
|
ls -la public/team-visualization-data.json && \
|
|
head -20 public/team-visualization-data.json
|
|
|
|
# Copier les fichiers nécessaires dans .techradar avant le build (comme le fait techradar.js)
|
|
RUN rm -rf .techradar/data/radar && \
|
|
mkdir -p .techradar/data/radar/2025-01-15 && \
|
|
cp -r radar-business/2025-01-15/* .techradar/data/radar/2025-01-15/ && \
|
|
# Supprimer toute release de démo (2017-03-01, 2024-03-01, etc.) éventuellement recopiée depuis le package
|
|
find .techradar/data/radar -mindepth 1 -maxdepth 1 ! -name '2025-01-15' -exec rm -rf {} + && \
|
|
cp radar-business/config-business.json .techradar/data/config.json && \
|
|
rm -rf .techradar/public && mkdir -p .techradar/public && \
|
|
cp -r public/* .techradar/public/ && \
|
|
cp public/team.html .techradar/public/team.html 2>/dev/null || true && \
|
|
cp public/team-visualization-data.json .techradar/public/team-visualization-data.json 2>/dev/null || true && \
|
|
cp about.md .techradar/data/about.md 2>/dev/null || echo "about.md not found, skipping" && \
|
|
cp custom.css .techradar/src/styles/custom.css 2>/dev/null || echo "custom.css not found, skipping" && \
|
|
echo "Fichiers public copiés" && \
|
|
echo "📁 Vérification des fichiers team dans .techradar/public/:" && \
|
|
ls -la .techradar/public/ | grep -E "(team\.html|team-visualization)" && echo "✅ Fichiers team trouvés" || (echo "⚠️ Fichiers team non trouvés dans .techradar/public/" && echo "📁 Contenu de public/ source:" && ls -la public/ | head -10) && \
|
|
echo "📁 Vérification que team.html existe dans public/ source:" && \
|
|
test -f public/team.html && echo "✅ public/team.html existe" || echo "❌ public/team.html n'existe pas"
|
|
|
|
# Diagnostic : compter les fichiers markdown copiés dans .techradar/data/radar
|
|
RUN echo "📊 Comptage des fichiers .md dans .techradar/data/radar" && \
|
|
find .techradar/data/radar -name "*.md" | wc -l && \
|
|
find .techradar/data/radar -name "*.md" | head -10
|
|
|
|
# Créer la page Next.js /team ET un fichier HTML statique /team/index.html
|
|
# La page Next.js pour le routing, le HTML statique pour garantir l'affichage
|
|
RUN mkdir -p .techradar/src/pages && \
|
|
cat > .techradar/src/pages/team.tsx << 'EOF'
|
|
import { useEffect } from 'react';
|
|
|
|
export default function TeamPage() {
|
|
useEffect(() => {
|
|
// Solution simple : rediriger vers une page HTML statique
|
|
// Cela évite tous les conflits React/DOM
|
|
console.log('🔄 TEAM PAGE: Redirection vers page HTML statique');
|
|
if (typeof window !== 'undefined') {
|
|
window.location.href = '/team-static.html';
|
|
}
|
|
}, []);
|
|
|
|
// Ne rien rendre - la redirection prend le relais immédiatement
|
|
return null;
|
|
}
|
|
EOF
|
|
RUN echo "✅ Page team.tsx créée (version ultra-simplifiée)" && \
|
|
echo "🔍 VÉRIFICATION: Contenu de team.tsx créé:" && \
|
|
cat .techradar/src/pages/team.tsx && \
|
|
echo "🔍 VÉRIFICATION: team.html dans .techradar/public/:" && \
|
|
ls -la .techradar/public/team.html
|
|
|
|
# Créer aussi un fichier HTML statique /team/index.html pour garantir l'accès
|
|
RUN mkdir -p .techradar/public/team && \
|
|
cat > .techradar/public/team/index.html << 'EOF'
|
|
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Équipe & Technologies - Laplank</title>
|
|
<style>
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
html, body {
|
|
width: 100%;
|
|
height: 100%;
|
|
overflow: hidden;
|
|
}
|
|
iframe {
|
|
width: 100%;
|
|
height: 100%;
|
|
border: none;
|
|
display: block;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<iframe src="/team.html" title="Équipe & Technologies"></iframe>
|
|
</body>
|
|
</html>
|
|
EOF
|
|
RUN echo "✅ Fichier /team/index.html créé (HTML statique)"
|
|
|
|
# Script Python pour ajouter le lien Équipe dans Navigation.tsx (supprime TOUS les doublons)
|
|
RUN cat > /tmp/add_team_link.py << 'PYEOF'
|
|
#!/usr/bin/env python3
|
|
import sys
|
|
import re
|
|
import os
|
|
|
|
f = ".techradar/src/components/Navigation/Navigation.tsx"
|
|
|
|
try:
|
|
# Vérifier que le fichier existe
|
|
if not os.path.exists(f):
|
|
print(f"❌ Fichier {f} introuvable", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
with open(f, 'r', encoding='utf-8') as file:
|
|
content = file.read()
|
|
|
|
# VÉRIFICATION PRÉLIMINAIRE: Détecter les doublons structurels
|
|
print("🔍 Vérification de la structure du composant...")
|
|
|
|
# Compter les éléments structurels
|
|
nav_patterns = [
|
|
r'<nav\s',
|
|
r'className.*[Nn]avigation',
|
|
r'export\s+(default\s+)?function\s+Navigation',
|
|
r'const\s+Navigation\s*='
|
|
]
|
|
nav_count = sum(len(re.findall(pattern, content)) for pattern in nav_patterns)
|
|
|
|
# Compter les <ul> (peut y en avoir 2 pour mobile/desktop)
|
|
ul_count = len(re.findall(r'<ul[^>]*>', content))
|
|
|
|
# Compter les logos (Image avec logo ou logoFile)
|
|
logo_patterns = [
|
|
r'logoFile',
|
|
r'logo\.svg',
|
|
r'[Ll]ogo',
|
|
r'Image.*logo'
|
|
]
|
|
logo_count = sum(len(re.findall(pattern, content)) for pattern in logo_patterns)
|
|
|
|
# Compter les fonctions Navigation
|
|
function_count = len(re.findall(r'(export\s+(default\s+)?function\s+Navigation|const\s+Navigation\s*=\s*\(|function\s+Navigation\s*\()', content))
|
|
|
|
print(f"📊 Structure détectée: {nav_count} nav, {ul_count} ul, {logo_count} logo, {function_count} fonction(s)")
|
|
|
|
# Détecter les duplications structurelles
|
|
if function_count > 1:
|
|
print(f"⚠️ ATTENTION: {function_count} fonction(s) Navigation détectée(s) - possible duplication du composant", file=sys.stderr)
|
|
# Extraire uniquement la première fonction Navigation
|
|
matches = list(re.finditer(r'(export\s+(default\s+)?function\s+Navigation|const\s+Navigation\s*=\s*\(|function\s+Navigation\s*\()', content))
|
|
if len(matches) > 1:
|
|
# Garder seulement jusqu'à la fin de la première fonction
|
|
first_end = matches[1].start() if len(matches) > 1 else len(content)
|
|
content = content[:first_end]
|
|
# Trouver la fin de la fonction (dernière accolade fermante avant la prochaine fonction)
|
|
brace_count = 0
|
|
in_function = False
|
|
for i, char in enumerate(content[matches[0].start():], matches[0].start()):
|
|
if char == '{':
|
|
brace_count += 1
|
|
in_function = True
|
|
elif char == '}':
|
|
brace_count -= 1
|
|
if in_function and brace_count == 0:
|
|
content = content[:i+1]
|
|
break
|
|
print(f"✅ Duplication du composant supprimée")
|
|
|
|
if ul_count > 3: # Plus de 3 ul suggère une duplication
|
|
print(f"⚠️ ATTENTION: {ul_count} éléments <ul> détectés - possible duplication", file=sys.stderr)
|
|
|
|
if logo_count > 5: # Plus de 5 références au logo suggère une duplication
|
|
print(f"⚠️ ATTENTION: {logo_count} références au logo détectées - possible duplication", file=sys.stderr)
|
|
|
|
# ÉTAPE 1: Supprimer TOUS les liens Équipe existants (même s'il n'y en a qu'un)
|
|
print("🧹 Nettoyage de tous les liens Équipe existants...")
|
|
|
|
# APPROCHE AGRESSIVE: Supprimer tous les blocs <li> contenant un lien vers /team
|
|
# Utiliser plusieurs patterns pour capturer tous les cas possibles
|
|
# Pattern 1: <li>...<Link href="/team"...>...</Link>...</li>
|
|
team_link_block_pattern = r'<li[^>]*>.*?<Link[^>]*href=["\']/?team(/|\.html)?["\'][^>]*>.*?</Link>.*?</li>'
|
|
content_cleaned = re.sub(team_link_block_pattern, '', content, flags=re.DOTALL | re.IGNORECASE)
|
|
|
|
# Pattern 2: Supprimer aussi les lignes contenant href="/team" même si elles ne sont pas dans un <li> complet
|
|
content_cleaned = re.sub(r'.*href=["\']/?team(/|\.html)?["\'].*\n', '', content_cleaned, flags=re.IGNORECASE)
|
|
|
|
# Pattern 3: Supprimer les blocs <li> qui pourraient contenir /team sur plusieurs lignes (format différent)
|
|
content_cleaned = re.sub(r'<li[^>]*>.*?/team.*?</li>', '', content_cleaned, flags=re.DOTALL | re.IGNORECASE)
|
|
|
|
# Compter combien de liens ont été supprimés
|
|
remaining_before = len(re.findall(r'href=["\']/?team(/|\.html)?["\']', content))
|
|
remaining_after = len(re.findall(r'href=["\']/?team(/|\.html)?["\']', content_cleaned))
|
|
team_links_removed = remaining_before - remaining_after
|
|
|
|
if team_links_removed > 0:
|
|
print(f"✅ {team_links_removed} lien(s) Équipe supprimé(s) (regex multiligne)")
|
|
elif remaining_after > 0:
|
|
print(f"⚠️ {remaining_after} lien(s) Équipe encore présent(s) après nettoyage regex, nettoyage manuel...")
|
|
# Nettoyage manuel ligne par ligne si la regex n'a pas tout capturé
|
|
lines = content_cleaned.splitlines(keepends=True)
|
|
if lines and not lines[-1].endswith('\n'):
|
|
lines[-1] = lines[-1] + '\n'
|
|
|
|
new_lines = []
|
|
skip_team_link = False
|
|
manual_removed = 0
|
|
|
|
i = 0
|
|
while i < len(lines):
|
|
line = lines[i]
|
|
|
|
# Détecter le début d'un lien Équipe
|
|
team_link_match = re.search(r'href=["\']/?team(/|\.html)?["\']|href=\{["\']/?team', line)
|
|
if team_link_match and not skip_team_link:
|
|
skip_team_link = True
|
|
manual_removed += 1
|
|
i += 1
|
|
continue
|
|
|
|
if skip_team_link:
|
|
if '</li>' in line:
|
|
skip_team_link = False
|
|
i += 1
|
|
continue
|
|
|
|
new_lines.append(line)
|
|
i += 1
|
|
|
|
if manual_removed > 0:
|
|
content_cleaned = ''.join(new_lines)
|
|
print(f"✅ {manual_removed} lien(s) Équipe supplémentaire(s) supprimé(s) (nettoyage manuel)")
|
|
|
|
lines = content_cleaned.splitlines(keepends=True)
|
|
if lines and not lines[-1].endswith('\n'):
|
|
lines[-1] = lines[-1] + '\n'
|
|
|
|
# ÉTAPE 2: Vérifier qu'il n'y a plus aucun lien team avant d'ajouter
|
|
final_check = len(re.findall(r'href=["\']/?team(/|\.html)?["\']', content_cleaned))
|
|
if final_check > 0:
|
|
print(f"⚠️ ATTENTION: {final_check} lien(s) Équipe encore présent(s) après nettoyage, nettoyage supplémentaire...", file=sys.stderr)
|
|
# Nettoyage supplémentaire avec une regex plus agressive
|
|
content_cleaned = re.sub(r'.*?href=["\']/?team(/|\.html)?["\'].*?\n', '', content_cleaned, flags=re.MULTILINE | re.IGNORECASE)
|
|
# Supprimer aussi les blocs <li> vides qui pourraient rester
|
|
content_cleaned = re.sub(r'<li[^>]*>\s*</li>\s*\n', '', content_cleaned)
|
|
final_check_2 = len(re.findall(r'href=["\']/?team(/|\.html)?["\']', content_cleaned))
|
|
if final_check_2 > 0:
|
|
print(f"❌ ERREUR: {final_check_2} lien(s) Équipe toujours présent(s) après nettoyage supplémentaire!", file=sys.stderr)
|
|
print("📄 Contenu autour des liens restants:", file=sys.stderr)
|
|
for match in re.finditer(r'href=["\']/?team(/|\.html)?["\']', content_cleaned):
|
|
start = max(0, match.start() - 50)
|
|
end = min(len(content_cleaned), match.end() + 50)
|
|
print(f" {content_cleaned[start:end]}", file=sys.stderr)
|
|
else:
|
|
print(f"✅ Tous les liens Équipe supprimés après nettoyage supplémentaire")
|
|
|
|
# ÉTAPE 3: Ajouter un seul lien Équipe au bon endroit
|
|
insert_idx = -1
|
|
for i, line in enumerate(lines):
|
|
if 'href="/overview"' in line:
|
|
for j in range(i, min(i+10, len(lines))):
|
|
if '</Link>' in lines[j] and j+1 < len(lines) and '</li>' in lines[j+1]:
|
|
insert_idx = j + 2
|
|
break
|
|
break
|
|
|
|
if insert_idx > 0:
|
|
new_lines = lines[:insert_idx] + [
|
|
' <li className={styles.item}>\n',
|
|
' <Link href="/team">\n',
|
|
' <span className={styles.label}>👥 Équipe</span>\n',
|
|
' </Link>\n',
|
|
' </li>\n'
|
|
] + lines[insert_idx:]
|
|
with open(f, 'w', encoding='utf-8') as file:
|
|
file.writelines(new_lines)
|
|
|
|
# Vérifier qu'il n'y a qu'un seul lien maintenant (inclut /team, /team/, /team.html)
|
|
with open(f, 'r', encoding='utf-8') as file:
|
|
final_content = file.read()
|
|
final_count = len(re.findall(r'href=["\']/?team(/|\.html)?["\']', final_content))
|
|
|
|
if final_count == 1:
|
|
print("✅ Navigation.tsx modifié - 1 seul lien Équipe présent")
|
|
sys.exit(0)
|
|
else:
|
|
print(f"⚠️ Attention: {final_count} lien(s) Équipe détecté(s) après modification", file=sys.stderr)
|
|
sys.exit(1)
|
|
else:
|
|
print("❌ Impossible de trouver l'emplacement pour insérer le lien", file=sys.stderr)
|
|
sys.exit(1)
|
|
except Exception as e:
|
|
print(f"❌ Erreur Python: {e}", file=sys.stderr)
|
|
import traceback
|
|
traceback.print_exc(file=sys.stderr)
|
|
sys.exit(1)
|
|
PYEOF
|
|
|
|
# Script shell pour gérer l'ajout du lien Équipe
|
|
RUN cat > /tmp/add_team_link.sh << 'SHEOF'
|
|
#!/bin/sh
|
|
set -e
|
|
|
|
echo "🔧 Modification de Navigation.tsx pour le lien Équipe..."
|
|
|
|
NAV_FILE=".techradar/src/components/Navigation/Navigation.tsx"
|
|
|
|
# Vérifier que le fichier existe
|
|
if [ ! -f "$NAV_FILE" ]; then
|
|
echo "❌ Fichier $NAV_FILE introuvable"
|
|
echo "📁 Répertoire actuel: $(pwd)"
|
|
echo "📁 Contenu de .techradar/src/components/:"
|
|
ls -la .techradar/src/components/ 2>/dev/null || echo "Répertoire non trouvé"
|
|
exit 1
|
|
fi
|
|
|
|
# Exécuter le script Python
|
|
if python3 /tmp/add_team_link.py; then
|
|
# Vérifier le résultat (inclut /team, /team/, /team.html)
|
|
team_count=$(grep -cE 'href="/team|href=\{"/team|href=["'"'"']/team' "$NAV_FILE" 2>/dev/null || echo "0")
|
|
echo "📊 Nombre d'occurrences trouvées: $team_count"
|
|
|
|
if [ "$team_count" -eq "1" ]; then
|
|
echo "✅ Lien Équipe présent (1 occurrence)"
|
|
elif [ "$team_count" -gt "1" ]; then
|
|
echo "❌ ERREUR: $team_count occurrences détectées - affichage des occurrences:"
|
|
grep -nE 'href="/team|href=\{"/team|href=["'"'"']/team' "$NAV_FILE" || true
|
|
echo "⚠️ Relance du nettoyage..."
|
|
python3 /tmp/add_team_link.py
|
|
final_count=$(grep -cE 'href="/team|href=\{"/team|href=["'"'"']/team' "$NAV_FILE" 2>/dev/null || echo "0")
|
|
if [ "$final_count" -gt "1" ]; then
|
|
echo "❌ ERREUR CRITIQUE: $final_count occurrences encore présentes après nettoyage!"
|
|
echo "📄 Aperçu complet de Navigation.tsx:"
|
|
cat "$NAV_FILE" || true
|
|
exit 1
|
|
else
|
|
echo "✅ Après nettoyage: $final_count occurrence(s)"
|
|
fi
|
|
else
|
|
echo "❌ Lien Équipe non trouvé après modification"
|
|
echo "📄 Aperçu de Navigation.tsx (premières 50 lignes):"
|
|
head -50 "$NAV_FILE" || true
|
|
exit 1
|
|
fi
|
|
|
|
# VÉRIFICATIONS POST-MODIFICATION: Détecter les doublons structurels
|
|
echo "🔍 Vérification des doublons structurels..."
|
|
|
|
# Compter les fonctions Navigation
|
|
function_count=$(grep -cE '(export\s+(default\s+)?function\s+Navigation|const\s+Navigation\s*=\s*\(|function\s+Navigation\s*\()' "$NAV_FILE" 2>/dev/null || echo "0")
|
|
if [ "$function_count" -gt "1" ]; then
|
|
echo "❌ ERREUR: $function_count fonction(s) Navigation détectée(s) - duplication du composant!"
|
|
echo "📄 Recherche des fonctions Navigation:"
|
|
grep -nE '(export\s+(default\s+)?function\s+Navigation|const\s+Navigation\s*=\s*\(|function\s+Navigation\s*\()' "$NAV_FILE" || true
|
|
exit 1
|
|
else
|
|
echo "✅ Composant Navigation unique ($function_count fonction)"
|
|
fi
|
|
|
|
# Compter les éléments <nav> ou className Navigation
|
|
nav_count=$(grep -cE '<nav\s|className.*[Nn]avigation' "$NAV_FILE" 2>/dev/null || echo "0")
|
|
if [ "$nav_count" -gt "2" ]; then
|
|
echo "⚠️ ATTENTION: $nav_count éléments nav détectés (attendu: 1-2)"
|
|
else
|
|
echo "✅ Structure nav correcte ($nav_count élément(s))"
|
|
fi
|
|
|
|
# Compter les éléments <ul>
|
|
ul_count=$(grep -c '<ul' "$NAV_FILE" 2>/dev/null || echo "0")
|
|
if [ "$ul_count" -gt "3" ]; then
|
|
echo "⚠️ ATTENTION: $ul_count éléments <ul> détectés (attendu: 1-3 pour mobile/desktop)"
|
|
else
|
|
echo "✅ Structure ul correcte ($ul_count élément(s))"
|
|
fi
|
|
|
|
# Compter les références au logo
|
|
logo_count=$(grep -cE 'logoFile|logo\.svg|[Ll]ogo' "$NAV_FILE" 2>/dev/null || echo "0")
|
|
if [ "$logo_count" -gt "5" ]; then
|
|
echo "⚠️ ATTENTION: $logo_count références au logo détectées (possible duplication)"
|
|
else
|
|
echo "✅ Références logo correctes ($logo_count référence(s))"
|
|
fi
|
|
|
|
# Vérifier qu'il n'y a qu'un seul export default
|
|
export_count=$(grep -c 'export default' "$NAV_FILE" 2>/dev/null || echo "0")
|
|
if [ "$export_count" -gt "1" ]; then
|
|
echo "❌ ERREUR: $export_count export default détectés - duplication du composant!"
|
|
exit 1
|
|
else
|
|
echo "✅ Export unique ($export_count export default)"
|
|
fi
|
|
|
|
echo "✅ Toutes les vérifications structurelles passées"
|
|
else
|
|
echo "❌ Erreur lors de l'exécution du script Python"
|
|
exit 1
|
|
fi
|
|
SHEOF
|
|
RUN chmod +x /tmp/add_team_link.sh && \
|
|
echo "🔍 VÉRIFICATION: Scripts modifiés:" && \
|
|
echo "=== team-block-script.js ===" && \
|
|
head -10 public/team-block-script.js && \
|
|
echo "=== strategie-script.js ===" && \
|
|
grep -A 2 -B 1 "__blockTeamPages" public/strategie-script.js || echo "❌ Protection non trouvée" && \
|
|
echo "=== config-business.json ===" && \
|
|
grep "jsFile" radar-business/config-business.json
|
|
|
|
# Exécuter le script
|
|
RUN /tmp/add_team_link.sh
|
|
|
|
# Builder l'application en mode production pour éviter Fast Refresh
|
|
# Utiliser WORKDIR pour changer de répertoire de manière fiable
|
|
WORKDIR /app/.techradar
|
|
RUN npm run build:data
|
|
RUN npm run build
|
|
# S'assurer que team.html et team-visualization-data.json sont copiés dans out/
|
|
# Next.js en mode export copie automatiquement les fichiers de public/, mais vérifions quand même
|
|
RUN if [ -d "out" ]; then \
|
|
echo "📁 Contenu de out/ avant copie:" && \
|
|
ls -la out/ | head -10 && \
|
|
echo "" && \
|
|
echo "🔍 Recherche de team.html..." && \
|
|
if [ -f "public/team.html" ]; then \
|
|
cp -v public/team.html out/team.html && echo "✅ team.html copié depuis public/ vers out/"; \
|
|
elif [ -f "/app/public/team.html" ]; then \
|
|
cp -v /app/public/team.html out/team.html && echo "✅ team.html copié depuis /app/public/ vers out/"; \
|
|
else \
|
|
echo "⚠️ team.html introuvable dans public/ ou /app/public/"; \
|
|
echo "📁 Contenu de public/:" && \
|
|
ls -la public/ 2>/dev/null | head -10 || echo "public/ non accessible"; \
|
|
echo "📁 Contenu de /app/public/:" && \
|
|
ls -la /app/public/ 2>/dev/null | head -10 || echo "/app/public/ non accessible"; \
|
|
fi && \
|
|
if [ -f "public/team-static.html" ]; then \
|
|
cp -v public/team-static.html out/team-static.html && echo "✅ team-static.html copié depuis public/ vers out/"; \
|
|
elif [ -f "/app/public/team-static.html" ]; then \
|
|
cp -v /app/public/team-static.html out/team-static.html && echo "✅ team-static.html copié depuis /app/public/ vers out/"; \
|
|
else \
|
|
echo "⚠️ team-static.html introuvable dans public/ ou /app/public/"; \
|
|
fi && \
|
|
if [ -f "public/team-visualization-data.json" ]; then \
|
|
cp -v public/team-visualization-data.json out/team-visualization-data.json && echo "✅ team-visualization-data.json copié dans out/"; \
|
|
else \
|
|
echo "⚠️ public/team-visualization-data.json introuvable"; \
|
|
fi && \
|
|
if [ -d "public/team" ]; then \
|
|
mkdir -p out/team && \
|
|
cp -rv public/team/* out/team/ && echo "✅ /team/index.html copié dans out/team/"; \
|
|
elif [ -d "/app/.techradar/public/team" ]; then \
|
|
mkdir -p out/team && \
|
|
cp -rv /app/.techradar/public/team/* out/team/ && echo "✅ /team/index.html copié depuis /app/.techradar/public/team/"; \
|
|
fi && \
|
|
echo "🔍 VÉRIFICATION: team.html dans out/:" && \
|
|
ls -la out/team.html 2>/dev/null || echo "❌ team.html absent de out/" && \
|
|
echo "🔍 VÉRIFICATION: team-static.html dans out/:" && \
|
|
ls -la out/team-static.html 2>/dev/null || echo "❌ team-static.html absent de out/" && \
|
|
echo "" && \
|
|
echo "📁 Vérification finale dans out/:" && \
|
|
ls -la out/ | grep -E "(team\.html|team-visualization)" && echo "✅ Fichiers team présents dans out/" || echo "⚠️ Fichiers team non trouvés dans out/"; \
|
|
else \
|
|
echo "❌ Dossier out/ introuvable après build"; \
|
|
ls -la . | head -20; \
|
|
fi && \
|
|
echo "" && \
|
|
echo "📋 Vérification finale de Navigation.tsx après build:" && \
|
|
grep -qE 'href="/team' src/components/Navigation/Navigation.tsx && echo "✅ Lien Équipe toujours présent dans Navigation.tsx après build" || echo "❌ Lien Équipe absent de Navigation.tsx après build" && \
|
|
echo "" && \
|
|
echo "🔍 Vérification des doublons dans le HTML généré..." && \
|
|
if [ -f "out/index.html" ]; then \
|
|
header_count=$(grep -oE '<header|<nav[^>]*>' out/index.html | wc -l | tr -d ' '); \
|
|
nav_count=$(grep -oE '<nav[^>]*>' out/index.html | wc -l | tr -d ' '); \
|
|
logo_count=$(grep -oE 'logo\.svg|logoFile|CoeurBox' out/index.html | wc -l | tr -d ' '); \
|
|
echo "📊 HTML généré: $header_count header/nav, $nav_count nav, $logo_count logo"; \
|
|
if [ "$header_count" -gt "2" ] || [ "$nav_count" -gt "2" ]; then \
|
|
echo "❌ ERREUR: Duplication détectée dans le HTML généré!"; \
|
|
echo "📄 Recherche des headers/nav dans index.html:"; \
|
|
grep -nE '<header|<nav' out/index.html | head -10 || true; \
|
|
exit 1; \
|
|
else \
|
|
echo "✅ HTML généré correct (pas de duplication structurelle)"; \
|
|
fi; \
|
|
if [ "$logo_count" -gt "5" ]; then \
|
|
echo "⚠️ ATTENTION: $logo_count références au logo dans le HTML (possible duplication)"; \
|
|
else \
|
|
echo "✅ Références logo correctes dans le HTML"; \
|
|
fi; \
|
|
else \
|
|
echo "⚠️ out/index.html non trouvé, vérification HTML ignorée"; \
|
|
fi
|
|
WORKDIR /app
|
|
|
|
# Exposition du port interne
|
|
EXPOSE 3000
|
|
|
|
# Démarrage du serveur via script (exporte les variables avant npm run serve)
|
|
CMD ["./scripts/start-business.sh"]
|