# 🎨 Feature: Icon Packs - Système de personnalisation des icônes

## 📋 Vue d'ensemble

Le système Icon Packs permet aux utilisateurs de choisir entre différents styles d'icônes pour les boutons d'action de l'application (Ajouter, Supprimer, Éditer, Enregistrer, Upload, etc.).

### Problème résolu

Auparavant, l'application utilisait uniquement des emojis Unicode (🗑️, 💾, ✏️) pour les icônes. Ce système apporte :
- **Flexibilité** : Choix entre emojis, FontAwesome (solid/regular), et Icons8
- **Cohérence visuelle** : Icônes uniformes selon le pack choisi
- **Accessibilité** : Alternative aux emojis pour les utilisateurs qui préfèrent des icônes SVG
- **Personnalisation** : Adaptation au goût et aux préférences de chaque utilisateur

---

## 🎯 Fonctionnalités

### Packs d'icônes disponibles

1. **Emojis Unicode** (par défaut)
   - Emojis colorés natifs
   - Pas de dépendance externe
   - Compatibilité universelle
   - Exemples : ➕ ✏️ 🗑️ 💾 📤

2. **FontAwesome Solid**
   - Icônes FontAwesome pleines (bold)
   - Style moderne et professionnel
   - Icônes SVG monochromes
   - S'adaptent à la couleur du bouton

3. **FontAwesome Regular**
   - Icônes FontAwesome fines (outline)
   - Style minimaliste et élégant
   - Variante légère de FontAwesome Solid
   - Parfait pour un design épuré

4. **Icons8 PNG**
   - Mix des icônes Icons8 existantes (PNG)
   - Combine emojis et icônes PNG
   - Utilise les icônes déjà présentes dans le projet
   - Style coloré et moderne

### Icônes supportées

Le système gère les icônes suivantes :
- `add` - Ajouter
- `edit` - Éditer
- `delete` - Supprimer
- `save` - Enregistrer
- `upload` - Upload/Téléverser
- `download` - Télécharger
- `image` - Image
- `file` - Fichier
- `pdf` - PDF
- `link` - Lien/URL
- `refresh` - Rafraîchir
- `search` - Rechercher
- `settings` - Paramètres
- `close` - Fermer
- `check` - Valider
- `warning` - Avertissement
- `info` - Information
- `copy` - Copier

---

## 🏗️ Architecture

### Fichiers créés

```
frontend/
├── js/
│   └── icon-manager.js          # Gestionnaire de packs d'icônes
├── css/
│   └── components.css            # CSS pour .btn-icon (mis à jour)
└── icons/
    └── svg/
        └── fa/
            ├── solid/            # FontAwesome Solid SVG
            └── regular/          # FontAwesome Regular SVG
```

### Structure du gestionnaire d'icônes

**`icon-manager.js`** - Module auto-initialisé (IIFE)

```javascript
const IconManager = {
  packs: ICON_PACKS,               // Configuration des packs
  getCurrentPack(),                // Récupère le pack actif
  applyPack(packName),             // Applique un nouveau pack
  getIcon(iconName, fallback),     // Récupère une icône
  getAllPacks(),                   // Liste tous les packs
  getPackInfo(packName),           // Infos sur un pack
  createButton(...),               // Helper pour créer un bouton
  updateAllButtons()               // Met à jour les boutons existants
};
```

### Stockage

Le pack d'icônes choisi est stocké dans `localStorage` :
```javascript
localStorage.getItem('benchtools_icon_pack') // 'emoji', 'fontawesome-solid', etc.
```

---

## 💻 Utilisation

### Via l'interface Settings

