- Rewrite index.css with complete SUMI token system (dark + light themes) - All --sumi-* variables: backgrounds, surfaces, borders, text, pigments, spacing, radius, shadows, glass, scrollbar, motion, z-index, layout - shadcn/Radix semantic mapping (--background, --foreground, etc.) - Tailwind @theme mapping with new fonts (Inter, Space Grotesk, JetBrains Mono) - SUMI keyframe animations (sumi-fade-in, sumi-slide-up, sumi-scale-in, etc.) - Delete 11 redundant CSS files (design-system.css, design-tokens.css, button.css, card.css, input.css, badge-avatar.css, header.css, fix-input-focus.css, fix-login-form.css, visual-enhancements.css, premium-utilities.css) - Update main.tsx: single CSS import (index.css only) - Update ThemeProvider: data-theme attribute instead of .dark class toggle - Update index.html FOUC script: data-theme attribute Co-authored-by: Cursor <cursoragent@cursor.com>
11 KiB
11 KiB
PHASE C — CARTOGRAPHIE DES COMPOSANTS
Total composants .tsx : 1 450 fichiers Total .ts : 620 fichiers Exclus : .test.tsx, .stories.tsx, types, configs
Composants UI primitifs (components/ui/)
src/components/ui/
├── button.tsx [149L] [dumb] [~200x imports] [props: 6+ButtonHTMLAttrs]
├── card.tsx [190L] [dumb] [~200x imports] [props: 3+HTMLAttrs] [7 sub-components]
├── skeleton.tsx [94L] [dumb] [~200x imports] [props: 3]
├── Toast.tsx [112L] [dumb] [~200x imports] [props: 4]
├── input.tsx [69L] [dumb] [~100x imports] [props: 3+InputHTMLAttrs]
├── modal.tsx [151L] [dumb] [~100x imports] [props: 8]
├── badge.tsx [225L] [dumb] [~30x imports] [props: 8]
├── avatar.tsx [306L] [dumb] [~30x imports] [props: 7] ⚠️ > 300L
├── table.tsx [306L] [dumb] [~30x imports] [props: 3+HTMLAttrs] ⚠️ > 300L
├── checkbox.tsx [130L] [dumb] [~50x imports] [props: 2+InputHTMLAttrs]
├── label.tsx [51L] [dumb] [~50x imports] [props: LabelHTMLAttrs]
├── FormField.tsx [218L] [dumb] [~50x imports] [props: 5]
├── textarea.tsx [105L] [dumb] [~30x imports] [props: 2+TextareaHTMLAttrs]
├── switch.tsx [103L] [dumb] [~20x imports] [props: 2+InputHTMLAttrs]
├── radio-group.tsx [229L] [dumb] [~10x imports] [props: 3]
├── slider.tsx [171L] [dumb] [~5x imports] [props: 7]
├── progress.tsx [209L] [dumb] [~10x imports] [props: 7]
├── alert.tsx [186L] [dumb] [~20x imports] [props: 3]
├── Spinner.tsx [109L] [dumb] [~30x imports] [props: 3]
├── loading-spinner.tsx [93L] [dumb] [~30x imports] [props: 2] ⚠️ Duplique Spinner
├── LoadingState.tsx [215L] [dumb] [~20x imports] [props: 6]
├── ErrorDisplay.tsx [247L] [dumb] [~10x imports] [props: 12]
├── ErrorBoundary.tsx [78L] [smart] [~5x imports] [props: 3]
├── empty-state.tsx [238L] [dumb] [~10x imports] [props: 6]
├── FAB.tsx [115L] [dumb] [~5x imports] [props: 5]
├── ImageCropper.tsx [212L] [smart] [~5x imports] [props: 5]
├── ImageViewerModal.tsx [231L] [dumb] [~5x imports] [props: 9]
├── WaveformVisualizer.tsx [166L] [smart] [~5x imports] [props: 7]
├── AstralBackground.tsx [142L] [smart] [~2x imports] [props: 0]
├── NavigationProgress.tsx [52L] [smart] [~1x imports] [props: 0]
├── ComingSoon.tsx [15L] [dumb] [~5x imports] [props: 1]
├── AnimatedNumber.tsx [17L] [dumb] [~5x imports] [props: 3]
├── ContentFadeIn.tsx [34L] [dumb] [~5x imports] [props: 2]
├── KeyboardShortcutsPanel.tsx [152L] [smart] [~1x imports] [props: 2]
├── Sidebar.tsx [218L] [dumb] [~10x imports] [props: 9]
├── DataList.tsx [42L] [dumb] [~10x imports] [props: 6] (generic)
├── scroll-area.tsx [57L] [dumb] [~20x imports] [props: HTMLAttrs]
├── dropdown.tsx [216L] [smart] [interne] [props: 6]
├── floating-input.tsx [95L] [dumb] [~5x imports] [props: 4+InputHTMLAttrs]
├── confirmation-dialog.tsx [166L] [dumb] [~20x imports] [props: 9]
├── button-loading.tsx [101L] [dumb] [~10x imports] [props: 2] ⚠️ Duplique Button.loading
├── focus-trap.tsx [127L] [smart] [interne] [props: 3]
├── dialog/ [~350L total] [dumb] [~100x imports] [9 sub-components]
├── dropdown-menu/ [~300L total] [dumb] [~30x imports] [11 sub-components]
├── tabs/ [~200L total] [dumb] [~20x imports] [4 sub-components]
├── tooltip/ [~200L total] [dumb] [~15x imports] [3 sub-components]
├── select/ [~250L total] [dumb] [~20x imports] [4 sub-components]
├── accordion/ [~200L total] [dumb] [~5x imports] [4 sub-components]
├── hover-card/ [~350L total] [smart] [~10x imports] [3 sub-components]
├── context-menu/ [359L] [smart] [~5x imports] [props: 3] 🔴 > 300L
├── date-picker/ [~250L total] [smart] [~5x imports] [3 sub-components]
├── file-upload/ [~300L total] [smart] [~10x imports] [5 sub-components]
├── avatar-upload/ [~250L total] [smart] [~10x imports] [5 sub-components]
├── optimized-image/ [~300L total] [smart] [~20x imports] [3 sub-components]
├── virtualized-list/ [~300L total] [smart] [~5x imports] [3 sub-components]
├── data-list/ [~200L total] [dumb] [~10x imports] [4 sub-components]
├── lazy-component/ [~250L total] [smart] [routes] [3 sub-components]
├── content-transition/ [~50L total] [dumb] [~5x imports] [1 component]
└── feature-highlight/ [~100L total] [dumb] [~5x imports] [1 component]
Layout (components/layout/)
src/components/layout/
├── Layout.tsx [58L] [dumb] [~1x] [props: 1]
├── DashboardLayout.tsx [61L] [dumb] [~1x] [props: 1]
├── Sidebar.tsx [295L] [dumb] [~2x] [props: 1]
├── Header.tsx [172L] [hybrid] [~2x] [props: 0] ⚠️ mélange auth/theme
├── Navbar.tsx [~100L] [dumb] [~1x] [props: ~3]
├── MobileBottomNav.tsx [~80L] [dumb] [~1x] [props: ~2]
├── PageTransition.tsx [~40L] [dumb] [~1x] [props: 1]
└── AudioPlayer.tsx [~100L] [smart] [~1x] [props: ~3]
Feature modules — Structure type
src/features/
├── auth/
│ ├── components/ [RegisterForm, LoginForm, AuthInput, OAuthButton, ...]
│ ├── hooks/ [useLogin, useRegister, ...]
│ ├── pages/ [LoginPage, RegisterPage, ForgotPasswordPage, ...]
│ ├── services/ [authService, emailVerificationService]
│ ├── store/ [authStore (Zustand)]
│ └── __tests__/ [integration tests]
├── player/
│ ├── components/ [GlobalPlayer, PlayerControls, PlayerBar, ...]
│ ├── hooks/ [usePlayer, useStreamSync, ...]
│ ├── services/ [playerService, syncClient]
│ └── store/ [playerStore (Zustand)]
├── tracks/
│ ├── api/ [trackApi (848L)]
│ ├── components/ [TrackList, TrackCard, TrackGrid, TrackSearch, ...]
│ ├── hooks/ [useTrackList, useInfiniteScroll, ...]
│ ├── pages/ [track-detail-page/ (décomposé)]
│ ├── services/ [trackService, commentService, uploadService, ...]
│ ├── types/ [types locaux]
│ └── __tests__/ [integration tests]
├── playlists/
│ ├── components/ [PlaylistHeader, PlaylistList, PlaylistSearch, ...]
│ ├── hooks/ [usePlaylist (631L ⚠️), ...]
│ ├── pages/ [playlist-detail-page/ (décomposé)]
│ ├── services/ [playlistService]
│ └── __tests__/ [integration tests]
├── chat/
│ ├── components/ [ChatMessages, ChatInput, VirtualizedChat, ...]
│ ├── pages/ [ChatPage]
│ ├── services/ [conversationService]
│ └── store/ [chatStore (Zustand)]
├── streaming/
│ ├── components/ [PlaybackDashboard, PlaybackHeatmap, BitrateSelector, ...]
│ ├── hooks/ [usePlaybackRealtime (496L ⚠️), usePlaybackAnalytics, ...]
│ └── services/ [hlsService, bitrateService, playbackAnalyticsService]
├── dashboard/
│ ├── hooks/ [useDashboard]
│ ├── pages/ [DashboardPage (329L ⚠️)]
│ └── services/ [dashboardService]
├── search/
│ ├── components/ [search/, search-page/]
│ ├── pages/ [SearchPage]
│ ├── services/ [searchService, unifiedSearchService]
│ └── utils/ [search utils]
├── profile/
│ ├── components/ [ProfileActions, ...]
│ ├── pages/ [user-profile-page/ (décomposé)]
│ ├── services/ [profileService, avatarService]
│ └── schemas/ [profile schemas]
├── settings/
│ ├── components/ [account-settings/]
│ ├── pages/ [SettingsPage]
│ ├── services/ [settingsService]
│ └── schemas/ [settings schemas]
├── notifications/
│ ├── components/ [notifications-page/]
│ └── services/ [notificationService]
├── upload/
│ └── components/ [upload-modal/]
├── admin/
│ └── api/ [auditService]
├── roles/
│ ├── components/ [RolesPage, ...]
│ ├── services/ [roleService]
│ └── types/ [role types]
├── sessions/
│ └── api/ [sessionsApi]
├── webhooks/
│ └── api/ [webhookApi]
├── stream/
│ └── pages/ [StreamPage]
├── studio/
│ └── components/ [cloud-file-browser/]
├── user/
│ └── components/ [profile/, profile-form/]
└── library/ (or inventory/)
├── hooks/ [useLibraryItems, useMyTracks]
└── pages/ [library-page/]
Tests associés — Couverture
| Module | Tests unitaires | Tests intégration | Stories | Verdict |
|---|---|---|---|---|
components/ui/ |
✅ 20+ .test.tsx | — | ✅ 30+ .stories.tsx | Bon |
features/auth/ |
✅ LoginPage.test, RegisterPage.test | ✅ auth.integration.test | ✅ AuthView.stories | Bon |
features/tracks/ |
✅ TrackUpload.test, TrackGrid.test | ✅ trackUpload.integration | ✅ Multiple stories | Bon |
features/playlists/ |
✅ Multiple tests | ✅ 2 integration tests | ✅ Multiple stories | Bon |
features/player/ |
✅ playerStore.test | — | ✅ PlayerBar stories | Partiel |
features/streaming/ |
✅ Multiple tests | — | — | Partiel |
features/chat/ |
— | — | ✅ ChatView.stories | ⚠️ Faible |
features/search/ |
— | — | — | 🔴 Absent |
features/dashboard/ |
— | — | — | 🔴 Absent |
components/layout/ |
✅ DashboardLayout.test | — | ✅ Multiple stories | Partiel |
Statistiques globales
| Métrique | Valeur |
|---|---|
| Total composants UI primitifs | 60+ |
| Composants > 300 lignes | 3 (avatar, table, context-menu) |
| Composants bien typés (props interface) | 97% |
| Feature modules structurés | 20 |
| Feature modules avec tests | ~60% |
| Feature modules avec stories | ~50% |
| Hooks custom | 50+ |
| Stores Zustand | 7 |
| Contextes React | 4 |