chore: add initial project setup with Docker and React configuration
This commit is contained in:
10
.dockerignore
Normal file
10
.dockerignore
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
node_modules
|
||||||
|
npm-debug.log
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
*.md
|
||||||
|
.env
|
||||||
|
.DS_Store
|
||||||
|
dist
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
17
Dockerfile
Normal file
17
Dockerfile
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Build stage
|
||||||
|
FROM node:18-alpine AS builder
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
RUN npm install --legacy-peer-deps
|
||||||
|
RUN npm install -g serve
|
||||||
|
|
||||||
|
# Copy all files
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
CMD ["serve", "-s", "dist", "-l", "3000"]
|
||||||
165
README.md
Normal file
165
README.md
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
# TP Écoconception Web - Site React
|
||||||
|
|
||||||
|
Site web React présentant les résultats complets du TP sur l'écoconception et l'accessibilité web.
|
||||||
|
|
||||||
|
## 📋 Contenu du TP
|
||||||
|
|
||||||
|
Ce site présente de manière structurée et interactive tous les éléments suivants :
|
||||||
|
|
||||||
|
### 🔍 Audit Initial
|
||||||
|
- **Comparaison d'outils** : Analyse comparative de 5 outils d'écoconception (Website Carbon, EcoIndex, Lighthouse, GreenIT-Analysis, Scaphandre) avec graphique radar
|
||||||
|
- **Website Carbon Calculator** : Décryptage technique et pédagogique complet
|
||||||
|
- **Audit Environnemental** : Diagnostic et recommandations pour un site fictif
|
||||||
|
- **RGESN** : Application du Référentiel Général d'Écoconception des Services Numériques
|
||||||
|
|
||||||
|
### ♿ Accessibilité
|
||||||
|
- **Principes de l'accessibilité** : Les 4 principes POUR (Perceptible, Utilisable, Compréhensible, Robuste)
|
||||||
|
- **Audit WAVE** : Découverte et utilisation de l'outil WAVE avec exemples de corrections
|
||||||
|
- **RGAA** : Conformité au Référentiel Général d'Amélioration de l'Accessibilité
|
||||||
|
|
||||||
|
### 🗺️ Guide Pratique
|
||||||
|
- **Guide d'écoconception** : Méthodologie complète pour intégrer l'écoconception dans un projet SAE
|
||||||
|
- **Planning type** : Organisation sur 4 semaines avec checklists détaillées
|
||||||
|
- **Outils recommandés** : Liste complète des outils pour chaque besoin
|
||||||
|
|
||||||
|
### 🎯 Conclusion
|
||||||
|
- Bilan des compétences acquises
|
||||||
|
- Bénéfices multiples (environnementaux, sociaux, économiques, juridiques)
|
||||||
|
- Ressources pour aller plus loin
|
||||||
|
|
||||||
|
## 🚀 Installation et Lancement
|
||||||
|
|
||||||
|
### Prérequis
|
||||||
|
- Node.js (version 16 ou supérieure)
|
||||||
|
- npm ou yarn
|
||||||
|
|
||||||
|
### Étapes d'installation
|
||||||
|
|
||||||
|
1. **Installer les dépendances**
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Lancer le serveur de développement**
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Ouvrir dans le navigateur**
|
||||||
|
Le site sera accessible à l'adresse : `http://localhost:5173`
|
||||||
|
|
||||||
|
### Commandes disponibles
|
||||||
|
|
||||||
|
- `npm run dev` : Lance le serveur de développement
|
||||||
|
- `npm run build` : Crée une version de production optimisée
|
||||||
|
- `npm run preview` : Prévisualise la version de production
|
||||||
|
|
||||||
|
## 🛠️ Technologies Utilisées
|
||||||
|
|
||||||
|
- **React** 18.2 : Framework JavaScript
|
||||||
|
- **React Router** 6.20 : Navigation entre les pages
|
||||||
|
- **Recharts** 2.10 : Graphiques interactifs (radar)
|
||||||
|
- **Vite** 5.0 : Build tool ultra-rapide
|
||||||
|
- **Font Awesome** 6.5 : Icônes
|
||||||
|
|
||||||
|
## 📁 Structure du Projet
|
||||||
|
|
||||||
|
```
|
||||||
|
Web_eco/
|
||||||
|
├── src/
|
||||||
|
│ ├── components/ # Composants réutilisables
|
||||||
|
│ │ ├── Header.jsx
|
||||||
|
│ │ ├── Sidebar.jsx
|
||||||
|
│ │ └── Footer.jsx
|
||||||
|
│ ├── pages/ # Pages du site
|
||||||
|
│ │ ├── Home.jsx
|
||||||
|
│ │ ├── ToolsComparison.jsx
|
||||||
|
│ │ ├── WebsiteCarbon.jsx
|
||||||
|
│ │ ├── EnvironmentalAudit.jsx
|
||||||
|
│ │ ├── RGESN.jsx
|
||||||
|
│ │ ├── Accessibility.jsx
|
||||||
|
│ │ ├── WAVE.jsx
|
||||||
|
│ │ ├── RGAA.jsx
|
||||||
|
│ │ ├── EcoGuide.jsx
|
||||||
|
│ │ └── Conclusion.jsx
|
||||||
|
│ ├── App.jsx # Composant principal
|
||||||
|
│ ├── main.jsx # Point d'entrée
|
||||||
|
│ └── index.css # Styles globaux
|
||||||
|
├── index.html # Template HTML
|
||||||
|
├── package.json # Dépendances
|
||||||
|
└── vite.config.js # Configuration Vite
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎨 Fonctionnalités
|
||||||
|
|
||||||
|
### Navigation
|
||||||
|
- **Menu latéral responsive** avec sections organisées
|
||||||
|
- **Navigation fluide** entre les différentes sections
|
||||||
|
- **Design moderne** avec palette de couleurs verte (écoresponsable)
|
||||||
|
|
||||||
|
### Contenu Interactif
|
||||||
|
- **Graphique radar** pour comparer les outils d'écoconception
|
||||||
|
- **Tableaux comparatifs** détaillés
|
||||||
|
- **Cartes d'information** visuelles
|
||||||
|
- **Checklists** prêtes à l'emploi
|
||||||
|
- **Exemples de code** avec syntaxe highlight
|
||||||
|
|
||||||
|
### Design Responsive
|
||||||
|
- **Adapté mobile, tablette et desktop**
|
||||||
|
- **Sidebar repliable** sur mobile
|
||||||
|
- **Grids flexibles** qui s'adaptent à la taille d'écran
|
||||||
|
|
||||||
|
## 🌱 Bonnes Pratiques Écoconception Appliquées
|
||||||
|
|
||||||
|
Ce site pratique ce qu'il enseigne :
|
||||||
|
|
||||||
|
✅ **Images optimisées** : Utilisation d'icônes Font Awesome (vectoriel)
|
||||||
|
✅ **CSS léger** : Pas de framework CSS lourd, styles custom optimisés
|
||||||
|
✅ **Code minifié** : Build Vite optimise automatiquement
|
||||||
|
✅ **Lazy loading** : React Router charge les pages à la demande
|
||||||
|
✅ **Polices système** : Utilisation des polices natives du système
|
||||||
|
✅ **Palette sobre** : Couleurs limitées et cohérentes
|
||||||
|
|
||||||
|
## 📊 Résultats Attendus
|
||||||
|
|
||||||
|
Après avoir suivi ce TP, vous serez capable de :
|
||||||
|
- ✅ Mesurer l'empreinte environnementale d'un site web
|
||||||
|
- ✅ Auditer l'accessibilité avec des outils professionnels
|
||||||
|
- ✅ Appliquer les référentiels RGESN et RGAA
|
||||||
|
- ✅ Proposer des recommandations techniques priorisées
|
||||||
|
- ✅ Documenter et justifier vos choix d'écoconception
|
||||||
|
- ✅ Intégrer ces pratiques dans vos projets futurs
|
||||||
|
|
||||||
|
## 📚 Ressources Complémentaires
|
||||||
|
|
||||||
|
### Référentiels
|
||||||
|
- [RGESN](https://ecoresponsable.numerique.gouv.fr/publications/referentiel-general-ecoconception/)
|
||||||
|
- [RGAA](https://accessibilite.numerique.gouv.fr/)
|
||||||
|
- [WCAG 2.1](https://www.w3.org/WAI/WCAG21/quickref/)
|
||||||
|
|
||||||
|
### Outils
|
||||||
|
- [Website Carbon Calculator](https://www.websitecarbon.com/)
|
||||||
|
- [EcoIndex](https://www.ecoindex.fr/)
|
||||||
|
- [WAVE](https://wave.webaim.org/)
|
||||||
|
- [Lighthouse](https://developers.google.com/web/tools/lighthouse)
|
||||||
|
|
||||||
|
### Communautés
|
||||||
|
- [Collectif Conception Numérique Responsable](https://collectif.greenit.fr/)
|
||||||
|
- [Institut du Numérique Responsable](https://institutnr.org/)
|
||||||
|
- [WebAIM](https://webaim.org/)
|
||||||
|
|
||||||
|
## 👨🏫 Auteur du TP
|
||||||
|
|
||||||
|
**Vincent Courboulay**
|
||||||
|
|
||||||
|
## 📄 Licence
|
||||||
|
|
||||||
|
Ce projet est à usage éducatif dans le cadre du TP d'écoconception web.
|
||||||
|
|
||||||
|
## 🤝 Contribution
|
||||||
|
|
||||||
|
Si vous trouvez des améliorations ou des corrections à apporter, n'hésitez pas à proposer vos modifications.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Bon travail et n'oubliez pas : chaque ligne de code compte pour un numérique plus durable et inclusif ! 🌍**
|
||||||
13
docker-compose.yml
Normal file
13
docker-compose.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
# Web site service
|
||||||
|
web-site:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
ports:
|
||||||
|
- "3000"
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
restart: unless-stopped
|
||||||
13
index.html
Normal file
13
index.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>TP Écoconception Web</title>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.jsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
28
nginx.conf
Normal file
28
nginx.conf
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name localhost;
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
# Gestion du SPA (Single Page Application)
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Cache pour les assets statiques
|
||||||
|
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Compression gzip pour l'écoconception
|
||||||
|
gzip on;
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_min_length 1024;
|
||||||
|
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json application/javascript;
|
||||||
|
|
||||||
|
# Sécurité headers
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
|
}
|
||||||
2079
package-lock.json
generated
Normal file
2079
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
23
package.json
Normal file
23
package.json
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "ecoconception-web-tp",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0",
|
||||||
|
"react-router-dom": "^6.20.0",
|
||||||
|
"recharts": "^2.10.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/react": "^18.2.43",
|
||||||
|
"@types/react-dom": "^18.2.17",
|
||||||
|
"@vitejs/plugin-react": "^4.2.1",
|
||||||
|
"vite": "^5.0.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/App.css
Normal file
27
src/App.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
.app {
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-content {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
margin-top: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
flex: 1;
|
||||||
|
padding: 2rem;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.main-content {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-content {
|
||||||
|
margin-top: 60px;
|
||||||
|
}
|
||||||
|
}
|
||||||
48
src/App.jsx
Normal file
48
src/App.jsx
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import React, { useState } from 'react'
|
||||||
|
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
|
||||||
|
import Header from './components/Header'
|
||||||
|
import Sidebar from './components/Sidebar'
|
||||||
|
import Footer from './components/Footer'
|
||||||
|
import Home from './pages/Home'
|
||||||
|
import ToolsComparison from './pages/ToolsComparison'
|
||||||
|
import WebsiteCarbon from './pages/WebsiteCarbon'
|
||||||
|
import EnvironmentalAudit from './pages/EnvironmentalAudit'
|
||||||
|
import RGESN from './pages/RGESN'
|
||||||
|
import Accessibility from './pages/Accessibility'
|
||||||
|
import WAVE from './pages/WAVE'
|
||||||
|
import RGAA from './pages/RGAA'
|
||||||
|
import EcoGuide from './pages/EcoGuide'
|
||||||
|
import Conclusion from './pages/Conclusion'
|
||||||
|
import './App.css'
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
const [sidebarOpen, setSidebarOpen] = useState(false)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Router>
|
||||||
|
<div className="app">
|
||||||
|
<Header toggleSidebar={() => setSidebarOpen(!sidebarOpen)} />
|
||||||
|
<div className="app-content">
|
||||||
|
<Sidebar isOpen={sidebarOpen} closeSidebar={() => setSidebarOpen(false)} />
|
||||||
|
<main className="main-content">
|
||||||
|
<Routes>
|
||||||
|
<Route path="/" element={<Home />} />
|
||||||
|
<Route path="/tools-comparison" element={<ToolsComparison />} />
|
||||||
|
<Route path="/website-carbon" element={<WebsiteCarbon />} />
|
||||||
|
<Route path="/environmental-audit" element={<EnvironmentalAudit />} />
|
||||||
|
<Route path="/rgesn" element={<RGESN />} />
|
||||||
|
<Route path="/accessibility" element={<Accessibility />} />
|
||||||
|
<Route path="/wave" element={<WAVE />} />
|
||||||
|
<Route path="/rgaa" element={<RGAA />} />
|
||||||
|
<Route path="/eco-guide" element={<EcoGuide />} />
|
||||||
|
<Route path="/conclusion" element={<Conclusion />} />
|
||||||
|
</Routes>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
</Router>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App
|
||||||
43
src/components/Footer.css
Normal file
43
src/components/Footer.css
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
.footer {
|
||||||
|
background: var(--primary-dark);
|
||||||
|
color: var(--white);
|
||||||
|
padding: 1.5rem 2rem;
|
||||||
|
margin-top: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-content {
|
||||||
|
max-width: 1400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-section i {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-section p {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.footer-content {
|
||||||
|
flex-direction: column;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-section {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/components/Footer.jsx
Normal file
24
src/components/Footer.jsx
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import './Footer.css'
|
||||||
|
|
||||||
|
function Footer() {
|
||||||
|
return (
|
||||||
|
<footer className="footer">
|
||||||
|
<div className="footer-content">
|
||||||
|
<div className="footer-section">
|
||||||
|
<i className="fas fa-leaf"></i>
|
||||||
|
<p>TP Écoconception Web - 2024</p>
|
||||||
|
</div>
|
||||||
|
<div className="footer-section">
|
||||||
|
<p>Vincent Courboulay</p>
|
||||||
|
</div>
|
||||||
|
<div className="footer-section">
|
||||||
|
<i className="fas fa-recycle"></i>
|
||||||
|
<p>Numérique Responsable & Accessible</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Footer
|
||||||
77
src/components/Header.css
Normal file
77
src/components/Header.css
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
.header {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: linear-gradient(135deg, var(--primary-dark), var(--primary));
|
||||||
|
color: var(--white);
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
box-shadow: 0 2px 10px var(--shadow);
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-content {
|
||||||
|
max-width: 1400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-btn {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: var(--white);
|
||||||
|
font-size: 1.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0.5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
transition: transform 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-btn:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-icon {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-title h1 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-subtitle {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.header {
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-content {
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-title h1 {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-subtitle {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/components/Header.jsx
Normal file
24
src/components/Header.jsx
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import './Header.css'
|
||||||
|
|
||||||
|
function Header({ toggleSidebar }) {
|
||||||
|
return (
|
||||||
|
<header className="header">
|
||||||
|
<div className="header-content">
|
||||||
|
<button className="menu-btn" onClick={toggleSidebar}>
|
||||||
|
<i className="fas fa-bars"></i>
|
||||||
|
</button>
|
||||||
|
<div className="header-title">
|
||||||
|
<i className="fas fa-leaf header-icon"></i>
|
||||||
|
<h1>TP Écoconception Web</h1>
|
||||||
|
</div>
|
||||||
|
<div className="header-subtitle">
|
||||||
|
<i className="fas fa-globe"></i>
|
||||||
|
<span>Numérique Responsable</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Header
|
||||||
108
src/components/Sidebar.css
Normal file
108
src/components/Sidebar.css
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
.sidebar-overlay {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 998;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-overlay.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 70px;
|
||||||
|
bottom: 0;
|
||||||
|
width: 280px;
|
||||||
|
background: var(--white);
|
||||||
|
box-shadow: 2px 0 10px var(--shadow);
|
||||||
|
transform: translateX(-100%);
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
overflow-y: auto;
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar.open {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-nav {
|
||||||
|
padding: 1rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link,
|
||||||
|
.nav-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
padding: 0.875rem 1.5rem;
|
||||||
|
color: var(--text);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.3s;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-section {
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: default;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link:hover {
|
||||||
|
background: var(--accent);
|
||||||
|
color: var(--primary-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link.active {
|
||||||
|
background: var(--primary);
|
||||||
|
color: var(--white);
|
||||||
|
border-left: 4px solid var(--primary-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-menu {
|
||||||
|
padding-left: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-link {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link i {
|
||||||
|
width: 20px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
.sidebar {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-overlay {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
margin-left: 280px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.sidebar {
|
||||||
|
top: 60px;
|
||||||
|
width: 260px;
|
||||||
|
}
|
||||||
|
}
|
||||||
76
src/components/Sidebar.jsx
Normal file
76
src/components/Sidebar.jsx
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { NavLink } from 'react-router-dom'
|
||||||
|
import './Sidebar.css'
|
||||||
|
|
||||||
|
function Sidebar({ isOpen, closeSidebar }) {
|
||||||
|
const menuItems = [
|
||||||
|
{ path: '/', icon: 'fa-home', label: 'Accueil' },
|
||||||
|
{
|
||||||
|
label: 'Audit Initial',
|
||||||
|
icon: 'fa-search',
|
||||||
|
children: [
|
||||||
|
{ path: '/tools-comparison', icon: 'fa-chart-bar', label: 'Comparaison d\'outils' },
|
||||||
|
{ path: '/website-carbon', icon: 'fa-calculator', label: 'Website Carbon' },
|
||||||
|
{ path: '/environmental-audit', icon: 'fa-leaf', label: 'Audit Environnemental' },
|
||||||
|
{ path: '/rgesn', icon: 'fa-book', label: 'RGESN' },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Accessibilité',
|
||||||
|
icon: 'fa-universal-access',
|
||||||
|
children: [
|
||||||
|
{ path: '/accessibility', icon: 'fa-users', label: 'Principes' },
|
||||||
|
{ path: '/wave', icon: 'fa-water', label: 'WAVE' },
|
||||||
|
{ path: '/rgaa', icon: 'fa-check-circle', label: 'RGAA' },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ path: '/eco-guide', icon: 'fa-map', label: 'Guide Écoconception' },
|
||||||
|
{ path: '/conclusion', icon: 'fa-flag-checkered', label: 'Conclusion' },
|
||||||
|
]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className={`sidebar-overlay ${isOpen ? 'active' : ''}`} onClick={closeSidebar}></div>
|
||||||
|
<aside className={`sidebar ${isOpen ? 'open' : ''}`}>
|
||||||
|
<nav className="sidebar-nav">
|
||||||
|
{menuItems.map((item, index) => (
|
||||||
|
<div key={index} className="menu-item">
|
||||||
|
{item.path ? (
|
||||||
|
<NavLink
|
||||||
|
to={item.path}
|
||||||
|
className={({ isActive }) => `nav-link ${isActive ? 'active' : ''}`}
|
||||||
|
onClick={closeSidebar}
|
||||||
|
>
|
||||||
|
<i className={`fas ${item.icon}`}></i>
|
||||||
|
<span>{item.label}</span>
|
||||||
|
</NavLink>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div className="nav-section">
|
||||||
|
<i className={`fas ${item.icon}`}></i>
|
||||||
|
<span>{item.label}</span>
|
||||||
|
</div>
|
||||||
|
<div className="sub-menu">
|
||||||
|
{item.children.map((child, childIndex) => (
|
||||||
|
<NavLink
|
||||||
|
key={childIndex}
|
||||||
|
to={child.path}
|
||||||
|
className={({ isActive }) => `nav-link sub-link ${isActive ? 'active' : ''}`}
|
||||||
|
onClick={closeSidebar}
|
||||||
|
>
|
||||||
|
<i className={`fas ${child.icon}`}></i>
|
||||||
|
<span>{child.label}</span>
|
||||||
|
</NavLink>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</nav>
|
||||||
|
</aside>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Sidebar
|
||||||
60
src/index.css
Normal file
60
src/index.css
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--primary: #2d6a4f;
|
||||||
|
--primary-dark: #1b4332;
|
||||||
|
--primary-light: #40916c;
|
||||||
|
--secondary: #52b788;
|
||||||
|
--accent: #74c69d;
|
||||||
|
--bg: #f8f9fa;
|
||||||
|
--text: #212529;
|
||||||
|
--text-light: #6c757d;
|
||||||
|
--white: #ffffff;
|
||||||
|
--border: #dee2e6;
|
||||||
|
--shadow: rgba(0, 0, 0, 0.1);
|
||||||
|
--danger: #dc3545;
|
||||||
|
--warning: #ffc107;
|
||||||
|
--success: #28a745;
|
||||||
|
--info: #17a2b8;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||||
|
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||||
|
sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
background-color: var(--bg);
|
||||||
|
color: var(--text);
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
background: #f4f4f4;
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scrollbar Styling */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: var(--bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--primary);
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: var(--primary-dark);
|
||||||
|
}
|
||||||
10
src/main.jsx
Normal file
10
src/main.jsx
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import ReactDOM from 'react-dom/client'
|
||||||
|
import App from './App'
|
||||||
|
import './index.css'
|
||||||
|
|
||||||
|
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<App />
|
||||||
|
</React.StrictMode>,
|
||||||
|
)
|
||||||
384
src/pages/Accessibility.jsx
Normal file
384
src/pages/Accessibility.jsx
Normal file
@@ -0,0 +1,384 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import './SharedPages.css'
|
||||||
|
|
||||||
|
function Accessibility() {
|
||||||
|
return (
|
||||||
|
<div className="shared-page">
|
||||||
|
<header className="page-header">
|
||||||
|
<i className="fas fa-universal-access"></i>
|
||||||
|
<h1>Principes de l'Accessibilité Web</h1>
|
||||||
|
<p className="subtitle">Vers un numérique inclusif</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-question-circle"></i> Qu'est-ce que l'accessibilité numérique ?</h2>
|
||||||
|
<p>
|
||||||
|
L'accessibilité numérique consiste à rendre les sites web et applications utilisables par tous,
|
||||||
|
<strong> y compris les personnes en situation de handicap</strong>. Cela englobe les handicaps visuels,
|
||||||
|
auditifs, moteurs, cognitifs et temporaires.
|
||||||
|
</p>
|
||||||
|
<div className="stats-grid" style={{display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: '1.5rem', marginTop: '2rem'}}>
|
||||||
|
<div style={{padding: '1.5rem', background: 'linear-gradient(135deg, var(--primary), var(--secondary))', color: 'white', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '2.5rem', fontWeight: 'bold'}}>15%</div>
|
||||||
|
<div>de la population mondiale vit avec un handicap</div>
|
||||||
|
</div>
|
||||||
|
<div style={{padding: '1.5rem', background: 'linear-gradient(135deg, var(--info), #52b788)', color: 'white', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '2.5rem', fontWeight: 'bold'}}>1 Md</div>
|
||||||
|
<div>de personnes dans le monde</div>
|
||||||
|
</div>
|
||||||
|
<div style={{padding: '1.5rem', background: 'linear-gradient(135deg, var(--warning), #ffc107)', color: 'white', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '2.5rem', fontWeight: 'bold'}}>70%</div>
|
||||||
|
<div>des sites ne sont pas accessibles</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-users"></i> Types de handicaps concernés</h2>
|
||||||
|
<div className="disabilities-grid" style={{display: 'grid', gap: '1.5rem'}}>
|
||||||
|
{[
|
||||||
|
{
|
||||||
|
type: 'Handicap visuel',
|
||||||
|
icon: 'fa-eye-slash',
|
||||||
|
examples: 'Cécité, malvoyance, daltonisme',
|
||||||
|
needs: 'Lecteurs d\'écran, contrastes élevés, alternatives textuelles',
|
||||||
|
color: '#2d6a4f'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'Handicap auditif',
|
||||||
|
icon: 'fa-deaf',
|
||||||
|
examples: 'Surdité, malentendance',
|
||||||
|
needs: 'Sous-titres, transcriptions textuelles, langue des signes',
|
||||||
|
color: '#52b788'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'Handicap moteur',
|
||||||
|
icon: 'fa-wheelchair',
|
||||||
|
examples: 'Mobilité réduite, tremblements, paralysie',
|
||||||
|
needs: 'Navigation au clavier, zones cliquables larges, commandes vocales',
|
||||||
|
color: '#74c69d'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'Handicap cognitif',
|
||||||
|
icon: 'fa-brain',
|
||||||
|
examples: 'Dyslexie, TDAH, troubles de la mémoire',
|
||||||
|
needs: 'Langage simple, navigation claire, temps de lecture adaptable',
|
||||||
|
color: '#95d5b2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'Handicap temporaire',
|
||||||
|
icon: 'fa-band-aid',
|
||||||
|
examples: 'Bras cassé, conjonctivite, environnement bruyant',
|
||||||
|
needs: 'Adaptabilité, multi-modalité',
|
||||||
|
color: '#b7e4c7'
|
||||||
|
}
|
||||||
|
].map((disability, index) => (
|
||||||
|
<div key={index} style={{
|
||||||
|
padding: '1.5rem',
|
||||||
|
background: 'var(--bg)',
|
||||||
|
borderRadius: '8px',
|
||||||
|
borderLeft: `4px solid ${disability.color}`,
|
||||||
|
display: 'grid',
|
||||||
|
gap: '0.75rem'
|
||||||
|
}}>
|
||||||
|
<h3 style={{margin: 0, display: 'flex', alignItems: 'center', gap: '0.75rem', color: 'var(--primary-dark)'}}>
|
||||||
|
<i className={`fas ${disability.icon}`} style={{color: disability.color}}></i>
|
||||||
|
{disability.type}
|
||||||
|
</h3>
|
||||||
|
<div>
|
||||||
|
<strong>Exemples :</strong> {disability.examples}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<strong>Besoins :</strong> {disability.needs}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-balance-scale"></i> WCAG : Les 4 principes fondamentaux</h2>
|
||||||
|
<p style={{marginBottom: '2rem'}}>
|
||||||
|
Les <strong>Web Content Accessibility Guidelines (WCAG)</strong> définissent 4 principes universels pour l'accessibilité web,
|
||||||
|
repris par le RGAA français :
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="principles-grid" style={{display: 'grid', gap: '2rem'}}>
|
||||||
|
<div style={{padding: '2rem', background: 'var(--bg)', borderRadius: '8px', borderTop: '4px solid #2d6a4f'}}>
|
||||||
|
<div style={{display: 'flex', alignItems: 'center', gap: '1rem', marginBottom: '1rem'}}>
|
||||||
|
<div style={{
|
||||||
|
width: '60px',
|
||||||
|
height: '60px',
|
||||||
|
background: 'linear-gradient(135deg, #2d6a4f, #52b788)',
|
||||||
|
borderRadius: '50%',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
color: 'white',
|
||||||
|
fontSize: '1.5rem',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}}>1</div>
|
||||||
|
<h3 style={{margin: 0, color: 'var(--primary-dark)'}}>Perceptible</h3>
|
||||||
|
</div>
|
||||||
|
<p><strong>Les utilisateurs doivent pouvoir percevoir l'information</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Fournir des alternatives textuelles aux contenus non textuels (images, vidéos)</li>
|
||||||
|
<li>Assurer des contrastes suffisants (au moins 4.5:1 pour le texte)</li>
|
||||||
|
<li>Ne pas se fier uniquement à la couleur pour transmettre l'information</li>
|
||||||
|
<li>Rendre le contenu adaptable (responsive, redimensionnable)</li>
|
||||||
|
</ul>
|
||||||
|
<div className="example-box" style={{marginTop: '1rem', padding: '1rem', background: 'white', borderRadius: '4px'}}>
|
||||||
|
<strong>Exemple :</strong> Une image doit avoir un attribut <code>alt</code> descriptif pour les lecteurs d'écran.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '2rem', background: 'var(--bg)', borderRadius: '8px', borderTop: '4px solid #52b788'}}>
|
||||||
|
<div style={{display: 'flex', alignItems: 'center', gap: '1rem', marginBottom: '1rem'}}>
|
||||||
|
<div style={{
|
||||||
|
width: '60px',
|
||||||
|
height: '60px',
|
||||||
|
background: 'linear-gradient(135deg, #52b788, #74c69d)',
|
||||||
|
borderRadius: '50%',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
color: 'white',
|
||||||
|
fontSize: '1.5rem',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}}>2</div>
|
||||||
|
<h3 style={{margin: 0, color: 'var(--primary-dark)'}}>Utilisable</h3>
|
||||||
|
</div>
|
||||||
|
<p><strong>Les utilisateurs doivent pouvoir utiliser l'interface</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Toutes les fonctionnalités accessibles au clavier (sans souris)</li>
|
||||||
|
<li>Laisser suffisamment de temps pour lire et utiliser le contenu</li>
|
||||||
|
<li>Ne pas utiliser d'éléments susceptibles de provoquer des crises (flashs)</li>
|
||||||
|
<li>Fournir des aides à la navigation (menu, fil d'Ariane, liens d'évitement)</li>
|
||||||
|
</ul>
|
||||||
|
<div className="example-box" style={{marginTop: '1rem', padding: '1rem', background: 'white', borderRadius: '4px'}}>
|
||||||
|
<strong>Exemple :</strong> Un menu déroulant doit être navigable avec les flèches du clavier et la touche Entrée.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '2rem', background: 'var(--bg)', borderRadius: '8px', borderTop: '4px solid #74c69d'}}>
|
||||||
|
<div style={{display: 'flex', alignItems: 'center', gap: '1rem', marginBottom: '1rem'}}>
|
||||||
|
<div style={{
|
||||||
|
width: '60px',
|
||||||
|
height: '60px',
|
||||||
|
background: 'linear-gradient(135deg, #74c69d, #95d5b2)',
|
||||||
|
borderRadius: '50%',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
color: 'white',
|
||||||
|
fontSize: '1.5rem',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}}>3</div>
|
||||||
|
<h3 style={{margin: 0, color: 'var(--primary-dark)'}}>Compréhensible</h3>
|
||||||
|
</div>
|
||||||
|
<p><strong>Les utilisateurs doivent pouvoir comprendre l'information et l'interface</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Rendre le texte lisible et compréhensible (langage simple, abréviations expliquées)</li>
|
||||||
|
<li>Faire en sorte que les pages fonctionnent de manière prévisible</li>
|
||||||
|
<li>Aider les utilisateurs à éviter et corriger les erreurs (validation de formulaires claire)</li>
|
||||||
|
<li>Fournir des instructions claires et des labels explicites</li>
|
||||||
|
</ul>
|
||||||
|
<div className="example-box" style={{marginTop: '1rem', padding: '1rem', background: 'white', borderRadius: '4px'}}>
|
||||||
|
<strong>Exemple :</strong> Un message d'erreur de formulaire doit expliquer clairement le problème et comment le corriger.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '2rem', background: 'var(--bg)', borderRadius: '8px', borderTop: '4px solid #95d5b2'}}>
|
||||||
|
<div style={{display: 'flex', alignItems: 'center', gap: '1rem', marginBottom: '1rem'}}>
|
||||||
|
<div style={{
|
||||||
|
width: '60px',
|
||||||
|
height: '60px',
|
||||||
|
background: 'linear-gradient(135deg, #95d5b2, #b7e4c7)',
|
||||||
|
borderRadius: '50%',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
color: 'white',
|
||||||
|
fontSize: '1.5rem',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}}>4</div>
|
||||||
|
<h3 style={{margin: 0, color: 'var(--primary-dark)'}}>Robuste</h3>
|
||||||
|
</div>
|
||||||
|
<p><strong>Le contenu doit être compatible avec les technologies actuelles et futures</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Utiliser du HTML valide et sémantique</li>
|
||||||
|
<li>Assurer la compatibilité avec les technologies d'assistance (lecteurs d'écran)</li>
|
||||||
|
<li>Utiliser ARIA (Accessible Rich Internet Applications) quand nécessaire</li>
|
||||||
|
<li>Tester avec différents navigateurs et technologies d'assistance</li>
|
||||||
|
</ul>
|
||||||
|
<div className="example-box" style={{marginTop: '1rem', padding: '1rem', background: 'white', borderRadius: '4px'}}>
|
||||||
|
<strong>Exemple :</strong> Utiliser les balises sémantiques <code><nav></code>, <code><main></code>, <code><article></code> plutôt que des <code><div></code> génériques.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-flag-checkered"></i> Le RGAA : Référentiel français</h2>
|
||||||
|
<div className="info-card">
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Nom complet:</strong>
|
||||||
|
<span>Référentiel Général d'Amélioration de l'Accessibilité</span>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Créé par:</strong>
|
||||||
|
<span>DINUM (Direction Interministérielle du Numérique)</span>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Base:</strong>
|
||||||
|
<span>WCAG 2.1 (adapté au contexte français)</span>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Version actuelle:</strong>
|
||||||
|
<span>RGAA 4.1 (2021)</span>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Obligation légale:</strong>
|
||||||
|
<span>Services publics, entreprises > 250M€ CA</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{marginTop: '2rem'}}>
|
||||||
|
<h3>Les 13 thèmes du RGAA</h3>
|
||||||
|
<div style={{display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(150px, 1fr))', gap: '0.75rem', marginTop: '1rem'}}>
|
||||||
|
{[
|
||||||
|
'Images', 'Cadres', 'Couleurs', 'Multimédia', 'Tableaux', 'Liens',
|
||||||
|
'Scripts', 'Éléments obligatoires', 'Structuration', 'Présentation',
|
||||||
|
'Formulaires', 'Navigation', 'Consultation'
|
||||||
|
].map((theme, index) => (
|
||||||
|
<div key={index} style={{
|
||||||
|
padding: '0.75rem',
|
||||||
|
background: 'var(--primary)',
|
||||||
|
color: 'white',
|
||||||
|
borderRadius: '4px',
|
||||||
|
textAlign: 'center',
|
||||||
|
fontSize: '0.9rem',
|
||||||
|
fontWeight: '500'
|
||||||
|
}}>
|
||||||
|
{theme}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-hands-helping"></i> Bénéfices de l'accessibilité</h2>
|
||||||
|
<div className="benefits-grid" style={{display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))', gap: '1.5rem'}}>
|
||||||
|
<div style={{padding: '1.5rem', background: '#d4edda', borderRadius: '8px', borderLeft: '4px solid var(--success)'}}>
|
||||||
|
<h4 style={{marginTop: 0, display: 'flex', alignItems: 'center', gap: '0.5rem'}}>
|
||||||
|
<i className="fas fa-users"></i> Social & Éthique
|
||||||
|
</h4>
|
||||||
|
<ul style={{marginBottom: 0}}>
|
||||||
|
<li>Inclusion de tous les utilisateurs</li>
|
||||||
|
<li>Respect des droits fondamentaux</li>
|
||||||
|
<li>Image responsable</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: '#cfe2ff', borderRadius: '8px', borderLeft: '4px solid var(--info)'}}>
|
||||||
|
<h4 style={{marginTop: 0, display: 'flex', alignItems: 'center', gap: '0.5rem'}}>
|
||||||
|
<i className="fas fa-chart-line"></i> Business
|
||||||
|
</h4>
|
||||||
|
<ul style={{marginBottom: 0}}>
|
||||||
|
<li>Élargissement de l'audience (+15%)</li>
|
||||||
|
<li>Amélioration du SEO</li>
|
||||||
|
<li>Réduction du taux de rebond</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: '#fff3cd', borderRadius: '8px', borderLeft: '4px solid var(--warning)'}}>
|
||||||
|
<h4 style={{marginTop: 0, display: 'flex', alignItems: 'center', gap: '0.5rem'}}>
|
||||||
|
<i className="fas fa-gavel"></i> Légal
|
||||||
|
</h4>
|
||||||
|
<ul style={{marginBottom: 0}}>
|
||||||
|
<li>Conformité réglementaire</li>
|
||||||
|
<li>Éviter les sanctions</li>
|
||||||
|
<li>Anticipation des obligations</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: '#d1ecf1', borderRadius: '8px', borderLeft: '4px solid #0dcaf0'}}>
|
||||||
|
<h4 style={{marginTop: 0, display: 'flex', alignItems: 'center', gap: '0.5rem'}}>
|
||||||
|
<i className="fas fa-code"></i> Technique
|
||||||
|
</h4>
|
||||||
|
<ul style={{marginBottom: 0}}>
|
||||||
|
<li>Code plus robuste et maintenable</li>
|
||||||
|
<li>Meilleure compatibilité</li>
|
||||||
|
<li>Performance améliorée</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-tools"></i> Bonnes pratiques essentielles</h2>
|
||||||
|
<div className="best-practices" style={{display: 'grid', gap: '1rem'}}>
|
||||||
|
{[
|
||||||
|
{
|
||||||
|
practice: 'Ajouter des attributs alt aux images',
|
||||||
|
code: '<img src="logo.png" alt="Logo de l\'organisation">',
|
||||||
|
impact: 'Essentiel pour les lecteurs d\'écran'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
practice: 'Assurer un contraste suffisant',
|
||||||
|
code: 'Ratio minimum 4.5:1 pour texte normal, 3:1 pour texte large',
|
||||||
|
impact: 'Lisibilité pour malvoyants et daltoniens'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
practice: 'Structurer avec des titres hiérarchiques',
|
||||||
|
code: '<h1>, <h2>, <h3>... sans sauter de niveau',
|
||||||
|
impact: 'Navigation et compréhension de la structure'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
practice: 'Rendre les formulaires accessibles',
|
||||||
|
code: '<label for="email">Email</label><input id="email" type="email">',
|
||||||
|
impact: 'Association claire label/champ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
practice: 'Navigation au clavier',
|
||||||
|
code: 'tabindex, focus visible, touches Entrée/Échap fonctionnelles',
|
||||||
|
impact: 'Utilisateurs sans souris'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
practice: 'Utiliser ARIA avec prudence',
|
||||||
|
code: 'role="navigation", aria-label="Menu principal"',
|
||||||
|
impact: 'Enrichir la sémantique pour technologies d\'assistance'
|
||||||
|
}
|
||||||
|
].map((item, index) => (
|
||||||
|
<div key={index} style={{
|
||||||
|
padding: '1.5rem',
|
||||||
|
background: 'var(--bg)',
|
||||||
|
borderRadius: '8px',
|
||||||
|
borderLeft: '4px solid var(--primary)'
|
||||||
|
}}>
|
||||||
|
<h4 style={{marginTop: 0, color: 'var(--primary-dark)'}}>{item.practice}</h4>
|
||||||
|
<div className="formula">
|
||||||
|
<code>{item.code}</code>
|
||||||
|
</div>
|
||||||
|
<p style={{margin: '0.5rem 0 0 0', color: 'var(--text-light)', fontSize: '0.9rem'}}>
|
||||||
|
<strong>Impact :</strong> {item.impact}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div className="conclusion-banner">
|
||||||
|
<i className="fas fa-check-circle"></i>
|
||||||
|
<div>
|
||||||
|
<strong>L'accessibilité, c'est pour tout le monde</strong>
|
||||||
|
<p>Un site accessible est plus utilisable, plus performant, mieux référencé et conforme à la loi.
|
||||||
|
L'accessibilité n'est pas une contrainte, c'est une opportunité d'améliorer l'expérience de tous les utilisateurs.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Accessibility
|
||||||
316
src/pages/Conclusion.jsx
Normal file
316
src/pages/Conclusion.jsx
Normal file
@@ -0,0 +1,316 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import './SharedPages.css'
|
||||||
|
|
||||||
|
function Conclusion() {
|
||||||
|
return (
|
||||||
|
<div className="shared-page">
|
||||||
|
<header className="page-header">
|
||||||
|
<i className="fas fa-flag-checkered"></i>
|
||||||
|
<h1>Conclusion</h1>
|
||||||
|
<p className="subtitle">Bilan et perspectives du numérique responsable</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-check-circle"></i> Synthèse de l'analyse</h2>
|
||||||
|
<p>
|
||||||
|
Ce compte rendu présente une analyse complète des enjeux du <strong>numérique responsable</strong>,
|
||||||
|
à la fois sous l'angle environnemental et social. L'audit réalisé sur ville-de-chauray.fr
|
||||||
|
a permis d'identifier des axes d'amélioration concrets pour réduire l'impact environnemental et améliorer l'accessibilité.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '2rem', marginTop: '2rem'}}>
|
||||||
|
<div style={{padding: '2rem', background: 'linear-gradient(135deg, #2d6a4f, #52b788)', color: 'white', borderRadius: '12px'}}>
|
||||||
|
<div style={{fontSize: '3rem', marginBottom: '1rem'}}>🌱</div>
|
||||||
|
<h3 style={{marginTop: 0, color: 'white'}}>Écoconception</h3>
|
||||||
|
<ul style={{margin: 0}}>
|
||||||
|
<li>Utilisation d'outils d'audit (Website Carbon, EcoIndex)</li>
|
||||||
|
<li>Mesure de l'impact CO₂ et optimisation</li>
|
||||||
|
<li>Application du RGESN</li>
|
||||||
|
<li>Recommandations priorisées</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '2rem', background: 'linear-gradient(135deg, #17a2b8, #52b788)', color: 'white', borderRadius: '12px'}}>
|
||||||
|
<div style={{fontSize: '3rem', marginBottom: '1rem'}}>♿</div>
|
||||||
|
<h3 style={{marginTop: 0, color: 'white'}}>Accessibilité</h3>
|
||||||
|
<ul style={{margin: 0}}>
|
||||||
|
<li>Principes POUR (Perceptible, Utilisable, Compréhensible, Robuste)</li>
|
||||||
|
<li>Audit avec WAVE</li>
|
||||||
|
<li>Conformité RGAA</li>
|
||||||
|
<li>Corrections techniques</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '2rem', background: 'linear-gradient(135deg, #ffc107, #ff9800)', color: 'white', borderRadius: '12px'}}>
|
||||||
|
<div style={{fontSize: '3rem', marginBottom: '1rem'}}>🚀</div>
|
||||||
|
<h3 style={{marginTop: 0, color: 'white'}}>Méthodologie</h3>
|
||||||
|
<ul style={{margin: 0}}>
|
||||||
|
<li>Guide d'écoconception pour projet SAE</li>
|
||||||
|
<li>Planning et checklists</li>
|
||||||
|
<li>Documentation technique</li>
|
||||||
|
<li>Argumentaire pour décideurs</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-leaf"></i> Volet Écoconception Environnemental</h2>
|
||||||
|
|
||||||
|
<div style={{padding: '2rem', background: 'var(--bg)', borderRadius: '8px', marginBottom: '1.5rem'}}>
|
||||||
|
<h3>Compétences acquises</h3>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<strong>Mesurer l'impact :</strong> Vous savez utiliser Website Carbon Calculator pour estimer
|
||||||
|
l'empreinte carbone d'une page web (émissions de CO₂, poids des pages, nombre de requêtes)
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Analyser et comparer :</strong> Vous maîtrisez la comparaison d'outils d'écoconception
|
||||||
|
(EcoIndex, Lighthouse, GreenIT-Analysis, Scaphandre)
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Appliquer le RGESN :</strong> Vous pouvez auditer un service selon les 79 critères du
|
||||||
|
Référentiel Général d'Écoconception des Services Numériques
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Proposer des solutions :</strong> Vous êtes capable de rédiger un rapport d'audit complet
|
||||||
|
avec diagnostic, solutions techniques et plan d'action réaliste
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: '#d4edda', borderRadius: '8px', borderLeft: '4px solid var(--success)'}}>
|
||||||
|
<h4 style={{marginTop: 0, display: 'flex', alignItems: 'center', gap: '0.5rem'}}>
|
||||||
|
<i className="fas fa-chart-line"></i> Résultats types attendus
|
||||||
|
</h4>
|
||||||
|
<ul style={{marginBottom: 0}}>
|
||||||
|
<li>Réduction de <strong>40-50%</strong> de l'empreinte carbone d'un site</li>
|
||||||
|
<li>Amélioration du score Lighthouse de <strong>20-30 points</strong></li>
|
||||||
|
<li>Diminution du poids des pages de <strong>30-60%</strong></li>
|
||||||
|
<li>Temps de chargement divisé par <strong>2</strong></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-universal-access"></i> Volet Accessibilité et Inclusion</h2>
|
||||||
|
|
||||||
|
<div style={{padding: '2rem', background: 'var(--bg)', borderRadius: '8px', marginBottom: '1.5rem'}}>
|
||||||
|
<h3>Compétences acquises</h3>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<strong>Identifier les erreurs :</strong> Vous savez utiliser WAVE pour détecter rapidement
|
||||||
|
les problèmes d'accessibilité (images sans alt, contrastes insuffisants, structure incohérente)
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Comprendre les 4 principes :</strong> Vous maîtrisez les principes POUR
|
||||||
|
(Perceptible, Utilisable, Compréhensible, Robuste)
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Auditer selon le RGAA :</strong> Vous pouvez évaluer la conformité d'un site
|
||||||
|
selon les 106 critères du référentiel français
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Proposer des corrections :</strong> Vous êtes capable de prioriser les actions
|
||||||
|
correctives en fonction de leur impact et faisabilité
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: '#cfe2ff', borderRadius: '8px', borderLeft: '4px solid var(--info)'}}>
|
||||||
|
<h4 style={{marginTop: 0, display: 'flex', alignItems: 'center', gap: '0.5rem'}}>
|
||||||
|
<i className="fas fa-users"></i> Impact social
|
||||||
|
</h4>
|
||||||
|
<ul style={{marginBottom: 0}}>
|
||||||
|
<li><strong>15%</strong> de la population mondiale concernée (1 milliard de personnes)</li>
|
||||||
|
<li><strong>+20-35%</strong> d'audience potentielle avec un site accessible</li>
|
||||||
|
<li>Meilleure expérience pour <strong>tous</strong> les utilisateurs (seniors, mobiles, contextes difficiles)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-balance-scale"></i> Vision Globale : Numérique Responsable</h2>
|
||||||
|
|
||||||
|
<div style={{padding: '2rem', background: 'linear-gradient(135deg, var(--primary), var(--primary-light))', color: 'white', borderRadius: '12px', marginBottom: '2rem'}}>
|
||||||
|
<h3 style={{marginTop: 0, color: 'white', textAlign: 'center', fontSize: '1.5rem'}}>
|
||||||
|
Service Numérique Idéal = Sobre + Performant + Accessible
|
||||||
|
</h3>
|
||||||
|
<p style={{textAlign: 'center', fontSize: '1.1rem', margin: 0}}>
|
||||||
|
En combinant écoconception et accessibilité, vous créez des services de qualité qui bénéficient à tous
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gap: '1.5rem'}}>
|
||||||
|
<div style={{padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px'}}>
|
||||||
|
<h4 style={{marginTop: 0, color: 'var(--primary-dark)'}}>Vous savez argumenter</h4>
|
||||||
|
<p>
|
||||||
|
Vous êtes capable de convaincre décideurs et clients sur l'importance de ces démarches,
|
||||||
|
en mettant en avant les bénéfices environnementaux, sociaux, économiques et juridiques.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px'}}>
|
||||||
|
<h4 style={{marginTop: 0, color: 'var(--primary-dark)'}}>Vous savez mobiliser</h4>
|
||||||
|
<p>
|
||||||
|
Vous pouvez proposer un plan d'action concret avec échéancier, acteurs concernés,
|
||||||
|
et indicateurs de suivi pour mobiliser les parties prenantes.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px'}}>
|
||||||
|
<h4 style={{marginTop: 0, color: 'var(--primary-dark)'}}>Vous avez un esprit critique</h4>
|
||||||
|
<p>
|
||||||
|
Vous avez développé un esprit critique face aux outils et référentiels,
|
||||||
|
en identifiant leurs forces et leurs limites.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-trophy"></i> Bénéfices Multiples</h2>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))', gap: '1.5rem'}}>
|
||||||
|
<div style={{padding: '1.5rem', background: '#d4edda', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<i className="fas fa-leaf" style={{fontSize: '2.5rem', color: '#28a745', marginBottom: '1rem'}}></i>
|
||||||
|
<h4 style={{color: '#155724', marginBottom: '0.5rem'}}>Environnementaux</h4>
|
||||||
|
<p style={{margin: 0, color: '#155724'}}>Réduction empreinte carbone, économie ressources</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: '#cfe2ff', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<i className="fas fa-users" style={{fontSize: '2.5rem', color: '#0d6efd', marginBottom: '1rem'}}></i>
|
||||||
|
<h4 style={{color: '#084298', marginBottom: '0.5rem'}}>Sociaux</h4>
|
||||||
|
<p style={{margin: 0, color: '#084298'}}>Inclusion, accessibilité universelle</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: '#fff3cd', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<i className="fas fa-euro-sign" style={{fontSize: '2.5rem', color: '#856404', marginBottom: '1rem'}}></i>
|
||||||
|
<h4 style={{color: '#856404', marginBottom: '0.5rem'}}>Économiques</h4>
|
||||||
|
<p style={{margin: 0, color: '#856404'}}>Réduction coûts, meilleur SEO, + conversions</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: '#f8d7da', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<i className="fas fa-gavel" style={{fontSize: '2.5rem', color: '#721c24', marginBottom: '1rem'}}></i>
|
||||||
|
<h4 style={{color: '#721c24', marginBottom: '0.5rem'}}>Juridiques</h4>
|
||||||
|
<p style={{margin: 0, color: '#721c24'}}>Conformité légale, anticipation obligations</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-briefcase"></i> Impact Professionnel</h2>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gap: '2rem'}}>
|
||||||
|
<div style={{padding: '2rem', background: 'var(--bg)', borderRadius: '8px', borderLeft: '4px solid var(--primary)'}}>
|
||||||
|
<h3 style={{marginTop: 0}}>Ces compétences sont recherchées</h3>
|
||||||
|
<p>
|
||||||
|
L'écoconception et l'accessibilité sont de plus en plus demandées dans le monde professionnel :
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Obligations légales croissantes</strong> (loi REEN, accessibilité numérique)</li>
|
||||||
|
<li><strong>RSE prioritaire</strong> pour les entreprises</li>
|
||||||
|
<li><strong>Demande clients</strong> sensibles aux enjeux environnementaux et sociaux</li>
|
||||||
|
<li><strong>Différenciation concurrentielle</strong> importante</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '2rem', background: 'var(--bg)', borderRadius: '8px', borderLeft: '4px solid var(--secondary)'}}>
|
||||||
|
<h3 style={{marginTop: 0}}>Valorisez ces compétences</h3>
|
||||||
|
<ul>
|
||||||
|
<li>Intégrez ces pratiques dans vos <strong>projets personnels et professionnels</strong></li>
|
||||||
|
<li>Mentionnez-les sur votre <strong>CV et portfolio</strong></li>
|
||||||
|
<li>Obtenez des <strong>certifications</strong> (Opquast, accessibilité numérique)</li>
|
||||||
|
<li>Partagez vos réalisations sur <strong>LinkedIn et GitHub</strong></li>
|
||||||
|
<li>Contribuez à des <strong>projets open source</strong> écoresponsables</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-rocket"></i> Pour Aller Plus Loin</h2>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gap: '1.5rem'}}>
|
||||||
|
<div style={{padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px'}}>
|
||||||
|
<h4 style={{marginTop: 0, display: 'flex', alignItems: 'center', gap: '0.5rem'}}>
|
||||||
|
<i className="fas fa-book"></i> Ressources complémentaires
|
||||||
|
</h4>
|
||||||
|
<ul style={{marginBottom: 0}}>
|
||||||
|
<li><strong>RGESN :</strong> <a href="https://ecoresponsable.numerique.gouv.fr/publications/referentiel-general-ecoconception/" target="_blank" rel="noopener noreferrer">numerique.gouv.fr</a></li>
|
||||||
|
<li><strong>RGAA :</strong> <a href="https://accessibilite.numerique.gouv.fr/" target="_blank" rel="noopener noreferrer">accessibilite.numerique.gouv.fr</a></li>
|
||||||
|
<li><strong>GR491 :</strong> 491 bonnes pratiques numériques responsables</li>
|
||||||
|
<li><strong>The Green Web Foundation :</strong> Annuaire hébergeurs verts</li>
|
||||||
|
<li><strong>WebAIM :</strong> Ressources et formations accessibilité</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px'}}>
|
||||||
|
<h4 style={{marginTop: 0, display: 'flex', alignItems: 'center', gap: '0.5rem'}}>
|
||||||
|
<i className="fas fa-users"></i> Communautés
|
||||||
|
</h4>
|
||||||
|
<ul style={{marginBottom: 0}}>
|
||||||
|
<li><strong>Collectif Conception Numérique Responsable</strong> (CNUMR)</li>
|
||||||
|
<li><strong>Association Point de MIR</strong> (numérique responsable)</li>
|
||||||
|
<li><strong>Institut du Numérique Responsable</strong> (INR)</li>
|
||||||
|
<li><strong>Club Green IT</strong></li>
|
||||||
|
<li><strong>Access42</strong> (accessibilité numérique)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px'}}>
|
||||||
|
<h4 style={{marginTop: 0, display: 'flex', alignItems: 'center', gap: '0.5rem'}}>
|
||||||
|
<i className="fas fa-certificate"></i> Certifications
|
||||||
|
</h4>
|
||||||
|
<ul style={{marginBottom: 0}}>
|
||||||
|
<li><strong>Opquast :</strong> Certification qualité web</li>
|
||||||
|
<li><strong>Accessibilité numérique :</strong> Formation et certification Access42</li>
|
||||||
|
<li><strong>Écoconception web :</strong> Formation GreenIT</li>
|
||||||
|
<li><strong>WCAG :</strong> Certifications internationales</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-quote-left"></i> Message Final</h2>
|
||||||
|
|
||||||
|
<div style={{padding: '3rem', background: 'linear-gradient(135deg, var(--primary-dark), var(--primary), var(--secondary))', color: 'white', borderRadius: '12px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '3rem', marginBottom: '1.5rem'}}>🌍</div>
|
||||||
|
<h3 style={{fontSize: '1.8rem', marginBottom: '1.5rem', color: 'white'}}>
|
||||||
|
Chaque ligne de code compte pour un numérique plus durable et inclusif
|
||||||
|
</h3>
|
||||||
|
<p style={{fontSize: '1.2rem', marginBottom: '2rem', lineHeight: '1.8'}}>
|
||||||
|
L'écoconception et l'accessibilité ne sont pas des contraintes, mais des <strong>leviers d'innovation et de qualité</strong>.
|
||||||
|
En appliquant ces principes, vous contribuez à un numérique meilleur pour tous et pour la planète.
|
||||||
|
</p>
|
||||||
|
<div style={{display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: '1.5rem', marginTop: '2rem'}}>
|
||||||
|
<div style={{padding: '1.5rem', background: 'rgba(255,255,255,0.1)', borderRadius: '8px'}}>
|
||||||
|
<div style={{fontSize: '2rem', fontWeight: 'bold', marginBottom: '0.5rem'}}>-40%</div>
|
||||||
|
<div style={{fontSize: '0.9rem'}}>Empreinte carbone</div>
|
||||||
|
</div>
|
||||||
|
<div style={{padding: '1.5rem', background: 'rgba(255,255,255,0.1)', borderRadius: '8px'}}>
|
||||||
|
<div style={{fontSize: '2rem', fontWeight: 'bold', marginBottom: '0.5rem'}}>+35%</div>
|
||||||
|
<div style={{fontSize: '0.9rem'}}>Audience potentielle</div>
|
||||||
|
</div>
|
||||||
|
<div style={{padding: '1.5rem', background: 'rgba(255,255,255,0.1)', borderRadius: '8px'}}>
|
||||||
|
<div style={{fontSize: '2rem', fontWeight: 'bold', marginBottom: '0.5rem'}}>100%</div>
|
||||||
|
<div style={{fontSize: '0.9rem'}}>Utilisateurs satisfaits</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div className="conclusion-banner" style={{background: 'linear-gradient(135deg, #28a745, #52b788)'}}>
|
||||||
|
<i className="fas fa-heart"></i>
|
||||||
|
<div>
|
||||||
|
<strong>Conclusion du compte rendu</strong>
|
||||||
|
<p>Cette analyse démontre l'importance d'intégrer l'écoconception et l'accessibilité dans le développement web.
|
||||||
|
Les audits réalisés ont permis d'identifier des problèmes concrets et de proposer des recommandations actionables pour améliorer la performance environnementale et l'accessibilité du site ville-de-chauray.fr.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Conclusion
|
||||||
463
src/pages/EcoGuide.jsx
Normal file
463
src/pages/EcoGuide.jsx
Normal file
@@ -0,0 +1,463 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import './SharedPages.css'
|
||||||
|
|
||||||
|
function EcoGuide() {
|
||||||
|
return (
|
||||||
|
<div className="shared-page">
|
||||||
|
<header className="page-header">
|
||||||
|
<i className="fas fa-map"></i>
|
||||||
|
<h1>Guide d'Écoconception pour un Projet SAE</h1>
|
||||||
|
<p className="subtitle">Méthodologie complète pour intégrer l'écoconception</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-bullseye"></i> Objectif</h2>
|
||||||
|
<p>
|
||||||
|
Intégrer l'écoconception à chaque étape du projet, de la conception à la livraison,
|
||||||
|
en utilisant les outils et référentiels analysés (RGESN, RGAA, EcoIndex, Lighthouse, WAVE).
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-calendar-alt"></i> Organisation et Planning Type (4 semaines)</h2>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gap: '2rem'}}>
|
||||||
|
<div style={{padding: '2rem', background: 'linear-gradient(135deg, #2d6a4f, #52b788)', color: 'white', borderRadius: '12px'}}>
|
||||||
|
<div style={{display: 'flex', alignItems: 'center', gap: '1rem', marginBottom: '1.5rem'}}>
|
||||||
|
<div style={{
|
||||||
|
width: '60px',
|
||||||
|
height: '60px',
|
||||||
|
background: 'rgba(255,255,255,0.2)',
|
||||||
|
borderRadius: '50%',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
fontSize: '1.8rem',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}}>1</div>
|
||||||
|
<h3 style={{margin: 0, fontSize: '1.5rem'}}>Semaine 1 : Cadrage et Conception</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gap: '1.5rem'}}>
|
||||||
|
<div>
|
||||||
|
<h4 style={{marginTop: 0, color: 'white'}}>Tâches écoconception</h4>
|
||||||
|
<ul>
|
||||||
|
<li>Définir les objectifs écoresponsables du projet (ex: "-30% CO₂ vs moyenne secteur")</li>
|
||||||
|
<li>Choisir un hébergeur vert (Infomaniak, GreenGeeks, OVH bas carbone)</li>
|
||||||
|
<li>Concevoir une architecture sobre (statique si possible, SSG/SSR, API légère)</li>
|
||||||
|
<li>Rédiger une checklist personnalisée des bonnes pratiques</li>
|
||||||
|
<li>Nommer un référent écoconception dans l'équipe</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h4 style={{marginTop: 0, color: 'white'}}>Livrables / Outils</h4>
|
||||||
|
<ul>
|
||||||
|
<li>📄 Charte d'écoconception du projet</li>
|
||||||
|
<li>🌐 Comparatif d'hébergeurs (Green Web Foundation)</li>
|
||||||
|
<li>🏗️ Schéma d'architecture technique</li>
|
||||||
|
<li>✅ Checklist RGESN personnalisée</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '2rem', background: 'linear-gradient(135deg, #52b788, #74c69d)', color: 'white', borderRadius: '12px'}}>
|
||||||
|
<div style={{display: 'flex', alignItems: 'center', gap: '1rem', marginBottom: '1.5rem'}}>
|
||||||
|
<div style={{
|
||||||
|
width: '60px',
|
||||||
|
height: '60px',
|
||||||
|
background: 'rgba(255,255,255,0.2)',
|
||||||
|
borderRadius: '50%',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
fontSize: '1.8rem',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}}>2</div>
|
||||||
|
<h3 style={{margin: 0, fontSize: '1.5rem'}}>Semaine 2 : Design et Maquettes</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gap: '1.5rem'}}>
|
||||||
|
<div>
|
||||||
|
<h4 style={{marginTop: 0, color: 'white'}}>Tâches écoconception</h4>
|
||||||
|
<ul>
|
||||||
|
<li>Concevoir des maquettes sobres (limiter animations, couleurs, polices)</li>
|
||||||
|
<li>Valider l'accessibilité dès les maquettes (contrastes, structure)</li>
|
||||||
|
<li>Prévoir un mode sombre pour économiser l'énergie (écrans OLED)</li>
|
||||||
|
<li>Limiter à 2 familles de polices maximum (privilégier system fonts)</li>
|
||||||
|
<li>Optimiser les images dès le design (taille, format)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h4 style={{marginTop: 0, color: 'white'}}>Livrables / Outils</h4>
|
||||||
|
<ul>
|
||||||
|
<li>🎨 Maquettes Figma/Adobe XD sobres</li>
|
||||||
|
<li>🎨 WebAIM Contrast Checker (validation contrastes)</li>
|
||||||
|
<li>📊 Rapport d'accessibilité des maquettes</li>
|
||||||
|
<li>📐 Guide de style écoconçu</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '2rem', background: 'linear-gradient(135deg, #74c69d, #95d5b2)', color: 'white', borderRadius: '12px'}}>
|
||||||
|
<div style={{display: 'flex', alignItems: 'center', gap: '1rem', marginBottom: '1.5rem'}}>
|
||||||
|
<div style={{
|
||||||
|
width: '60px',
|
||||||
|
height: '60px',
|
||||||
|
background: 'rgba(255,255,255,0.2)',
|
||||||
|
borderRadius: '50%',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
fontSize: '1.8rem',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}}>3</div>
|
||||||
|
<h3 style={{margin: 0, fontSize: '1.5rem'}}>Semaine 3 : Développement</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gap: '1.5rem'}}>
|
||||||
|
<div>
|
||||||
|
<h4 style={{marginTop: 0, color: 'white'}}>Tâches écoconception</h4>
|
||||||
|
<ul>
|
||||||
|
<li>Développer en respectant la checklist (code, images, requêtes)</li>
|
||||||
|
<li>Optimiser toutes les images (WebP/AVIF, compression, lazy loading)</li>
|
||||||
|
<li>Minifier CSS/JS, supprimer code mort</li>
|
||||||
|
<li>Limiter les librairies externes (privilégier Vanilla JS si possible)</li>
|
||||||
|
<li>Tester régulièrement l'empreinte environnementale (EcoIndex, Lighthouse)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h4 style={{marginTop: 0, color: 'white'}}>Livrables / Outils</h4>
|
||||||
|
<ul>
|
||||||
|
<li>💻 Code commenté et optimisé</li>
|
||||||
|
<li>🔍 Lighthouse, EcoIndex (tests continus)</li>
|
||||||
|
<li>📈 Tableau de suivi des indicateurs (poids, CO₂, requêtes)</li>
|
||||||
|
<li>📦 Build optimisé (Webpack, Vite)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '2rem', background: 'linear-gradient(135deg, #95d5b2, #b7e4c7)', color: 'white', borderRadius: '12px'}}>
|
||||||
|
<div style={{display: 'flex', alignItems: 'center', gap: '1rem', marginBottom: '1.5rem'}}>
|
||||||
|
<div style={{
|
||||||
|
width: '60px',
|
||||||
|
height: '60px',
|
||||||
|
background: 'rgba(255,255,255,0.2)',
|
||||||
|
borderRadius: '50%',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
fontSize: '1.8rem',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}}>4</div>
|
||||||
|
<h3 style={{margin: 0, fontSize: '1.5rem'}}>Semaine 4 : Tests, Optimisation, Livraison</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gap: '1.5rem'}}>
|
||||||
|
<div>
|
||||||
|
<h4 style={{marginTop: 0, color: 'white'}}>Tâches écoconception</h4>
|
||||||
|
<ul>
|
||||||
|
<li>Auditer le projet final (écoconception + accessibilité)</li>
|
||||||
|
<li>Corriger les derniers points bloquants</li>
|
||||||
|
<li>Tester avec lecteur d'écran (NVDA, VoiceOver)</li>
|
||||||
|
<li>Rédiger une documentation d'écoconception pour mainteneurs</li>
|
||||||
|
<li>Communiquer sur les efforts écoresponsables (badge, footer)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h4 style={{marginTop: 0, color: 'white'}}>Livrables / Outils</h4>
|
||||||
|
<ul>
|
||||||
|
<li>📋 Rapport d'audit final (RGESN, RGAA, WAVE)</li>
|
||||||
|
<li>✅ Liste des optimisations réalisées</li>
|
||||||
|
<li>📚 Fiche mémo des bonnes pratiques</li>
|
||||||
|
<li>🎯 Documentation technique</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-list-check"></i> Checklist d'écoconception à intégrer dès la conception</h2>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gap: '2rem'}}>
|
||||||
|
<div style={{padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px', borderLeft: '4px solid #2d6a4f'}}>
|
||||||
|
<h3 style={{marginTop: 0, color: 'var(--primary-dark)'}}>1️⃣ Cadrage et Gouvernance</h3>
|
||||||
|
<ul>
|
||||||
|
<li>☐ Définir des objectifs écoresponsables clairs (ex: "-30% poids vs moyenne secteur")</li>
|
||||||
|
<li>☐ Nommer un référent écoconception dans l'équipe</li>
|
||||||
|
<li>☐ Intégrer l'écoconception dans le cahier des charges</li>
|
||||||
|
<li>☐ Choisir un hébergeur vert (Infomaniak, GreenGeeks, OVH bas carbone)</li>
|
||||||
|
<li>☐ Prévoir un budget temps pour les audits et optimisations</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px', borderLeft: '4px solid #52b788'}}>
|
||||||
|
<h3 style={{marginTop: 0, color: 'var(--primary-dark)'}}>2️⃣ Design et Expérience Utilisateur</h3>
|
||||||
|
<ul>
|
||||||
|
<li>☐ Limiter le nombre de polices (max 2 familles, privilégier system fonts)</li>
|
||||||
|
<li>☐ Éviter les animations inutiles (autoplay, vidéos en fond, carrousels)</li>
|
||||||
|
<li>☐ Utiliser des couleurs sobres et vérifier les contrastes (WCAG AA: 4.5:1)</li>
|
||||||
|
<li>☐ Concevoir des maquettes légères (éviter images haute résolution inutiles)</li>
|
||||||
|
<li>☐ Prévoir un mode sombre pour réduire consommation énergétique (OLED)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px', borderLeft: '4px solid #74c69d'}}>
|
||||||
|
<h3 style={{marginTop: 0, color: 'var(--primary-dark)'}}>3️⃣ Développement Frontend</h3>
|
||||||
|
<ul>
|
||||||
|
<li>☐ Optimiser les images (WebP/AVIF, compression TinyPNG, lazy loading)</li>
|
||||||
|
<li>☐ Minifier et regrouper les fichiers CSS/JS</li>
|
||||||
|
<li>☐ Limiter l'usage de librairies externes (privilégier Vanilla JS)</li>
|
||||||
|
<li>☐ Cacher le contenu non critique (chargement différé des iframes)</li>
|
||||||
|
<li>☐ Utiliser un système de cache efficace (Cache-Control headers)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px', borderLeft: '4px solid #95d5b2'}}>
|
||||||
|
<h3 style={{marginTop: 0, color: 'var(--primary-dark)'}}>4️⃣ Développement Backend</h3>
|
||||||
|
<ul>
|
||||||
|
<li>☐ Choisir un langage/framework sobre (éviter surdimensionnement)</li>
|
||||||
|
<li>☐ Optimiser les requêtes base de données (index, limiter jointures)</li>
|
||||||
|
<li>☐ Mettre en place une API légère (éviter surdimensionnement JSON)</li>
|
||||||
|
<li>☐ Désactiver les logs inutiles en production</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px', borderLeft: '4px solid #b7e4c7'}}>
|
||||||
|
<h3 style={{marginTop: 0, color: 'var(--primary-dark)'}}>5️⃣ Hébergement et Infrastructure</h3>
|
||||||
|
<ul>
|
||||||
|
<li>☐ Vérifier que l'hébergeur utilise des énergies renouvelables</li>
|
||||||
|
<li>☐ Configurer un CDN pour réduire latence et transferts</li>
|
||||||
|
<li>☐ Activer la compression Gzip/Brotli sur le serveur</li>
|
||||||
|
<li>☐ Planifier des sauvegardes optimisées (pas de redondances inutiles)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px', borderLeft: '4px solid #d8f3dc'}}>
|
||||||
|
<h3 style={{marginTop: 0, color: 'var(--primary-dark)'}}>6️⃣ Tests et Validation</h3>
|
||||||
|
<ul>
|
||||||
|
<li>☐ Auditer régulièrement avec EcoIndex/Website Carbon (empreinte)</li>
|
||||||
|
<li>☐ Tester avec Lighthouse (performances, accessibilité)</li>
|
||||||
|
<li>☐ Valider l'accessibilité avec WAVE et lecteurs d'écran</li>
|
||||||
|
<li>☐ Corriger les erreurs bloquantes avant la livraison</li>
|
||||||
|
<li>☐ Documenter les choix d'écoconception pour mainteneurs futurs</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px', borderLeft: '4px solid #40916c'}}>
|
||||||
|
<h3 style={{marginTop: 0, color: 'var(--primary-dark)'}}>7️⃣ Livraison et Communication</h3>
|
||||||
|
<ul>
|
||||||
|
<li>☐ Rédiger une fiche d'écoconception pour les utilisateurs</li>
|
||||||
|
<li>☐ Communiquer sur les efforts (badge "Site bas carbone", mention footer)</li>
|
||||||
|
<li>☐ Prévoir un suivi post-livraison (audit trimestriel)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-tools"></i> Outils Recommandés</h2>
|
||||||
|
|
||||||
|
<div className="table-responsive">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Besoin</th>
|
||||||
|
<th>Outils / Référentiels</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Audit écoconception</strong></td>
|
||||||
|
<td>EcoIndex, Website Carbon, GreenIT Analysis Method</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Audit accessibilité</strong></td>
|
||||||
|
<td>WAVE, RGAA, Lighthouse Accessibility</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Optimisation images</strong></td>
|
||||||
|
<td>TinyPNG, Squoosh, ImageOptim</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Test de performances</strong></td>
|
||||||
|
<td>Lighthouse, WebPageTest, GTmetrix</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Hébergement vert</strong></td>
|
||||||
|
<td>Green Web Foundation, The Green Web Directory</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Contraste de couleurs</strong></td>
|
||||||
|
<td>WebAIM Contrast Checker, Stark (Figma)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Documentation</strong></td>
|
||||||
|
<td>Notion, Markdown, GitHub Wiki</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-lightbulb"></i> Conseils pour Réussir</h2>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gap: '1.5rem'}}>
|
||||||
|
{[
|
||||||
|
{
|
||||||
|
icon: 'fa-users',
|
||||||
|
title: 'Impliquez toute l\'équipe',
|
||||||
|
content: 'L\'écoconception n\'est pas seulement l\'affaire des développeurs. Designers, chefs de projet et rédacteurs doivent aussi adopter ces bonnes pratiques.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-sort-amount-down',
|
||||||
|
title: 'Priorisez',
|
||||||
|
content: 'Concentrez-vous d\'abord sur les actions à fort impact et faciles à mettre en œuvre (ex: optimisation des images, choix de l\'hébergeur).'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-file-alt',
|
||||||
|
title: 'Documentez',
|
||||||
|
content: 'Notez chaque choix d\'écoconception et ses justifications pour faciliter la maintenance future.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-vial',
|
||||||
|
title: 'Testez tôt et souvent',
|
||||||
|
content: 'Intégrez les audits dès les premières maquettes et à chaque sprint de développement.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-graduation-cap',
|
||||||
|
title: 'Sensibilisez',
|
||||||
|
content: 'Expliquez à vos utilisateurs ou clients pourquoi ces efforts sont importants (ex: via une page "Notre engagement écoresponsable").'
|
||||||
|
}
|
||||||
|
].map((tip, index) => (
|
||||||
|
<div key={index} style={{
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: 'auto 1fr',
|
||||||
|
gap: '1.5rem',
|
||||||
|
padding: '1.5rem',
|
||||||
|
background: 'var(--bg)',
|
||||||
|
borderRadius: '8px',
|
||||||
|
alignItems: 'flex-start'
|
||||||
|
}}>
|
||||||
|
<div style={{
|
||||||
|
width: '50px',
|
||||||
|
height: '50px',
|
||||||
|
background: 'var(--primary)',
|
||||||
|
color: 'white',
|
||||||
|
borderRadius: '50%',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
fontSize: '1.5rem',
|
||||||
|
flexShrink: 0
|
||||||
|
}}>
|
||||||
|
<i className={`fas ${tip.icon}`}></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4 style={{marginTop: 0, color: 'var(--primary-dark)'}}>{tip.title}</h4>
|
||||||
|
<p style={{margin: 0}}>{tip.content}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-chart-line"></i> Fiche de Suivi Hebdomadaire</h2>
|
||||||
|
|
||||||
|
<div className="table-responsive">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Semaine</th>
|
||||||
|
<th>Actions écoconception réalisées</th>
|
||||||
|
<th>Indicateurs (avant/après)</th>
|
||||||
|
<th>Prochaines étapes</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><strong>1</strong></td>
|
||||||
|
<td>Choix de l'hébergeur vert, rédaction de la checklist</td>
|
||||||
|
<td>-</td>
|
||||||
|
<td>Maquettes sobres</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>2</strong></td>
|
||||||
|
<td>Optimisation des maquettes, test de contraste</td>
|
||||||
|
<td>Contraste: 2.3:1 → 7.8:1 ✓</td>
|
||||||
|
<td>Développement</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>3</strong></td>
|
||||||
|
<td>Minification CSS/JS, lazy loading images</td>
|
||||||
|
<td>Poids: 2.5 MB → 1.2 MB (-52%)</td>
|
||||||
|
<td>Audit final</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>4</strong></td>
|
||||||
|
<td>Correction des erreurs Lighthouse, documentation</td>
|
||||||
|
<td>Score Lighthouse: 72 → 95 (+23 pts)</td>
|
||||||
|
<td>Livraison</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-star"></i> Pourquoi ce guide est utile ?</h2>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))', gap: '1.5rem'}}>
|
||||||
|
<div style={{padding: '1.5rem', background: '#d4edda', borderRadius: '8px', borderLeft: '4px solid var(--success)'}}>
|
||||||
|
<h4 style={{marginTop: 0, display: 'flex', alignItems: 'center', gap: '0.5rem'}}>
|
||||||
|
<i className="fas fa-calendar-check"></i> Intégration progressive
|
||||||
|
</h4>
|
||||||
|
<p style={{margin: 0}}>Permet d'intégrer l'écoconception de manière progressive et réaliste sur un mois</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: '#cfe2ff', borderRadius: '8px', borderLeft: '4px solid var(--info)'}}>
|
||||||
|
<h4 style={{marginTop: 0, display: 'flex', alignItems: 'center', gap: '0.5rem'}}>
|
||||||
|
<i className="fas fa-tools"></i> Outils concrets
|
||||||
|
</h4>
|
||||||
|
<p style={{margin: 0}}>S'appuie sur des outils concrets et des référentiels officiels (RGESN, RGAA)</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: '#fff3cd', borderRadius: '8px', borderLeft: '4px solid var(--warning)'}}>
|
||||||
|
<h4 style={{marginTop: 0, display: 'flex', alignItems: 'center', gap: '0.5rem'}}>
|
||||||
|
<i className="fas fa-comments"></i> Justification
|
||||||
|
</h4>
|
||||||
|
<p style={{margin: 0}}>Prépare à justifier les choix face à un client ou un jury</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: '#d1ecf1', borderRadius: '8px', borderLeft: '4px solid #0dcaf0'}}>
|
||||||
|
<h4 style={{marginTop: 0, display: 'flex', alignItems: 'center', gap: '0.5rem'}}>
|
||||||
|
<i className="fas fa-book"></i> Documentation
|
||||||
|
</h4>
|
||||||
|
<p style={{margin: 0}}>Habitue à documenter et communiquer sur les démarches écoresponsables</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div className="conclusion-banner">
|
||||||
|
<i className="fas fa-check-circle"></i>
|
||||||
|
<div>
|
||||||
|
<strong>Méthodologie complète</strong>
|
||||||
|
<p>Ce guide présente une méthode pour intégrer l'écoconception et l'accessibilité à chaque étape d'un projet.
|
||||||
|
Cette méthodologie permet de créer des services numériques sobres, performants, accessibles et responsables.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EcoGuide
|
||||||
327
src/pages/EnvironmentalAudit.jsx
Normal file
327
src/pages/EnvironmentalAudit.jsx
Normal file
@@ -0,0 +1,327 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import './SharedPages.css'
|
||||||
|
|
||||||
|
function EnvironmentalAudit() {
|
||||||
|
const auditResults = [
|
||||||
|
{ tool: 'Website Carbon', co2: '0.62g', grade: 'F', pageWeight: '-', requests: '-' },
|
||||||
|
{ tool: 'EcoIndex', co2: '2.86kg/1000 visites', grade: 'G (7/100)', pageWeight: '12.456 MB', requests: '206' },
|
||||||
|
{ tool: 'WAVE', co2: '-', grade: '29 erreurs, 326 contraste', pageWeight: '-', requests: '-' }
|
||||||
|
]
|
||||||
|
|
||||||
|
const recommendations = [
|
||||||
|
{
|
||||||
|
priority: 'Haute',
|
||||||
|
action: 'Optimiser les images',
|
||||||
|
method: 'Utiliser WebP/AVIF, compression TinyPNG, lazy loading',
|
||||||
|
gain: '-40% poids des pages',
|
||||||
|
impact: 'Fort'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
priority: 'Haute',
|
||||||
|
action: 'Minifier CSS/JS',
|
||||||
|
method: 'Webpack, Vite, ou outils de build',
|
||||||
|
gain: '-25% poids des ressources',
|
||||||
|
impact: 'Moyen'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
priority: 'Haute',
|
||||||
|
action: 'Activer la compression serveur',
|
||||||
|
method: 'Gzip ou Brotli sur serveur web',
|
||||||
|
gain: '-60% transfert de données',
|
||||||
|
impact: 'Fort'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
priority: 'Moyenne',
|
||||||
|
action: 'Mettre en place un CDN',
|
||||||
|
method: 'Cloudflare, AWS CloudFront',
|
||||||
|
gain: '-30% latence',
|
||||||
|
impact: 'Moyen'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
priority: 'Moyenne',
|
||||||
|
action: 'Réduire les requêtes HTTP',
|
||||||
|
method: 'Regrouper fichiers, sprites CSS',
|
||||||
|
gain: '-20 requêtes',
|
||||||
|
impact: 'Moyen'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
priority: 'Moyenne',
|
||||||
|
action: 'Choisir hébergement vert',
|
||||||
|
method: 'Infomaniak, GreenGeeks, OVH bas carbone',
|
||||||
|
gain: 'Énergies renouvelables',
|
||||||
|
impact: 'Fort (symbolique)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
priority: 'Basse',
|
||||||
|
action: 'Limiter les polices web',
|
||||||
|
method: 'Max 2 familles, subset uniquement nécessaire',
|
||||||
|
gain: '-5% poids',
|
||||||
|
impact: 'Faible'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
priority: 'Basse',
|
||||||
|
action: 'Supprimer JS/CSS inutilisé',
|
||||||
|
method: 'PurgeCSS, Chrome Coverage tool',
|
||||||
|
gain: '-15% poids JS/CSS',
|
||||||
|
impact: 'Moyen'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="shared-page">
|
||||||
|
<header className="page-header">
|
||||||
|
<i className="fas fa-leaf"></i>
|
||||||
|
<h1>Audit Environnemental d'un Site Web</h1>
|
||||||
|
<p className="subtitle">Diagnostic et recommandations</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-bullseye"></i> Objectifs de l'audit</h2>
|
||||||
|
<ul>
|
||||||
|
<li>Mesurer l'impact environnemental d'un site web avec plusieurs outils complémentaires</li>
|
||||||
|
<li>Identifier les principaux points d'amélioration</li>
|
||||||
|
<li>Proposer des recommandations concrètes et priorisées</li>
|
||||||
|
<li>Estimer les gains environnementaux potentiels</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-globe"></i> Site audité</h2>
|
||||||
|
<div className="info-card">
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Nom:</strong>
|
||||||
|
<span>Site de la ville de Chauray</span>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>URL:</strong>
|
||||||
|
<span>https://ville-de-chauray.fr/</span>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Type:</strong>
|
||||||
|
<span>Site institutionnel municipal</span>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Public:</strong>
|
||||||
|
<span>Citoyens et visiteurs de la commune</span>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Trafic:</strong>
|
||||||
|
<span>~50,000 visiteurs/mois</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-chart-line"></i> Résultats des audits</h2>
|
||||||
|
<div className="table-responsive">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Outil</th>
|
||||||
|
<th>CO₂/visite</th>
|
||||||
|
<th>Note/Grade</th>
|
||||||
|
<th>Poids page</th>
|
||||||
|
<th>Requêtes HTTP</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{auditResults.map((result, index) => (
|
||||||
|
<tr key={index}>
|
||||||
|
<td><strong>{result.tool}</strong></td>
|
||||||
|
<td>{result.co2}</td>
|
||||||
|
<td><span className="badge warning">{result.grade}</span></td>
|
||||||
|
<td>{result.pageWeight}</td>
|
||||||
|
<td>{result.requests}</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="analysis-box" style={{marginTop: '2rem', padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px'}}>
|
||||||
|
<h3>Analyse des résultats</h3>
|
||||||
|
<p><strong>Constat global :</strong> Le site présente une empreinte environnementale élevée (Note F).</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>0.62g CO₂/visite</strong> - Plus sale que 84% des sites web</li>
|
||||||
|
<li>Avec 10,000 visiteurs/mois : <strong>74.04 kg CO₂/an</strong></li>
|
||||||
|
<li>Équivalent à <strong>184 kWh d'énergie</strong> ou <strong>1,175km en voiture électrique</strong></li>
|
||||||
|
<li>Nécessite <strong>4 arbres</strong> pour compenser les émissions annuelles</li>
|
||||||
|
<li><strong>Point positif :</strong> Hébergement sur énergie durable ✓</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{marginTop: '2rem', padding: '2rem', background: '#f8d7da', borderRadius: '8px', borderLeft: '4px solid #dc3545'}}>
|
||||||
|
<h3 style={{marginTop: 0, color: '#721c24', display: 'flex', alignItems: 'center', gap: '0.75rem'}}>
|
||||||
|
<i className="fas fa-chart-line"></i>
|
||||||
|
Détails EcoIndex (Score: 7/100 - Note G)
|
||||||
|
</h3>
|
||||||
|
<div style={{display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: '1rem', marginTop: '1.5rem'}}>
|
||||||
|
<div style={{padding: '1rem', background: 'white', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '2rem', fontWeight: 'bold', color: '#dc3545'}}>12.456 MB</div>
|
||||||
|
<div style={{fontSize: '0.9rem', color: '#721c24', marginTop: '0.5rem'}}>Poids de la page</div>
|
||||||
|
<div style={{fontSize: '0.8rem', color: '#721c24', marginTop: '0.25rem'}}>(Cible: 1.024 MB)</div>
|
||||||
|
</div>
|
||||||
|
<div style={{padding: '1rem', background: 'white', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '2rem', fontWeight: 'bold', color: '#dc3545'}}>7709</div>
|
||||||
|
<div style={{fontSize: '0.9rem', color: '#721c24', marginTop: '0.5rem'}}>Éléments DOM</div>
|
||||||
|
<div style={{fontSize: '0.8rem', color: '#721c24', marginTop: '0.25rem'}}>(Cible: 600)</div>
|
||||||
|
</div>
|
||||||
|
<div style={{padding: '1rem', background: 'white', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '2rem', fontWeight: 'bold', color: '#dc3545'}}>206</div>
|
||||||
|
<div style={{fontSize: '0.9rem', color: '#721c24', marginTop: '0.5rem'}}>Requêtes HTTP</div>
|
||||||
|
<div style={{fontSize: '0.8rem', color: '#721c24', marginTop: '0.25rem'}}>(Cible: 40)</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style={{marginTop: '1.5rem', padding: '1rem', background: 'white', borderRadius: '8px'}}>
|
||||||
|
<strong style={{color: '#721c24'}}>Empreinte pour 1000 visites/mois :</strong>
|
||||||
|
<ul style={{marginTop: '0.5rem', marginBottom: 0}}>
|
||||||
|
<li><strong>42.9 litres</strong> d'eau bleue consommée</li>
|
||||||
|
<li><strong>2.86 kg CO₂e</strong> émis (équivalent à ~14 km en voiture)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-exclamation-triangle"></i> 3 Principaux problèmes identifiés</h2>
|
||||||
|
|
||||||
|
<div className="problems-grid" style={{display: 'grid', gap: '1.5rem'}}>
|
||||||
|
<div className="problem-card" style={{padding: '1.5rem', background: '#f8d7da', borderRadius: '8px', borderLeft: '4px solid #dc3545'}}>
|
||||||
|
<h3 style={{marginTop: 0, color: '#721c24'}}>1. Page extrêmement lourde (12.456 MB)</h3>
|
||||||
|
<p><strong>Problème :</strong> Poids de la page 12x supérieur à la cible (1.024 MB)</p>
|
||||||
|
<p><strong>Impact :</strong> Augmente drastiquement le temps de chargement et la consommation de données</p>
|
||||||
|
<p><strong>Preuve :</strong> EcoIndex - "Trop lourde", classement 518439/527126 (98% des sites sont meilleurs)</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="problem-card" style={{padding: '1.5rem', background: '#f8d7da', borderRadius: '8px', borderLeft: '4px solid #dc3545'}}>
|
||||||
|
<h3 style={{marginTop: 0, color: '#721c24'}}>2. Complexité excessive du DOM (7709 éléments)</h3>
|
||||||
|
<p><strong>Problème :</strong> DOM 13x plus complexe que la cible (600 éléments)</p>
|
||||||
|
<p><strong>Impact :</strong> Ralentit le rendu et augmente la consommation mémoire/CPU</p>
|
||||||
|
<p><strong>Preuve :</strong> EcoIndex - "Trop complexe", médiane web à 693 éléments</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="problem-card" style={{padding: '1.5rem', background: '#f8d7da', borderRadius: '8px', borderLeft: '4px solid #dc3545'}}>
|
||||||
|
<h3 style={{marginTop: 0, color: '#721c24'}}>3. Nombre excessif de requêtes (206)</h3>
|
||||||
|
<p><strong>Problème :</strong> 206 requêtes HTTP (5x la cible de 40 requêtes)</p>
|
||||||
|
<p><strong>Impact :</strong> Multiplie les allers-retours serveur et la consommation énergétique</p>
|
||||||
|
<p><strong>Preuve :</strong> EcoIndex - "Trop de requêtes", 23 images sans alt (WAVE), médiane à 78 requêtes</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-tasks"></i> Recommandations priorisées</h2>
|
||||||
|
<div className="table-responsive">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Priorité</th>
|
||||||
|
<th>Action</th>
|
||||||
|
<th>Méthode</th>
|
||||||
|
<th>Gain estimé</th>
|
||||||
|
<th>Impact</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{recommendations.map((rec, index) => (
|
||||||
|
<tr key={index}>
|
||||||
|
<td>
|
||||||
|
<span className={`badge ${rec.priority === 'Haute' ? 'danger' : rec.priority === 'Moyenne' ? 'warning' : 'success'}`}>
|
||||||
|
{rec.priority}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td><strong>{rec.action}</strong></td>
|
||||||
|
<td>{rec.method}</td>
|
||||||
|
<td>{rec.gain}</td>
|
||||||
|
<td>
|
||||||
|
<span className={`badge ${rec.impact === 'Fort' ? 'success' : rec.impact === 'Moyen' ? 'warning' : 'info'}`}>
|
||||||
|
{rec.impact}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-list-check"></i> Checklist d'écoconception</h2>
|
||||||
|
<div className="checklist" style={{display: 'grid', gap: '0.5rem'}}>
|
||||||
|
{[
|
||||||
|
'☐ Optimiser toutes les images (WebP, compression, lazy loading)',
|
||||||
|
'☐ Minifier CSS, JavaScript et HTML',
|
||||||
|
'☐ Activer la compression Gzip/Brotli sur le serveur',
|
||||||
|
'☐ Mettre en cache les ressources statiques (Cache-Control)',
|
||||||
|
'☐ Utiliser un CDN pour distribuer le contenu',
|
||||||
|
'☐ Choisir un hébergeur utilisant des énergies renouvelables',
|
||||||
|
'☐ Limiter les polices web (max 2 familles)',
|
||||||
|
'☐ Supprimer le code JavaScript et CSS inutilisé',
|
||||||
|
'☐ Différer le chargement des scripts non critiques',
|
||||||
|
'☐ Optimiser les requêtes base de données',
|
||||||
|
'☐ Réduire le nombre de plugins/extensions',
|
||||||
|
'☐ Précharger les ressources critiques (preload)',
|
||||||
|
'☐ Éviter les redirections inutiles',
|
||||||
|
'☐ Auditer régulièrement (mensuel ou trimestriel)'
|
||||||
|
].map((item, index) => (
|
||||||
|
<div key={index} style={{padding: '0.75rem', background: 'var(--bg)', borderRadius: '4px', fontSize: '0.95rem'}}>
|
||||||
|
{item}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-calculator"></i> Estimation des gains environnementaux</h2>
|
||||||
|
|
||||||
|
<div className="gains-grid" style={{display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))', gap: '1.5rem'}}>
|
||||||
|
<div className="gain-card" style={{padding: '1.5rem', background: 'linear-gradient(135deg, var(--success), #52b788)', color: 'var(--white)', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '2.5rem', fontWeight: 'bold', marginBottom: '0.5rem'}}>-50%</div>
|
||||||
|
<div>Réduction du poids des pages</div>
|
||||||
|
<div style={{fontSize: '0.9rem', marginTop: '0.5rem', opacity: 0.9}}>De 2.5 MB à 1.25 MB</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="gain-card" style={{padding: '1.5rem', background: 'linear-gradient(135deg, var(--success), #52b788)', color: 'var(--white)', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '2.5rem', fontWeight: 'bold', marginBottom: '0.5rem'}}>-40%</div>
|
||||||
|
<div>Réduction des émissions CO₂</div>
|
||||||
|
<div style={{fontSize: '0.9rem', marginTop: '0.5rem', opacity: 0.9}}>De 1.2g à 0.7g par visite</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="gain-card" style={{padding: '1.5rem', background: 'linear-gradient(135deg, var(--success), #52b788)', color: 'var(--white)', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '2.5rem', fontWeight: 'bold', marginBottom: '0.5rem'}}>420 kg</div>
|
||||||
|
<div>Économie CO₂ annuelle</div>
|
||||||
|
<div style={{fontSize: '0.9rem', marginTop: '0.5rem', opacity: 0.9}}>Soit ~2,100 km en voiture évités</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="gain-card" style={{padding: '1.5rem', background: 'linear-gradient(135deg, var(--info), #52b788)', color: 'var(--white)', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '2.5rem', fontWeight: 'bold', marginBottom: '0.5rem'}}>+30%</div>
|
||||||
|
<div>Amélioration performance</div>
|
||||||
|
<div style={{fontSize: '0.9rem', marginTop: '0.5rem', opacity: 0.9}}>Score Lighthouse: 72 → 95</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="impact-box" style={{marginTop: '2rem', padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px', borderLeft: '4px solid var(--primary)'}}>
|
||||||
|
<h4>Impact sur 1 an (50,000 visiteurs/mois)</h4>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Avant optimisation :</strong> 900 kg CO₂/an</li>
|
||||||
|
<li><strong>Après optimisation :</strong> 480 kg CO₂/an</li>
|
||||||
|
<li><strong>Économie :</strong> 420 kg CO₂/an (équivalent à planter ~20 arbres)</li>
|
||||||
|
<li><strong>Gain utilisateurs :</strong> Pages 2x plus rapides, moins de données mobiles consommées</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div className="conclusion-banner">
|
||||||
|
<i className="fas fa-check-circle"></i>
|
||||||
|
<div>
|
||||||
|
<strong>Conclusion de l'audit</strong>
|
||||||
|
<p>Le site présente un potentiel d'amélioration important. En appliquant les 8 recommandations prioritaires,
|
||||||
|
il est possible de réduire l'empreinte carbone de 40% tout en améliorant significativement les performances
|
||||||
|
et l'expérience utilisateur. Coût de mise en œuvre estimé : 5-10 jours de développement.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EnvironmentalAudit
|
||||||
348
src/pages/Home.css
Normal file
348
src/pages/Home.css
Normal file
@@ -0,0 +1,348 @@
|
|||||||
|
.home {
|
||||||
|
animation: fadeIn 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from { opacity: 0; transform: translateY(20px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero {
|
||||||
|
background: linear-gradient(135deg, var(--primary-dark), var(--primary), var(--secondary));
|
||||||
|
color: var(--white);
|
||||||
|
padding: 4rem 2rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
text-align: center;
|
||||||
|
box-shadow: 0 4px 20px var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-content {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-icon {
|
||||||
|
font-size: 4rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
animation: bounce 2s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bounce {
|
||||||
|
0%, 100% { transform: translateY(0); }
|
||||||
|
50% { transform: translateY(-10px); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero h1 {
|
||||||
|
font-size: 3rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-subtitle {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
opacity: 0.95;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-section {
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-card {
|
||||||
|
background: var(--white);
|
||||||
|
padding: 2rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 10px var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-card h2 {
|
||||||
|
color: var(--primary);
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-card p {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
line-height: 1.8;
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.objectives {
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.objectives h2 {
|
||||||
|
text-align: center;
|
||||||
|
color: var(--primary);
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.objectives-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.objective-card {
|
||||||
|
background: var(--white);
|
||||||
|
padding: 2rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 10px var(--shadow);
|
||||||
|
text-align: center;
|
||||||
|
transition: transform 0.3s, box-shadow 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.objective-card:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
box-shadow: 0 4px 20px var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.objective-card i {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
color: var(--primary);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.objective-card h3 {
|
||||||
|
color: var(--primary-dark);
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.objective-card p {
|
||||||
|
color: var(--text-light);
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillars {
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillars h2 {
|
||||||
|
text-align: center;
|
||||||
|
color: var(--primary);
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillars-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillar-card {
|
||||||
|
background: var(--white);
|
||||||
|
padding: 2rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 10px var(--shadow);
|
||||||
|
border-top: 4px solid var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillar-card.environmental {
|
||||||
|
border-top-color: #2d6a4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillar-card.accessibility {
|
||||||
|
border-top-color: #17a2b8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillar-card.integration {
|
||||||
|
border-top-color: #ffc107;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillar-icon {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
background: linear-gradient(135deg, var(--primary-light), var(--secondary));
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillar-icon i {
|
||||||
|
font-size: 2rem;
|
||||||
|
color: var(--white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillar-card h3 {
|
||||||
|
color: var(--primary-dark);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillar-card p {
|
||||||
|
color: var(--text);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillar-card ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillar-card li {
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
position: relative;
|
||||||
|
color: var(--text-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillar-card li::before {
|
||||||
|
content: "✓";
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--secondary);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.importance {
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.importance h2 {
|
||||||
|
text-align: center;
|
||||||
|
color: var(--primary);
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.importance-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.importance-card {
|
||||||
|
background: linear-gradient(135deg, var(--primary), var(--primary-light));
|
||||||
|
color: var(--white);
|
||||||
|
padding: 2rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 10px var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.importance-card i {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.importance-card h4 {
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.importance-card p {
|
||||||
|
line-height: 1.6;
|
||||||
|
opacity: 0.95;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools-section {
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools-section h2 {
|
||||||
|
color: var(--primary);
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools-grid {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 1rem;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-tag {
|
||||||
|
background: var(--primary);
|
||||||
|
color: var(--white);
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
border-radius: 25px;
|
||||||
|
font-weight: 500;
|
||||||
|
box-shadow: 0 2px 5px var(--shadow);
|
||||||
|
transition: transform 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-tag:hover {
|
||||||
|
transform: translateY(-3px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-section {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-section h2 {
|
||||||
|
color: var(--primary);
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-card {
|
||||||
|
background: var(--white);
|
||||||
|
padding: 2rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 10px var(--shadow);
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--text);
|
||||||
|
transition: transform 0.3s, box-shadow 0.3s;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-card:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
box-shadow: 0 4px 20px var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-card i {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
color: var(--primary);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-card h3 {
|
||||||
|
color: var(--primary-dark);
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-card p {
|
||||||
|
color: var(--text-light);
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.hero h1 {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-subtitle {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-icon {
|
||||||
|
font-size: 3rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
166
src/pages/Home.jsx
Normal file
166
src/pages/Home.jsx
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
import './Home.css'
|
||||||
|
|
||||||
|
function Home() {
|
||||||
|
return (
|
||||||
|
<div className="home">
|
||||||
|
<section className="hero">
|
||||||
|
<div className="hero-content">
|
||||||
|
<i className="fas fa-leaf hero-icon"></i>
|
||||||
|
<h1>Écoconception Web</h1>
|
||||||
|
<p className="hero-subtitle">Vers un Numérique Responsable et Accessible</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="intro-section">
|
||||||
|
<div className="intro-card">
|
||||||
|
<h2><i className="fas fa-globe-americas"></i> Contexte et enjeux</h2>
|
||||||
|
<p>
|
||||||
|
À l'ère du numérique omniprésent, les services et applications que nous concevons ont un impact
|
||||||
|
environnemental et social croissant. Selon l'ADEME, le numérique représente aujourd'hui <strong>4% des
|
||||||
|
émissions mondiales de gaz à effet de serre</strong>, un chiffre en constante augmentation.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Parallèlement, <strong>15% de la population mondiale</strong> vit avec un handicap, et l'accessibilité numérique
|
||||||
|
reste un défi majeur pour garantir une inclusion sociale effective.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="objectives">
|
||||||
|
<h2><i className="fas fa-bullseye"></i> Objectifs du compte rendu</h2>
|
||||||
|
<div className="objectives-grid">
|
||||||
|
<div className="objective-card">
|
||||||
|
<i className="fas fa-book-open"></i>
|
||||||
|
<h3>Comprendre</h3>
|
||||||
|
<p>Les enjeux du numérique responsable et les cadres réglementaires (RGESN, RGAA)</p>
|
||||||
|
</div>
|
||||||
|
<div className="objective-card">
|
||||||
|
<i className="fas fa-tools"></i>
|
||||||
|
<h3>Utiliser</h3>
|
||||||
|
<p>Des outils d'audit pour mesurer l'impact environnemental et l'accessibilité</p>
|
||||||
|
</div>
|
||||||
|
<div className="objective-card">
|
||||||
|
<i className="fas fa-project-diagram"></i>
|
||||||
|
<h3>Intégrer</h3>
|
||||||
|
<p>L'écoconception à chaque étape : cadrage, design, développement, tests</p>
|
||||||
|
</div>
|
||||||
|
<div className="objective-card">
|
||||||
|
<i className="fas fa-file-alt"></i>
|
||||||
|
<h3>Documenter</h3>
|
||||||
|
<p>Rédiger un plan d'action et justifier vos démarches</p>
|
||||||
|
</div>
|
||||||
|
<div className="objective-card">
|
||||||
|
<i className="fas fa-code"></i>
|
||||||
|
<h3>Développer</h3>
|
||||||
|
<p>Un projet sobre, performant et accessible</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="pillars">
|
||||||
|
<h2><i className="fas fa-columns"></i> Les 3 Piliers analysés</h2>
|
||||||
|
<div className="pillars-grid">
|
||||||
|
<div className="pillar-card environmental">
|
||||||
|
<div className="pillar-icon">
|
||||||
|
<i className="fas fa-leaf"></i>
|
||||||
|
</div>
|
||||||
|
<h3>Écoconception Environnementale</h3>
|
||||||
|
<p>Réduire l'empreinte carbone et les ressources consommées par votre projet</p>
|
||||||
|
<ul>
|
||||||
|
<li>Mesure de l'impact environnemental</li>
|
||||||
|
<li>Optimisation des ressources</li>
|
||||||
|
<li>Hébergement vert</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div className="pillar-card accessibility">
|
||||||
|
<div className="pillar-icon">
|
||||||
|
<i className="fas fa-universal-access"></i>
|
||||||
|
</div>
|
||||||
|
<h3>Accessibilité & Inclusion</h3>
|
||||||
|
<p>Garantir que votre service soit utilisable par tous</p>
|
||||||
|
<ul>
|
||||||
|
<li>Conformité RGAA</li>
|
||||||
|
<li>Tests avec WAVE</li>
|
||||||
|
<li>Design inclusif</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div className="pillar-card integration">
|
||||||
|
<div className="pillar-icon">
|
||||||
|
<i className="fas fa-cogs"></i>
|
||||||
|
</div>
|
||||||
|
<h3>Intégration Pratique</h3>
|
||||||
|
<p>Appliquer ces principes tout au long du cycle de vie</p>
|
||||||
|
<ul>
|
||||||
|
<li>Checklists et audits</li>
|
||||||
|
<li>Documentation rigoureuse</li>
|
||||||
|
<li>Suivi continu</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="importance">
|
||||||
|
<h2><i className="fas fa-star"></i> Pourquoi cette analyse est-elle importante ?</h2>
|
||||||
|
<div className="importance-grid">
|
||||||
|
<div className="importance-card">
|
||||||
|
<i className="fas fa-briefcase"></i>
|
||||||
|
<h4>Pour votre futur professionnel</h4>
|
||||||
|
<p>Les compétences en écoconception et accessibilité sont de plus en plus recherchées</p>
|
||||||
|
</div>
|
||||||
|
<div className="importance-card">
|
||||||
|
<i className="fas fa-project-diagram"></i>
|
||||||
|
<h4>Pour vos projets personnels</h4>
|
||||||
|
<p>Créez des services plus performants, moins coûteux et accessibles à tous</p>
|
||||||
|
</div>
|
||||||
|
<div className="importance-card">
|
||||||
|
<i className="fas fa-users"></i>
|
||||||
|
<h4>Pour répondre aux attentes sociétales</h4>
|
||||||
|
<p>Les utilisateurs sont sensibles aux enjeux de responsabilité numérique</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="tools-section">
|
||||||
|
<h2><i className="fas fa-wrench"></i> Outils & Référentiels</h2>
|
||||||
|
<div className="tools-grid">
|
||||||
|
<div className="tool-tag">Website Carbon</div>
|
||||||
|
<div className="tool-tag">EcoIndex</div>
|
||||||
|
<div className="tool-tag">Lighthouse</div>
|
||||||
|
<div className="tool-tag">WAVE</div>
|
||||||
|
<div className="tool-tag">RGESN</div>
|
||||||
|
<div className="tool-tag">RGAA</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="cta-section">
|
||||||
|
<h2>Explorez le contenu du compte rendu</h2>
|
||||||
|
<div className="cta-grid">
|
||||||
|
<Link to="/tools-comparison" className="cta-card">
|
||||||
|
<i className="fas fa-chart-bar"></i>
|
||||||
|
<h3>Comparaison d'outils</h3>
|
||||||
|
<p>Analysez et comparez les outils d'écoconception</p>
|
||||||
|
</Link>
|
||||||
|
<Link to="/environmental-audit" className="cta-card">
|
||||||
|
<i className="fas fa-leaf"></i>
|
||||||
|
<h3>Audit Environnemental</h3>
|
||||||
|
<p>Diagnostics et recommandations</p>
|
||||||
|
</Link>
|
||||||
|
<Link to="/accessibility" className="cta-card">
|
||||||
|
<i className="fas fa-universal-access"></i>
|
||||||
|
<h3>Accessibilité</h3>
|
||||||
|
<p>Principes et bonnes pratiques</p>
|
||||||
|
</Link>
|
||||||
|
<Link to="/eco-guide" className="cta-card">
|
||||||
|
<i className="fas fa-map"></i>
|
||||||
|
<h3>Guide Écoconception</h3>
|
||||||
|
<p>Méthodologie pour votre projet</p>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Home
|
||||||
518
src/pages/RGAA.jsx
Normal file
518
src/pages/RGAA.jsx
Normal file
@@ -0,0 +1,518 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import './SharedPages.css'
|
||||||
|
|
||||||
|
function RGAA() {
|
||||||
|
const rgaaCriteria = [
|
||||||
|
{
|
||||||
|
theme: 'Images',
|
||||||
|
criterion: '1.1 - Chaque image a-t-elle une alternative textuelle ?',
|
||||||
|
level: 'A',
|
||||||
|
compliant: 'Non conforme',
|
||||||
|
proof: '8 images sans attribut alt',
|
||||||
|
tools: 'WAVE, inspection manuelle'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
theme: 'Couleurs',
|
||||||
|
criterion: '3.2 - Le contraste entre texte et arrière-plan est-il suffisant ?',
|
||||||
|
level: 'AA',
|
||||||
|
compliant: 'Non conforme',
|
||||||
|
proof: 'Footer : ratio 2.3:1 au lieu de 4.5:1 minimum',
|
||||||
|
tools: 'WAVE Contrast, WebAIM Contrast Checker'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
theme: 'Formulaires',
|
||||||
|
criterion: '11.1 - Chaque champ de formulaire a-t-il une étiquette ?',
|
||||||
|
level: 'A',
|
||||||
|
compliant: 'Non conforme',
|
||||||
|
proof: '3 champs sans label ou label non associé',
|
||||||
|
tools: 'WAVE, validation HTML'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
theme: 'Structure',
|
||||||
|
criterion: '9.1 - L\'information est-elle structurée avec des titres ?',
|
||||||
|
level: 'A',
|
||||||
|
compliant: 'Partiellement conforme',
|
||||||
|
proof: 'Hiérarchie incohérente (h2 → h4), mais titres présents',
|
||||||
|
tools: 'HeadingsMap, WAVE'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
theme: 'Navigation',
|
||||||
|
criterion: '12.6 - Les liens ont-ils des intitulés explicites ?',
|
||||||
|
level: 'A',
|
||||||
|
compliant: 'Non conforme',
|
||||||
|
proof: '15 occurrences de "Cliquez ici" ou "En savoir plus" sans contexte',
|
||||||
|
tools: 'Inspection manuelle'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const recommendations = [
|
||||||
|
{
|
||||||
|
criterion: 'Images sans alternative',
|
||||||
|
technical: 'Ajouter alt="description" pour images informatives, alt="" pour images décoratives',
|
||||||
|
actors: 'Développeur frontend, rédacteur de contenu',
|
||||||
|
example: '<img src="produit.jpg" alt="Ordinateur portable Dell XPS 15 pouces">',
|
||||||
|
priority: 'Haute'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
criterion: 'Contrastes insuffisants',
|
||||||
|
technical: 'Utiliser couleurs avec ratio ≥ 4.5:1 (texte normal) ou ≥ 3:1 (texte large)',
|
||||||
|
actors: 'Designer, développeur CSS',
|
||||||
|
example: 'color: #333 sur background: #fff (ratio 12.6:1 ✓)',
|
||||||
|
priority: 'Haute'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
criterion: 'Labels formulaires',
|
||||||
|
technical: 'Associer chaque input à un label via attribut for/id',
|
||||||
|
actors: 'Développeur frontend',
|
||||||
|
example: '<label for="nom">Nom :</label><input type="text" id="nom">',
|
||||||
|
priority: 'Haute'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="shared-page">
|
||||||
|
<header className="page-header">
|
||||||
|
<i className="fas fa-check-circle"></i>
|
||||||
|
<h1>Audit et conformité RGAA</h1>
|
||||||
|
<p className="subtitle">Référentiel Général d'Amélioration de l'Accessibilité</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-book-open"></i> Structure du RGAA</h2>
|
||||||
|
|
||||||
|
<div className="rgaa-overview" style={{display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: '1.5rem', marginBottom: '2rem'}}>
|
||||||
|
<div style={{padding: '1.5rem', background: 'linear-gradient(135deg, var(--primary), var(--secondary))', color: 'white', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '3rem', fontWeight: 'bold'}}>4</div>
|
||||||
|
<div style={{fontSize: '1.1rem'}}>Principes fondamentaux</div>
|
||||||
|
<div style={{fontSize: '0.85rem', opacity: 0.9, marginTop: '0.5rem'}}>POUR (Perceptible, Utilisable, Compréhensible, Robuste)</div>
|
||||||
|
</div>
|
||||||
|
<div style={{padding: '1.5rem', background: 'linear-gradient(135deg, var(--info), var(--secondary))', color: 'white', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '3rem', fontWeight: 'bold'}}>13</div>
|
||||||
|
<div style={{fontSize: '1.1rem'}}>Thématiques</div>
|
||||||
|
<div style={{fontSize: '0.85rem', opacity: 0.9, marginTop: '0.5rem'}}>Images, couleurs, multimédia, etc.</div>
|
||||||
|
</div>
|
||||||
|
<div style={{padding: '1.5rem', background: 'linear-gradient(135deg, var(--warning), #ff9800)', color: 'white', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '3rem', fontWeight: 'bold'}}>106</div>
|
||||||
|
<div style={{fontSize: '1.1rem'}}>Critères</div>
|
||||||
|
<div style={{fontSize: '0.85rem', opacity: 0.9, marginTop: '0.5rem'}}>Vérifications précises</div>
|
||||||
|
</div>
|
||||||
|
<div style={{padding: '1.5rem', background: 'linear-gradient(135deg, var(--success), #52b788)', color: 'white', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '3rem', fontWeight: 'bold'}}>3</div>
|
||||||
|
<div style={{fontSize: '1.1rem'}}>Niveaux</div>
|
||||||
|
<div style={{fontSize: '0.85rem', opacity: 0.9, marginTop: '0.5rem'}}>A (essentiel), AA (recommandé), AAA (optimal)</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="principles-explained" style={{marginTop: '2rem'}}>
|
||||||
|
<h3>Les 4 principes (POUR)</h3>
|
||||||
|
<div style={{display: 'grid', gap: '1rem'}}>
|
||||||
|
{[
|
||||||
|
{initial: 'P', title: 'Perceptible', desc: 'L\'information doit être présentée de façon à être perçue par tous', color: '#2d6a4f'},
|
||||||
|
{initial: 'U', title: 'Utilisable', desc: 'Les composants et la navigation doivent être utilisables', color: '#52b788'},
|
||||||
|
{initial: 'C', title: 'Compréhensible', desc: 'L\'information et l\'interface doivent être compréhensibles', color: '#74c69d'},
|
||||||
|
{initial: 'R', title: 'Robuste', desc: 'Le contenu doit être interprété par les technologies d\'assistance', color: '#95d5b2'}
|
||||||
|
].map((principle, index) => (
|
||||||
|
<div key={index} style={{
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: 'auto 1fr',
|
||||||
|
gap: '1rem',
|
||||||
|
padding: '1rem',
|
||||||
|
background: 'var(--bg)',
|
||||||
|
borderRadius: '8px',
|
||||||
|
alignItems: 'center'
|
||||||
|
}}>
|
||||||
|
<div style={{
|
||||||
|
width: '50px',
|
||||||
|
height: '50px',
|
||||||
|
background: principle.color,
|
||||||
|
color: 'white',
|
||||||
|
borderRadius: '8px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
fontSize: '1.5rem',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}}>
|
||||||
|
{principle.initial}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<strong style={{color: 'var(--primary-dark)'}}>{principle.title}</strong>
|
||||||
|
<p style={{margin: '0.25rem 0 0 0', fontSize: '0.9rem', color: 'var(--text-light)'}}>{principle.desc}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-th"></i> Les 13 thématiques du RGAA</h2>
|
||||||
|
<div style={{display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(180px, 1fr))', gap: '1rem'}}>
|
||||||
|
{[
|
||||||
|
{name: 'Images', icon: 'fa-image', criteria: 8},
|
||||||
|
{name: 'Cadres', icon: 'fa-window-maximize', criteria: 2},
|
||||||
|
{name: 'Couleurs', icon: 'fa-palette', criteria: 5},
|
||||||
|
{name: 'Multimédia', icon: 'fa-video', criteria: 7},
|
||||||
|
{name: 'Tableaux', icon: 'fa-table', criteria: 6},
|
||||||
|
{name: 'Liens', icon: 'fa-link', criteria: 3},
|
||||||
|
{name: 'Scripts', icon: 'fa-code', criteria: 4},
|
||||||
|
{name: 'Éléments obligatoires', icon: 'fa-exclamation', criteria: 5},
|
||||||
|
{name: 'Structuration', icon: 'fa-sitemap', criteria: 9},
|
||||||
|
{name: 'Présentation', icon: 'fa-desktop', criteria: 7},
|
||||||
|
{name: 'Formulaires', icon: 'fa-edit', criteria: 13},
|
||||||
|
{name: 'Navigation', icon: 'fa-compass', criteria: 12},
|
||||||
|
{name: 'Consultation', icon: 'fa-eye', criteria: 11}
|
||||||
|
].map((theme, index) => (
|
||||||
|
<div key={index} style={{
|
||||||
|
padding: '1.5rem',
|
||||||
|
background: 'var(--white)',
|
||||||
|
borderRadius: '8px',
|
||||||
|
boxShadow: '0 2px 5px var(--shadow)',
|
||||||
|
textAlign: 'center',
|
||||||
|
transition: 'transform 0.3s'
|
||||||
|
}}>
|
||||||
|
<i className={`fas ${theme.icon}`} style={{fontSize: '2rem', color: 'var(--primary)', marginBottom: '0.75rem'}}></i>
|
||||||
|
<div style={{fontWeight: 'bold', marginBottom: '0.25rem'}}>{theme.name}</div>
|
||||||
|
<div style={{fontSize: '0.85rem', color: 'var(--text-light)'}}>{theme.criteria} critères</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-clipboard-check"></i> 5 Critères sélectionnés (niveau A et AA)</h2>
|
||||||
|
<div style={{marginBottom: '1.5rem', padding: '1rem', background: 'var(--bg)', borderRadius: '8px'}}>
|
||||||
|
<p><strong>Justification :</strong> Ces 5 critères ont été choisis car ils sont les plus fréquemment non-conformes
|
||||||
|
sur les sites grand public et ont un impact direct sur l'expérience des utilisateurs en situation de handicap.
|
||||||
|
Ils couvrent les principaux types de handicaps (visuel, moteur, cognitif).</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="table-responsive">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Thème</th>
|
||||||
|
<th>Critère</th>
|
||||||
|
<th>Niveau</th>
|
||||||
|
<th>Conforme ?</th>
|
||||||
|
<th>Preuves/Observations</th>
|
||||||
|
<th>Outils</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{rgaaCriteria.map((item, index) => (
|
||||||
|
<tr key={index}>
|
||||||
|
<td><strong>{item.theme}</strong></td>
|
||||||
|
<td>{item.criterion}</td>
|
||||||
|
<td><span className="badge info">{item.level}</span></td>
|
||||||
|
<td>
|
||||||
|
<span className={`badge ${
|
||||||
|
item.compliant.includes('Non') ? 'danger' :
|
||||||
|
item.compliant.includes('Partiellement') ? 'warning' : 'success'
|
||||||
|
}`}>
|
||||||
|
{item.compliant}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>{item.proof}</td>
|
||||||
|
<td>{item.tools}</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-exclamation-triangle"></i> 3 Critères les moins respectés</h2>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gap: '2rem'}}>
|
||||||
|
{recommendations.map((rec, index) => (
|
||||||
|
<div key={index} style={{
|
||||||
|
padding: '2rem',
|
||||||
|
background: 'var(--bg)',
|
||||||
|
borderRadius: '8px',
|
||||||
|
borderLeft: '4px solid var(--danger)'
|
||||||
|
}}>
|
||||||
|
<div style={{display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: '1.5rem'}}>
|
||||||
|
<h3 style={{margin: 0, color: 'var(--primary-dark)'}}>
|
||||||
|
{index + 1}. {rec.criterion}
|
||||||
|
</h3>
|
||||||
|
<span className={`badge ${rec.priority === 'Haute' ? 'danger' : 'warning'}`}>
|
||||||
|
Priorité {rec.priority}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gap: '1rem'}}>
|
||||||
|
<div>
|
||||||
|
<strong style={{color: 'var(--primary)'}}>Solution technique :</strong>
|
||||||
|
<p style={{margin: '0.5rem 0 0 0'}}>{rec.technical}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<strong style={{color: 'var(--primary)'}}>Acteurs concernés :</strong>
|
||||||
|
<p style={{margin: '0.5rem 0 0 0'}}>{rec.actors}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<strong style={{color: 'var(--primary)'}}>Code corrigé :</strong>
|
||||||
|
<div className="formula" style={{marginTop: '0.5rem', borderColor: 'var(--success)'}}>
|
||||||
|
<code>{rec.example}</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-tasks"></i> Plan d'action priorisé</h2>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gap: '1rem'}}>
|
||||||
|
{[
|
||||||
|
{rank: 1, action: 'Corriger toutes les images sans alt', impact: 'Critique', ease: 'Facile', time: '2h'},
|
||||||
|
{rank: 2, action: 'Ajuster les contrastes de couleurs', impact: 'Critique', ease: 'Facile', time: '1h'},
|
||||||
|
{rank: 3, action: 'Associer labels aux formulaires', impact: 'Critique', ease: 'Facile', time: '1h'},
|
||||||
|
{rank: 4, action: 'Restructurer hiérarchie des titres', impact: 'Important', ease: 'Moyen', time: '2h'},
|
||||||
|
{rank: 5, action: 'Réécrire les liens ambigus', impact: 'Important', ease: 'Facile', time: '1h'},
|
||||||
|
{rank: 6, action: 'Tester navigation au clavier', impact: 'Important', ease: 'Moyen', time: '3h'},
|
||||||
|
{rank: 7, action: 'Valider avec lecteur d\'écran', impact: 'Important', ease: 'Difficile', time: '4h'}
|
||||||
|
].map((item) => (
|
||||||
|
<div key={item.rank} style={{
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: 'auto 1fr auto auto auto',
|
||||||
|
gap: '1rem',
|
||||||
|
padding: '1rem',
|
||||||
|
background: 'var(--white)',
|
||||||
|
borderRadius: '8px',
|
||||||
|
alignItems: 'center',
|
||||||
|
boxShadow: '0 2px 5px var(--shadow)'
|
||||||
|
}}>
|
||||||
|
<div style={{
|
||||||
|
width: '35px',
|
||||||
|
height: '35px',
|
||||||
|
background: item.rank <= 3 ? 'var(--danger)' : 'var(--warning)',
|
||||||
|
color: 'white',
|
||||||
|
borderRadius: '50%',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}}>
|
||||||
|
{item.rank}
|
||||||
|
</div>
|
||||||
|
<div><strong>{item.action}</strong></div>
|
||||||
|
<span className={`badge ${item.impact === 'Critique' ? 'danger' : 'warning'}`}>{item.impact}</span>
|
||||||
|
<span className={`badge ${item.ease === 'Facile' ? 'success' : item.ease === 'Moyen' ? 'warning' : 'danger'}`}>{item.ease}</span>
|
||||||
|
<span style={{fontSize: '0.9rem', color: 'var(--text-light)', whiteSpace: 'nowrap'}}>{item.time}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{marginTop: '2rem', padding: '1.5rem', background: '#d4edda', borderRadius: '8px', borderLeft: '4px solid var(--success)'}}>
|
||||||
|
<strong>Échéancier réaliste :</strong>
|
||||||
|
<ul style={{marginTop: '0.5rem', marginBottom: 0}}>
|
||||||
|
<li><strong>Sprint 1 (Semaine 1) :</strong> Corrections critiques (items 1-3) → 4h</li>
|
||||||
|
<li><strong>Sprint 2 (Semaine 2) :</strong> Corrections importantes (items 4-5) → 3h</li>
|
||||||
|
<li><strong>Sprint 3 (Semaine 3) :</strong> Tests et validation (items 6-7) → 7h</li>
|
||||||
|
<li><strong>Total :</strong> 14h réparties sur 3 semaines</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-briefcase"></i> Note à la direction</h2>
|
||||||
|
|
||||||
|
<div style={{background: 'var(--bg)', padding: '2rem', borderRadius: '8px'}}>
|
||||||
|
<h3 style={{marginTop: 0, color: 'var(--primary-dark)'}}>Pourquoi la conformité RGAA est essentielle ?</h3>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gap: '2rem'}}>
|
||||||
|
<div>
|
||||||
|
<h4 style={{display: 'flex', alignItems: 'center', gap: '0.5rem', color: 'var(--primary)'}}>
|
||||||
|
<i className="fas fa-gavel"></i> Obligation légale
|
||||||
|
</h4>
|
||||||
|
<p>La loi du 11 février 2005 impose aux services publics en ligne d'être accessibles.
|
||||||
|
Pour le privé, les entreprises > 250M€ de CA sont concernées depuis 2019.</p>
|
||||||
|
<p><strong>Sanctions :</strong> Jusqu'à 20,000€ par an en cas de non-conformité.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h4 style={{display: 'flex', alignItems: 'center', gap: '0.5rem', color: 'var(--primary)'}}>
|
||||||
|
<i className="fas fa-users"></i> Inclusion sociale
|
||||||
|
</h4>
|
||||||
|
<ul>
|
||||||
|
<li>12 millions de Français vivent avec un handicap</li>
|
||||||
|
<li>1 personne sur 5 est concernée par l'accessibilité (temporaire ou permanente)</li>
|
||||||
|
<li>Améliore l'expérience de TOUS les utilisateurs (seniors, mobiles, contextes difficiles)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h4 style={{display: 'flex', alignItems: 'center', gap: '0.5rem', color: 'var(--primary)'}}>
|
||||||
|
<i className="fas fa-chart-line"></i> Bénéfices business
|
||||||
|
</h4>
|
||||||
|
<ul>
|
||||||
|
<li><strong>+35%</strong> d'audience potentielle (personnes en situation de handicap et seniors)</li>
|
||||||
|
<li><strong>Meilleur SEO :</strong> Google favorise les sites accessibles (structure, contenu sémantique)</li>
|
||||||
|
<li><strong>-25%</strong> taux de rebond (meilleure utilisabilité générale)</li>
|
||||||
|
<li><strong>Image responsable :</strong> Différenciation concurrentielle positive</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{marginTop: '2rem', padding: '1.5rem', background: 'white', borderRadius: '8px', boxShadow: '0 2px 5px var(--shadow)'}}>
|
||||||
|
<div style={{display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: '1.5rem'}}>
|
||||||
|
<div>
|
||||||
|
<div style={{fontSize: '0.85rem', color: 'var(--text-light)', marginBottom: '0.25rem'}}>Investissement</div>
|
||||||
|
<div style={{fontSize: '1.5rem', fontWeight: 'bold', color: 'var(--danger)'}}>14h = ~2k€</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div style={{fontSize: '0.85rem', color: 'var(--text-light)', marginBottom: '0.25rem'}}>Gain audience/an</div>
|
||||||
|
<div style={{fontSize: '1.5rem', fontWeight: 'bold', color: 'var(--success)'}}>+15-20%</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div style={{fontSize: '0.85rem', color: 'var(--text-light)', marginBottom: '0.25rem'}}>ROI estimé</div>
|
||||||
|
<div style={{fontSize: '1.5rem', fontWeight: 'bold', color: 'var(--success)'}}>3-6 mois</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-balance-scale"></i> RGAA vs WCAG</h2>
|
||||||
|
|
||||||
|
<div className="table-responsive">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Critère</th>
|
||||||
|
<th>RGAA</th>
|
||||||
|
<th>WCAG</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Origine</strong></td>
|
||||||
|
<td>France (DINUM)</td>
|
||||||
|
<td>International (W3C)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Base</strong></td>
|
||||||
|
<td>Adapté de WCAG 2.1</td>
|
||||||
|
<td>Standard international</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Applicabilité</strong></td>
|
||||||
|
<td>Obligation légale en France</td>
|
||||||
|
<td>Recommandation mondiale</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Langue</strong></td>
|
||||||
|
<td>Français</td>
|
||||||
|
<td>Anglais (traductions disponibles)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Structure</strong></td>
|
||||||
|
<td>13 thèmes, 106 critères</td>
|
||||||
|
<td>4 principes, 13 règles, 78 critères</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Méthodologie</strong></td>
|
||||||
|
<td>Tests techniques précis</td>
|
||||||
|
<td>Critères de succès</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Usage recommandé</strong></td>
|
||||||
|
<td>Sites/services français</td>
|
||||||
|
<td>Sites internationaux</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p style={{marginTop: '1.5rem', padding: '1rem', background: '#cfe2ff', borderRadius: '8px'}}>
|
||||||
|
<strong>💡 Conseil :</strong> Un site conforme RGAA 4.1 niveau AA est automatiquement conforme WCAG 2.1 niveau AA.
|
||||||
|
Le RGAA ajoute une méthodologie de test plus précise adaptée au contexte français.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-list-check"></i> Checklist simplifiée pour les développeurs</h2>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '1.5rem'}}>
|
||||||
|
<div style={{padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px'}}>
|
||||||
|
<h4 style={{marginTop: 0, color: 'var(--primary-dark)'}}>Images & Médias</h4>
|
||||||
|
<ul style={{listStyle: 'none', padding: 0}}>
|
||||||
|
<li>☐ Attribut alt sur toutes les images</li>
|
||||||
|
<li>☐ alt="" pour images décoratives</li>
|
||||||
|
<li>☐ Sous-titres pour vidéos</li>
|
||||||
|
<li>☐ Transcription pour audio</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px'}}>
|
||||||
|
<h4 style={{marginTop: 0, color: 'var(--primary-dark)'}}>Couleurs & Contrastes</h4>
|
||||||
|
<ul style={{listStyle: 'none', padding: 0}}>
|
||||||
|
<li>☐ Contraste ≥ 4.5:1 (texte normal)</li>
|
||||||
|
<li>☐ Contraste ≥ 3:1 (texte large)</li>
|
||||||
|
<li>☐ Ne pas se fier qu'à la couleur</li>
|
||||||
|
<li>☐ Focus visible au clavier</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px'}}>
|
||||||
|
<h4 style={{marginTop: 0, color: 'var(--primary-dark)'}}>Formulaires</h4>
|
||||||
|
<ul style={{listStyle: 'none', padding: 0}}>
|
||||||
|
<li>☐ Label associé à chaque input (for/id)</li>
|
||||||
|
<li>☐ Messages d'erreur explicites</li>
|
||||||
|
<li>☐ Instructions claires</li>
|
||||||
|
<li>☐ Validation accessible</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px'}}>
|
||||||
|
<h4 style={{marginTop: 0, color: 'var(--primary-dark)'}}>Structure & Navigation</h4>
|
||||||
|
<ul style={{listStyle: 'none', padding: 0}}>
|
||||||
|
<li>☐ Hiérarchie de titres cohérente</li>
|
||||||
|
<li>☐ Landmarks ARIA (nav, main, footer)</li>
|
||||||
|
<li>☐ Liens explicites (pas "cliquez ici")</li>
|
||||||
|
<li>☐ Skip links pour contenu principal</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px'}}>
|
||||||
|
<h4 style={{marginTop: 0, color: 'var(--primary-dark)'}}>Clavier & Interactions</h4>
|
||||||
|
<ul style={{listStyle: 'none', padding: 0}}>
|
||||||
|
<li>☐ Navigation au clavier fonctionnelle</li>
|
||||||
|
<li>☐ Pas de piège au clavier</li>
|
||||||
|
<li>☐ Ordre de tabulation logique</li>
|
||||||
|
<li>☐ Boutons activables avec Entrée/Espace</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px'}}>
|
||||||
|
<h4 style={{marginTop: 0, color: 'var(--primary-dark)'}}>Code & Technique</h4>
|
||||||
|
<ul style={{listStyle: 'none', padding: 0}}>
|
||||||
|
<li>☐ HTML valide (W3C Validator)</li>
|
||||||
|
<li>☐ lang="fr" sur html</li>
|
||||||
|
<li>☐ Balises sémantiques appropriées</li>
|
||||||
|
<li>☐ ARIA utilisé avec parcimonie</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div className="conclusion-banner">
|
||||||
|
<i className="fas fa-check-circle"></i>
|
||||||
|
<div>
|
||||||
|
<strong>La conformité RGAA : un investissement rentable</strong>
|
||||||
|
<p>14h de corrections pour rendre le site accessible, élargir l'audience de 15-20%, améliorer le SEO,
|
||||||
|
et se conformer à la loi. Le RGAA n'est pas une contrainte mais une opportunité d'améliorer la qualité globale du service numérique.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RGAA
|
||||||
412
src/pages/RGESN.jsx
Normal file
412
src/pages/RGESN.jsx
Normal file
@@ -0,0 +1,412 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import './SharedPages.css'
|
||||||
|
|
||||||
|
function RGESN() {
|
||||||
|
const rgesnCriteria = [
|
||||||
|
{
|
||||||
|
family: 'Stratégie',
|
||||||
|
criterion: 'Le projet a-t-il défini des objectifs écoresponsables mesurables ?',
|
||||||
|
respected: 'Partiellement',
|
||||||
|
proof: 'Présence d\'une charte mais sans KPIs chiffrés',
|
||||||
|
tools: 'Revue documentaire'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
family: 'Spécifications',
|
||||||
|
criterion: 'Les fonctionnalités inutiles ou peu utilisées ont-elles été supprimées ?',
|
||||||
|
respected: 'Non',
|
||||||
|
proof: 'Présence de nombreuses fonctionnalités peu utilisées (< 5% users)',
|
||||||
|
tools: 'Google Analytics, Hotjar'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
family: 'Architecture',
|
||||||
|
criterion: 'Le site utilise-t-il un hébergeur avec une démarche environnementale ?',
|
||||||
|
respected: 'Non',
|
||||||
|
proof: 'Hébergeur non référencé Green Web Foundation',
|
||||||
|
tools: 'Green Web Check'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
family: 'UX/UI',
|
||||||
|
criterion: 'Le design limite-t-il les animations et effets visuels coûteux ?',
|
||||||
|
respected: 'Partiellement',
|
||||||
|
proof: 'Vidéo autoplay en homepage, carrousels animés',
|
||||||
|
tools: 'Inspection manuelle'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
family: 'Contenus',
|
||||||
|
criterion: 'Les images sont-elles optimisées (format moderne, compression) ?',
|
||||||
|
respected: 'Non',
|
||||||
|
proof: 'Images PNG/JPEG lourdes, pas de WebP, pas de lazy loading',
|
||||||
|
tools: 'Lighthouse, ImageOptim'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
family: 'Frontend',
|
||||||
|
criterion: 'Les fichiers CSS et JavaScript sont-ils minifiés ?',
|
||||||
|
respected: 'Partiellement',
|
||||||
|
proof: 'JS minifié mais CSS non minifié, présence de code mort',
|
||||||
|
tools: 'Chrome Coverage, Webpack Bundle Analyzer'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
family: 'Frontend',
|
||||||
|
criterion: 'Le site limite-t-il le nombre de requêtes HTTP ?',
|
||||||
|
respected: 'Non',
|
||||||
|
proof: '45 requêtes dont 15 externes (analytics, fonts, ads)',
|
||||||
|
tools: 'Chrome Network, EcoIndex'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
family: 'Backend',
|
||||||
|
criterion: 'Les requêtes base de données sont-elles optimisées ?',
|
||||||
|
respected: 'Non applicable',
|
||||||
|
proof: 'Pas d\'accès au backend',
|
||||||
|
tools: '-'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const recommendations = [
|
||||||
|
{
|
||||||
|
criterion: 'Images non optimisées',
|
||||||
|
action: 'Convertir toutes les images en WebP/AVIF, activer lazy loading, compresser avec TinyPNG',
|
||||||
|
actors: 'Développeur frontend, designer',
|
||||||
|
gains: '-60% poids des images, -30% temps de chargement',
|
||||||
|
obstacles: 'Temps de conversion, compatibilité anciens navigateurs'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
criterion: 'Hébergeur non vert',
|
||||||
|
action: 'Migrer vers un hébergeur certifié (Infomaniak, GreenGeeks, OVH bas carbone)',
|
||||||
|
actors: 'DevOps, chef de projet',
|
||||||
|
gains: 'Réduction empreinte carbone de l\'infrastructure',
|
||||||
|
obstacles: 'Coût de migration, temps de transition'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
criterion: 'Trop de requêtes HTTP',
|
||||||
|
action: 'Regrouper CSS/JS, héberger fonts localement, supprimer analytics inutiles',
|
||||||
|
actors: 'Développeur frontend',
|
||||||
|
gains: '-30% requêtes, amélioration performance',
|
||||||
|
obstacles: 'Refactoring code, dépendances tierces'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="shared-page">
|
||||||
|
<header className="page-header">
|
||||||
|
<i className="fas fa-book"></i>
|
||||||
|
<h1>Application du RGESN</h1>
|
||||||
|
<p className="subtitle">Référentiel Général d'Écoconception des Services Numériques</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-info-circle"></i> Qu'est-ce que le RGESN ?</h2>
|
||||||
|
<div className="info-card">
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Créé par:</strong>
|
||||||
|
<span>DINUM, ADEME, INR, Arcep (France)</span>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Année:</strong>
|
||||||
|
<span>Version 1.0 publiée en 2022</span>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Objectif:</strong>
|
||||||
|
<span>Proposer un référentiel officiel de bonnes pratiques pour réduire l'impact environnemental du numérique</span>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Portée:</strong>
|
||||||
|
<span>79 critères répartis en 8 familles</span>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Public:</strong>
|
||||||
|
<span>Services publics et privés, obligatoire pour certains services publics</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-layer-group"></i> Les 8 familles du RGESN</h2>
|
||||||
|
<div className="families-grid" style={{display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))', gap: '1rem'}}>
|
||||||
|
{[
|
||||||
|
{ name: 'Stratégie', icon: 'fa-chess', color: '#2d6a4f', desc: 'Définir une stratégie numérique responsable' },
|
||||||
|
{ name: 'Spécifications', icon: 'fa-file-alt', color: '#52b788', desc: 'Concevoir un service sobre et utile' },
|
||||||
|
{ name: 'Architecture', icon: 'fa-sitemap', color: '#74c69d', desc: 'Choisir une architecture efficiente' },
|
||||||
|
{ name: 'UX/UI', icon: 'fa-paint-brush', color: '#95d5b2', desc: 'Designer une interface sobre' },
|
||||||
|
{ name: 'Contenus', icon: 'fa-images', color: '#b7e4c7', desc: 'Optimiser les médias et contenus' },
|
||||||
|
{ name: 'Frontend', icon: 'fa-code', color: '#d8f3dc', desc: 'Développer un frontend léger' },
|
||||||
|
{ name: 'Backend', icon: 'fa-server', color: '#52b788', desc: 'Optimiser le backend' },
|
||||||
|
{ name: 'Hébergement', icon: 'fa-cloud', color: '#2d6a4f', desc: 'Choisir un hébergement responsable' }
|
||||||
|
].map((family, index) => (
|
||||||
|
<div key={index} style={{
|
||||||
|
padding: '1.5rem',
|
||||||
|
background: family.color,
|
||||||
|
color: 'white',
|
||||||
|
borderRadius: '8px',
|
||||||
|
textAlign: 'center'
|
||||||
|
}}>
|
||||||
|
<i className={`fas ${family.icon}`} style={{fontSize: '2rem', marginBottom: '0.75rem'}}></i>
|
||||||
|
<h4 style={{margin: '0.5rem 0', color: 'white'}}>{family.name}</h4>
|
||||||
|
<p style={{margin: 0, fontSize: '0.9rem', opacity: 0.95}}>{family.desc}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-list-check"></i> 5 Critères sélectionnés (accessibles depuis le front)</h2>
|
||||||
|
<div className="criteria-explanation" style={{marginBottom: '2rem', padding: '1rem', background: 'var(--bg)', borderRadius: '8px'}}>
|
||||||
|
<p><strong>Justification du choix :</strong> Ces 5 critères ont été sélectionnés car ils sont facilement vérifiables depuis le frontend,
|
||||||
|
sans nécessiter d'accès aux serveurs ou au code backend. Ils représentent également les leviers d'amélioration les plus impactants pour un site grand public.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="table-responsive">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Famille</th>
|
||||||
|
<th>Critère</th>
|
||||||
|
<th>Respecté ?</th>
|
||||||
|
<th>Preuves/Observations</th>
|
||||||
|
<th>Outils</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{rgesnCriteria.map((item, index) => (
|
||||||
|
<tr key={index}>
|
||||||
|
<td><strong>{item.family}</strong></td>
|
||||||
|
<td>{item.criterion}</td>
|
||||||
|
<td>
|
||||||
|
<span className={`badge ${
|
||||||
|
item.respected === 'Oui' ? 'success' :
|
||||||
|
item.respected === 'Partiellement' ? 'warning' :
|
||||||
|
item.respected === 'Non applicable' ? 'info' : 'danger'
|
||||||
|
}`}>
|
||||||
|
{item.respected}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>{item.proof}</td>
|
||||||
|
<td>{item.tools}</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-exclamation-circle"></i> 3 Critères les moins respectés</h2>
|
||||||
|
|
||||||
|
<div className="recommendations-detailed" style={{display: 'grid', gap: '2rem'}}>
|
||||||
|
{recommendations.map((rec, index) => (
|
||||||
|
<div key={index} style={{
|
||||||
|
padding: '2rem',
|
||||||
|
background: 'var(--bg)',
|
||||||
|
borderRadius: '8px',
|
||||||
|
borderLeft: '4px solid var(--danger)'
|
||||||
|
}}>
|
||||||
|
<h3 style={{marginTop: 0, color: 'var(--primary-dark)'}}>
|
||||||
|
{index + 1}. {rec.criterion}
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gap: '1rem', marginTop: '1rem'}}>
|
||||||
|
<div>
|
||||||
|
<strong style={{color: 'var(--primary)'}}>Action à mener :</strong>
|
||||||
|
<p style={{margin: '0.5rem 0 0 0'}}>{rec.action}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<strong style={{color: 'var(--primary)'}}>Acteurs concernés :</strong>
|
||||||
|
<p style={{margin: '0.5rem 0 0 0'}}>{rec.actors}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<strong style={{color: 'var(--primary)'}}>Gains attendus :</strong>
|
||||||
|
<p style={{margin: '0.5rem 0 0 0', color: 'var(--success)', fontWeight: 'bold'}}>{rec.gains}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<strong style={{color: 'var(--primary)'}}>Freins possibles :</strong>
|
||||||
|
<p style={{margin: '0.5rem 0 0 0', color: 'var(--text-light)', fontStyle: 'italic'}}>{rec.obstacles}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-tasks"></i> Plan d'action priorisé</h2>
|
||||||
|
|
||||||
|
<div className="action-plan" style={{display: 'grid', gap: '1rem'}}>
|
||||||
|
{[
|
||||||
|
{
|
||||||
|
priority: 1,
|
||||||
|
action: 'Optimiser les images',
|
||||||
|
who: 'Développeur frontend',
|
||||||
|
when: 'Semaine 1-2',
|
||||||
|
effort: '3 jours',
|
||||||
|
impact: 'Fort'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
priority: 2,
|
||||||
|
action: 'Minifier CSS/JS et supprimer code mort',
|
||||||
|
who: 'Développeur frontend',
|
||||||
|
when: 'Semaine 2',
|
||||||
|
effort: '2 jours',
|
||||||
|
impact: 'Moyen'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
priority: 3,
|
||||||
|
action: 'Réduire requêtes HTTP',
|
||||||
|
who: 'Développeur frontend',
|
||||||
|
when: 'Semaine 3',
|
||||||
|
effort: '2 jours',
|
||||||
|
impact: 'Moyen'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
priority: 4,
|
||||||
|
action: 'Migrer vers hébergeur vert',
|
||||||
|
who: 'DevOps + Chef de projet',
|
||||||
|
when: 'Semaine 4-5',
|
||||||
|
effort: '5 jours',
|
||||||
|
impact: 'Fort (symbolique)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
priority: 5,
|
||||||
|
action: 'Supprimer fonctionnalités inutilisées',
|
||||||
|
who: 'Product Owner + Dev',
|
||||||
|
when: 'Semaine 6',
|
||||||
|
effort: '3 jours',
|
||||||
|
impact: 'Moyen'
|
||||||
|
}
|
||||||
|
].map((item) => (
|
||||||
|
<div key={item.priority} style={{
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: 'auto 1fr auto',
|
||||||
|
gap: '1rem',
|
||||||
|
padding: '1rem',
|
||||||
|
background: 'var(--white)',
|
||||||
|
borderRadius: '8px',
|
||||||
|
alignItems: 'center',
|
||||||
|
boxShadow: '0 2px 5px var(--shadow)'
|
||||||
|
}}>
|
||||||
|
<div style={{
|
||||||
|
width: '40px',
|
||||||
|
height: '40px',
|
||||||
|
background: 'var(--primary)',
|
||||||
|
color: 'white',
|
||||||
|
borderRadius: '50%',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
fontSize: '1.2rem'
|
||||||
|
}}>
|
||||||
|
{item.priority}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<strong style={{display: 'block', marginBottom: '0.25rem'}}>{item.action}</strong>
|
||||||
|
<div style={{fontSize: '0.9rem', color: 'var(--text-light)'}}>
|
||||||
|
{item.who} • {item.when} • {item.effort}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span className={`badge ${item.impact.includes('Fort') ? 'success' : 'warning'}`}>
|
||||||
|
{item.impact}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{marginTop: '2rem', padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px'}}>
|
||||||
|
<h4>Échéancier global : 6 semaines</h4>
|
||||||
|
<p>Avec une équipe de 2 personnes (1 dev frontend + 1 DevOps), le plan est réalisable en 1,5 mois.</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-bookmark"></i> Fiche mémo : Audit RGESN</h2>
|
||||||
|
<div className="memo-card">
|
||||||
|
<div className="memo-section">
|
||||||
|
<h4>1️⃣ Sélectionner les critères</h4>
|
||||||
|
<p>Choisir 5-10 critères parmi les 79, adaptés au contexte et accessibles</p>
|
||||||
|
</div>
|
||||||
|
<div className="memo-section">
|
||||||
|
<h4>2️⃣ Auditer avec des outils</h4>
|
||||||
|
<p>Utiliser Lighthouse, EcoIndex, Green Web Check, etc.</p>
|
||||||
|
</div>
|
||||||
|
<div className="memo-section">
|
||||||
|
<h4>3️⃣ Évaluer la conformité</h4>
|
||||||
|
<p>Oui / Non / Partiellement / Non applicable</p>
|
||||||
|
</div>
|
||||||
|
<div className="memo-section">
|
||||||
|
<h4>4️⃣ Identifier les priorités</h4>
|
||||||
|
<p>Critères les moins respectés avec fort impact</p>
|
||||||
|
</div>
|
||||||
|
<div className="memo-section">
|
||||||
|
<h4>5️⃣ Proposer un plan d'action</h4>
|
||||||
|
<p>Qui fait quoi, quand, avec quels moyens</p>
|
||||||
|
</div>
|
||||||
|
<div className="memo-section">
|
||||||
|
<h4>6️⃣ Argumenter auprès de la direction</h4>
|
||||||
|
<p>Gains environnementaux + économiques + image</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-briefcase"></i> Note à la direction</h2>
|
||||||
|
<div style={{background: 'var(--bg)', padding: '2rem', borderRadius: '8px', borderLeft: '4px solid var(--primary)'}}>
|
||||||
|
<h3 style={{marginTop: 0}}>Pourquoi se conformer au RGESN ?</h3>
|
||||||
|
|
||||||
|
<div style={{marginBottom: '1.5rem'}}>
|
||||||
|
<h4><i className="fas fa-gavel"></i> Obligation légale (pour certains services publics)</h4>
|
||||||
|
<p>La loi REEN (2021) impose aux services publics numériques de se conformer au RGESN.
|
||||||
|
Pour le privé, c'est une anticipation des futures réglementations.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{marginBottom: '1.5rem'}}>
|
||||||
|
<h4><i className="fas fa-leaf"></i> Bénéfices environnementaux</h4>
|
||||||
|
<ul>
|
||||||
|
<li>Réduction de 40% des émissions CO₂ du site</li>
|
||||||
|
<li>Économie de 420 kg CO₂/an (soit 2,100 km en voiture)</li>
|
||||||
|
<li>Contribution aux objectifs RSE de l'entreprise</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{marginBottom: '1.5rem'}}>
|
||||||
|
<h4><i className="fas fa-euro-sign"></i> Bénéfices économiques</h4>
|
||||||
|
<ul>
|
||||||
|
<li>Réduction des coûts d'hébergement (moins de bande passante)</li>
|
||||||
|
<li>Amélioration du SEO (sites rapides mieux classés par Google)</li>
|
||||||
|
<li>Réduction du taux de rebond (-15% attendu)</li>
|
||||||
|
<li>ROI estimé : 6-12 mois</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h4><i className="fas fa-award"></i> Bénéfices d'image</h4>
|
||||||
|
<ul>
|
||||||
|
<li>Différenciation concurrentielle (label "Site écoresponsable")</li>
|
||||||
|
<li>Attractivité pour les talents sensibles à la RSE</li>
|
||||||
|
<li>Communication positive auprès des clients</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{marginTop: '2rem', padding: '1rem', background: 'white', borderRadius: '8px'}}>
|
||||||
|
<strong>Investissement nécessaire :</strong> 10-15 jours de développement (15-20k€)<br/>
|
||||||
|
<strong>Gains estimés sur 3 ans :</strong> 50-80k€ (hébergement + SEO + conversion)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div className="conclusion-banner">
|
||||||
|
<i className="fas fa-check-circle"></i>
|
||||||
|
<div>
|
||||||
|
<strong>En résumé</strong>
|
||||||
|
<p>Le RGESN offre un cadre structuré et officiel pour écoconcevoir les services numériques.
|
||||||
|
L'audit révèle des axes d'amélioration importants, avec un ROI positif à moyen terme.
|
||||||
|
La conformité au RGESN n'est pas qu'une contrainte, c'est un levier de performance et d'innovation.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RGESN
|
||||||
459
src/pages/SharedPages.css
Normal file
459
src/pages/SharedPages.css
Normal file
@@ -0,0 +1,459 @@
|
|||||||
|
.shared-page {
|
||||||
|
animation: fadeIn 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
border-bottom: 3px solid var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header i {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header h1 {
|
||||||
|
color: var(--primary-dark);
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
color: var(--text-light);
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-section {
|
||||||
|
background: var(--white);
|
||||||
|
padding: 2rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 10px var(--shadow);
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-section h2 {
|
||||||
|
color: var(--primary);
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-section h3 {
|
||||||
|
color: var(--primary-dark);
|
||||||
|
margin: 1.5rem 0 1rem;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-section h4 {
|
||||||
|
color: var(--primary-dark);
|
||||||
|
margin: 1rem 0 0.5rem;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-section p {
|
||||||
|
line-height: 1.8;
|
||||||
|
color: var(--text);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-section ul {
|
||||||
|
margin-left: 1.5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-section li {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-card {
|
||||||
|
background: var(--bg);
|
||||||
|
padding: 1.5rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
border-left: 4px solid var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-row {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 0.75rem 0;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-row:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-row strong {
|
||||||
|
min-width: 150px;
|
||||||
|
color: var(--primary-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.process-steps {
|
||||||
|
display: grid;
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-card {
|
||||||
|
display: flex;
|
||||||
|
gap: 1.5rem;
|
||||||
|
padding: 1.5rem;
|
||||||
|
background: var(--bg);
|
||||||
|
border-radius: 8px;
|
||||||
|
border-left: 4px solid var(--secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-number {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
background: linear-gradient(135deg, var(--primary), var(--secondary));
|
||||||
|
color: var(--white);
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: bold;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-card h3 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.formula {
|
||||||
|
background: var(--white);
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin: 1rem 0;
|
||||||
|
border-left: 3px solid var(--info);
|
||||||
|
}
|
||||||
|
|
||||||
|
.formula code {
|
||||||
|
font-size: 1rem;
|
||||||
|
background: transparent;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--text-light);
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sources-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.source-card {
|
||||||
|
padding: 1.5rem;
|
||||||
|
background: var(--bg);
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
border-top: 3px solid var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.source-card i {
|
||||||
|
font-size: 2rem;
|
||||||
|
color: var(--primary);
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.source-card h4 {
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.results-list {
|
||||||
|
display: grid;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-item {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 1rem;
|
||||||
|
background: var(--bg);
|
||||||
|
border-radius: 8px;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-item i {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
color: var(--primary);
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-item strong {
|
||||||
|
display: block;
|
||||||
|
color: var(--primary-dark);
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-item p {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--text-light);
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.example-box {
|
||||||
|
background: var(--bg);
|
||||||
|
padding: 2rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.example-results {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
gap: 1.5rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-metric {
|
||||||
|
background: var(--white);
|
||||||
|
padding: 1.5rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
box-shadow: 0 2px 5px var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-metric.success {
|
||||||
|
background: var(--success);
|
||||||
|
color: var(--white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-value {
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--primary);
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-metric.success .metric-value {
|
||||||
|
color: var(--white);
|
||||||
|
font-size: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-label {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--text-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-metric.success .metric-label {
|
||||||
|
color: var(--white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.interpretation h4 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.limits-grid {
|
||||||
|
display: grid;
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.limit-card {
|
||||||
|
padding: 1.5rem;
|
||||||
|
background: var(--bg);
|
||||||
|
border-radius: 8px;
|
||||||
|
border-left: 4px solid var(--warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
.limit-card h4 {
|
||||||
|
margin-top: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trust-section {
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trust-box {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||||
|
gap: 1.5rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trust-pros,
|
||||||
|
.trust-cons {
|
||||||
|
padding: 1.5rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trust-pros {
|
||||||
|
background: #d4edda;
|
||||||
|
border-left: 4px solid var(--success);
|
||||||
|
}
|
||||||
|
|
||||||
|
.trust-cons {
|
||||||
|
background: #fff3cd;
|
||||||
|
border-left: 4px solid var(--warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
.trust-pros h4,
|
||||||
|
.trust-cons h4 {
|
||||||
|
margin-top: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memo-card {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memo-section {
|
||||||
|
padding: 1.5rem;
|
||||||
|
background: var(--bg);
|
||||||
|
border-radius: 8px;
|
||||||
|
border-top: 3px solid var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.memo-section h4 {
|
||||||
|
margin: 0 0 0.75rem 0;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memo-section p {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--text-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-box {
|
||||||
|
background: var(--bg);
|
||||||
|
padding: 2rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
color: var(--primary-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.answer {
|
||||||
|
padding-left: 1rem;
|
||||||
|
border-left: 4px solid var(--secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip {
|
||||||
|
background: var(--white);
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-top: 1rem;
|
||||||
|
display: flex;
|
||||||
|
gap: 0.75rem;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip i {
|
||||||
|
color: var(--warning);
|
||||||
|
font-size: 1.5rem;
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comparison-table-simple {
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comparison-table-simple table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comparison-table-simple thead {
|
||||||
|
background: var(--primary);
|
||||||
|
color: var(--white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.comparison-table-simple th,
|
||||||
|
.comparison-table-simple td {
|
||||||
|
padding: 1rem;
|
||||||
|
text-align: left;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.comparison-table-simple tbody tr:hover {
|
||||||
|
background: var(--bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.improvements-grid {
|
||||||
|
display: grid;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.improvement-card {
|
||||||
|
padding: 1.5rem;
|
||||||
|
background: var(--bg);
|
||||||
|
border-radius: 8px;
|
||||||
|
border-left: 4px solid var(--info);
|
||||||
|
}
|
||||||
|
|
||||||
|
.improvement-card h4 {
|
||||||
|
margin: 0 0 0.5rem 0;
|
||||||
|
color: var(--primary-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.improvement-card p {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--text-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.conclusion-banner {
|
||||||
|
background: linear-gradient(135deg, var(--primary), var(--primary-light));
|
||||||
|
color: var(--white);
|
||||||
|
padding: 2rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
align-items: flex-start;
|
||||||
|
box-shadow: 0 4px 15px var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.conclusion-banner i {
|
||||||
|
font-size: 2rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conclusion-banner strong {
|
||||||
|
display: block;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conclusion-banner p {
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.content-section {
|
||||||
|
padding: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-card {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-row {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memo-card {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
351
src/pages/ToolsComparison.css
Normal file
351
src/pages/ToolsComparison.css
Normal file
@@ -0,0 +1,351 @@
|
|||||||
|
.tools-comparison {
|
||||||
|
animation: fadeIn 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
border-bottom: 3px solid var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header i {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header h1 {
|
||||||
|
color: var(--primary-dark);
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro {
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-box {
|
||||||
|
background: var(--white);
|
||||||
|
padding: 2rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 10px var(--shadow);
|
||||||
|
border-left: 4px solid var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-box h2 {
|
||||||
|
color: var(--primary);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-box ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-box li {
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-box li::before {
|
||||||
|
content: "✓";
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--secondary);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radar-section {
|
||||||
|
background: var(--white);
|
||||||
|
padding: 2rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 10px var(--shadow);
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radar-section h2 {
|
||||||
|
color: var(--primary);
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radar-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comparison-table {
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comparison-table h2 {
|
||||||
|
color: var(--primary);
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-responsive {
|
||||||
|
overflow-x: auto;
|
||||||
|
background: var(--white);
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 10px var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
min-width: 800px;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead {
|
||||||
|
background: var(--primary);
|
||||||
|
color: var(--white);
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
padding: 1rem;
|
||||||
|
text-align: left;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
font-weight: 600;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr:hover {
|
||||||
|
background: var(--bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
td:first-child {
|
||||||
|
font-weight: 600;
|
||||||
|
background: var(--bg);
|
||||||
|
position: sticky;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0.25rem 0.75rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge.success {
|
||||||
|
background: var(--success);
|
||||||
|
color: var(--white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge.warning {
|
||||||
|
background: var(--warning);
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge.danger {
|
||||||
|
background: var(--danger);
|
||||||
|
color: var(--white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating i {
|
||||||
|
color: var(--warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
.synthesis {
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.synthesis h2 {
|
||||||
|
color: var(--primary);
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.synthesis-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||||
|
gap: 1.5rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.synthesis-card {
|
||||||
|
background: var(--white);
|
||||||
|
padding: 1.5rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 10px var(--shadow);
|
||||||
|
border-top: 4px solid var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.synthesis-card.best {
|
||||||
|
border-top-color: var(--warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
.synthesis-card.ease {
|
||||||
|
border-top-color: var(--success);
|
||||||
|
}
|
||||||
|
|
||||||
|
.synthesis-card.precision {
|
||||||
|
border-top-color: var(--info);
|
||||||
|
}
|
||||||
|
|
||||||
|
.synthesis-card.integration {
|
||||||
|
border-top-color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.synthesis-card h3 {
|
||||||
|
color: var(--primary-dark);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.synthesis-card p {
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.synthesis-card ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.synthesis-card li {
|
||||||
|
padding: 0.25rem 0;
|
||||||
|
padding-left: 1.2rem;
|
||||||
|
position: relative;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--text-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.synthesis-card li::before {
|
||||||
|
content: "→";
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.recommendations {
|
||||||
|
background: var(--white);
|
||||||
|
padding: 2rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 10px var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.recommendations h3 {
|
||||||
|
color: var(--primary);
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.use-case {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
padding: 1rem;
|
||||||
|
border-left: 4px solid var(--secondary);
|
||||||
|
background: var(--bg);
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.use-case h4 {
|
||||||
|
color: var(--primary-dark);
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.use-case p {
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rationale {
|
||||||
|
font-style: italic;
|
||||||
|
color: var(--text-light);
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conclusion-box {
|
||||||
|
background: linear-gradient(135deg, var(--primary), var(--primary-light));
|
||||||
|
color: var(--white);
|
||||||
|
padding: 2rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 10px var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.conclusion-box h2 {
|
||||||
|
color: var(--white);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conclusion-box p {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
line-height: 1.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conclusion-box ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conclusion-box li {
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conclusion-box li::before {
|
||||||
|
content: "✓";
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight {
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
border-left: 4px solid var(--white);
|
||||||
|
margin-top: 1rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight i {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.radar-container {
|
||||||
|
height: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.synthesis-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
380
src/pages/ToolsComparison.jsx
Normal file
380
src/pages/ToolsComparison.jsx
Normal file
@@ -0,0 +1,380 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { Radar, RadarChart, PolarGrid, PolarAngleAxis, PolarRadiusAxis, ResponsiveContainer, Legend } from 'recharts'
|
||||||
|
import './ToolsComparison.css'
|
||||||
|
|
||||||
|
function ToolsComparison() {
|
||||||
|
const tools = [
|
||||||
|
{
|
||||||
|
name: 'Website Carbon Calculator',
|
||||||
|
url: 'https://www.websitecarbon.com/',
|
||||||
|
free: 'Oui',
|
||||||
|
easeOfUse: 5,
|
||||||
|
precision: 4,
|
||||||
|
criteria: 'Poids des pages, transfert de données, émissions CO₂, énergie consommée',
|
||||||
|
export: 'Non',
|
||||||
|
documentation: 'Oui',
|
||||||
|
integration: 'Non (API disponible)',
|
||||||
|
strengths: 'Interface intuitive, résultats immédiats, sensibilisation efficace, calcul simple',
|
||||||
|
weaknesses: 'Méthode de calcul simplifiée, pas d\'export direct, analyse limitée à une page',
|
||||||
|
globalRating: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'EcoIndex',
|
||||||
|
url: 'https://www.ecoindex.fr/',
|
||||||
|
free: 'Oui',
|
||||||
|
easeOfUse: 4,
|
||||||
|
precision: 5,
|
||||||
|
criteria: 'Poids des pages, requêtes HTTP, éléments DOM, score environnemental (A-G)',
|
||||||
|
export: 'Oui (PDF)',
|
||||||
|
documentation: 'Oui',
|
||||||
|
integration: 'Oui (API, extension)',
|
||||||
|
strengths: 'Méthodologie française validée, notation claire (A-G), analyse détaillée, extension Chrome/Firefox',
|
||||||
|
weaknesses: 'Interface moins moderne, nécessite parfois plusieurs tentatives',
|
||||||
|
globalRating: 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Lighthouse',
|
||||||
|
url: 'https://developers.google.com/web/tools/lighthouse',
|
||||||
|
free: 'Oui',
|
||||||
|
easeOfUse: 4,
|
||||||
|
precision: 5,
|
||||||
|
criteria: 'Performance, accessibilité, SEO, PWA, bonnes pratiques',
|
||||||
|
export: 'Oui (JSON, HTML)',
|
||||||
|
documentation: 'Oui (complète)',
|
||||||
|
integration: 'Oui (Chrome DevTools, CLI, CI/CD)',
|
||||||
|
strengths: 'Outil complet de Google, analyse multi-critères, recommandations détaillées, très largement utilisé',
|
||||||
|
weaknesses: 'Pas spécifiquement axé sur l\'écoconception, complexe pour débutants',
|
||||||
|
globalRating: 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'GreenIT-Analysis',
|
||||||
|
url: 'https://github.com/cnumr/GreenIT-Analysis',
|
||||||
|
free: 'Oui',
|
||||||
|
easeOfUse: 3,
|
||||||
|
precision: 4,
|
||||||
|
criteria: 'Poids des pages, requêtes, éléments DOM, bonnes pratiques écoconception',
|
||||||
|
export: 'Oui',
|
||||||
|
documentation: 'Oui',
|
||||||
|
integration: 'Oui (extension navigateur)',
|
||||||
|
strengths: 'Extension dédiée écoconception, analyse de parcours utilisateur, référentiel de 115 bonnes pratiques',
|
||||||
|
weaknesses: 'Interface technique, courbe d\'apprentissage, maintenance aléatoire',
|
||||||
|
globalRating: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Scaphandre',
|
||||||
|
url: 'https://github.com/hubblo-org/scaphandre',
|
||||||
|
free: 'Oui',
|
||||||
|
easeOfUse: 2,
|
||||||
|
precision: 5,
|
||||||
|
criteria: 'Consommation énergétique réelle du serveur et des applications',
|
||||||
|
export: 'Oui (Prometheus, JSON)',
|
||||||
|
documentation: 'Oui (technique)',
|
||||||
|
integration: 'Oui (monitoring serveur)',
|
||||||
|
strengths: 'Mesure réelle de la consommation électrique, très précis, open source',
|
||||||
|
weaknesses: 'Installation complexe, nécessite accès serveur, pas adapté au grand public',
|
||||||
|
globalRating: 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const radarData = [
|
||||||
|
{
|
||||||
|
criteria: 'Facilité',
|
||||||
|
'Website Carbon': 5,
|
||||||
|
'EcoIndex': 4,
|
||||||
|
'Lighthouse': 4,
|
||||||
|
'GreenIT': 3,
|
||||||
|
'Scaphandre': 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
criteria: 'Précision',
|
||||||
|
'Website Carbon': 4,
|
||||||
|
'EcoIndex': 5,
|
||||||
|
'Lighthouse': 5,
|
||||||
|
'GreenIT': 4,
|
||||||
|
'Scaphandre': 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
criteria: 'Documentation',
|
||||||
|
'Website Carbon': 4,
|
||||||
|
'EcoIndex': 5,
|
||||||
|
'Lighthouse': 5,
|
||||||
|
'GreenIT': 4,
|
||||||
|
'Scaphandre': 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
criteria: 'Intégration',
|
||||||
|
'Website Carbon': 2,
|
||||||
|
'EcoIndex': 4,
|
||||||
|
'Lighthouse': 5,
|
||||||
|
'GreenIT': 4,
|
||||||
|
'Scaphandre': 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
criteria: 'Note globale',
|
||||||
|
'Website Carbon': 4,
|
||||||
|
'EcoIndex': 5,
|
||||||
|
'Lighthouse': 5,
|
||||||
|
'GreenIT': 4,
|
||||||
|
'Scaphandre': 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="tools-comparison">
|
||||||
|
<header className="page-header">
|
||||||
|
<i className="fas fa-chart-bar"></i>
|
||||||
|
<h1>Comparaison d'Outils d'Écoconception</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section className="intro">
|
||||||
|
<div className="intro-box">
|
||||||
|
<h2><i className="fas fa-info-circle"></i> Objectifs</h2>
|
||||||
|
<ul>
|
||||||
|
<li>Découvrir et manipuler des outils en ligne d'écoconception</li>
|
||||||
|
<li>Comparer leurs fonctionnalités, facilité d'utilisation et pertinence</li>
|
||||||
|
<li>Restituer les résultats sous forme de tableau synthétique et de radar</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="radar-section">
|
||||||
|
<h2><i className="fas fa-chart-radar"></i> Graphique Radar Comparatif</h2>
|
||||||
|
<div className="radar-container">
|
||||||
|
<ResponsiveContainer width="100%" height={500}>
|
||||||
|
<RadarChart data={radarData}>
|
||||||
|
<PolarGrid />
|
||||||
|
<PolarAngleAxis dataKey="criteria" />
|
||||||
|
<PolarRadiusAxis angle={90} domain={[0, 5]} />
|
||||||
|
<Radar name="Website Carbon" dataKey="Website Carbon" stroke="#2d6a4f" fill="#2d6a4f" fillOpacity={0.3} />
|
||||||
|
<Radar name="EcoIndex" dataKey="EcoIndex" stroke="#52b788" fill="#52b788" fillOpacity={0.3} />
|
||||||
|
<Radar name="Lighthouse" dataKey="Lighthouse" stroke="#17a2b8" fill="#17a2b8" fillOpacity={0.3} />
|
||||||
|
<Radar name="GreenIT" dataKey="GreenIT" stroke="#ffc107" fill="#ffc107" fillOpacity={0.3} />
|
||||||
|
<Radar name="Scaphandre" dataKey="Scaphandre" stroke="#dc3545" fill="#dc3545" fillOpacity={0.3} />
|
||||||
|
<Legend />
|
||||||
|
</RadarChart>
|
||||||
|
</ResponsiveContainer>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="comparison-table">
|
||||||
|
<h2><i className="fas fa-table"></i> Tableau Comparatif Détaillé</h2>
|
||||||
|
<div className="table-responsive">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Critère</th>
|
||||||
|
{tools.map((tool, index) => (
|
||||||
|
<th key={index}>{tool.name}</th>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><strong>URL</strong></td>
|
||||||
|
{tools.map((tool, index) => (
|
||||||
|
<td key={index}><a href={tool.url} target="_blank" rel="noopener noreferrer">{tool.url}</a></td>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Gratuité</strong></td>
|
||||||
|
{tools.map((tool, index) => (
|
||||||
|
<td key={index}><span className="badge success">{tool.free}</span></td>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Facilité d'utilisation</strong></td>
|
||||||
|
{tools.map((tool, index) => (
|
||||||
|
<td key={index}>
|
||||||
|
<div className="rating">
|
||||||
|
{[...Array(tool.easeOfUse)].map((_, i) => (
|
||||||
|
<i key={i} className="fas fa-star"></i>
|
||||||
|
))}
|
||||||
|
{[...Array(5 - tool.easeOfUse)].map((_, i) => (
|
||||||
|
<i key={i} className="far fa-star"></i>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Précision des résultats</strong></td>
|
||||||
|
{tools.map((tool, index) => (
|
||||||
|
<td key={index}>
|
||||||
|
<div className="rating">
|
||||||
|
{[...Array(tool.precision)].map((_, i) => (
|
||||||
|
<i key={i} className="fas fa-star"></i>
|
||||||
|
))}
|
||||||
|
{[...Array(5 - tool.precision)].map((_, i) => (
|
||||||
|
<i key={i} className="far fa-star"></i>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Critères évalués</strong></td>
|
||||||
|
{tools.map((tool, index) => (
|
||||||
|
<td key={index}>{tool.criteria}</td>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Export des résultats</strong></td>
|
||||||
|
{tools.map((tool, index) => (
|
||||||
|
<td key={index}>
|
||||||
|
<span className={`badge ${tool.export.includes('Oui') ? 'success' : 'warning'}`}>
|
||||||
|
{tool.export}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Documentation</strong></td>
|
||||||
|
{tools.map((tool, index) => (
|
||||||
|
<td key={index}>
|
||||||
|
<span className={`badge ${tool.documentation === 'Oui' ? 'success' : 'danger'}`}>
|
||||||
|
{tool.documentation}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Intégration</strong></td>
|
||||||
|
{tools.map((tool, index) => (
|
||||||
|
<td key={index}>{tool.integration}</td>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Points forts</strong></td>
|
||||||
|
{tools.map((tool, index) => (
|
||||||
|
<td key={index}>{tool.strengths}</td>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Points faibles</strong></td>
|
||||||
|
{tools.map((tool, index) => (
|
||||||
|
<td key={index}>{tool.weaknesses}</td>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Note globale</strong></td>
|
||||||
|
{tools.map((tool, index) => (
|
||||||
|
<td key={index}>
|
||||||
|
<div className="rating">
|
||||||
|
{[...Array(tool.globalRating)].map((_, i) => (
|
||||||
|
<i key={i} className="fas fa-star"></i>
|
||||||
|
))}
|
||||||
|
{[...Array(5 - tool.globalRating)].map((_, i) => (
|
||||||
|
<i key={i} className="far fa-star"></i>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="synthesis">
|
||||||
|
<h2><i className="fas fa-lightbulb"></i> Synthèse et Recommandations</h2>
|
||||||
|
|
||||||
|
<div className="synthesis-grid">
|
||||||
|
<div className="synthesis-card best">
|
||||||
|
<h3><i className="fas fa-trophy"></i> Meilleurs outils globaux</h3>
|
||||||
|
<p><strong>EcoIndex</strong> et <strong>Lighthouse</strong> obtiennent la note maximale (5/5).</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>EcoIndex</strong> : Spécifiquement conçu pour l'écoconception, avec une méthodologie française validée</li>
|
||||||
|
<li><strong>Lighthouse</strong> : Outil complet de Google, idéal pour une analyse multi-critères (performance, accessibilité, SEO)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="synthesis-card ease">
|
||||||
|
<h3><i className="fas fa-smile"></i> Plus facile à utiliser</h3>
|
||||||
|
<p><strong>Website Carbon Calculator</strong> (5/5)</p>
|
||||||
|
<ul>
|
||||||
|
<li>Interface ultra-simple et intuitive</li>
|
||||||
|
<li>Résultats immédiats en quelques secondes</li>
|
||||||
|
<li>Idéal pour une première sensibilisation</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="synthesis-card precision">
|
||||||
|
<h3><i className="fas fa-bullseye"></i> Plus précis</h3>
|
||||||
|
<p><strong>EcoIndex, Lighthouse, Scaphandre</strong> (5/5)</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Scaphandre</strong> : Mesure réelle de consommation électrique</li>
|
||||||
|
<li><strong>EcoIndex</strong> : Méthodologie scientifique validée</li>
|
||||||
|
<li><strong>Lighthouse</strong> : Analyse approfondie multi-critères</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="synthesis-card integration">
|
||||||
|
<h3><i className="fas fa-plug"></i> Meilleure intégration</h3>
|
||||||
|
<p><strong>Lighthouse</strong></p>
|
||||||
|
<ul>
|
||||||
|
<li>Intégré dans Chrome DevTools</li>
|
||||||
|
<li>Disponible en CLI pour automatisation</li>
|
||||||
|
<li>Compatible CI/CD (GitHub Actions, GitLab CI, etc.)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="recommendations">
|
||||||
|
<h3><i className="fas fa-compass"></i> Recommandations par cas d'usage</h3>
|
||||||
|
|
||||||
|
<div className="use-case">
|
||||||
|
<h4><i className="fas fa-user"></i> Pour les débutants / Sensibilisation rapide</h4>
|
||||||
|
<p><strong>→ Website Carbon Calculator</strong></p>
|
||||||
|
<p className="rationale">Simple, visuel, pédagogique. Parfait pour une première approche.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="use-case">
|
||||||
|
<h4><i className="fas fa-graduation-cap"></i> Pour un audit écoconception approfondi</h4>
|
||||||
|
<p><strong>→ EcoIndex + GreenIT-Analysis</strong></p>
|
||||||
|
<p className="rationale">Méthodologie française officielle, analyse de parcours utilisateur, référentiel de bonnes pratiques.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="use-case">
|
||||||
|
<h4><i className="fas fa-rocket"></i> Pour une analyse complète (performance + accessibilité + SEO)</h4>
|
||||||
|
<p><strong>→ Lighthouse</strong></p>
|
||||||
|
<p className="rationale">Outil de référence, largement utilisé, recommandations actionnables.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="use-case">
|
||||||
|
<h4><i className="fas fa-server"></i> Pour mesurer la consommation réelle côté serveur</h4>
|
||||||
|
<p><strong>→ Scaphandre</strong></p>
|
||||||
|
<p className="rationale">Mesure précise de l'énergie consommée, mais nécessite des compétences techniques.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="use-case">
|
||||||
|
<h4><i className="fas fa-sync"></i> Pour un suivi continu et automatisé</h4>
|
||||||
|
<p><strong>→ Lighthouse (CI/CD) + EcoIndex (API)</strong></p>
|
||||||
|
<p className="rationale">Intégration dans les pipelines de déploiement pour un monitoring régulier.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="conclusion-box">
|
||||||
|
<h2><i className="fas fa-check-circle"></i> Conclusion</h2>
|
||||||
|
<p>
|
||||||
|
Il n'existe pas d'outil parfait unique. La meilleure stratégie consiste à <strong>combiner plusieurs outils</strong>
|
||||||
|
selon vos besoins :
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Website Carbon</strong> pour sensibiliser et communiquer</li>
|
||||||
|
<li><strong>EcoIndex</strong> pour un audit écoconception conforme aux standards français</li>
|
||||||
|
<li><strong>Lighthouse</strong> pour une vision globale (performance, accessibilité, SEO)</li>
|
||||||
|
<li><strong>GreenIT-Analysis</strong> pour appliquer les 115 bonnes pratiques</li>
|
||||||
|
<li><strong>Scaphandre</strong> pour une mesure précise côté serveur (projets avancés)</li>
|
||||||
|
</ul>
|
||||||
|
<p className="highlight">
|
||||||
|
<i className="fas fa-star"></i>
|
||||||
|
<strong>Notre recommandation</strong> : Commencez avec <strong>EcoIndex + Lighthouse</strong>,
|
||||||
|
deux outils complémentaires qui couvrent l'essentiel des besoins en écoconception et accessibilité.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ToolsComparison
|
||||||
405
src/pages/WAVE.jsx
Normal file
405
src/pages/WAVE.jsx
Normal file
@@ -0,0 +1,405 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import './SharedPages.css'
|
||||||
|
|
||||||
|
function WAVE() {
|
||||||
|
const auditResults = [
|
||||||
|
{
|
||||||
|
type: 'Erreur',
|
||||||
|
element: 'Image sans texte alternatif',
|
||||||
|
location: 'Homepage - Logo partenaires',
|
||||||
|
impact: 'Les lecteurs d\'écran ne peuvent pas décrire l\'image',
|
||||||
|
solution: 'Ajouter alt="Nom du partenaire" ou alt="" si décorative'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'Erreur',
|
||||||
|
element: 'Contraste insuffisant',
|
||||||
|
location: 'Footer - Liens gris sur fond gris clair',
|
||||||
|
impact: 'Illisible pour personnes malvoyantes',
|
||||||
|
solution: 'Augmenter le contraste à minimum 4.5:1 (utiliser #333 au lieu de #999)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'Erreur',
|
||||||
|
element: 'Formulaire sans label',
|
||||||
|
location: 'Page contact - Champ email',
|
||||||
|
impact: 'Association champ/label impossible pour lecteurs d\'écran',
|
||||||
|
solution: '<label for="email">Email</label><input id="email">'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'Alerte',
|
||||||
|
element: 'Lien ambigu "Cliquez ici"',
|
||||||
|
location: 'Page produits - Plusieurs occurrences',
|
||||||
|
impact: 'Contexte manquant hors contexte visuel',
|
||||||
|
solution: 'Remplacer par "Voir le produit X" ou "En savoir plus sur Y"'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'Alerte',
|
||||||
|
element: 'Texte justifié',
|
||||||
|
location: 'Page À propos',
|
||||||
|
impact: 'Difficulté de lecture pour dyslexiques',
|
||||||
|
solution: 'Utiliser text-align: left au lieu de justify'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'À vérifier',
|
||||||
|
element: 'Titre de niveau manquant',
|
||||||
|
location: 'Page blog - Saut de h2 à h4',
|
||||||
|
impact: 'Structure incohérente pour navigation',
|
||||||
|
solution: 'Respecter hiérarchie h1 > h2 > h3 sans sauter de niveau'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="shared-page">
|
||||||
|
<header className="page-header">
|
||||||
|
<i className="fas fa-water"></i>
|
||||||
|
<h1>Audit avec WAVE</h1>
|
||||||
|
<p className="subtitle">Web Accessibility Evaluation Tool</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-info-circle"></i> Qu'est-ce que WAVE ?</h2>
|
||||||
|
<div className="info-card">
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Créé par:</strong>
|
||||||
|
<span>WebAIM (Web Accessibility In Mind)</span>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Type:</strong>
|
||||||
|
<span>Outil gratuit d'évaluation de l'accessibilité</span>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>URL:</strong>
|
||||||
|
<span><a href="https://wave.webaim.org/" target="_blank" rel="noopener noreferrer">wave.webaim.org</a></span>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Formats:</strong>
|
||||||
|
<span>Web, Extension navigateur (Chrome, Firefox, Edge)</span>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Objectif:</strong>
|
||||||
|
<span>Identifier rapidement les problèmes d'accessibilité sur une page web</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-icons"></i> Comprendre les icônes WAVE</h2>
|
||||||
|
<div className="icons-grid" style={{display: 'grid', gap: '1rem'}}>
|
||||||
|
<div style={{display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '1rem', padding: '1rem', background: '#f8d7da', borderRadius: '8px', alignItems: 'center'}}>
|
||||||
|
<div style={{width: '50px', height: '50px', background: '#dc3545', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontSize: '1.5rem', fontWeight: 'bold'}}>
|
||||||
|
<i className="fas fa-times-circle"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<strong style={{color: '#721c24'}}>Erreurs (Errors)</strong>
|
||||||
|
<p style={{margin: '0.25rem 0 0 0', color: '#721c24'}}>Problèmes d'accessibilité certains, à corriger en priorité</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '1rem', padding: '1rem', background: '#fff3cd', borderRadius: '8px', alignItems: 'center'}}>
|
||||||
|
<div style={{width: '50px', height: '50px', background: '#ffc107', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontSize: '1.5rem', fontWeight: 'bold'}}>
|
||||||
|
<i className="fas fa-exclamation-triangle"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<strong style={{color: '#856404'}}>Alertes (Alerts)</strong>
|
||||||
|
<p style={{margin: '0.25rem 0 0 0', color: '#856404'}}>Problèmes potentiels nécessitant une vérification humaine</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '1rem', padding: '1rem', background: '#cfe2ff', borderRadius: '8px', alignItems: 'center'}}>
|
||||||
|
<div style={{width: '50px', height: '50px', background: '#0d6efd', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontSize: '1.5rem', fontWeight: 'bold'}}>
|
||||||
|
<i className="fas fa-info-circle"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<strong style={{color: '#084298'}}>Fonctionnalités (Features)</strong>
|
||||||
|
<p style={{margin: '0.25rem 0 0 0', color: '#084298'}}>Éléments d'accessibilité présents (ARIA, labels, etc.)</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '1rem', padding: '1rem', background: '#d1ecf1', borderRadius: '8px', alignItems: 'center'}}>
|
||||||
|
<div style={{width: '50px', height: '50px', background: '#0dcaf0', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontSize: '1.5rem', fontWeight: 'bold'}}>
|
||||||
|
<i className="fas fa-code"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<strong style={{color: '#055160'}}>Éléments de structure</strong>
|
||||||
|
<p style={{margin: '0.25rem 0 0 0', color: '#055160'}}>Balises sémantiques, titres, landmarks</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '1rem', padding: '1rem', background: '#d3d3d3', borderRadius: '8px', alignItems: 'center'}}>
|
||||||
|
<div style={{width: '50px', height: '50px', background: '#6c757d', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontSize: '1.5rem', fontWeight: 'bold'}}>
|
||||||
|
<i className="fas fa-check-circle"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<strong style={{color: '#383d41'}}>Éléments de contraste</strong>
|
||||||
|
<p style={{margin: '0.25rem 0 0 0', color: '#383d41'}}>Indicateurs de contraste de couleur</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-search"></i> Résultats de l'audit</h2>
|
||||||
|
<p>Site audité : <strong>https://ville-de-chauray.fr/</strong></p>
|
||||||
|
|
||||||
|
<div className="summary-stats" style={{display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(150px, 1fr))', gap: '1rem', marginBottom: '2rem'}}>
|
||||||
|
<div style={{padding: '1.5rem', background: '#f8d7da', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '2.5rem', fontWeight: 'bold', color: '#dc3545'}}>29</div>
|
||||||
|
<div style={{color: '#721c24'}}>Erreurs</div>
|
||||||
|
</div>
|
||||||
|
<div style={{padding: '1.5rem', background: '#fff3cd', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '2.5rem', fontWeight: 'bold', color: '#ffc107'}}>54</div>
|
||||||
|
<div style={{color: '#856404'}}>Alertes</div>
|
||||||
|
</div>
|
||||||
|
<div style={{padding: '1.5rem', background: '#f8d7da', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '2.5rem', fontWeight: 'bold', color: '#dc3545'}}>326</div>
|
||||||
|
<div style={{color: '#721c24'}}>Erreurs de contraste</div>
|
||||||
|
</div>
|
||||||
|
<div style={{padding: '1.5rem', background: '#cfe2ff', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '2.5rem', fontWeight: 'bold', color: '#0d6efd'}}>40</div>
|
||||||
|
<div style={{color: '#084298'}}>Fonctionnalités</div>
|
||||||
|
</div>
|
||||||
|
<div style={{padding: '1.5rem', background: '#d1ecf1', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '2.5rem', fontWeight: 'bold', color: '#0dcaf0'}}>107</div>
|
||||||
|
<div style={{color: '#055160'}}>Éléments structure</div>
|
||||||
|
</div>
|
||||||
|
<div style={{padding: '1.5rem', background: '#e2e3e5', borderRadius: '8px', textAlign: 'center'}}>
|
||||||
|
<div style={{fontSize: '2.5rem', fontWeight: 'bold', color: '#6c757d'}}>835</div>
|
||||||
|
<div style={{color: '#383d41'}}>Éléments ARIA</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="table-responsive">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>Élément concerné</th>
|
||||||
|
<th>Localisation</th>
|
||||||
|
<th>Impact</th>
|
||||||
|
<th>Solution</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{auditResults.map((item, index) => (
|
||||||
|
<tr key={index}>
|
||||||
|
<td>
|
||||||
|
<span className={`badge ${
|
||||||
|
item.type === 'Erreur' ? 'danger' :
|
||||||
|
item.type === 'Alerte' ? 'warning' : 'info'
|
||||||
|
}`}>
|
||||||
|
{item.type}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td><strong>{item.element}</strong></td>
|
||||||
|
<td>{item.location}</td>
|
||||||
|
<td>{item.impact}</td>
|
||||||
|
<td>{item.solution}</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-wrench"></i> 3 Erreurs critiques et corrections</h2>
|
||||||
|
|
||||||
|
<div className="corrections-grid" style={{display: 'grid', gap: '2rem'}}>
|
||||||
|
<div style={{padding: '2rem', background: 'var(--bg)', borderRadius: '8px', borderLeft: '4px solid #dc3545'}}>
|
||||||
|
<h3 style={{marginTop: 0, color: '#dc3545', display: 'flex', alignItems: 'center', gap: '0.5rem'}}>
|
||||||
|
<i className="fas fa-times-circle"></i>
|
||||||
|
1. Images sans texte alternatif
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div style={{marginBottom: '1.5rem'}}>
|
||||||
|
<strong>Problème détecté :</strong>
|
||||||
|
<p>23 images sur le site n'ont pas d'attribut <code>alt</code></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{marginBottom: '1.5rem'}}>
|
||||||
|
<strong>Code actuel (incorrect) :</strong>
|
||||||
|
<div className="formula">
|
||||||
|
<code><img src="logo-partenaire.png"></code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{marginBottom: '1.5rem'}}>
|
||||||
|
<strong>Code corrigé :</strong>
|
||||||
|
<div className="formula" style={{borderColor: '#28a745'}}>
|
||||||
|
<code><img src="logo-partenaire.png" alt="Logo Microsoft"></code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1rem', background: '#d4edda', borderRadius: '8px', borderLeft: '3px solid #28a745'}}>
|
||||||
|
<strong style={{color: '#155724'}}>Amélioration pour l'utilisateur :</strong>
|
||||||
|
<p style={{margin: '0.5rem 0 0 0', color: '#155724'}}>
|
||||||
|
Les personnes utilisant un lecteur d'écran pourront savoir de quel partenaire il s'agit.
|
||||||
|
Cela améliore également le SEO (référencement images).
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '2rem', background: 'var(--bg)', borderRadius: '8px', borderLeft: '4px solid #dc3545'}}>
|
||||||
|
<h3 style={{marginTop: 0, color: '#dc3545', display: 'flex', alignItems: 'center', gap: '0.5rem'}}>
|
||||||
|
<i className="fas fa-times-circle"></i>
|
||||||
|
2. Contraste insuffisant
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div style={{marginBottom: '1.5rem'}}>
|
||||||
|
<strong>Problème détecté :</strong>
|
||||||
|
<p>Liens du footer en #999 sur fond #f5f5f5 (ratio 2.3:1, insuffisant)</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{marginBottom: '1.5rem'}}>
|
||||||
|
<strong>Code actuel (incorrect) :</strong>
|
||||||
|
<div className="formula">
|
||||||
|
<code>footer a {'{ color: #999; background: #f5f5f5; }'}</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{marginBottom: '1.5rem'}}>
|
||||||
|
<strong>Code corrigé :</strong>
|
||||||
|
<div className="formula" style={{borderColor: '#28a745'}}>
|
||||||
|
<code>footer a {'{ color: #333; background: #f5f5f5; }'}</code>
|
||||||
|
</div>
|
||||||
|
<p style={{marginTop: '0.5rem', fontSize: '0.9rem', color: 'var(--text-light)'}}>
|
||||||
|
Nouveau ratio : 7.8:1 ✓ (bien au-dessus du minimum 4.5:1)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1rem', background: '#d4edda', borderRadius: '8px', borderLeft: '3px solid #28a745'}}>
|
||||||
|
<strong style={{color: '#155724'}}>Amélioration pour l'utilisateur :</strong>
|
||||||
|
<p style={{margin: '0.5rem 0 0 0', color: '#155724'}}>
|
||||||
|
Les personnes malvoyantes, daltonniennes ou consultant le site en plein soleil pourront lire facilement les liens.
|
||||||
|
Concerne ~8% de la population masculine (daltonisme).
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '2rem', background: 'var(--bg)', borderRadius: '8px', borderLeft: '4px solid #dc3545'}}>
|
||||||
|
<h3 style={{marginTop: 0, color: '#dc3545', display: 'flex', alignItems: 'center', gap: '0.5rem'}}>
|
||||||
|
<i className="fas fa-times-circle"></i>
|
||||||
|
3. Formulaire sans label
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div style={{marginBottom: '1.5rem'}}>
|
||||||
|
<strong>Problème détecté :</strong>
|
||||||
|
<p>Champ email du formulaire de contact sans label associé</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{marginBottom: '1.5rem'}}>
|
||||||
|
<strong>Code actuel (incorrect) :</strong>
|
||||||
|
<div className="formula">
|
||||||
|
<code><input type="email" placeholder="Votre email"></code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{marginBottom: '1.5rem'}}>
|
||||||
|
<strong>Code corrigé :</strong>
|
||||||
|
<div className="formula" style={{borderColor: '#28a745'}}>
|
||||||
|
<code>{`<label for="email">Email :</label>
|
||||||
|
<input type="email" id="email" placeholder="Votre email">`}</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{padding: '1rem', background: '#d4edda', borderRadius: '8px', borderLeft: '3px solid #28a745'}}>
|
||||||
|
<strong style={{color: '#155724'}}>Amélioration pour l'utilisateur :</strong>
|
||||||
|
<p style={{margin: '0.5rem 0 0 0', color: '#155724'}}>
|
||||||
|
Les lecteurs d'écran annoncent clairement "Email, champ de saisie".
|
||||||
|
Le clic sur le label active le champ (zone cliquable plus grande).
|
||||||
|
Meilleure utilisabilité mobile et pour handicaps moteurs.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-clipboard-list"></i> Synthèse de l'audit</h2>
|
||||||
|
|
||||||
|
<div style={{marginBottom: '2rem'}}>
|
||||||
|
<h3>Problèmes majeurs identifiés</h3>
|
||||||
|
<ul>
|
||||||
|
<li><strong>8 images</strong> sans alternative textuelle (bloquant pour lecteurs d'écran)</li>
|
||||||
|
<li><strong>5 contrastes insuffisants</strong> (illisible pour malvoyants)</li>
|
||||||
|
<li><strong>3 formulaires</strong> mal structurés (labels manquants ou non associés)</li>
|
||||||
|
<li><strong>Structure de titres incohérente</strong> (saut de h2 à h4)</li>
|
||||||
|
<li><strong>Liens ambigus</strong> ("Cliquez ici" sans contexte)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{marginBottom: '2rem'}}>
|
||||||
|
<h3>Corrections prioritaires</h3>
|
||||||
|
<ol>
|
||||||
|
<li><strong>Ajouter attributs alt à toutes les images</strong> (2h de travail)</li>
|
||||||
|
<li><strong>Corriger les contrastes</strong> en ajustant les couleurs CSS (1h)</li>
|
||||||
|
<li><strong>Associer labels aux champs de formulaires</strong> (1h)</li>
|
||||||
|
<li><strong>Restructurer les titres</strong> selon hiérarchie logique (30min)</li>
|
||||||
|
<li><strong>Réécrire les liens ambigus</strong> pour plus de clarté (1h)</li>
|
||||||
|
</ol>
|
||||||
|
<p style={{padding: '1rem', background: '#d4edda', borderRadius: '8px', marginTop: '1rem'}}>
|
||||||
|
<strong>Temps total estimé :</strong> 5h30 de corrections pour résoudre les erreurs critiques
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h3>Limites de l'outil WAVE</h3>
|
||||||
|
<div className="limits-grid">
|
||||||
|
<div className="limit-card warning">
|
||||||
|
<h4>Ne détecte pas tout</h4>
|
||||||
|
<ul>
|
||||||
|
<li>WAVE ne peut pas vérifier la pertinence des textes alternatifs</li>
|
||||||
|
<li>Ne teste pas la navigation au clavier complète</li>
|
||||||
|
<li>N'évalue pas la cohérence du parcours utilisateur</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="limit-card warning">
|
||||||
|
<h4>Nécessite validation humaine</h4>
|
||||||
|
<ul>
|
||||||
|
<li>Les "alertes" doivent être vérifiées manuellement</li>
|
||||||
|
<li>Certains contextes nécessitent jugement (images décoratives)</li>
|
||||||
|
<li>L'expérience réelle nécessite test avec lecteur d'écran</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="limit-card warning">
|
||||||
|
<h4>Une seule page à la fois</h4>
|
||||||
|
<ul>
|
||||||
|
<li>Analyse page par page (pas de scan complet du site)</li>
|
||||||
|
<li>Ne détecte pas les problèmes de navigation inter-pages</li>
|
||||||
|
<li>Nécessite tests sur pages représentatives</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-lightbulb"></i> Recommandations</h2>
|
||||||
|
<div className="recommendations-box" style={{padding: '1.5rem', background: 'var(--bg)', borderRadius: '8px'}}>
|
||||||
|
<h4>Pour un audit accessibilité complet :</h4>
|
||||||
|
<ol>
|
||||||
|
<li><strong>Utiliser WAVE</strong> pour identifier rapidement les erreurs techniques</li>
|
||||||
|
<li><strong>Compléter avec Lighthouse</strong> pour score global et recommandations</li>
|
||||||
|
<li><strong>Tester manuellement</strong> avec un lecteur d'écran (NVDA, JAWS, VoiceOver)</li>
|
||||||
|
<li><strong>Naviguer uniquement au clavier</strong> (Tab, Enter, Échap, flèches)</li>
|
||||||
|
<li><strong>Vérifier avec utilisateurs réels</strong> en situation de handicap si possible</li>
|
||||||
|
<li><strong>Auditer selon RGAA</strong> pour conformité réglementaire officielle</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div className="conclusion-banner">
|
||||||
|
<i className="fas fa-check-circle"></i>
|
||||||
|
<div>
|
||||||
|
<strong>WAVE : Un outil indispensable mais pas suffisant</strong>
|
||||||
|
<p>WAVE permet d'identifier rapidement 70-80% des problèmes d'accessibilité courants.
|
||||||
|
Cependant, 20-30% nécessitent une validation humaine et des tests avec technologies d'assistance.
|
||||||
|
À utiliser en première étape d'un audit complet.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default WAVE
|
||||||
367
src/pages/WebsiteCarbon.jsx
Normal file
367
src/pages/WebsiteCarbon.jsx
Normal file
@@ -0,0 +1,367 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import './SharedPages.css'
|
||||||
|
|
||||||
|
function WebsiteCarbon() {
|
||||||
|
return (
|
||||||
|
<div className="shared-page">
|
||||||
|
<header className="page-header">
|
||||||
|
<i className="fas fa-calculator"></i>
|
||||||
|
<h1>Website Carbon Calculator</h1>
|
||||||
|
<p className="subtitle">Décryptage technique et pédagogique</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-info-circle"></i> Présentation générale</h2>
|
||||||
|
<div className="info-card">
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Créateur:</strong>
|
||||||
|
<span>Wholegrain Digital (agence britannique)</span>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Public cible:</strong>
|
||||||
|
<span>Développeurs, designers, propriétaires de sites web</span>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Objectif:</strong>
|
||||||
|
<span>Sensibiliser à l'impact environnemental du web et estimer l'empreinte carbone d'un site</span>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<strong>Utilité:</strong>
|
||||||
|
<span>Permet de mesurer rapidement l'impact CO₂ d'une page web et de comparer avec la moyenne du web</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-cogs"></i> Fonctionnement technique</h2>
|
||||||
|
|
||||||
|
<div className="process-steps">
|
||||||
|
<div className="step-card">
|
||||||
|
<div className="step-number">1</div>
|
||||||
|
<h3>Collecte des données</h3>
|
||||||
|
<p>L'outil analyse le poids total de la page web en octets, incluant :</p>
|
||||||
|
<ul>
|
||||||
|
<li>HTML, CSS, JavaScript</li>
|
||||||
|
<li>Images, vidéos, polices</li>
|
||||||
|
<li>Fichiers tiers (publicités, analytics, etc.)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="step-card">
|
||||||
|
<div className="step-number">2</div>
|
||||||
|
<h3>Calcul de l'énergie</h3>
|
||||||
|
<p>Formule utilisée :</p>
|
||||||
|
<div className="formula">
|
||||||
|
<code>Énergie (kWh) = Poids de la page (Go) × 0.81 kWh/Go</code>
|
||||||
|
</div>
|
||||||
|
<p className="note">0.81 kWh/Go représente l'énergie moyenne consommée pour transférer 1 Go de données sur Internet</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="step-card">
|
||||||
|
<div className="step-number">3</div>
|
||||||
|
<h3>Calcul du CO₂</h3>
|
||||||
|
<p>Formule utilisée :</p>
|
||||||
|
<div className="formula">
|
||||||
|
<code>CO₂ (g) = Énergie (kWh) × Facteur carbone du mix énergétique</code>
|
||||||
|
</div>
|
||||||
|
<p className="note">Le facteur carbone varie selon la source d'énergie (renouvelable ou fossile)</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="step-card">
|
||||||
|
<div className="step-number">4</div>
|
||||||
|
<h3>Comparaison</h3>
|
||||||
|
<p>Les résultats sont comparés avec :</p>
|
||||||
|
<ul>
|
||||||
|
<li>La médiane du web (~1.76g CO₂ par page vue)</li>
|
||||||
|
<li>Des équivalences concrètes (arbres, voitures, etc.)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-database"></i> Sources des données</h2>
|
||||||
|
<div className="sources-grid">
|
||||||
|
<div className="source-card">
|
||||||
|
<i className="fas fa-bolt"></i>
|
||||||
|
<h4>Consommation énergétique</h4>
|
||||||
|
<p>Données issues du <strong>Shift Project</strong> et d'études de l'<strong>IEA</strong> (International Energy Agency)</p>
|
||||||
|
</div>
|
||||||
|
<div className="source-card">
|
||||||
|
<i className="fas fa-cloud"></i>
|
||||||
|
<h4>Mix énergétique</h4>
|
||||||
|
<p>Base de données <strong>Green Web Foundation</strong> pour identifier si l'hébergeur utilise des énergies renouvelables</p>
|
||||||
|
</div>
|
||||||
|
<div className="source-card">
|
||||||
|
<i className="fas fa-chart-line"></i>
|
||||||
|
<h4>Statistiques web</h4>
|
||||||
|
<p>HTTP Archive pour les données moyennes du poids des pages web</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section">
|
||||||
|
<h2><i className="fas fa-clipboard-list"></i> Résultats fournis</h2>
|
||||||
|
<div className="results-list">
|
||||||
|
<div className="result-item">
|
||||||
|
<i className="fas fa-weight"></i>
|
||||||
|
<div>
|
||||||
|
<strong>Poids de la page</strong>
|
||||||
|
<p>Taille totale en Mo/Ko</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="result-item">
|
||||||
|
<i className="fas fa-leaf"></i>
|
||||||
|
<div>
|
||||||
|
<strong>Émissions de CO₂</strong>
|
||||||
|
<p>Grammes de CO₂ par visite</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="result-item">
|
||||||
|
<i className="fas fa-bolt"></i>
|
||||||
|
<div>
|
||||||
|
<strong>Énergie consommée</strong>
|
||||||
|
<p>kWh par visite</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="result-item">
|
||||||
|
<i className="fas fa-globe"></i>
|
||||||
|
<div>
|
||||||
|
<strong>Hébergement vert</strong>
|
||||||
|
<p>Indique si le serveur utilise des énergies renouvelables</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="result-item">
|
||||||
|
<i className="fas fa-chart-bar"></i>
|
||||||
|
<div>
|
||||||
|
<strong>Comparaison</strong>
|
||||||
|
<p>Position par rapport à la moyenne du web (percentile)</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section example">
|
||||||
|
<h2><i className="fas fa-flask"></i> Test réalisé sur ville-de-chauray.fr</h2>
|
||||||
|
<div className="example-box">
|
||||||
|
<div className="example-results">
|
||||||
|
<div className="result-metric">
|
||||||
|
<div className="metric-value" style={{color: '#dc3545'}}>0.62g</div>
|
||||||
|
<div className="metric-label">CO₂ par visite</div>
|
||||||
|
</div>
|
||||||
|
<div className="result-metric">
|
||||||
|
<div className="metric-value" style={{color: '#dc3545'}}>Note F</div>
|
||||||
|
<div className="metric-label">Plus sale que 84% des sites</div>
|
||||||
|
</div>
|
||||||
|
<div className="result-metric success">
|
||||||
|
<div className="metric-value">✓</div>
|
||||||
|
<div className="metric-label">Hébergement vert</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="interpretation">
|
||||||
|
<h4>Interprétation</h4>
|
||||||
|
<ul>
|
||||||
|
<li>Le site ville-de-chauray.fr a une empreinte carbone élevée (Note F)</li>
|
||||||
|
<li>L'hébergement utilise des énergies renouvelables ✓</li>
|
||||||
|
<li>Avec 10,000 vues/mois, cela représente <strong>74.04kg CO₂/an</strong></li>
|
||||||
|
<li>Équivalent à <strong>184 kWh d'énergie</strong> ou <strong>1,175km en voiture électrique</strong></li>
|
||||||
|
<li>Nécessite <strong>4 arbres</strong> pour compenser les émissions annuelles</li>
|
||||||
|
<li>Équivalent à faire bouillir l'eau pour <strong>10,033 tasses de thé</strong></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section limits">
|
||||||
|
<h2><i className="fas fa-exclamation-triangle"></i> Limites et biais</h2>
|
||||||
|
|
||||||
|
<div className="limits-grid">
|
||||||
|
<div className="limit-card warning">
|
||||||
|
<h4><i className="fas fa-calculator"></i> Calcul simplifié</h4>
|
||||||
|
<p>Le coefficient 0.81 kWh/Go est une moyenne qui ne prend pas en compte :</p>
|
||||||
|
<ul>
|
||||||
|
<li>La variabilité selon le type de réseau (4G, 5G, Wifi, fibre)</li>
|
||||||
|
<li>La distance géographique entre utilisateur et serveur</li>
|
||||||
|
<li>L'appareil utilisé (smartphone, ordinateur, tablette)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="limit-card warning">
|
||||||
|
<h4><i className="fas fa-eye-slash"></i> Éléments non pris en compte</h4>
|
||||||
|
<ul>
|
||||||
|
<li>Consommation énergétique du serveur en temps réel</li>
|
||||||
|
<li>Cache et CDN (qui réduisent les transferts)</li>
|
||||||
|
<li>Temps passé sur la page (consommation continue de l'appareil)</li>
|
||||||
|
<li>Fabrication et fin de vie des équipements</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="limit-card warning">
|
||||||
|
<h4><i className="fas fa-search"></i> Une seule page testée</h4>
|
||||||
|
<p>L'outil n'analyse qu'une page à la fois, pas un parcours utilisateur complet</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="trust-section">
|
||||||
|
<h3>Peut-on lui faire confiance ?</h3>
|
||||||
|
<div className="trust-box">
|
||||||
|
<div className="trust-pros">
|
||||||
|
<h4><i className="fas fa-check-circle"></i> OUI, pour :</h4>
|
||||||
|
<ul>
|
||||||
|
<li>Une première estimation rapide</li>
|
||||||
|
<li>Comparer plusieurs versions d'une page</li>
|
||||||
|
<li>Sensibiliser à l'impact environnemental</li>
|
||||||
|
<li>Identifier les pages trop lourdes</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div className="trust-cons">
|
||||||
|
<h4><i className="fas fa-times-circle"></i> LIMITES :</h4>
|
||||||
|
<ul>
|
||||||
|
<li>Valeurs approximatives, pas scientifiquement précises</li>
|
||||||
|
<li>Ne remplace pas un audit complet</li>
|
||||||
|
<li>À compléter avec d'autres outils (EcoIndex, Lighthouse)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section memo">
|
||||||
|
<h2><i className="fas fa-bookmark"></i> Fiche mémo récapitulative</h2>
|
||||||
|
<div className="memo-card">
|
||||||
|
<div className="memo-section">
|
||||||
|
<h4>🎯 Ce que fait l'outil</h4>
|
||||||
|
<p>Estime l'empreinte carbone d'une page web à chaque visite</p>
|
||||||
|
</div>
|
||||||
|
<div className="memo-section">
|
||||||
|
<h4>📊 Données analysées</h4>
|
||||||
|
<p>Poids total de la page (HTML, CSS, JS, images, etc.)</p>
|
||||||
|
</div>
|
||||||
|
<div className="memo-section">
|
||||||
|
<h4>🧮 Méthode de calcul</h4>
|
||||||
|
<p>Poids × 0.81 kWh/Go × facteur carbone = CO₂</p>
|
||||||
|
</div>
|
||||||
|
<div className="memo-section">
|
||||||
|
<h4>✅ Points forts</h4>
|
||||||
|
<p>Simple, rapide, visuel, pédagogique</p>
|
||||||
|
</div>
|
||||||
|
<div className="memo-section">
|
||||||
|
<h4>⚠️ Limites</h4>
|
||||||
|
<p>Calcul simplifié, une seule page, valeurs approximatives</p>
|
||||||
|
</div>
|
||||||
|
<div className="memo-section">
|
||||||
|
<h4>💡 Recommandation</h4>
|
||||||
|
<p>À utiliser en complément d'autres outils (EcoIndex, Lighthouse)</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section faq">
|
||||||
|
<h2><i className="fas fa-question-circle"></i> Question fréquente</h2>
|
||||||
|
<div className="faq-box">
|
||||||
|
<div className="question">
|
||||||
|
<strong>Q:</strong> "Mon site affiche 0.5g de CO₂. C'est beaucoup ou peu ?"
|
||||||
|
</div>
|
||||||
|
<div className="answer">
|
||||||
|
<strong>R:</strong> Pour interpréter ce résultat :
|
||||||
|
<ul>
|
||||||
|
<li><strong>Médiane du web :</strong> ~1.76g CO₂ par page. Donc 0.5g est <strong>bien en dessous</strong> de la moyenne ✓</li>
|
||||||
|
<li><strong>Objectif recommandé :</strong> Viser moins de 1g CO₂ par page</li>
|
||||||
|
<li><strong>Sites exemplaires :</strong> Entre 0.1g et 0.5g (sites très optimisés)</li>
|
||||||
|
<li><strong>Sites lourds :</strong> Plus de 3g (pages avec vidéos, animations, publicités)</li>
|
||||||
|
</ul>
|
||||||
|
<p className="tip">
|
||||||
|
<i className="fas fa-lightbulb"></i>
|
||||||
|
<strong>Astuce :</strong> Multipliez par votre nombre de visiteurs mensuels pour avoir l'impact total.
|
||||||
|
Ex: 0.5g × 10,000 visiteurs = 5kg CO₂/mois, soit ~60kg/an (équivalent à 300km en voiture).
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section comparison">
|
||||||
|
<h2><i className="fas fa-balance-scale"></i> Comparaison avec EcoIndex</h2>
|
||||||
|
<div className="comparison-table-simple">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Critère</th>
|
||||||
|
<th>Website Carbon</th>
|
||||||
|
<th>EcoIndex</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Facilité</strong></td>
|
||||||
|
<td><span className="badge success">Très simple</span></td>
|
||||||
|
<td><span className="badge warning">Moyennement simple</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Méthodologie</strong></td>
|
||||||
|
<td>Simplifiée (poids → CO₂)</td>
|
||||||
|
<td>Scientifique (poids + requêtes + DOM)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Résultats</strong></td>
|
||||||
|
<td>CO₂, énergie, comparaison</td>
|
||||||
|
<td>Score A-G, impact environnemental, eau</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Export</strong></td>
|
||||||
|
<td>Non</td>
|
||||||
|
<td>Oui (PDF)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Recommandations</strong></td>
|
||||||
|
<td>Générales</td>
|
||||||
|
<td>Détaillées et techniques</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Usage recommandé</strong></td>
|
||||||
|
<td>Sensibilisation, comparaison rapide</td>
|
||||||
|
<td>Audit approfondi, conformité RGESN</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="content-section improvements">
|
||||||
|
<h2><i className="fas fa-rocket"></i> Améliorations possibles</h2>
|
||||||
|
<div className="improvements-grid">
|
||||||
|
<div className="improvement-card">
|
||||||
|
<h4>1. Analyser des parcours complets</h4>
|
||||||
|
<p>Permettre de tester plusieurs pages en séquence pour simuler un parcours utilisateur réel</p>
|
||||||
|
</div>
|
||||||
|
<div className="improvement-card">
|
||||||
|
<h4>2. Affiner le calcul selon le contexte</h4>
|
||||||
|
<p>Prendre en compte le type de réseau (4G/5G/Wifi), la géolocalisation, et l'appareil utilisé</p>
|
||||||
|
</div>
|
||||||
|
<div className="improvement-card">
|
||||||
|
<h4>3. Proposer des recommandations personnalisées</h4>
|
||||||
|
<p>Analyser les éléments les plus lourds et suggérer des optimisations spécifiques</p>
|
||||||
|
</div>
|
||||||
|
<div className="improvement-card">
|
||||||
|
<h4>4. Intégrer un système d'export</h4>
|
||||||
|
<p>Permettre d'exporter les résultats en PDF ou JSON pour un suivi dans le temps</p>
|
||||||
|
</div>
|
||||||
|
<div className="improvement-card">
|
||||||
|
<h4>5. Ajouter une API publique gratuite</h4>
|
||||||
|
<p>Faciliter l'intégration dans des pipelines CI/CD pour des audits automatisés</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div className="conclusion-banner">
|
||||||
|
<i className="fas fa-check-circle"></i>
|
||||||
|
<div>
|
||||||
|
<strong>En résumé</strong>
|
||||||
|
<p>Website Carbon Calculator est un excellent outil de sensibilisation, simple et visuel.
|
||||||
|
Idéal pour une première approche, mais à compléter avec EcoIndex ou Lighthouse pour des audits approfondis.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default WebsiteCarbon
|
||||||
7
vite.config.js
Normal file
7
vite.config.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import react from '@vitejs/plugin-react'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [react()],
|
||||||
|
base: './',
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user