222 lines
11 KiB
Markdown
222 lines
11 KiB
Markdown
# Skeleton Loaders, Toast Notifications, Indicateur Visuel et Raccourcis Clavier
|
||
|
||
**Auteur** : Équipe 4NK
|
||
**Date** : 2025-01-27
|
||
|
||
## Objectif
|
||
|
||
Implémenter les quatre premières améliorations UX de priorité haute :
|
||
1. Skeleton loaders - Remplacer les messages "Loading..." par des skeleton loaders
|
||
2. Toast notifications - Intégrer le système de toast pour les confirmations visuelles
|
||
3. Indicateur visuel pour contenu débloqué - Badge et bordure distinctive pour les articles débloqués
|
||
4. Raccourcis clavier de base - `/` pour focus sur recherche, `Esc` pour fermer modals/overlays
|
||
|
||
## Impacts
|
||
|
||
### Skeleton loaders
|
||
|
||
- **Expérience utilisateur** : Amélioration de la perception de performance en affichant la structure du contenu pendant le chargement
|
||
- **Cohérence visuelle** : Remplacement des messages textuels par des éléments visuels cohérents avec le design system
|
||
- **Feedback visuel** : Animation subtile pour indiquer le chargement actif
|
||
|
||
### Toast notifications
|
||
|
||
- **Feedback utilisateur** : Confirmations visuelles immédiates après les actions importantes
|
||
- **Accessibilité** : Toasts avec `role="alert"` et `aria-live="polite"` pour les screen readers
|
||
- **Expérience utilisateur** : Retour visuel clair et non intrusif pour les actions réussies
|
||
|
||
### Indicateur visuel pour contenu débloqué
|
||
|
||
- **Clarté visuelle** : Identification immédiate des articles déjà débloqués
|
||
- **Feedback positif** : Confirmation visuelle que l'utilisateur a accès au contenu complet
|
||
- **Accessibilité** : Badge avec `aria-label` pour les screen readers
|
||
|
||
### Raccourcis clavier de base
|
||
|
||
- **Efficacité** : Réduction du nombre de clics pour accéder à la recherche
|
||
- **Accessibilité** : Navigation au clavier améliorée
|
||
- **Expérience utilisateur** : Raccourcis intuitifs et standards
|
||
|
||
## Modifications
|
||
|
||
### Skeleton loaders
|
||
|
||
1. **`components/ArticlesList.tsx`** :
|
||
- Ajout de `ArticleCardSkeleton` qui reproduit la structure d'une carte d'article
|
||
- Remplacement de `LoadingState` par un affichage de 3 skeletons
|
||
|
||
2. **`components/AuthorsList.tsx`** :
|
||
- Ajout de `AuthorCardSkeleton` qui reproduit la structure d'une carte d'auteur
|
||
- Remplacement de `LoadingState` par un affichage de 4 skeletons en grille
|
||
|
||
3. **`components/UserArticlesList.tsx`** :
|
||
- Ajout de `ArticleCardSkeleton` (identique à ArticlesList)
|
||
- Remplacement de `ArticlesLoading` par un affichage de 3 skeletons
|
||
- Ajout de l'import `Skeleton`
|
||
|
||
4. **`components/authorPage/AuthorPageContent.tsx`** :
|
||
- Extraction de `AuthorPageLoadingSkeleton`, `AuthorPageError`, `AuthorPageNotFound` pour respecter `max-lines-per-function`
|
||
- Remplacement du message de chargement par des skeletons représentant la structure de la page auteur
|
||
|
||
5. **`components/authorPresentationEditor/AuthorPresentationEditor.tsx`** :
|
||
- Remplacement de `LoadingNotice` par des skeletons représentant la structure du formulaire
|
||
- Ajout de l'import `Skeleton`
|
||
|
||
6. **`components/DocsContent.tsx`** :
|
||
- Remplacement du message de chargement par des skeletons représentant la structure du contenu markdown
|
||
- Suppression de l'import `t` non utilisé
|
||
|
||
7. **`components/FundingGauge.tsx`** :
|
||
- Remplacement de `FundingGaugeLoading` par des skeletons représentant la structure du gauge
|
||
- Ajout de l'import `Skeleton`
|
||
|
||
### Toast notifications
|
||
|
||
1. **`components/ui/ToastContainer.tsx`** (nouveau) :
|
||
- Création du système de gestion des toasts avec `ToastProvider` et `useToast` hook
|
||
- Gestion d'une pile de toasts avec suppression automatique après durée configurable
|
||
- Affichage des toasts en position fixe (top-right) avec z-index élevé
|
||
|
||
2. **`pages/_app.tsx`** :
|
||
- Intégration du `ToastProvider` dans l'application pour rendre les toasts disponibles globalement
|
||
|
||
3. **`components/ArticleCard.tsx`** :
|
||
- Ajout d'un toast de succès après déblocage réussi d'un article
|
||
- Extraction de `useArticleCardState` pour respecter `max-lines-per-function`
|
||
- Extraction de `ArticleCardContent` pour réduire le nombre de lignes de `ArticleCard`
|
||
|
||
4. **`components/ArticleEditor.tsx`** :
|
||
- Ajout d'un toast de succès après publication réussie via `useEffect`
|
||
- Extraction de `usePublishSuccessToast` pour respecter `max-lines-per-function`
|
||
|
||
5. **`components/PaymentModal.tsx`** :
|
||
- Ajout d'un toast de succès après copie d'invoice dans `copyInvoiceToClipboard`
|
||
- Ajout d'un toast de succès après initiation du paiement dans `openWalletForInvoice`
|
||
- Mise à jour de `usePaymentModalState` pour accepter `showToast` optionnel
|
||
|
||
6. **`hooks/useArticlePayment.ts`** :
|
||
- Refactoring pour accepter un objet de paramètres au lieu de paramètres individuels (respect de `max-params`)
|
||
- Ajout du support `showToast` optionnel pour afficher des toasts après paiement réussi
|
||
- Propagation de `showToast` à travers `checkPaymentAndUnlock` et `startArticlePaymentFlow`
|
||
|
||
7. **`locales/fr.txt` et `locales/en.txt`** :
|
||
- Ajout des clés de traduction pour les toasts :
|
||
- `article.unlock.success` : "Article débloqué avec succès!" / "Article unlocked successfully!"
|
||
- `article.publish.success` : "Article publié avec succès!" / "Article published successfully!"
|
||
- `payment.modal.copySuccess` : "Facture copiée dans le presse-papiers" / "Invoice copied to clipboard"
|
||
- `payment.modal.paymentInitiated` : "Paiement initié avec succès" / "Payment initiated successfully"
|
||
- Ajout des clés de traduction manquantes pour `payment.modal.*` déjà utilisées dans le code
|
||
|
||
### Indicateur visuel pour contenu débloqué
|
||
|
||
1. **`components/ArticleCard.tsx`** :
|
||
- Ajout d'un badge "Débloqué" avec icône SVG de cadenas ouvert dans `ArticleHeader`
|
||
- Badge affiché uniquement si `article.paid === true`
|
||
- Badge avec variant "success" (vert) et `aria-label` pour l'accessibilité
|
||
- Ajout d'une bordure distinctive (border-2 border-neon-green/40) et d'un glow vert (shadow-[0_0_5px_#00ff41,0_0_10px_#00ff41]) sur la Card pour les articles débloqués
|
||
- Utilisation de `shadow-[...]` avec les valeurs de `tailwind.config.js` (glow-green)
|
||
|
||
2. **`locales/fr.txt` et `locales/en.txt`** :
|
||
- Ajout de la clé de traduction `article.unlocked.badge` : "Débloqué" / "Unlocked"
|
||
|
||
### Raccourcis clavier de base
|
||
|
||
1. **`hooks/useKeyboardShortcuts.ts`** (nouveau) :
|
||
- Création du hook pour gérer les raccourcis clavier globaux
|
||
- Détection de la touche `/` pour focus sur la barre de recherche
|
||
- Vérification que l'utilisateur n'est pas déjà dans un champ de saisie avant d'activer le raccourci
|
||
- Recherche de l'input avec `role="search"` et focus/select automatique
|
||
|
||
2. **`components/ui/Input.tsx`** :
|
||
- Ajout du support `forwardRef` pour permettre le focus programmatique
|
||
- Conservation de toutes les fonctionnalités existantes
|
||
|
||
3. **`components/SearchBar.tsx`** :
|
||
- Ajout du support `forwardRef` pour permettre le focus programmatique
|
||
- Ajout de `role="search"` pour l'accessibilité et la détection par le hook
|
||
- Ajout de `aria-label` pour l'accessibilité
|
||
|
||
4. **`pages/_app.tsx`** :
|
||
- Intégration du hook `useKeyboardShortcuts` dans l'application pour activer les raccourcis globaux
|
||
|
||
6. **`components/NotificationPanel.tsx`** :
|
||
- Ajout de la gestion de `Esc` pour fermer le panel de notifications
|
||
- Ajout de `useEffect` pour écouter les événements clavier
|
||
|
||
7. **`components/createSeriesModal/CreateSeriesModalView.tsx`** :
|
||
- Ajout de la gestion de `Esc` pour fermer la modal de création de série
|
||
- Ajout de la gestion du clic sur l'overlay pour fermer la modal
|
||
- Ajout de `document.body.style.overflow = 'hidden'` pour empêcher le scroll pendant l'ouverture
|
||
|
||
8. **Raccourci `Esc`** :
|
||
- Déjà implémenté pour les modals via `useModalKeyboard` dans `components/ui/Modal.tsx`
|
||
- Déjà implémenté pour le menu mobile via `useEffect` dans `components/ui/MobileMenu.tsx`
|
||
- Ajouté pour `NotificationPanel` et `CreateSeriesModalView`
|
||
|
||
## Modalités de déploiement
|
||
|
||
1. **Vérification** :
|
||
- `npm run type-check` : Aucune erreur TypeScript
|
||
- `npm run lint` : Aucune erreur de linting (4 warnings acceptables sur l'utilisation de l'index dans les keys pour les skeletons)
|
||
|
||
2. **Déploiement** :
|
||
- Utiliser les scripts de déploiement existants (`deploy.sh`, `update-from-git.sh`, `update-remote-git.sh`)
|
||
- Validation explicite requise avant déploiement
|
||
|
||
## Modalités d'analyse
|
||
|
||
1. **Skeleton loaders** :
|
||
- Vérifier visuellement que les skeletons apparaissent pendant le chargement des listes
|
||
- Vérifier que les animations de pulse sont fluides
|
||
- Vérifier que les skeletons disparaissent correctement une fois les données chargées
|
||
|
||
2. **Toast notifications** :
|
||
- Vérifier que les toasts apparaissent après :
|
||
- Déblocage réussi d'un article
|
||
- Publication réussie d'un article
|
||
- Copie d'invoice dans le presse-papiers
|
||
- Initiation du paiement avec Alby
|
||
- Vérifier que les toasts disparaissent automatiquement après 5 secondes (2 secondes pour la copie)
|
||
- Vérifier que les toasts peuvent être fermés manuellement via le bouton ×
|
||
- Vérifier l'accessibilité avec un screen reader (toasts annoncés via `aria-live="polite"`)
|
||
|
||
3. **Indicateur visuel pour contenu débloqué** :
|
||
- Vérifier que le badge "Débloqué" apparaît dans le header des articles débloqués
|
||
- Vérifier que l'icône de cadenas ouvert est visible dans le badge
|
||
- Vérifier que les cartes d'articles débloqués ont une bordure verte distinctive et un glow vert
|
||
- Vérifier que les articles non débloqués n'ont pas de badge ni de bordure distinctive
|
||
- Vérifier l'accessibilité avec un screen reader (badge annoncé via `aria-label`)
|
||
|
||
4. **Raccourcis clavier de base** :
|
||
- Vérifier que la touche `/` focus la barre de recherche et sélectionne son contenu
|
||
- Vérifier que le raccourci `/` ne s'active pas si l'utilisateur est déjà dans un champ de saisie (input, textarea, contenteditable)
|
||
- Vérifier que la touche `Esc` ferme les modals (`Modal.tsx`)
|
||
- Vérifier que la touche `Esc` ferme le menu mobile (`MobileMenu.tsx`)
|
||
- Vérifier que la touche `Esc` ferme le panel de notifications (`NotificationPanel.tsx`)
|
||
- Vérifier que la touche `Esc` ferme la modal de création de série (`CreateSeriesModalView.tsx`)
|
||
- Tester sur différentes pages (HomeView, ProfileView) pour s'assurer que le raccourci `/` fonctionne partout
|
||
|
||
## Pages affectées
|
||
|
||
- `components/ArticlesList.tsx`
|
||
- `components/AuthorsList.tsx`
|
||
- `components/UserArticlesList.tsx`
|
||
- `components/authorPage/AuthorPageContent.tsx`
|
||
- `components/authorPresentationEditor/AuthorPresentationEditor.tsx`
|
||
- `components/DocsContent.tsx`
|
||
- `components/FundingGauge.tsx`
|
||
- `components/ui/ToastContainer.tsx` (nouveau)
|
||
- `components/ArticleCard.tsx`
|
||
- `components/ArticleEditor.tsx`
|
||
- `components/PaymentModal.tsx`
|
||
- `hooks/useArticlePayment.ts`
|
||
- `pages/_app.tsx`
|
||
- `locales/fr.txt`
|
||
- `locales/en.txt`
|
||
- `components/ui/index.ts`
|
||
- `hooks/useKeyboardShortcuts.ts` (nouveau)
|
||
- `components/NotificationPanel.tsx`
|
||
- `components/createSeriesModal/CreateSeriesModalView.tsx`
|
||
- `docs/migration-status.md`
|
||
- `docs/todo-remaining.md`
|