1. Ouvrir **Settings** : [http://localhost:8087/settings.html](http://localhost:8087/settings.html)
2. Section **"Pack d'icônes"**
3. Sélectionner un pack dans la liste déroulante
4. Prévisualiser les icônes en temps réel
5. Cliquer sur **"Appliquer le pack d'icônes"**
6. La page se recharge et applique les nouvelles icônes

### Via JavaScript

#### Récupérer une icône

```javascript
// Récupérer l'icône "delete" selon le pack actif
const deleteIcon = window.IconManager.getIcon('delete');

// Avec fallback personnalisé
const saveIcon = window.IconManager.getIcon('save', '💾');

// Ou via la fonction helper dans utils.js
const addIcon = getIcon('add', '+');
```

#### Créer un bouton avec icône

```javascript
// Via IconManager
const btnHtml = window.IconManager.createButton('delete', 'Supprimer', 'btn btn-danger');

// Via helper function (utils.js)
const btnHtml = createIconButton('add', 'Ajouter', 'btn btn-primary', 'addItem()');
// Résultat: <button class="btn btn-primary" onclick="addItem()" data-icon="add">
//             <span class="btn-icon-wrapper">[icône]</span> Ajouter
//           </button>
```

#### Appliquer un pack programmatiquement

```javascript
// Changer le pack d'icônes
window.IconManager.applyPack('fontawesome-solid');

// Écouter les changements de pack
window.addEventListener('iconPackChanged', (event) => {
  console.log('Nouveau pack:', event.detail.pack);
  console.log('Nom:', event.detail.packName);
});
```

### Exemple dans le HTML

#### Avant (emojis en dur)

```html
<button class="btn btn-danger" onclick="deleteItem()">
  🗑️ Supprimer
</button>
```

#### Après (système dynamique)

```html
<button class="btn btn-danger" onclick="deleteItem()" data-icon="delete">
  <span class="btn-icon-wrapper"></span> Supprimer
</button>

<script>
// L'icône est injectée automatiquement au chargement
document.addEventListener('DOMContentLoaded', () => {
  const icon = window.IconManager.getIcon('delete');
  document.querySelector('[data-icon="delete"] .btn-icon-wrapper').innerHTML = icon;
});
</script>
```

#### Meilleure approche (génération JavaScript)

```javascript
// Dans votre code de rendu
function renderDeleteButton() {
  return createIconButton('delete', 'Supprimer', 'btn btn-danger', 'deleteItem()');
}

// Ou directement
container.innerHTML += createIconButton('add', 'Ajouter', 'btn btn-primary', 'addItem()');
```

---

## 🎨 Styling CSS

### Classes CSS pour les icônes

```css
/* Icône SVG dans un bouton */
.btn-icon {
  width: var(--button-icon-size, 24px);
  height: var(--button-icon-size, 24px);
  vertical-align: middle;
  filter: brightness(0) invert(1); /* Blanc par défaut */
}

/* Wrapper pour mise à jour dynamique */
.btn-icon-wrapper {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Adaptation selon le type de bouton */
.btn-primary .btn-icon { filter: brightness(0) invert(1); }
.btn-secondary .btn-icon { filter: brightness(0.8); }
.btn-danger .btn-icon { filter: brightness(0) invert(1); }
```

### Variables CSS

Les tailles d'icônes sont contrôlables via variables CSS :

```css
:root {
  --section-icon-size: 32px;  /* Icônes dans les titres */
  --button-icon-size: 24px;   /* Icônes dans les boutons */
}
```

Ces variables sont modifiables dans **Settings > Préférences d'affichage**.

---

## 📦 Configuration des packs

### Ajouter un nouveau pack

#### 1. Éditer `icon-manager.js`

```javascript
const ICON_PACKS = {
  // ... packs existants
  'mon-pack': {
    name: 'Mon Pack Personnalisé',
    description: 'Description de mon pack',
    icons: {
      'add': '➕',  // ou <img src="...">
      'edit': '✏️',
      'delete': '🗑️',
      'save': '💾',
      // ... autres icônes
    }
  }
};
```

#### 2. Ajouter l'option dans `settings.html`

```html
<select id="iconPack" class="form-control">
  <!-- ... options existantes -->
  <option value="mon-pack">Mon Pack Personnalisé</option>
</select>
```

#### 3. (Optionnel) Ajouter des assets

Si vous utilisez des SVG/PNG personnalisés :
- Placer les fichiers dans `frontend/icons/custom/`
- Référencer avec le bon chemin dans la config

---

## 🔧 API du gestionnaire d'icônes

### `IconManager.getCurrentPack()`

Retourne le nom du pack actuellement actif.

```javascript
const currentPack = window.IconManager.getCurrentPack();
// Retourne: 'emoji' | 'fontawesome-solid' | 'fontawesome-regular' | 'icons8'
```

### `IconManager.applyPack(packName)`

Change le pack d'icônes et sauvegarde dans localStorage.

```javascript
window.IconManager.applyPack('fontawesome-solid');
// Retourne: true (succès) ou false (pack inconnu)
```

### `IconManager.getIcon(iconName, fallback)`

Récupère le HTML d'une icône selon le pack actif.

```javascript
const icon = window.IconManager.getIcon('delete', '🗑️');
// Retourne: '<img src="icons/svg/fa/solid/trash-can.svg" class="btn-icon" alt="Delete">'
// ou '🗑️' selon le pack
```

### `IconManager.getAllPacks()`

Liste tous les packs disponibles.

```javascript
const packs = window.IconManager.getAllPacks();
// Retourne: ['emoji', 'fontawesome-solid', 'fontawesome-regular', 'icons8']
```

### `IconManager.getPackInfo(packName)`

Récupère les informations d'un pack.

```javascript
const packInfo = window.IconManager.getPackInfo('fontawesome-solid');
// Retourne: { name: 'FontAwesome Solid', description: '...', icons: {...} }
```

### `IconManager.updateAllButtons()`

Met à jour dynamiquement toutes les icônes de la page.

```javascript
window.IconManager.updateAllButtons();
// Parcourt tous les [data-icon] et met à jour leur contenu
```

---

## 🧪 Tests

### Tester un pack d'icônes

1. Ouvrir la page **Settings**
2. Changer de pack dans la section "Pack d'icônes"
3. Observer l'aperçu en temps réel
4. Cliquer sur "Appliquer"
5. Vérifier que toutes les pages utilisent le nouveau pack

### Console de développement

```javascript
// Lister tous les packs
console.log(window.IconManager.getAllPacks());

// Tester chaque icône d'un pack
const pack = window.IconManager.getPackInfo('fontawesome-solid');
Object.keys(pack.icons).forEach(iconName => {
  console.log(iconName, pack.icons[iconName]);
});

// Forcer un pack sans recharger
window.IconManager.applyPack('fontawesome-regular');
window.IconManager.updateAllButtons();
```

---

## 🐛 Dépannage

### Les icônes ne changent pas

**Solution** :
1. Vérifier que `icon-manager.js` est chargé dans la page
2. Ouvrir la console (F12) et vérifier les erreurs
3. Vérifier que les boutons ont l'attribut `data-icon`
4. Essayer de recharger la page avec Ctrl+F5

### Les icônes SVG n'apparaissent pas

**Solution** :
1. Vérifier que les fichiers SVG existent dans `frontend/icons/svg/fa/`
2. Vérifier les permissions des fichiers
3. Ouvrir la console réseau (F12 > Network) et chercher les erreurs 404
4. Vérifier le chemin dans `icon-manager.js`

### Les icônes sont trop grandes/petites

**Solution** :
1. Aller dans **Settings > Préférences d'affichage**
2. Ajuster "Taille des icônes de bouton"
3. Ou modifier manuellement la variable CSS :
```javascript
document.documentElement.style.setProperty('--button-icon-size', '20px');
```

### Le pack ne se sauvegarde pas

**Solution** :
1. Vérifier que localStorage est activé :
```javascript
console.log(localStorage.getItem('benchtools_icon_pack'));
```
2. Vider le cache du navigateur (Ctrl+Shift+Del)
3. Tester en navigation privée pour isoler le problème

---

## 📊 Comparaison des packs

| Pack | Type | Taille | Couleur | Avantages | Inconvénients |
|------|------|--------|---------|-----------|---------------|
| **Emojis Unicode** | Natif | Variable | Oui | Universel, pas de dépendance | Rendu variable selon OS |
| **FontAwesome Solid** | SVG | 24px | Mono | Professionnel, cohérent | Nécessite assets SVG |
| **FontAwesome Regular** | SVG | 24px | Mono | Élégant, minimaliste | Moins visible que Solid |
| **Icons8 PNG** | PNG | 48px | Oui | Coloré, moderne | Mix de styles |

---

## 🔮 Évolutions futures

### Fonctionnalités prévues

- [ ] **Import de packs personnalisés** : Permettre l'upload d'un fichier JSON définissant un pack
- [ ] **Éditeur visuel de pack** : Interface pour créer son propre pack
- [ ] **Thèmes d'icônes** : Packs adaptés automatiquement au thème actif
- [ ] **Icônes animées** : Support des GIF ou animations CSS
- [ ] **Marketplace de packs** : Partager et télécharger des packs créés par la communauté

### Améliorations techniques

- [ ] Lazy loading des icônes SVG
- [ ] Sprite SVG pour réduire les requêtes HTTP
- [ ] Support des web fonts (Font Awesome CDN)
- [ ] Cache des icônes dans IndexedDB
- [ ] Mode hors-ligne avec Service Worker

---

## 📚 Ressources

### Documentation connexe

- [FEATURE_THEME_SYSTEM.md](FEATURE_THEME_SYSTEM.md) - Système de thèmes
- [GUIDE_THEMES.md](GUIDE_THEMES.md) - Guide utilisateur des thèmes
- [frontend/css/themes/README.md](../frontend/css/themes/README.md) - Guide de création de thèmes

### Ressources externes

- [FontAwesome Icons](https://fontawesome.com/icons) - Catalogue complet FontAwesome
- [Icons8](https://icons8.com/) - Bibliothèque Icons8
- [Emojipedia](https://emojipedia.org/) - Référence Unicode emojis

---

## 📝 Exemple complet d'intégration

### Avant (ancien code)

```html
<button class="btn btn-primary" onclick="addItem()">➕ Ajouter</button>
<button class="btn btn-danger" onclick="deleteItem()">🗑️ Supprimer</button>
```

### Après (nouveau système)

#### HTML

```html
<div id="actionButtons"></div>
```

#### JavaScript

```javascript
// Fonction de rendu
function renderActionButtons() {
  const container = document.getElementById('actionButtons');

  const buttons = [
    createIconButton('add', 'Ajouter', 'btn btn-primary', 'addItem()'),
    createIconButton('delete', 'Supprimer', 'btn btn-danger', 'deleteItem()')
  ];

  container.innerHTML = buttons.join(' ');
}

// Rendu initial
document.addEventListener('DOMContentLoaded', renderActionButtons);

// Re-rendu lors du changement de pack
window.addEventListener('iconPackChanged', renderActionButtons);
```

---

## 🎓 Bonnes pratiques

### 1. Toujours utiliser data-icon

```html
<!-- ✅ BON -->
<button class="btn" data-icon="delete" onclick="del()">
  <span class="btn-icon-wrapper"></span> Supprimer
</button>

<!-- ❌ MAUVAIS -->
<button class="btn" onclick="del()">🗑️ Supprimer</button>
```

### 2. Préférer createIconButton()

```javascript
// ✅ BON - Génération via helper
const btn = createIconButton('save', 'Enregistrer', 'btn btn-primary', 'save()');

// ❌ MAUVAIS - HTML en dur
const btn = '<button class="btn btn-primary" onclick="save()">💾 Enregistrer</button>';
```

### 3. Écouter iconPackChanged pour les mises à jour

```javascript
// ✅ BON - Re-render automatique
window.addEventListener('iconPackChanged', () => {
  renderMyComponent();
});

// ❌ MAUVAIS - Icônes statiques
// Pas de mise à jour après changement de pack
```

### 4. Fournir un fallback

```javascript
// ✅ BON
const icon = getIcon('custom-icon', '❓');

// ❌ RISQUÉ
const icon = getIcon('custom-icon');
// Retourne '?' si l'icône n'existe pas
```

---

## 📄 Licence

Ce système fait partie de Linux BenchTools et est distribué sous la même licence que le projet principal.

---

**Créé le** : 2026-01-11
**Auteur** : Linux BenchTools Team
**Version** : 1.0.0
