2026-02-05 13:18:17 +00:00
# Audit Deep Dive — Frontend Veza (vs standards SaaS type Discord/Spotify)
**Date** : 2026-02-05
**Périmètre** : `apps/web` — structure des composants, styles (Tailwind / KŌDŌ), stories Storybook, décorateur global, accessibilité.
**Référentiel** : cohérence design system, états d’ interface, complexité des composants, illusion applicative, a11y.
---
## Synthèse exécutive
Le frontend s’ appuie sur un **système de design KŌDŌ** riche (tokens CSS, thème clair/sombre) et un **Storybook stabilisé** (0 erreur réseau/console, contrat documenté). Les écarts principaux par rapport à des standards type Discord/Spotify portent sur : **utilisation encore forte de valeurs arbitraires** malgré les tokens, **états d’ interface incomplets** dans de nombreuses stories (Loading/Error/Disabled/Focus), **plusieurs composants “monolithes”** difficiles à tester et à faire évoluer, **décorateur Storybook** sans gestion des transitions ni du feedback tactile, et **a11y** partiellement couverte (addon présent, tests a11y en “todo”).
Les problèmes sont classés en **Bloquant** , **Amélioration** et **Perfectionnement** .
---
## 1. Cohérence du système de design
### Ce qui est en place
- **Tokens centralisés** dans `src/index.css` : palette (void, cyan, magenta, lime), sémantiques (primary, destructive, success, warning), radius (`--radius`), durées (`--duration-fast`, `--duration-normal` , etc.), easings, glows, glass.
- **Thème Tailwind v4** via `@theme inline` : couleurs (`--color-primary`, `--color-sidebar-*` ), radius (`--radius-sm` à `--radius-2xl` ), typo (font-sans, font-mono, font-display).
- **Composants UI de base** : `button.tsx` utilise des tokens (`bg-kodo-cyan`, `ring-kodo-cyan` , `focus-visible:ring-2` ), CVA pour variants/sizes, pas de valeurs arbitraires dans les variants.
### Problèmes identifiés
| Criticité | Constat | Détail |
|-----------|--------|--------|
| **Amélioration** | Valeurs arbitraires nombreuses | Plus de **170 fichiers** contiennent des classes type `h-[…]` , `w-[…]` , `p-[…]` , `gap-[…]` , `rounded-[…]` . Ex. : `h-[400px]` , `w-[300px]` , `min-h-[600px]` , `w-[500px]` , `h-[70px]` dans stories et composants. |
| **Amélioration** | Stories comme source de dérive | Les stories utilisent souvent des conteneurs en `h-[600px]` , `w-[300px]` pour le rendu. Ces valeurs ne s’ appuient pas sur les tokens (ex. `--radius-lg` , `h-96` , `max-w-3xl` ). |
| **Perfectionnement** | Échelle d’ espacement | Les tokens d’ espacement (4px, 8px, 16px, 24px…) sont partiellement reflétés en Tailwind ; des `p-4` , `p-8` coexistent avec des `p-[12px]` ou `gap-[11px]` ponctuels. |
### Recommandations
- **Remplacer progressivement** les valeurs arbitraires par des tokens : par ex. `h-[400px]` → `h-[var(--height-panel)]` ou `min-h-96` si une scale est définie.
- **Documenter une scale de hauteurs/largeurs** (cards, modals, sidebars) dans le design system et l’ utiliser dans les stories.
- **Linter / règle custom** (stylelint ou ESLint) pour limiter les `[…px]` / `[…]rem` hors tokens.
### Mise à jour (nettoyage systémique)
**Layout primitives** ont été ajoutées dans `src/index.css` pour **App/Layouts** et **App/Pages** :
- **Variables CSS** (`:root`) : `--layout-content-max-width` (100rem), `--layout-main-min-height` , `--layout-page-min-height` (37.5rem), `--layout-page-min-height-sm` (25rem), `--layout-story-decorator-min-height` (12rem).
- **Classes utilitaires** (`@layer utilities`) : `.max-w-layout-content` , `.min-h-layout-main` , `.min-h-layout-page` , `.min-h-layout-page-sm` , `.min-h-layout-story` .
- **Remplacements effectués** : `max-w-[1600px]` → `max-w-layout-content` (Layout, DashboardLayout, ChatPage) ; `min-h-[calc(100vh-64px)]` → `min-h-layout-main` (Layout) ; `min-h-[600px]` → `min-h-layout-page` (UserProfilePage, SettingsPage, PlaylistDetailPage) ; `min-h-[400px]` → `min-h-layout-page-sm` (LibraryPage, SessionsPage) ; `min-h-[200px]` (Navbar story) → `min-h-layout-story` ; `md:w-[400px]` (AudioPlayer) → `md:w-96` ; `min-h-[44px]` → `min-h-11` (PlaylistListPage) ; `min-w-[140px]` → `min-w-36` (SettingsPage) ; `h-[60%]` / `h-[40%]` → `h-3/5` / `h-2/5` (LibraryPage). Les ombres et valeurs viewport (ex. `h-[60vh]` ) sont laissées en l’ état.
---
## 2. Qualité des états d’ interface (stories)
### Ce qui est en place
- **Loading / Skeleton** : `LoadingState` , `Skeleton` , `TrackListSkeleton` , `PlayerLoading` ont des stories dédiées.
- **Error** : `ErrorDisplay` , `PlayerError` , `AuthErrorMessage` , `ErrorBoundary` , `Alert` (variant error) sont couverts.
- **Focus** : Le `Button` a `focus-visible:ring-2 focus-visible:ring-kodo-cyan` ; plusieurs composants UI (input, checkbox, select, tabs) ont du `focus:` ou `focus-visible:` .
- **Disabled** : Présent dans ~23 fichiers de stories (Button, Checkbox, VolumeControl, etc.).
### Problèmes identifiés
| Criticité | Constat | Détail |
|-----------|--------|--------|
| **Bloquant** | Addon a11y non exploité | Dans `.storybook/preview.tsx` , `a11y: { test: 'todo' }` — les tests a11y ne sont pas exécutés en CI ni utilisés comme garde-fou. |
| **Amélioration** | Loading “factice” sur Button | La story `LoadingState` du Button est un `disabled` + texte "Loading..." sans spinner ni `aria-busy` . Les standards SaaS montrent un état de chargement explicite (spinner + désactivation). |
| **Amélioration** | États manquants par type de composant | Beaucoup de composants “carte” ou “liste” n’ ont qu’ un état Default : pas de story **Empty** , **Error** , **Loading** ou **Disabled** (ex. plusieurs vues Playlist, Track, Chat, Commerce). |
| **Amélioration** | Hover / Active peu documentés | Peu de stories nommées "Hover" ou "Active" ; les variants sont surtout visuels. Pas de démo systématique des états interactifs (hover/active) pour les boutons et liens. |
| **Perfectionnement** | Focus visible inégal | Une soixantaine de fichiers de composants utilisent `focus:` ou `focus-visible:` ; d’ autres (cards cliquables, list items, custom controls) peuvent ne pas avoir de ring/outline visible. |
### Recommandations
- Passer **a11y.test** de `'todo'` à une config réelle (ex. `runOnly` avec règles WCAG 2.1 AA) et faire échouer le build/audit si des violations sont détectées.
- Ajouter une story **Loading** réaliste au Button (spinner + `disabled` + `aria-busy` ) et un état **Disabled** explicite partout où l’ action peut être désactivée.
- Pour les listes/cartes (Playlist, Track, Chat, Commerce), ajouter au moins **Empty** et **Error** (et **Loading** si async).
- Documenter **Hover** / **Active** dans les stories des composants interactifs (boutons, nav, sidebar) pour valider la cohérence visuelle.
---
## 3. Complexité des composants (“composants dieux”)
### Composants les plus volumineux (≥ ~400 lignes)
| Fichier | Lignes | Responsabilités identifiées |
|---------|--------|------------------------------|
2026-02-05 19:21:28 +00:00
| ~~`ProfileForm.tsx`~~ | ~~678~~ | **Refactorisé 2026-02-05** : module `profile-form/` avec `useProfileForm` , `ProfileCompletionCard` , `ProfileFormSkeleton` , schéma dédié. Stories : Default, Loading, Error, ProfileFormSkeleton. Re-export depuis `ProfileForm.tsx` . |
2026-02-05 19:31:26 +00:00
| ~~`ProfileView.tsx`~~ | ~~602~~ | **Refactorisé 2026-02-05** : module `profile-view/` avec `useProfileViewData` , sous-composants (TrackCard, PlaylistCard, Sidebar, Overview, TracksTab, PlaylistsTab, AboutTab), `ProfileViewSkeleton` . Stories : Default, Loading, Error, ProfileViewSkeleton. Re-export depuis `ProfileView.tsx` . |
2026-02-05 19:40:12 +00:00
| ~~`GearView.tsx`~~ | ~~559~~ | **Refactorisé 2026-02-05** : module `gear-view/` avec `useGearView` , `GearViewToolbar` , `GearViewSkeleton` ; props pour stories. Stories : Default, Loading, Empty, Error, GearViewSkeleton. Re-export depuis `GearView.tsx` . |
2026-02-05 18:21:09 +00:00
| ~~`CommentThread.tsx`~~ | ~~547~~ | **Refactorisé 2026-02-05** : module `comment-thread/` avec hooks et sous-composants (voir ci-dessous). |
2026-02-05 19:49:46 +00:00
| ~~`LazyComponent.tsx`~~ | ~~505~~ | **Refactorisé 2026-02-05** : module `lazy-component/` avec `LazyErrorFallback` , `LazyErrorBoundary` , `createLazyComponent` , `lazyExports` . Stories : LazyErrorFallback (Default, WithRetry, NoError), LazyComponent (Default, Loading). Re-export depuis `LazyComponent.tsx` . |
2026-02-05 20:19:58 +00:00
| ~~`CloudFileBrowser.tsx`~~ | ~~503~~ | **Module existant** : `features/studio/components/cloud-file-browser/` — orchestrateur CloudFileBrowser.tsx (~188 lignes), FileToolbar, FileTable, FileGrid, FileGridCard, FileTableRow, CloudFileBrowserSkeleton, types. Ancien fichier monolithe `components/studio/CloudFileBrowser.tsx` supprimé. |
2026-02-07 03:16:43 +00:00
| ~~`router/index.tsx`~~ | ~~458~~ | **Refactorisé 2026-02-05** : module `router/` avec `types` (RouteEntry), `PublicRoute` , `ProtectedLayoutRoute` , `routeConfig` (getPublicRoutes, getPublicStandaloneRoutes, getProtectedRoutes, getErrorRoutes), `AppRouter` . Routes rendues par config. Tests mis à jour (mocks LazyComponent, PublicRoute, ProtectedRoute, ProtectedLayoutRoute). Re-export depuis `router/index.tsx` . |
2026-02-05 18:46:03 +00:00
| ~~`Search.tsx`~~ | ~~494~~ | **Refactorisé 2026-02-05** : module `features/search/components/search/` avec hooks et sous-composants (voir ci-dessous). |
2026-02-05 20:03:23 +00:00
| ~~`UploadModal.tsx`~~ | ~~486~~ | **Refactorisé 2026-02-05** : module `upload-modal/` avec `useUploadModal` , `UploadModalDropzone` , `UploadModalFileDisplay` , `UploadModalProgress` , `UploadModalErrorAlert` , `UploadModalMetadataForm` . Stories : Default, Open. Re-export depuis `UploadModal.tsx` . |
2026-02-05 20:09:32 +00:00
| ~~`file-upload.tsx`~~ | ~~478~~ | **Refactorisé 2026-02-05** : module `components/ui/file-upload/` avec `useFileUpload` , `FileUploadDropzone` , `FileUploadErrorList` , `FileUploadFileList` . Stories : Default, Empty, ImagesOnly, MaxSize, Disabled, Error, StateSimulation. Point d’ entrée `file-upload/index.ts` . |
2026-02-05 19:07:56 +00:00
| ~~`ChatSidebar.tsx`~~ | ~~469~~ | **Refactorisé 2026-02-05** : module `chat-sidebar/` avec hooks (`useChatConversations`, `useConversationActions` ) et sous-composants (Header, Empty, Skeleton, ConversationItem). Stories : Default, Empty, Error, ChatSidebarSkeleton. |
2026-02-05 20:16:43 +00:00
| ~~`select.tsx`~~ | ~~466~~ | **Refactorisé 2026-02-05** : module `components/ui/select/` avec `useSelect` , `SelectTrigger` , `SelectDropdownContent` , `SelectOptionItem` . Stories : Default, Empty, Disabled, Grouped, MultiSelect. Point d’ entrée `select/index.ts` . |
2026-02-05 20:34:54 +00:00
| ~~`NotificationsPage.tsx`~~ | ~~421~~ | **Refactorisé 2026-02-05** : module `features/notifications/components/notifications-page/` avec `useNotificationsPage` , Header, Filters, Item, Empty, Error, Skeleton. Stories : Default, Loading, Error, Empty. Re-export depuis `pages/NotificationsPage.tsx` . |
2026-02-05 20:39:51 +00:00
| ~~`SearchPage.tsx`~~ | ~~235~~ | **Refactorisé 2026-02-05** : module `features/search/components/search-page/` avec `useSearchPage` , Header, Discovery, Empty, Error, Results, Skeleton. Stories : Default, Loading, Empty, Error. MSW : GET search → SearchResults. |
2026-02-05 20:45:27 +00:00
| ~~`FileManagerView.tsx`~~ | ~~449~~ | **Refactorisé 2026-02-05** : module `components/views/file-manager-view/` avec `useFileManagerView` , Header, Toolbar, Table, Grid, Empty, Skeleton. Stories : Default, Loading, Empty. Re-export depuis `FileManagerView.tsx` . |
2026-02-05 20:50:42 +00:00
| ~~`RegisterPage.tsx`~~ | ~~380~~ | **Refactorisé 2026-02-05** : module `features/auth/components/register-page/` avec `useRegisterPage` , RegisterPageForm, RegisterPageVerificationNotice, RegisterPageSkeleton. Stories : Default, Loading, WithError. Re-export depuis `pages/RegisterPage.tsx` . |
2026-02-06 10:28:03 +00:00
| ~~`MonitoringDashboard.tsx`~~ | ~~423~~ | **Refactorisé 2026-02-05** : module `components/monitoring/monitoring-dashboard/` avec `useMonitoringDashboard` , `MonitoringDashboardContent` (découpé en Header, Stats, ValidationCard, ErrorsCard, PerformanceCard), `MonitoringDashboardSkeleton` , types. Stories : Default, Loading, Error. Layout primitive `min-h-layout-page-sm` pour skeleton et erreur. Re-export depuis `MonitoringDashboard.tsx` . |
2026-02-05 21:04:54 +00:00
| ~~`PlaybackDashboard.tsx`~~ | ~~434~~ | **Refactorisé 2026-02-05** : module `features/streaming/components/playback-dashboard/` avec `usePlaybackDashboard` , StatsCard, TrendsCard, Charts, DetailedCard, Content, Skeleton. Stories : Default, Loading, Error, Empty. MSW : GET `/api/v1/tracks/:id/playback/dashboard` . Re-export depuis `PlaybackDashboard.tsx` . |
2026-02-05 21:09:42 +00:00
| ~~`ShareLinkManager.tsx`~~ | ~~413~~ | **Refactorisé 2026-02-05** : module `components/share/share-link-manager/` avec `useShareLinkManager` , CreateForm, Item, Empty, Content, Skeleton. Props optionnelles `initialLinks` , `isLoading` . Stories : Default, Empty, Loading, Error. Re-export depuis `ShareLinkManager.tsx` . |
2026-02-05 21:15:27 +00:00
| ~~`date-picker.tsx`~~ | ~~445~~ | **Refactorisé 2026-02-05** : module `components/ui/date-picker/` avec `useDatePicker` , `DatePickerTrigger` , `DatePickerCalendar` , types. Stories : SingleDate, DateRange, Disabled. Point d’ entrée `date-picker/index.ts` . |
2026-02-05 21:21:13 +00:00
| ~~`avatar-upload.tsx`~~ | ~~436~~ | **Refactorisé 2026-02-05** : module `components/ui/avatar-upload/` avec `useAvatarUpload` , `AvatarUploadDropzone` , `AvatarUploadActions` , `AvatarUploadSkeleton` . Stories : Default, WithExistingAvatar, Disabled, Large, Loading. MSW : POST avatar retourne `avatar_url` . Point d’ entrée `avatar-upload/index.ts` . |
2026-02-05 21:31:48 +00:00
| ~~`optimized-image.tsx`~~ | ~~407~~ | **Refactorisé 2026-02-05** : module `components/ui/optimized-image/` avec types, `generateImageSources` , `BlurPlaceholder` , `useImageFormatSupport` , `OptimizedImage` , `OptimizedImageSkeleton` , `useImagePreloader` , `ResponsiveImage` . Stories : Default, WithPlaceholder, ErrorState, Loading (skeleton). Re-export depuis `optimized-image.tsx` . |
2026-02-05 21:36:06 +00:00
| ~~`DataList.tsx`~~ | ~~398~~ | **Refactorisé 2026-02-05** : module `components/ui/data-list/` avec types, `DataListSkeleton` , `DataListEmpty` , `DataListError` , `DataList` . Modal/Dropdown retirés (doublons de `modal.tsx` /`dropdown.tsx`). Stories : Default, Loading, Empty, Error, Skeleton. Re-export depuis `DataList.tsx` . |
2026-02-05 21:40:19 +00:00
| ~~`components/player/AudioPlayer.tsx`~~ | ~~405~~ | **Refactorisé 2026-02-05** : module `components/player/audio-player/` avec types, `useAudioPlayerEffects` , `AudioPlayerTrackInfo` , `AudioPlayerControls` , `AudioPlayerProgress` , `AudioPlayerVolume` , `AudioPlayerSkeleton` , `AudioPlayer` . Stories : Default (avec mock store), Skeleton. Re-export depuis `AudioPlayer.tsx` . |
2026-02-05 21:46:26 +00:00
| ~~`TrackFilters.tsx`~~ | ~~401~~ | **Refactorisé 2026-02-05** : module `features/tracks/components/track-filters/` avec `useTrackFilters` , `TrackFiltersHeader` , `TrackFiltersSearch` , `TrackFiltersGrid` , `TrackFiltersClear` , `TrackFiltersSkeleton` . Stories : Default, Collapsible, Loading. Re-export depuis `TrackFilters.tsx` . |
2026-02-05 21:55:11 +00:00
| ~~`PlaylistList.tsx`~~ | ~~380~~ | **Refactorisé 2026-02-05** : module `features/playlists/components/playlist-list/` avec `usePlaylistList` , `PlaylistListToolbar` , `PlaylistListEmpty` , `PlaylistListError` . Skeleton existant `PlaylistListSkeleton` . Stories : Default, Grid, Empty (MSW), Loading (skeleton). Re-export depuis `PlaylistList.tsx` . |
2026-02-05 22:00:02 +00:00
| ~~`dialog.tsx`~~ | ~~365~~ | **Refactorisé 2026-02-05** : module `components/ui/dialog/` avec types, `Dialog` , `DialogHeader` , `DialogBody` , `DialogFooter` , `DialogContent` , `DialogDescription` , `DialogTitle` , `DialogTrigger` , `DialogSkeleton` . Stories : Default, Alert, Composition, Loading. Re-export depuis `dialog.tsx` . |
2026-02-06 01:27:58 +00:00
| ~~`dropdown-menu.tsx`~~ | ~~345~~ | **Refactorisé 2026-02-05** : module `components/ui/dropdown-menu/` avec types, `DropdownMenuTrigger` , `DropdownMenuContent` , `DropdownMenuItem` , `DropdownMenuCheckboxItem` , `DropdownMenuRadioItem` , `DropdownMenuLabel` , `DropdownMenuSeparator` , `DropdownMenuShortcut` , `DropdownMenuPlaceholders` (Group, Portal, Sub, SubContent, SubTrigger, RadioGroup). Dropdown base (`dropdown.tsx`) : `open` / `defaultOpen` pour mode contrôlé. Conformité UI : `min-w-32` (pas de valeur arbitraire). Re-export depuis `dropdown-menu.tsx` . |
2026-02-06 01:33:34 +00:00
| ~~`accordion.tsx`~~ | ~~335~~ | **Refactorisé 2026-02-05** : module `components/ui/accordion/` avec types, `Accordion` , `AccordionItem` , `AccordionTrigger` , `AccordionContent` . Conformité UI : `max-h-[5000px]` → `max-h-none` , stories `w-[500px]` → `max-w-xl` . Re-export depuis `accordion.tsx` . |
2026-02-06 09:12:56 +00:00
| ~~`tabs.tsx`~~ | ~~330~~ | **Refactorisé 2026-02-05** : module `components/ui/tabs/` avec types, `Tabs` , `TabsList` , `TabsTrigger` , `TabsContent` . Stories `w-[400px]` → `max-w-md` . Re-export depuis `tabs.tsx` . |
2026-02-06 09:32:46 +00:00
| ~~`tooltip.tsx`~~ | ~~327~~ | **Refactorisé 2026-02-05** : module `components/ui/tooltip/` avec types, `useTooltip` , `TooltipContent` , `Tooltip` . Handlers hover sur wrapper, click/focus sur enfant (cloneElement). Conformité : `max-w-xs` par défaut, stories `h-[200px]` → `min-h-layout-story` . Re-export depuis `tooltip.tsx` . |
2026-02-06 10:23:10 +00:00
| ~~`Table.tsx` (data)~~ | ~~323~~ | **Refactorisé 2026-02-05** : module `components/data/table/` avec types, `useTable` , `TableHeadRow` , `TableBodyRows` , `Table` . Conformité : largeur colonnes via style (pas de classe arbitraire). Stories : Default, Empty, Paginated, Selectable (Data/Table). Re-export depuis `Table.tsx` . |
2026-02-06 10:36:31 +00:00
| ~~`FormBuilder.tsx`~~ | ~~316~~ | **Refactorisé 2026-02-05** : module `components/forms/form-builder/` avec types, `useFormBuilder` , `FormBuilderFieldWidget` , `FormBuilder` . Conformité : textarea `min-h-[80px]` → `min-h-20` . Stories : Default, Empty, Disabled (Components/Forms/FormBuilder). Re-export depuis `FormBuilder.tsx` . |
2026-02-06 10:45:29 +00:00
| ~~`EditProfile.tsx`~~ | ~~310~~ | **Refactorisé 2026-02-05** : module `components/settings/profile/edit-profile/` avec types, `cropUtils` , `useEditProfile` , `EditProfileImagesCard` , `EditProfileIdentityCard` , `EditProfileSidebar` , `EditProfileSkeleton` . Conformité : textarea `min-h-[100px]` → `min-h-24` . Stories : Default, Loading (Skeleton). Re-export depuis `EditProfile.tsx` . |
2026-02-06 11:35:28 +00:00
| ~~`GroupDetailView.tsx`~~ | ~~307~~ | **Refactorisé 2026-02-05** : module `components/social/groups/group-detail-view/` avec types (`ExtendedGroup`, `GroupMember` , `GroupEvent` ), `useGroupDetailView` , `GroupDetailViewHeader` , `GroupDetailViewMembers` , `GroupDetailViewEvents` , `GroupDetailViewSidebar` , `GroupDetailViewSkeleton` . Conformité : `text-[10px]` → `text-xs` , `min-w-[80px]` → `min-w-20` . Stories : Default, Loading. Re-export depuis `GroupDetailView.tsx` . |
2026-02-06 12:11:09 +00:00
| ~~`UserProfilePage.tsx`~~ | ~~318~~ | **Refactorisé 2026-02-05** : module `features/profile/pages/user-profile-page/` avec `useUserProfilePage` , `UserProfilePageHero` , `UserProfilePageHeader` , `UserProfilePageTabs` , `UserProfilePageSkeleton` , `UserProfilePageError` . Conformité : stats `text-[10px]` → `text-xs` . Stories : Default (route /u/demo), Loading (Skeleton), NotFound (route /u/notfound). MSW : GET `/api/v1/users/by-username/:username` (404 pour notfound). Re-export depuis `UserProfilePage.tsx` . |
2026-02-06 12:19:48 +00:00
| ~~`DiscoverView.tsx`~~ | ~~300~~ | **Refactorisé 2026-02-05** : module `components/views/discover-view/` avec `useDiscoverView` , `DiscoverViewHero` , `DiscoverViewTrending` , `DiscoverViewNewReleases` , `DiscoverViewGenres` , `DiscoverViewSkeleton` , `DiscoverViewError` . Conformité : loading `h-[50vh]` → Skeleton ; badge UPDATED `text-[10px]` → `text-xs` ; erreur `min-h-layout-page-sm` . Stories : Default, Loading (Skeleton), Error. Re-export depuis `DiscoverView.tsx` . |
2026-02-06 12:26:57 +00:00
| ~~`features/library/UploadModal.tsx`~~ | ~~317~~ | **Refactorisé 2026-02-05** : module `features/library/components/upload-modal/` avec `useLibraryUploadModal` , `UploadModalForm` , `UploadModalFooter` , types (`UploadModalProps`, `UploadFormData` , `ALLOWED_AUDIO_TYPES` , `MAX_FILE_SIZE_BYTES` ). Stories inchangées : Default, Controlled. Re-export depuis `UploadModal.tsx` . |
2026-02-06 12:37:31 +00:00
| ~~`features/player/components/AudioPlayer.tsx`~~ | ~~374~~ | **Refactorisé 2026-02-05** : module `features/player/components/audio-player/` avec `useAudioPlayerLifecycle` , `AudioPlayerCompact` , `AudioPlayerFull` , `AudioPlayerSkeleton` . Stories : Playing, Paused, Loading (Skeleton), Error. Re-export et default export depuis `AudioPlayer.tsx` . 20 tests passent. |
2026-02-05 22:04:31 +00:00
| ~~`AccountSettings.tsx`~~ | ~~362~~ | **Refactorisé 2026-02-05** : module `features/settings/components/account-settings/` avec `useAccountSettings` , `AccountSettingsErrorBanner` , `AccountSettingsPasswordCard` , `AccountSettingsExportCard` , `AccountSettingsDeleteCard` , `AccountSettingsSkeleton` . Stories : Default, Loading. Re-export depuis `AccountSettings.tsx` . |
2026-02-05 22:09:51 +00:00
| ~~`TrackSearchFilters.tsx`~~ | ~~348~~ | **Refactorisé 2026-02-05** : module `features/tracks/components/track-search-filters/` avec `useTrackSearchFilters` , `TrackSearchFiltersBasic` , `TrackSearchFiltersAdvanced` , `TrackSearchFiltersSkeleton` . Stories : Default, Applied, Loading. Re-export depuis `TrackSearchFilters.tsx` . |
2026-02-05 22:19:26 +00:00
| ~~`SessionsPage.tsx`~~ | ~~351~~ | **Refactorisé 2026-02-05** : module `features/auth/components/sessions-page/` avec `useSessionsPage` , `SessionsPageHeader` , `SessionsPageErrorBanner` , `SessionsPageRevokeAllButton` , `SessionsPageSessionItem` , `SessionsPageContent` , `SessionsPageEmpty` , `SessionsPageSkeleton` . Stories : Default, Loading, Empty, Error. MSW : GET/DELETE auth/sessions. Re-export depuis `pages/SessionsPage.tsx` . |
2026-02-05 22:24:57 +00:00
| ~~`ProjectDetailView.tsx`~~ | ~~367~~ | **Refactorisé 2026-02-05** : module `components/studio/projects/project-detail-view/` avec `useProjectDetailView` , `ProjectDetailViewHeader` , `ProjectDetailViewTabs` , `ProjectDetailViewOverview` , `ProjectDetailViewFiles` , `ProjectDetailViewSettings` , `ProjectDetailViewSidebar` , `ProjectDetailViewSkeleton` . Stories : Default, Loading, Empty. Re-export depuis `projects/ProjectDetailView.tsx` . |
2026-02-05 22:31:25 +00:00
| ~~`PlaybackHeatmap.tsx`~~ | ~~353~~ | **Refactorisé 2026-02-05** : module `features/streaming/components/playback-heatmap/` avec `usePlaybackHeatmap` , `PlaybackHeatmapHeader` , `PlaybackHeatmapStats` , `PlaybackHeatmapGrid` , `PlaybackHeatmapSkeleton` , `PlaybackHeatmapError` , `PlaybackHeatmapEmpty` . Stories : Default, CustomSegmentSize, Loading, Empty, Error. MSW : GET `/api/v1/tracks/:id/playback/heatmap` . Re-export depuis `PlaybackHeatmap.tsx` . |
2026-02-05 22:38:28 +00:00
| ~~`ProductDetailView.tsx`~~ | ~~352~~ | **Refactorisé 2026-02-05** : module `components/marketplace/product-detail-view/` avec `useProductDetailView` , `ProductDetailViewHeader` , `ProductDetailViewGallery` , `ProductDetailViewInfo` , `ProductDetailViewLicenses` , `ProductDetailViewDescription` , `ProductDetailViewReviews` , `ProductDetailViewSimilar` , `ProductDetailViewSkeleton` . Stories : Default, Loading, Empty, WithReviews. Re-export depuis `ProductDetailView.tsx` . |
2026-02-05 22:46:20 +00:00
| ~~`CourseLearningView.tsx`~~ | ~~353~~ | **Refactorisé 2026-02-05** : module `components/education/course-learning-view/` avec `useCourseLearningView` , `CourseLearningViewHeader` , `CourseLearningViewPlayer` , `CourseLearningViewTabs` , `CourseLearningViewSidebar` , `CourseLearningViewSkeleton` . Layout `min-h-layout-main` . Stories : Default, Loading, Empty, Complete. Re-export depuis `CourseLearningView.tsx` . |
2026-02-05 22:52:47 +00:00
| ~~`CourseDetailView.tsx`~~ | ~~348~~ | **Refactorisé 2026-02-05** : module `components/education/course-detail-view/` avec `useCourseDetailView` , `CourseDetailViewHeader` , `CourseDetailViewTabs` , `CourseDetailViewSidebar` , `CourseDetailViewSkeleton` . Stories : Default, Loading, Empty, Enrolled. Re-export depuis `CourseDetailView.tsx` . |
2026-02-05 23:00:58 +00:00
| ~~`LibraryManager.tsx`~~ | ~~337~~ | **Refactorisé 2026-02-05** : module `features/library/components/library-manager/` avec `useLibraryManager` , Header, Toolbar, Error, Empty, Content, Stats, `LibraryManagerSkeleton` . Layout `min-h-layout-page` . Stories : Default, Loading, Empty, Error. MSW : GET /api/v1/tracks. Re-export depuis `LibraryManager.tsx` . |
2026-02-07 03:31:15 +00:00
| ~~`features/library/pages/LibraryPage.tsx`~~ | ~~281~~ | **Refactorisé 2026-02-05** : module `features/library/pages/library-page/` avec types, utils (safeFormatDistanceToNow, getArtistName, formatDuration), `useLibraryPage` , `LibraryPageToolbar` , `LibraryPageEmpty` , `LibraryPageGrid` , `LibraryPageList` , `LibraryPageSkeleton` . Layout `min-h-layout-page-sm` (Empty). Stories : Default, Empty (initialTracks []), Loading (Skeleton). Re-export depuis `LibraryPage.tsx` . |
2026-02-07 03:44:30 +00:00
| ~~`features/chat/components/VirtualizedChatMessages.tsx`~~ | ~~287~~ | **Refactorisé 2026-02-05** : module `features/chat/components/virtualized-chat-messages/` avec types (MESSAGE_HEIGHT, CONTAINER_HEIGHT), `useChatMessages` , `VirtualizedChatMessageItem` , `VirtualizedChatMessagesEmpty` , `VirtualizedChatMessagesLoadingIndicator` , `VirtualizedChatMessagesScrollButton` , `VirtualizedChatMessagesSkeleton` . Layout `min-h-layout-page-sm` (Empty, Skeleton). Stories : Default, Empty, Loading (Skeleton). Re-export depuis `VirtualizedChatMessages.tsx` . |
2026-02-07 03:54:00 +00:00
| ~~`features/playlists/components/PlaylistAnalytics.tsx`~~ | ~~284~~ | **Refactorisé 2026-02-05** : module `features/playlists/components/playlist-analytics/` avec types (`PlaylistAnalyticsData`), `usePlaylistAnalytics` , `PlaylistAnalyticsStatCard` , `PlaylistAnalyticsMainCard` , `PlaylistAnalyticsAdvancedCard` , `PlaylistAnalyticsZeroState` , `PlaylistAnalyticsError` , `PlaylistAnalyticsNoData` , `PlaylistAnalyticsSkeleton` . Layout `min-h-layout-story` (Skeleton, Error, NoData). Props `initialAnalytics` , `initialError` , `forceLoading` pour stories. Stories : Default, Empty, Error, Loading (Skeleton). Re-export depuis `PlaylistAnalytics.tsx` . |
2026-02-07 04:04:24 +00:00
| ~~`features/tracks/components/TrackListPagination.tsx`~~ | ~~283~~ | **Refactorisé 2026-02-05** : module `features/tracks/components/track-list-pagination/` avec types, `utils` (getVisiblePages, getItemsRange), `TrackListPaginationInfo` , `TrackListPaginationNav` , `TrackListPaginationSkeleton` . Conformité UI : `border-kodo-steel` → `border-border` , `text-kodo-*` → `text-foreground` /`text-muted-foreground`, `bg-kodo-cyan` → `bg-primary` , `focus:ring-blue-500` → `focus-visible:ring-ring` . Stories : Default, MiddlePage, LastPage, ManyPages, Disabled, Loading (Skeleton). Re-export depuis `TrackListPagination.tsx` . |
2026-02-07 04:46:19 +00:00
| ~~`components/inventory/EquipmentDetailView.tsx`~~ | ~~279~~ | **Refactorisé 2026-02-05** : module `components/inventory/equipment-detail-view/` avec types, `useEquipmentDetailView` , `EquipmentDetailViewNav` , `EquipmentDetailViewGallery` , `EquipmentDetailViewSpecsCard` , `EquipmentDetailViewHeader` , `EquipmentDetailViewWarrantyCard` , `EquipmentDetailViewDocsCard` , `EquipmentDetailViewServiceCard` , `EquipmentDetailViewNotFound` , `EquipmentDetailViewSkeleton` . Conformité : `text-kodo-*` → tokens, `text-[10px]` → `text-xs` , loading `h-[50vh]` → Skeleton. Props `initialItem` , `forceLoading` pour stories. Stories : Default (initialItem), Loading (Skeleton), NotFound. Re-export depuis `EquipmentDetailView.tsx` . |
2026-02-07 05:10:30 +00:00
| ~~`features/playlists/components/PlaylistActions.tsx`~~ | ~~277~~ | **Refactorisé 2026-02-05** : module `features/playlists/components/playlist-actions/` avec types (`PlaylistActionsProps`), `usePlaylistActions` , `PlaylistActionsButtons` , `PlaylistActionsEditDialog` , `PlaylistActionsSkeleton` , `ConfirmationDialog` (suppression). Conformité : `min-h-11` , tokens success (`text-green-600`). Stories : Default, WithShare, Loading (Skeleton). ToastProvider dans décorateur. Ancien fichier monolithe supprimé ; import depuis `playlist-actions` . |
2026-02-07 05:47:07 +00:00
| ~~`features/playlists/pages/PlaylistDetailPage.tsx`~~ | ~~270~~ | **Refactorisé 2026-02-05** : module `features/playlists/pages/playlist-detail-page/` avec types (`PlaylistDetailPageProps`), `usePlaylistDetailPage` , `PlaylistDetailPageHero` , `PlaylistDetailPageCoverAndInfo` , `PlaylistDetailPageActionsBar` , `PlaylistDetailPageTabs` , `PlaylistDetailPageNotFound` , `PlaylistDetailPageSkeleton` . Layout `min-h-layout-page` . Stories : Default (route `/playlists/demo-playlist` ), Loading (Skeleton), NotFound. Re-export depuis `PlaylistDetailPage.tsx` . |
2026-02-07 05:57:46 +00:00
| ~~`features/tracks/pages/TrackDetailPage.tsx`~~ | ~~238~~ | **Refactorisé 2026-02-05** : module `features/tracks/pages/track-detail-page/` avec types (`TrackDetailPageProps`), `utils` (formatDuration), `useTrackDetailPage` , `TrackDetailPageHero` , `TrackDetailPageCoverAndActions` , `TrackDetailPageInfo` , `TrackDetailPageTabs` , `TrackDetailPageNotFound` , `TrackDetailPageSkeleton` . Layout `min-h-layout-page` . Stories : Default (route `/tracks/demo-track` ), Loading (Skeleton), NotFound. Re-export depuis `TrackDetailPage.tsx` . |
2026-02-05 23:07:42 +00:00
| ~~`NotificationMenu.tsx`~~ | ~~339~~ | **Refactorisé 2026-02-05** : module `components/notifications/notification-menu/` avec `useNotificationMenu` , Trigger, Dropdown, List, Item, `NotificationMenuSkeleton` . Dropdown `max-h-96` . Stories : Default, Loading, Empty, Error, Skeleton. Re-export depuis `NotificationMenu.tsx` . |
2026-02-05 23:14:41 +00:00
| ~~`PlaylistTrackList.tsx`~~ | ~~309~~ | **Refactorisé 2026-02-05** : module `features/playlists/components/playlist-track-list/` avec `usePlaylistTrackList` , Empty, SortableItem, Skeleton, utils. Stories : Default, Loading, Empty, Reordering. Re-export depuis `PlaylistTrackList.tsx` et `PlaylistTrackListSkeleton.tsx` . |
2026-02-05 23:22:33 +00:00
| ~~`AddTrackToPlaylistModal.tsx`~~ | ~~324~~ | **Refactorisé 2026-02-05** : module `features/playlists/components/add-track-to-playlist-modal/` avec `useAddTrackToPlaylistModal` , `AddTrackToPlaylistModalSearch` , `AddTrackToPlaylistModalList` , `AddTrackToPlaylistModalTrackRow` , `AddTrackToPlaylistModalFooter` , `AddTrackToPlaylistModalSkeleton` . Liste `max-h-96` . Stories : Default, Loading (Skeleton). Re-export depuis `AddTrackToPlaylistModal.tsx` . |
2026-02-05 23:37:26 +00:00
| ~~`PlaylistBatchActions.tsx`~~ | ~~323~~ | **Refactorisé 2026-02-05** : module `features/playlists/components/playlist-batch-actions/` avec `usePlaylistBatchActions` , `exportUtils` , `PlaylistBatchActionsBar` , `PlaylistBatchActionsButtons` , `PlaylistBatchActionsDeleteDialog` , `PlaylistBatchActionsSkeleton` . Boutons `min-h-11` . Stories : Default, SingleSelection, Loading. Re-export depuis `PlaylistBatchActions.tsx` . |
2026-02-05 23:47:47 +00:00
| ~~`PlaylistSearch.tsx`~~ | ~~331~~ | **Refactorisé 2026-02-05** : module `features/playlists/components/playlist-search/` avec `usePlaylistSearch` , `PlaylistSearchBar` , `PlaylistSearchFilters` , `PlaylistSearchResults` , `PlaylistSearchSkeleton` . Chargement avec Spinner. PLAYLIST_SEARCH activé en Storybook (VITE_STORYBOOK). MSW : GET `/api/v1/playlists/search` . Stories : Default, Loading, Empty, Error. Re-export depuis `PlaylistSearch.tsx` . |
2026-02-05 23:53:10 +00:00
| ~~`CreatePlaylistDialog.tsx`~~ | ~~186~~ | **Refactorisé 2026-02-05** : module `features/playlists/components/create-playlist-dialog/` avec `schema` , `useCreatePlaylistDialog` , `CreatePlaylistDialogForm` , `CreatePlaylistDialogSkeleton` . Bouton Créer avec Spinner. Stories : Default, Loading. Re-export depuis `CreatePlaylistDialog.tsx` . |
2026-02-05 23:58:07 +00:00
| ~~`SharePlaylistModal.tsx`~~ | ~~145~~ | **Refactorisé 2026-02-05** : module `features/playlists/components/share-playlist-modal/` avec `useSharePlaylistModal` , `SharePlaylistModalContent` , `SharePlaylistModalSkeleton` . ErrorDisplay + retry. Stories : Default, Loading, Error. Re-export depuis `SharePlaylistModal.tsx` . |
2026-02-06 00:04:43 +00:00
| ~~`AddCollaboratorModal.tsx`~~ | ~~200~~ | **Refactorisé 2026-02-05** : module `features/playlists/components/add-collaborator-modal/` avec `useAddCollaboratorModal` , `AddCollaboratorModalForm` , `AddCollaboratorModalSkeleton` . ErrorDisplay (validation + mutation, retry). Stories : Default, Loading, Error (MSW). Re-export depuis `AddCollaboratorModal.tsx` . |
2026-02-06 00:12:44 +00:00
| ~~`UploadView.tsx`~~ | ~~301~~ | **Refactorisé 2026-02-05** : module `components/views/upload-view/` avec `useUploadView` , `UploadViewStepper` , `UploadViewStep1` , `UploadViewStep2` , `UploadViewStep3` , `UploadViewSkeleton` . Layout `min-h-layout-page` , `max-h-96` . Stories : Default, Loading, Empty, Error. Re-export depuis `UploadView.tsx` . |
2026-02-06 00:26:01 +00:00
| ~~`TwoFactorSetup.tsx`~~ | ~~322~~ | **Refactorisé 2026-02-05** : module `components/settings/security/two-factor-setup/` avec `useTwoFactorSetup` , `TwoFactorSetupHeader` , `TwoFactorSetupStep1` , `TwoFactorSetupStep2` , `TwoFactorSetupStep3` , `TwoFactorSetupSkeleton` . Stories : Default, Step1, Step2, Loading, Error (MSW). Re-export depuis `TwoFactorSetup.tsx` . |
2026-02-06 00:35:21 +00:00
| ~~`TrackHistory.tsx`~~ | ~~324~~ | **Refactorisé 2026-02-05** : module `features/tracks/components/track-history/` avec `useTrackHistory` , `TrackHistoryHeader` , `TrackHistoryEmpty` , `TrackHistoryItemRow` , `TrackHistoryPagination` , `TrackHistorySkeleton` , `trackHistoryUtils` . Stories : Default, Loading, Empty, Error (MSW). Re-export depuis `TrackHistory.tsx` . |
2026-02-06 00:45:05 +00:00
| ~~`ProjectsManager.tsx`~~ | ~~322~~ | **Refactorisé 2026-02-05** : module `components/studio/projects-manager/` avec `useProjectsManager` , `ProjectsManagerHeader` , `ProjectsManagerFilterBar` , `ProjectsManagerCard` , `ProjectsManagerAddCard` , `ProjectsManagerEmpty` , `ProjectsManagerSkeleton` . Stories : Default, Loading, Empty. Re-export depuis `ProjectsManager.tsx` . |
2026-02-06 00:51:46 +00:00
| ~~`CreateProjectModal.tsx`~~ | ~~127~~ | **Refactorisé 2026-02-05** : module `components/studio/projects/create-project-modal/` avec `useCreateProjectModal` , `CreateProjectModalHeader` , `CreateProjectModalForm` , `CreateProjectModalFooter` , `CreateProjectModalSkeleton` . Stories : Default, Loading. Re-export depuis `projects/CreateProjectModal.tsx` . |
2026-02-06 00:57:44 +00:00
| ~~`GoLiveView.tsx`~~ | ~~255~~ | **Refactorisé 2026-02-05** : module `components/studio/go-live-view/` avec `useGoLiveView` , `GoLiveViewHeader` , `GoLiveViewPreview` , `GoLiveViewStreamInfo` , `GoLiveViewEncoderSetup` , `GoLiveViewQuickInstructions` , `GoLiveViewMicLevel` , `GoLiveViewSkeleton` . Stories : Default, Loading. Re-export depuis `GoLiveView.tsx` . |
2026-02-06 01:02:23 +00:00
| ~~`ConnectivityView.tsx`~~ | ~~192~~ | **Refactorisé 2026-02-05** : module `components/studio/connectivity-view/` avec `useConnectivityView` , `ConnectivityViewWebDAV` , `ConnectivityViewWebhooks` , `ConnectivityViewSkeleton` . Stories : Default, Loading. Re-export depuis `ConnectivityView.tsx` . |
2026-02-06 01:07:27 +00:00
| ~~`AIToolsView.tsx`~~ | ~~188~~ | **Refactorisé 2026-02-05** : module `components/studio/ai-tools-view/` avec `useAIToolsView` , `AIToolsViewToolGrid` , `AIToolsViewWorkspace` , `AIToolsViewSkeleton` , constantes `AI_TOOLS` . Stories : Default, Loading. Re-export depuis `AIToolsView.tsx` . |
2026-02-06 01:11:58 +00:00
| ~~`CloudSettingsView.tsx`~~ | ~~113~~ | **Refactorisé 2026-02-05** : module `components/studio/cloud-settings-view/` avec `useCloudSettingsView` , `CloudSettingsViewQuota` , `CloudSettingsViewPreferences` , `CloudSettingsViewSkeleton` . Stories : Default, Loading. Re-export depuis `CloudSettingsView.tsx` . |
2026-02-06 01:18:00 +00:00
| ~~`StudioView.tsx`~~ | ~~169~~ | **Refactorisé 2026-02-05** : module `components/views/studio-view/` avec `useStudioView` , `StudioViewHeader` , `StudioViewSidebar` , `StudioViewNavButton` , `StudioViewContent` , `StudioViewProjectsSwitch` , `StudioViewSkeleton` . Layout `min-h-layout-main` ; `w-[65%]` → `w-2/3` . Stories : Default, Projects, Loading. Re-export depuis `StudioView.tsx` . |
2026-02-06 12:46:58 +00:00
| ~~`context/AudioContext.tsx`~~ | ~~343~~ | **Refactorisé 2026-02-05** : module `context/audio-context/` avec `types` (VisualizerSettings, AudioContextType), `mockTracks` , `useAudioContextValue` , `AudioContext` (createContext, useAudio, AudioProvider). Re-export depuis `AudioContext.tsx` . 12 tests passent. Correction : `toggleMute` bascule `isMuted` (au lieu de play). |
2026-02-06 12:55:32 +00:00
| ~~`components/ui/virtualized-list.tsx`~~ | ~~295~~ | **Refactorisé 2026-02-05** : module `components/ui/virtualized-list/` avec `types` (VirtualizedListProps), `VirtualizedList` , `useInfiniteScroll` , `useScrollPosition` . Re-export depuis `virtualized-list.tsx` (import explicite depuis `./virtualized-list/index` ). Stories : Default, SmallItems. 4 tests passent (mock useVirtualizer complété). |
2026-02-06 13:06:09 +00:00
| ~~`components/views/FileDetailsView.tsx`~~ | ~~292~~ | **Refactorisé 2026-02-05** : module `components/views/file-details-view/` avec `types` (FileDetailsViewProps, ActivityItem, VersionItem), `mockData` (MOCK_ACTIVITY, MOCK_VERSIONS, getMockFile), `useFileDetailsView` , Header, Preview, Metadata, Activity, Versions, Storage, `FileDetailsViewSkeleton` . Layout : `min-h-[400px]` → `min-h-layout-page-sm` , badge LATEST `text-[10px]` → `text-xs` . Stories : Default, Loading (Skeleton). Re-export depuis `FileDetailsView.tsx` . |
2026-02-06 13:17:28 +00:00
| ~~`components/seller/CreateProductView.tsx`~~ | ~~292~~ | **Refactorisé 2026-02-05** : module `components/seller/create-product-view/` avec `types` (LicenseConfig), `useCreateProductView` , Header, CoverCard, FilesCard, DetailsCard, PricingCard, `CreateProductViewSkeleton` . Textarea `min-h-[120px]` → `min-h-24` . MSW : POST `/api/v1/marketplace/products` . Stories : Default, Loading (Skeleton). Re-export depuis `CreateProductView.tsx` . |
2026-02-06 13:25:15 +00:00
| ~~`features/chat/components/ChatInterface.tsx`~~ | ~~291~~ | **Refactorisé 2026-02-05** : module `features/chat/components/chat-interface/` avec `types` (ChatInterfaceProps), `useChatInterface` (wsService, loadMessages, loadChatStats, formatTimestamp), Header, Messages, Input, `ChatInterfaceSkeleton` . Stories : Default, ProductionRoom, Loading (Skeleton). Decorator `h-[600px]` → `min-h-layout-page` . Re-export depuis `ChatInterface.tsx` . |
2026-02-06 16:43:34 +00:00
| ~~`components/settings/account/AccountSettings.tsx`~~ | ~~289~~ | **Refactorisé 2026-02-05** : module `components/settings/account/account-settings/` avec `types` (AccountSettingsUserMock, AccountSettingsToggles), `useAccountSettingsPage` (view, modals, user, toggles, theme), IdentityCard, PreferencesCard, NotificationsCard, PrivacyCard, DangerCard, `AccountSettingsSkeleton` . Privacy labels `text-[10px]` → `text-xs` . Stories : Default, Loading (Skeleton). Decorator `min-h-screen` → `min-h-layout-page` . Re-export depuis `AccountSettings.tsx` . |
2026-02-06 16:54:39 +00:00
| ~~`components/admin/AdminDashboardView.tsx`~~ | ~~289~~ | **Refactorisé 2026-02-05** : module `components/admin/admin-dashboard-view/` avec `types` (DashboardStats, UploadItem, AuditLogItem, StatCardProps), `useAdminDashboardView` , Header, StatCard, TrafficCard, ProtocolsCard, NodeHealthCard, Tabs (Moderation/Signals/Logs), `AdminDashboardSkeleton` . Layout `max-w-[1600px]` → `max-w-layout-content` , `text-[10px]` → `text-xs` , `gap-[2px]` → `gap-0.5` . Stories : Default, Loading (Skeleton). Decorator `min-h-screen` → `min-h-layout-page` . Re-export depuis `AdminDashboardView.tsx` . |
2026-02-06 17:04:47 +00:00
| ~~`components/views/CheckoutView.tsx`~~ | ~~288~~ | **Refactorisé 2026-02-05** : module `components/views/checkout-view/` avec `types` (CheckoutViewProps, CheckoutFormState), `useCheckoutView` , `CheckoutViewHeader` , `CheckoutViewBillingCard` , `CheckoutViewPaymentCard` , `CheckoutViewOrderSummary` , `CheckoutViewSkeleton` . Stories : Default, Loading (Skeleton), Processing, Success. Decorator `min-h-screen` → `min-h-layout-page` . Re-export depuis `CheckoutView.tsx` . |
2026-02-06 17:16:11 +00:00
| ~~`components/views/LiveView.tsx`~~ | ~~270~~ | **Refactorisé 2026-02-05** : module `components/views/live-view/` avec `types` (LiveViewProps, LiveViewChatMessage), `mockData` (FEATURED_STREAM, CHAT_MESSAGES), `useLiveView` , `LiveViewPlayer` , `LiveViewStreamInfo` , `LiveViewRecommended` , `LiveViewChat` , `LiveViewSkeleton` . Layout `h-[calc(100vh-120px)]` → `min-h-layout-main` ; `text-[10px]` → `text-xs` . Stories : Default, Loading (Skeleton). Decorator `min-h-screen` → `min-h-layout-page` . Re-export depuis `LiveView.tsx` . |
2026-02-06 17:34:24 +00:00
| ~~`components/views/AnalyticsView.tsx`~~ | ~~260~~ | **Refactorisé 2026-02-05** : module `components/views/analytics-view/` avec `types` (AnalyticsViewProps, DateRangeKey, GlobalStats, TopTrackRow, TrafficSource, DeviceStats, ChartHoverData), `useAnalyticsView` , `AnalyticsViewHeader` , `AnalyticsViewKpiGrid` , `AnalyticsViewChart` , `AnalyticsViewOrigins` , `AnalyticsViewPlatforms` , `AnalyticsViewTopTracks` , `AnalyticsViewSkeleton` . Données via `analyticsService` . Conformité : `text-[10px]` → `text-xs` , `tracking-[0.2em]` → `tracking-wide` . Stories : Default, Loading (Skeleton). Decorator `min-h-screen` → `min-h-layout-page` . Re-export depuis `AnalyticsView.tsx` . |
2026-02-06 20:26:33 +00:00
| ~~`components/views/MarketplaceView.tsx`~~ | ~~196~~ | **Refactorisé 2026-02-05** : module `components/views/marketplace-view/` avec `types` (MarketplaceViewProps, MarketplaceCategory), `useMarketplaceView` (products, allProducts, filters, marketplaceService / fallback mock), `MarketplaceViewHeader` , `MarketplaceViewCategories` , `MarketplaceViewSidebar` , `MarketplaceViewGrid` , `MarketplaceViewSkeleton` . Layout `min-h-screen` → `min-h-layout-page` . Stories : Default, Loading (Skeleton). Decorator `min-h-layout-page` . Re-export depuis `MarketplaceView.tsx` . |
2026-02-06 20:35:06 +00:00
| ~~`components/views/SocialView.tsx`~~ | ~~189~~ | **Refactorisé 2026-02-05** : module `components/views/social-view/` avec `types` (SocialViewProps, SocialTabKey), `useSocialView` (feedTracks via trackService.list, activeTab, playTrack), `SocialViewSidebar` , `SocialViewFeed` , `SocialViewFeedItem` , `SocialViewTrending` , `SocialViewSkeleton` . Stories : Default, Loading (Skeleton). Decorator `min-h-screen` → `min-h-layout-page` . Re-export depuis `SocialView.tsx` . |
2026-02-06 20:43:08 +00:00
| ~~`components/views/PurchasesView.tsx`~~ | ~~175~~ | **Refactorisé 2026-02-05** : module `components/views/purchases-view/` avec `types` (PurchasesViewProps, Purchase), `usePurchasesView` (commerceService.getPurchases, search, refundOrderId, activeDownloadId, handleDownload), `PurchasesViewHeader` , `PurchasesViewItem` , `PurchasesViewList` , `PurchasesViewSkeleton` . RefundRequestModal dans l’ orchestrateur. Stories : Default, Empty (initialPurchases []), Loading (Skeleton). Decorator `min-h-layout-page` . Re-export depuis `PurchasesView.tsx` . |
2026-02-06 20:51:30 +00:00
| ~~`components/views/CartView.tsx`~~ | ~~176~~ | **Refactorisé 2026-02-05** : module `components/views/cart-view/` avec `types` (CartViewProps, CartDiscount), `useCartView` (useCartStore, promo, tax/finalTotal), `CartViewEmpty` , `CartViewHeader` , `CartViewSummary` , `CartViewSecure` , `CartViewSkeleton` . PromoCodeModal dans l'orchestrateur. Layout `min-h-[60vh]` → `min-h-layout-page-sm` . Stories : Default, Empty, Loading (Skeleton). Decorator `min-h-layout-page` . Re-export depuis `CartView.tsx` . |
2026-02-06 21:00:12 +00:00
| ~~`components/views/SettingsView.tsx`~~ | ~~167~~ | **Refactorisé 2026-02-05** : module `components/views/settings-view/` avec `types` (SettingsViewProps, SettingsTabId, SettingsTabConfig), `useSettingsView` (activeTab, setActiveTab, tabs avec icônes), `SettingsViewHeader` , `SettingsViewTabs` , `SettingsViewContent` (switch onglets), `SettingsViewSkeleton` . Layout `min-h-[500px]` → `min-h-layout-page` , placeholders audio/notifications `min-h-layout-page-sm` . Stories : Default (initialTab), Loading (Skeleton). Decorator `min-h-layout-page` . Re-export depuis `SettingsView.tsx` . |
2026-02-06 21:11:45 +00:00
| ~~`components/views/EducationView.tsx`~~ | ~~164~~ | **Refactorisé 2026-02-05** : module `components/views/education-view/` avec `types` (EducationViewProps, initialCourses), `useEducationView` (search, filters, courses, loading, filtered, educationService.getCatalog), `EducationViewHeader` , `EducationViewFilters` , `EducationViewEmpty` , `EducationViewSkeleton` . Layout `min-h-layout-page` . Stories : Default, Loading (Skeleton), Empty (initialCourses []). Decorator `min-h-layout-page` . Re-export depuis `EducationView.tsx` . |
2026-02-06 21:23:19 +00:00
| ~~`components/views/NotificationsView.tsx`~~ | ~~124~~ | **Refactorisé 2026-02-05** : module `components/views/notifications-view/` avec `types` (NotificationsViewProps, NotificationsFilterKey), `useNotificationsView` (socialService.getNotifications, filter, handleRead, handleMarkAllRead, handleClearAll), `NotificationsViewHeader` , `NotificationsViewFilters` , `NotificationsViewItem` , `NotificationsViewEmpty` , `NotificationsViewSkeleton` . Layout `min-h-layout-page` . Stories : Default, Loading (Skeleton), Empty (initialNotifications []). Decorator `min-h-layout-page` . Re-export depuis `NotificationsView.tsx` . |
2026-02-06 21:32:04 +00:00
| ~~`components/views/AdminView.tsx`~~ | ~~96~~ | **Refactorisé 2026-02-05** : module `components/views/admin-view/` avec `types` (AdminViewProps, AdminSubViewId, AdminTabConfig), `useAdminView` (activeTab, setActiveTab, tabs avec icônes), `AdminViewSidebar` , `AdminViewContent` (switch sous-vues), `AdminViewSkeleton` . Layout `h-[calc(100vh-140px)]` → `min-h-layout-main` , `text-[10px]` → `text-xs` . Stories : Default (currentSubView), Loading (Skeleton). Decorator `min-h-layout-page` . Re-export depuis `AdminView.tsx` . |
2026-02-07 02:54:38 +00:00
| ~~`components/views/AuthView.tsx`~~ | ~~77~~ | **Refactorisé 2026-02-05** : module `components/views/auth-view/` avec `types` (AuthViewProps, AuthStep), `useAuthView` (currentStep, show2FA, handleLoginSuccess, useAuth), `AuthViewContent` (LoginForm, RegisterForm, ForgotPasswordForm, TwoFactorVerify, placeholders), `AuthViewSkeleton` . Placeholders `min-h-layout-page-sm` . Stories : Default (LOGIN), Loading (Skeleton), RegisterStep. Decorator `min-h-layout-page` . Re-export depuis `AuthView.tsx` . |
2026-02-07 03:01:30 +00:00
| ~~`components/views/ChatView.tsx`~~ | ~~10~~ | **Refactorisé 2026-02-05** : module `components/views/chat-view/` avec `types` (ChatViewProps), `ChatView` (wrapper ChatInterface), `ChatViewSkeleton` . Layout `h-[calc(100vh-6rem)]` → `min-h-layout-main` . Stories : Default, Loading (Skeleton). Decorator `min-h-layout-page` . Re-export depuis `ChatView.tsx` . |
2026-02-05 13:18:17 +00:00
### Problèmes identifiés
| Criticité | Constat | Détail |
|-----------|--------|--------|
2026-02-05 20:19:58 +00:00
| **Amélioration** | Trop de responsabilités dans un seul fichier | Réduit : **CloudFileBrowser** est désormais un module (FileToolbar, FileTable, FileGrid, etc.) dans `features/studio/components/cloud-file-browser/` . |
2026-02-05 13:18:17 +00:00
| **Amélioration** | Logique métier + UI mélangées | **CommentThread** , **ProfileForm** , **Search** : logique (appels API, état) et rendu (JSX) dans le même composant ; pas de découpage net en hooks + sous-composants. |
| **Perfectionnement** | Réutilisabilité limitée | **GearView** , **ProfileView** : vues “pages” très spécifiques ; extraire des blocs (Header, Stats, List, Filters) permettrait des stories et des tests plus ciblés. |
### Recommandations
2026-02-05 20:19:58 +00:00
- **CloudFileBrowser** : déjà découpé dans `features/studio/components/cloud-file-browser/` (FileToolbar, FileTable, FileGrid, CloudFileBrowserSkeleton, etc.) ; ancien monolithe `components/studio/` supprimé.
2026-02-05 18:21:09 +00:00
- **CommentThread (fait 2026-02-05)** : logique extraite dans `useCommentReplies` , `useCommentActions` ; rendu délégué à `CommentThreadHeader` , `CommentThreadContent` , `CommentThreadActions` , `CommentReplyForm` , `CommentRepliesList` ; `CommentThreadSkeleton` pour l’ état Loading. Stories : Default, WithReplies, DeeplyNested, Edited, EmptyReplies, LoadingReplies, ReplyError. MSW : PUT `/api/v1/comments/:id` ajouté.
2026-02-05 19:31:26 +00:00
- **ProfileForm (fait 2026-02-05)** : module `features/user/components/profile-form/` avec `useProfileForm` , `ProfileCompletionCard` , `ProfileFormSkeleton` , schéma zod dédié. Stories : Default, Loading, Error, ProfileFormSkeleton. Re-export depuis `ProfileForm.tsx` .
- **ProfileView (fait 2026-02-05)** : module `components/views/profile-view/` avec `useProfileViewData` ; sous-composants `ProfileViewTrackCard` , `ProfileViewPlaylistCard` , `ProfileViewSidebar` , `ProfileViewOverview` , `ProfileViewTracksTab` , `ProfileViewPlaylistsTab` , `ProfileViewAboutTab` , `ProfileViewSkeleton` . Stories : Default, Loading, Error, ProfileViewSkeleton. Re-export depuis `ProfileView.tsx` .
2026-02-05 18:46:03 +00:00
- **Search (fait 2026-02-05)** : logique extraite dans `useSearchSuggestions` ; présentiel `SearchInput` , `SearchDropdown` , `SearchSkeleton` ; orchestrateur dans `Search.tsx` . Stories : Default, NoHistory, Loading, Empty, Error. Re-export depuis `components/search/Search` .
2026-02-05 19:07:56 +00:00
- **ChatSidebar (fait 2026-02-05)** : module `features/chat/components/chat-sidebar/` avec `useChatConversations` , `useConversationActions` ; sous-composants `ChatSidebarHeader` , `ChatSidebarEmpty` , `ChatSidebarSkeleton` , `ConversationItem` . Stories : Default, Empty, Error, ChatSidebarSkeleton. Re-export depuis `ChatSidebar.tsx` .
2026-02-05 19:40:12 +00:00
- **GearView (fait 2026-02-05)** : module `components/views/gear-view/` avec `useGearView` (filter, search, viewMode, itemsOverride, isLoading, error), `GearViewToolbar` , `GearViewSkeleton` . Stories : Default, Loading, Empty, Error, GearViewSkeleton. Re-export depuis `GearView.tsx` .
2026-02-05 19:49:46 +00:00
- **LazyComponent (fait 2026-02-05)** : module `components/ui/lazy-component/` avec `LazyErrorFallback` , `LazyErrorBoundary` , `createLazyComponent` , `lazyExports` . Stories : LazyErrorFallback (Default, WithRetry, NoError), LazyComponent (Default, Loading). Layout primitive `min-h-layout-page-sm` pour l’ erreur. Re-export depuis `LazyComponent.tsx` .
2026-02-05 20:03:23 +00:00
- **UploadModal (fait 2026-02-05)** : module `features/upload/components/upload-modal/` avec `useUploadModal` , sous-composants (Dropzone, FileDisplay, Progress, ErrorAlert, MetadataForm). Stories : Default, Open. Re-export depuis `UploadModal.tsx` .
2026-02-05 20:09:32 +00:00
- **file-upload (fait 2026-02-05)** : module `components/ui/file-upload/` avec `useFileUpload` , `FileUploadDropzone` , `FileUploadErrorList` , `FileUploadFileList` . Stories : Default, Empty, Error, Disabled, etc. Point d’ entrée `file-upload/index.ts` .
2026-02-05 20:16:43 +00:00
- **select (fait 2026-02-05)** : module `components/ui/select/` avec `useSelect` , `SelectTrigger` , `SelectDropdownContent` , `SelectOptionItem` . Stories : Default, Empty, Disabled, Grouped, MultiSelect. Point d’ entrée `select/index.ts` .
2026-02-05 20:34:54 +00:00
- **NotificationsPage (fait 2026-02-05)** : module `features/notifications/components/notifications-page/` avec `useNotificationsPage` , Header, Filters, Item, Empty, Error, Skeleton. Stories : Default, Loading, Error, Empty. MSW : GET notifications aligné avec notificationService.
2026-02-05 20:39:51 +00:00
- **SearchPage (fait 2026-02-05)** : module `features/search/components/search-page/` avec `useSearchPage` , Header, Discovery, Empty, Error, Results, Skeleton. Stories : Default, Loading, Empty, Error. MSW : GET /api/v1/search → SearchResults.
2026-02-05 20:45:27 +00:00
- **FileManagerView (fait 2026-02-05)** : module `components/views/file-manager-view/` avec `useFileManagerView` , Header, Toolbar, Table, Grid, Empty, Skeleton. Stories : Default, Loading, Empty.
2026-02-05 20:50:42 +00:00
- **RegisterPage (fait 2026-02-05)** : module `features/auth/components/register-page/` avec `useRegisterPage` , Form, VerificationNotice, Skeleton. Stories : Default, Loading, WithError.
2026-02-05 20:57:59 +00:00
- **MonitoringDashboard (fait 2026-02-05)** : module `components/monitoring/monitoring-dashboard/` avec `useMonitoringDashboard` , Content, Skeleton, état Error avec réessai. Stories : Default, Loading, Error.
2026-02-05 21:04:54 +00:00
- **PlaybackDashboard (fait 2026-02-05)** : module `features/streaming/components/playback-dashboard/` avec `usePlaybackDashboard` , StatsCard, TrendsCard, Charts, DetailedCard, Skeleton. Stories : Default, Loading, Error, Empty. MSW playback dashboard.
2026-02-05 21:09:42 +00:00
- **ShareLinkManager (fait 2026-02-05)** : module `components/share/share-link-manager/` avec `useShareLinkManager` , CreateForm, Item, Empty, Content, Skeleton. Stories : Default, Empty, Loading, Error.
2026-02-05 21:15:27 +00:00
- **date-picker (fait 2026-02-05)** : module `components/ui/date-picker/` avec `useDatePicker` , Trigger, Calendar. Stories : SingleDate, DateRange, Disabled.
2026-02-05 21:21:13 +00:00
- **avatar-upload (fait 2026-02-05)** : module `components/ui/avatar-upload/` avec `useAvatarUpload` , Dropzone, Actions, Skeleton. Stories : Default, WithExistingAvatar, Disabled, Large, Loading.
2026-02-05 21:31:48 +00:00
- **optimized-image (fait 2026-02-05)** : module `components/ui/optimized-image/` avec types, `generateImageSources` , `BlurPlaceholder` , `useImageFormatSupport` , `OptimizedImage` , `OptimizedImageSkeleton` , `useImagePreloader` , `ResponsiveImage` . Stories : Default, WithPlaceholder, ErrorState, Loading.
2026-02-05 21:36:06 +00:00
- **DataList (fait 2026-02-05)** : module `components/ui/data-list/` avec types, `DataListSkeleton` , `DataListEmpty` , `DataListError` , `DataList` . Stories : Default, Loading, Empty, Error, Skeleton.
2026-02-05 21:40:19 +00:00
- **AudioPlayer components/player (fait 2026-02-05)** : module `components/player/audio-player/` avec `useAudioPlayerEffects` , `AudioPlayerTrackInfo` , `AudioPlayerControls` , `AudioPlayerProgress` , `AudioPlayerVolume` , `AudioPlayerSkeleton` . Stories : Default, Skeleton.
2026-02-05 21:46:26 +00:00
- **TrackFilters (fait 2026-02-05)** : module `features/tracks/components/track-filters/` avec `useTrackFilters` , `TrackFiltersHeader` , `TrackFiltersSearch` , `TrackFiltersGrid` , `TrackFiltersClear` , `TrackFiltersSkeleton` . Stories : Default, Collapsible, Loading.
2026-02-05 22:09:51 +00:00
- **TrackSearchFilters (fait 2026-02-05)** : module `features/tracks/components/track-search-filters/` avec `useTrackSearchFilters` , `TrackSearchFiltersBasic` , `TrackSearchFiltersAdvanced` , `TrackSearchFiltersSkeleton` . Stories : Default, Applied, Loading.
2026-02-05 22:19:26 +00:00
- **SessionsPage (fait 2026-02-05)** : module `features/auth/components/sessions-page/` avec `useSessionsPage` , Header, ErrorBanner, RevokeAllButton, SessionItem, Content, Empty, Skeleton. Stories : Default, Loading, Empty, Error. MSW : GET/DELETE auth/sessions.
2026-02-05 22:24:57 +00:00
- **ProjectDetailView (fait 2026-02-05)** : module `components/studio/projects/project-detail-view/` avec `useProjectDetailView` , Header, Tabs, Overview, Files, Settings, Sidebar, Skeleton. Stories : Default, Loading, Empty.
2026-02-05 22:31:25 +00:00
- **PlaybackHeatmap (fait 2026-02-05)** : module `features/streaming/components/playback-heatmap/` avec `usePlaybackHeatmap` , Header, Stats, Grid, Skeleton, Error, Empty. Stories : Default, CustomSegmentSize, Loading, Empty, Error. MSW : GET heatmap.
2026-02-05 22:38:28 +00:00
- **ProductDetailView (fait 2026-02-05)** : module `components/marketplace/product-detail-view/` avec `useProductDetailView` , Header, Gallery, Info, Licenses, Description, Reviews, Similar, Skeleton. Stories : Default, Loading, Empty, WithReviews.
2026-02-05 22:46:20 +00:00
- **CourseLearningView (fait 2026-02-05)** : module `components/education/course-learning-view/` avec `useCourseLearningView` , Header, Player, Tabs, Sidebar, Skeleton. Layout `min-h-layout-main` . Stories : Default, Loading, Empty, Complete.
2026-02-05 22:52:47 +00:00
- **CourseDetailView (fait 2026-02-05)** : module `components/education/course-detail-view/` avec `useCourseDetailView` , Header, Tabs, Sidebar, Skeleton. Stories : Default, Loading, Empty, Enrolled.
2026-02-05 23:00:58 +00:00
- **LibraryManager (fait 2026-02-05)** : module `features/library/components/library-manager/` avec `useLibraryManager` , Header, Toolbar, Error, Empty, Content, Stats, Skeleton. Stories : Default, Loading, Empty, Error. MSW GET /tracks.
2026-02-05 23:07:42 +00:00
- **NotificationMenu (fait 2026-02-05)** : module `components/notifications/notification-menu/` avec `useNotificationMenu` , Trigger, Dropdown, List, Item, Skeleton. Stories : Default, Loading, Empty, Error, Skeleton.
2026-02-05 23:14:41 +00:00
- **PlaylistTrackList (fait 2026-02-05)** : module `features/playlists/components/playlist-track-list/` avec `usePlaylistTrackList` , Empty, SortableItem, Skeleton. Stories : Default, Loading, Empty, Reordering.
2026-02-05 23:22:33 +00:00
- **AddTrackToPlaylistModal (fait 2026-02-05)** : module `features/playlists/components/add-track-to-playlist-modal/` avec `useAddTrackToPlaylistModal` , Search, List, TrackRow, Footer, Skeleton. Stories : Default, Loading.
2026-02-05 23:37:26 +00:00
- **PlaylistBatchActions (fait 2026-02-05)** : module `features/playlists/components/playlist-batch-actions/` avec `usePlaylistBatchActions` , exportUtils, Bar, Buttons, DeleteDialog, Skeleton. Stories : Default, SingleSelection, Loading.
2026-02-05 23:47:47 +00:00
- **PlaylistSearch (fait 2026-02-05)** : module `features/playlists/components/playlist-search/` avec `usePlaylistSearch` , Bar, Filters, Results, Skeleton. Stories : Default, Loading, Empty, Error. MSW playlists/search.
2026-02-05 23:53:10 +00:00
- **CreatePlaylistDialog (fait 2026-02-05)** : module `features/playlists/components/create-playlist-dialog/` avec schema zod, `useCreatePlaylistDialog` , Form, Skeleton. Stories : Default, Loading.
2026-02-05 23:58:07 +00:00
- **SharePlaylistModal (fait 2026-02-05)** : module `features/playlists/components/share-playlist-modal/` avec `useSharePlaylistModal` , Content, Skeleton. Stories : Default, Loading, Error.
2026-02-06 00:04:43 +00:00
- **AddCollaboratorModal (fait 2026-02-05)** : module `features/playlists/components/add-collaborator-modal/` avec `useAddCollaboratorModal` , Form, Skeleton. Stories : Default, Loading, Error (MSW). ErrorDisplay pour validation et mutation avec retry.
2026-02-06 00:12:44 +00:00
- **UploadView (fait 2026-02-05)** : module `components/views/upload-view/` avec `useUploadView` , Stepper, Step1/2/3, Skeleton. Stories : Default, Loading, Empty, Error.
2026-02-06 00:26:01 +00:00
- **TwoFactorSetup (fait 2026-02-05)** : module `components/settings/security/two-factor-setup/` avec `useTwoFactorSetup` , Header, Step1/2/3, Skeleton. Stories : Default, Step1, Step2, Loading, Error (MSW).
2026-02-06 00:35:21 +00:00
- **TrackHistory (fait 2026-02-05)** : module `features/tracks/components/track-history/` avec `useTrackHistory` , Header, Empty, ItemRow, Pagination, Skeleton, trackHistoryUtils. Stories : Default, Loading, Empty, Error (MSW).
2026-02-06 00:45:05 +00:00
- **ProjectsManager (fait 2026-02-05)** : module `components/studio/projects-manager/` avec `useProjectsManager` , Header, FilterBar, Card, AddCard, Empty, Skeleton. Stories : Default, Loading, Empty.
2026-02-06 00:51:46 +00:00
- **CreateProjectModal (fait 2026-02-05)** : module `components/studio/projects/create-project-modal/` avec `useCreateProjectModal` , Header, Form, Footer, Skeleton. Stories : Default, Loading.
2026-02-06 00:57:44 +00:00
- **GoLiveView (fait 2026-02-05)** : module `components/studio/go-live-view/` avec `useGoLiveView` , Header, Preview, StreamInfo, EncoderSetup, QuickInstructions, MicLevel, Skeleton. Stories : Default, Loading.
2026-02-06 01:02:23 +00:00
- **ConnectivityView (fait 2026-02-05)** : module `components/studio/connectivity-view/` avec `useConnectivityView` , WebDAV, Webhooks, Skeleton. Stories : Default, Loading.
2026-02-06 01:07:27 +00:00
- **AIToolsView (fait 2026-02-05)** : module `components/studio/ai-tools-view/` avec `useAIToolsView` , ToolGrid, Workspace, Skeleton, AI_TOOLS. Stories : Default, Loading. Conformité : text-xs, min-h-layout-page-sm ; pas de ToastProvider en story.
2026-02-06 01:11:58 +00:00
- **CloudSettingsView (fait 2026-02-05)** : module `components/studio/cloud-settings-view/` avec `useCloudSettingsView` , Quota, Preferences, Skeleton. Stories : Default, Loading.
2026-02-06 01:18:00 +00:00
- **StudioView (fait 2026-02-05)** : module `components/views/studio-view/` avec `useStudioView` , Header, Sidebar, NavButton, Content, ProjectsSwitch, Skeleton. Stories : Default, Projects, Loading. Conformité : h-[calc(...)] → min-h-layout-main, w-[65%] → w-2/3.
2026-02-05 21:55:11 +00:00
- **PlaylistList (fait 2026-02-05)** : module `features/playlists/components/playlist-list/` avec `usePlaylistList` , `PlaylistListToolbar` , `PlaylistListEmpty` , `PlaylistListError` . Stories : Default, Grid, Empty (MSW), Loading (skeleton).
2026-02-05 22:00:02 +00:00
- **dialog (fait 2026-02-05)** : module `components/ui/dialog/` avec Dialog, Header, Body, Footer, Content, Description, Title, Trigger, DialogSkeleton. Stories : Default, Alert, Composition, Loading.
2026-02-06 01:27:58 +00:00
- **dropdown-menu (fait 2026-02-05)** : module `components/ui/dropdown-menu/` avec types, Trigger, Content, Item, CheckboxItem, RadioItem, Label, Separator, Shortcut, Placeholders. Dropdown base : open/defaultOpen. Re-export depuis `dropdown-menu.tsx` .
2026-02-06 01:33:34 +00:00
- **accordion (fait 2026-02-05)** : module `components/ui/accordion/` avec types, Accordion, AccordionItem, AccordionTrigger, AccordionContent. Stories : Default, Multiple. Re-export depuis `accordion.tsx` .
2026-02-06 09:12:56 +00:00
- **tabs (fait 2026-02-05)** : module `components/ui/tabs/` avec types, Tabs, TabsList, TabsTrigger, TabsContent. Stories : Default. Re-export depuis `tabs.tsx` .
2026-02-06 09:32:46 +00:00
- **tooltip (fait 2026-02-05)** : module `components/ui/tooltip/` avec useTooltip, TooltipContent, Tooltip. Stories : Default, Positions, ManualTrigger. Re-export depuis `tooltip.tsx` .
2026-02-05 22:04:31 +00:00
- **AccountSettings (fait 2026-02-05)** : module `features/settings/components/account-settings/` avec `useAccountSettings` , ErrorBanner, PasswordCard, ExportCard, DeleteCard, AccountSettingsSkeleton. Stories : Default, Loading.
2026-02-05 20:16:43 +00:00
- Les autres composants volumineux restants : appliquer le même principe pour améliorer la testabilité et la maintenabilité.
2026-02-05 13:18:17 +00:00
---
## 4. Fidélité de l’ illusion applicative (StorybookDecorator)
### Ce qui est en place
- **Providers centralisés** : `I18nextProvider` , `ThemeProvider` , `QueryClientProvider` , `ToastProvider` , `AudioProvider` , `AuthProvider` , `MemoryRouter` .
- **Router** : `parameters.router.initialEntries` pour les stories dépendant d’ une route.
- **Thème** : bascule light/dark via globals Storybook (backgrounds).
- **Toasts** : en mode Storybook, toasts loggés en console (pas d’ affichage intrusif).
### Problèmes identifiés
| Criticité | Constat | Détail |
|-----------|--------|--------|
| **Amélioration** | Pas de gestion des transitions | Aucun wrapper `prefers-reduced-motion` ni fourniture de context pour désactiver les animations en Storybook. Les transitions CSS (`--duration-*`) sont appliquées telles quelles ; pas de mode “réduit” pour les tests ou l’ accessibilité. |
| **Amélioration** | Feedback tactile non simulé | Pas de décorateur ou paramètre pour simuler états tactiles (active, press) ou pointer (hover) de façon déterministe. Utile pour valider les états “pressed” / “hover” de boutons et cartes. |
| **Perfectionnement** | Couleurs de fond en dur | Le décorateur utilise `#0a0a0a` et `#ffffff` en inline style au lieu des tokens (`var(--background)`). En cas d’ évolution du thème, le conteneur Storybook peut diverger de l’ app. |
| **Perfectionnement** | Pas de “viewport” par défaut | Des viewports custom (mobile, tablet, desktop) existent ; le décorateur ne force pas de viewport par story. Pour un rendu type “app”, un conteneur largeur max (ex. 1440px) pourrait être optionnel. |
### Recommandations
- Ajouter un **paramètre** (ex. `parameters.motion: 'reduce'` ) et un wrapper qui applique `prefers-reduced-motion: reduce` (media query ou class) pour tester le comportement sans animations.
- Utiliser **les tokens** pour le fond du conteneur : `background: 'var(--background)'` (et s’ assurer que les variables sont bien appliquées dans l’ iframe).
- Optionnel : décorateur ou paramètre pour forcer un **état “interaction”** (hover/active) sur le premier élément focusable, pour valider le focus visible et les états actifs dans les stories.
---
## 5. Accessibilité (a11y)
### Ce qui est en place
- **ARIA / rôles** : utilisés dans une soixantaine de composants (table, select, modal, tabs, pagination, breadcrumbs, tooltip, checkbox, progress, alert, etc.).
- **Contrastes** : palette KŌDŌ en oklch avec séparation sémantique (primary, destructive, muted, etc.) ; fonds et textes prévus pour être lisibles.
- **Addon a11y** : présent dans Storybook ; config actuelle `a11y: { test: 'todo' }` .
- **Focus visible** : `button` , `input` , `checkbox` , `select` , `tabs` ont des styles `focus-visible:ring` ou équivalent.
### Problèmes identifiés
| Criticité | Constat | Détail |
|-----------|--------|--------|
| **Bloquant** | Tests a11y non actifs | Tant que `test: 'todo'` , aucune violation a11y ne fait échouer l’ audit ni le build. Risque de régressions (contraste, labels, rôles). |
| **Amélioration** | Contraste à vérifier sur cas réels | Les combinaisons `muted-foreground` sur `muted` , ou textes sur “glass” / dégradés, n’ ont pas été vérifiées automatiquement. Un audit manuel ou des tests a11y ciblés (contrast, label) sont recommandés. |
| **Amélioration** | Zones cliquables non boutons | Cartes ou lignes entières cliquables sans `role="button"` ni `tabIndex={0}` ni gestion clavier (Enter/Space) — à vérifier dans les composants “card” et “list”. |
| **Perfectionnement** | Annonces live (toasts, chargement) | Pas de revue systématique des `aria-live` , `aria-busy` , `aria-atomic` pour les toasts et états de chargement. |
### Recommandations
- **Activer les tests a11y** dans Storybook : définir `a11y: { runOnly: { type: 'tag', values: ['wcag2a', 'wcag2aa'] } }` (ou équivalent) et intégrer le résultat à l’ audit (ou au moins au build Storybook) pour faire échouer en cas de violations.
- Vérifier les **cartes et listes cliquables** : soit `<button>` ou `div` avec `role="button"` , `tabIndex={0}` , et gestion `onKeyDown` (Enter/Space).
- Planifier un **audit contraste** (manuel ou outil) sur les écrans clés (login, player, sidebar, modales) et documenter les ratios pour les combinaisons utilisées.
---
## 6. Tableau de synthèse par criticité
| Criticité | Thème | Action prioritaire |
|-----------|--------|--------------------|
| **Bloquant** | a11y | Activer les tests a11y dans Storybook (retirer `test: 'todo'` , définir des règles WCAG et les faire échouer le job si besoin). |
| **Amélioration** | Design system | Réduire les valeurs arbitraires (h-[…], w-[…]) en les remplaçant par des tokens ou des utilitaires Tailwind cohérents. |
| **Amélioration** | États d’ interface | Compléter les stories : Loading réaliste (Button), Empty/Error/Loading pour listes et cartes, états Disabled et si possible Hover/Active. |
| **Amélioration** | Composants dieux | Découper CloudFileBrowser, CommentThread, ProfileForm/ProfileView en sous-composants et hooks testables. |
| **Amélioration** | Illusion applicative | Utiliser les tokens pour le fond du décorateur ; ajouter support reduced-motion et optionnellement états hover/active. |
| **Amélioration** | a11y | Vérifier cartes/listes cliquables (rôle, clavier) ; audit contraste sur écrans clés. |
| **Perfectionnement** | Design system | Scale d’ espacement/hauteurs documentée ; linter pour limiter les valeurs arbitraires. |
| **Perfectionnement** | États d’ interface | Stories Hover/Active explicites ; revue focus visible sur tous les contrôles. |
| **Perfectionnement** | Composants | Extraire blocs réutilisables des vues “page” (GearView, ProfileView, Search). |
| **Perfectionnement** | a11y | Revue `aria-live` / `aria-busy` pour toasts et chargement. |
---
## 7. Prochaines étapes suggérées
1. **Court terme** : Activer a11y dans Storybook et corriger les violations bloquantes ; ajouter les stories Empty/Error (et Loading si pertinent) aux composants listes/cartes les plus utilisés.
2. **Moyen terme** : Découper 2– 3 composants “dieux” (ex. CloudFileBrowser, CommentThread) et aligner les nouvelles stories sur les tokens (réduction des valeurs arbitraires).
3. **Long terme** : Documenter une grille de hauteurs/largeurs et une checklist “états d’ interface” pour toute nouvelle story ; intégrer reduced-motion et feedback tactile dans le décorateur.
---
*Rapport généré dans le cadre de l’ audit frontend Veza — Storybook stabilisé, contrat dans `docs/STORYBOOK_CONTRACT.md` .*