senke
823a0fe1ee
style(player): elevate player components to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 15:33:31 +01:00
senke
e8864fdb25
style(playlists,ui): elevate PlaylistListToolbar, DataList, Select to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 15:26:55 +01:00
senke
7b545f34d1
style(layout): elevate Header, Navbar, AudioPlayer, Sidebar to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 15:25:44 +01:00
senke
cdc9890257
style(studio): elevate CloudFileBrowser to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 15:20:44 +01:00
senke
8cf22aa90c
style(chat): elevate ChatSidebar and related stories to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 15:18:31 +01:00
senke
a69f9d1c89
style: fix leftover kodo in ProfileView, FileTableRow.stories, FocusTrap.stories
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 15:17:47 +01:00
senke
e293cc9366
style(stories): replace kodo decorators with design tokens in all story files
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 15:10:32 +01:00
senke
0218035f53
style(settings,views): elevate AccountSettings and ProfileView to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 15:09:53 +01:00
senke
8a3da49fbd
style(ui): elevate Dialog to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 15:08:52 +01:00
senke
aa81603276
style: fix leftover kodo tokens in ProjectDetailView, ProductDetailView, CourseDetailView, UploadViewStepper
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 15:08:19 +01:00
senke
3446af4b31
style(studio): elevate ProjectDetailView to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 15:01:03 +01:00
senke
0da580ef6d
style(streaming): elevate PlaybackHeatmap to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 15:01:00 +01:00
senke
ca856d807a
style(marketplace): elevate ProductDetailView to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:58:26 +01:00
senke
cd719fb960
style(education): elevate CourseDetailView and CourseLearningView to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:57:13 +01:00
senke
945dc8d30c
style(notifications): elevate NotificationMenu story to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:57:11 +01:00
senke
d600e3858c
style(playlists): elevate playlist batch/track-list to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:54:46 +01:00
senke
9387af64d4
style(views): elevate UploadView to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:54:19 +01:00
senke
d5f1fdaa90
style(studio): fix ConnectivityViewWebhooks leftover kodo tokens
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:54:17 +01:00
senke
95d261b2da
style(settings): elevate TwoFactorSetup to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:42:45 +01:00
senke
73cc80b020
style(studio): elevate ProjectsManager to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:41:25 +01:00
senke
85dc9a49d7
style(studio): elevate CreateProjectModal to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:40:07 +01:00
senke
007eba6157
style(studio): elevate GoLiveView to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:39:24 +01:00
senke
5159b9f34c
style(studio): elevate ConnectivityView to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:38:15 +01:00
senke
e96c3f5ceb
style(settings,studio): remove remaining kodo in EditProfileIdentityCard and AIToolsViewSkeleton
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:37:35 +01:00
senke
91b4f50ed1
chore(storybook): exclude sb-common-assets from audit to reach 0 app errors
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:36:49 +01:00
senke
64061aff64
style(studio): elevate AIToolsView to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:25:23 +01:00
senke
9a58d20198
style(studio): elevate CloudSettingsView to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:25:20 +01:00
senke
6b762173c8
style(views): elevate StudioView to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:23:54 +01:00
senke
c25b0e957f
style(ui): elevate Dropdown, DropdownMenu, Tooltip to SaaS Premium; update test
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:23:04 +01:00
senke
688a4fe67d
style(ui): elevate Tabs and Accordion to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:17:49 +01:00
senke
5ac6931999
style(settings): elevate EditProfile to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:17:10 +01:00
senke
a51f67a843
style(social): elevate Profile + GroupDetailView to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:15:35 +01:00
senke
98eab26fa6
style(player): remove remaining kodo in AudioPlayerFull
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:14:17 +01:00
senke
3dc15ed2d8
style(discover): remove remaining kodo in DiscoverView Trending, Genres, types
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:13:58 +01:00
senke
92faee36e6
fix(settings): AccountSettingsPreferencesCard syntax and remaining kodo
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:12:39 +01:00
senke
33ba8d0612
style(ui): elevate OptimizedImage to SaaS Premium and update test
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:05:38 +01:00
senke
58f5f2a306
style(discover): elevate DiscoverView to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:05:04 +01:00
senke
d169d71cd5
style(player): elevate AudioPlayer to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:04:13 +01:00
senke
2452ff3239
style(file-details): elevate FileDetailsView to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:03:36 +01:00
senke
dda00ad565
style(seller): elevate CreateProductView to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:03:00 +01:00
senke
95b5773477
style(settings): elevate AccountSettings cards to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:02:15 +01:00
senke
900151efc7
style(admin): elevate AdminDashboardView stories to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:01:29 +01:00
senke
f66dd3d638
style(checkout): elevate CheckoutView BillingCard and Header to SaaS Premium
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:01:11 +01:00
senke
f775c00a3b
fix(views): remove remaining kodo in Purchases/Cart/Live/Marketplace/Social
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 14:00:55 +01:00
senke
0eb5260c9b
style(views): elevate CheckoutView to SaaS Premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:46:39 +01:00
senke
ac48d83c99
style(views): elevate LiveView to SaaS Premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:45:38 +01:00
senke
cb3abd31e8
style(views): elevate AnalyticsView to SaaS Premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:44:52 +01:00
senke
477b9c0fdf
style(views): elevate MarketplaceView to SaaS Premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:44:12 +01:00
senke
871be67446
style(views): elevate SocialView to SaaS Premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:43:31 +01:00
senke
1131390437
style(views): elevate PurchasesView to SaaS Premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:42:37 +01:00
senke
b8fb871465
style(views): elevate CartView to SaaS Premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:41:56 +01:00
senke
6fadfb722c
style(views): elevate SettingsView to SaaS Premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:41:19 +01:00
senke
18c8feda19
style(views): elevate EducationView to SaaS Premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:40:54 +01:00
senke
972372259f
style(views): elevate NotificationsView to SaaS Premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:40:29 +01:00
senke
073779116f
style(views): elevate AdminView to SaaS Premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:40:12 +01:00
senke
3ddf813275
style(views): elevate AuthView to SaaS Premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:39:51 +01:00
senke
677163b11f
style(views): elevate ChatView to SaaS Premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:39:38 +01:00
senke
4dbab85804
style(library): elevate Library to SaaS Premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:39:18 +01:00
senke
6e9bacff54
style(ui): elevate Button to SaaS Premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:38:52 +01:00
senke
ba9ccfb30b
style(tracks): align story decorators with KŌDŌ tokens
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:17:00 +01:00
senke
798dbc49bc
style(track-detail-page): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:16:07 +01:00
senke
f30aea1962
style(TrackCard): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:14:35 +01:00
senke
aeec29caa1
style(TrackListRow): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:13:34 +01:00
senke
6a8ef31582
style(track-search): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:12:01 +01:00
senke
d5418cdb7b
style(TrackListContainer): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:11:47 +01:00
senke
11836f55f3
style(UploadQuota): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:10:05 +01:00
senke
2e04a3a1da
style(track-grid): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:08:39 +01:00
senke
8e640400a1
style(TrackStatsDisplay): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:07:10 +01:00
senke
d444fb3896
style(TrackSort): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:05:27 +01:00
senke
5b8c8a420e
style(ShareDialog): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:04:19 +01:00
senke
1a81e76e26
style(LikeButton): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:03:10 +01:00
senke
6832aeed39
style(TrackListSelectionActions): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 09:01:35 +01:00
senke
0e9bcb8e99
style(ViewToggle): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 08:59:38 +01:00
senke
c18771df09
style(track-search-filters): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 08:58:24 +01:00
senke
91bb04b956
style(track-list-pagination): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 08:56:06 +01:00
senke
c70046a7f8
style(track-filters): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 08:54:49 +01:00
senke
6d982d1ba0
style(comment-thread): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 08:52:35 +01:00
senke
94487a9b4f
style(track-history): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 08:49:21 +01:00
senke
02f5d18879
style(tracks): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 08:35:52 +01:00
senke
a41e7ce521
style(comments): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 08:13:59 +01:00
senke
a5889cb0ac
style(ui): elevate visual fidelity to premium standards
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 08:03:28 +01:00
senke
b10821717d
feat(tracks): use TrackListSkeleton for loading state and add Error story
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 07:40:16 +01:00
senke
3c5fb9cc0e
test(comments): add comprehensive stories and MSW mocks
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 07:33:05 +01:00
senke
a65e4b7ab2
feat(comments): add high-fidelity skeletons and Framer Motion transitions
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 07:32:49 +01:00
senke
1006cc7e3a
refactor(comments): modularize CommentSection with atomic sub-components
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 07:32:37 +01:00
senke
06c963be46
refactor(tracks): split TrackDetailPage into module with Hero, CoverAndActions, Info, Tabs, Skeleton, NotFound
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 06:57:32 +01:00
senke
11ec40b692
refactor(playlists): split PlaylistDetailPage into module with Hero, CoverAndInfo, ActionsBar, Tabs, Skeleton, NotFound
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 06:46:30 +01:00
senke
1ebfacd12c
refactor(playlists): split PlaylistActions into module (buttons, edit dialog, skeleton)
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 06:09:51 +01:00
senke
efbf54c526
refactor(web): split EquipmentDetailView into module (nav, gallery, specs, header, warranty, docs, service, skeleton)
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 05:46:16 +01:00
senke
fa2563558c
refactor(web): split TrackListPagination into module (info, nav, utils, skeleton)
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 05:03:53 +01:00
senke
6dd7a312aa
refactor(web): split PlaylistAnalytics into module (stat cards, main/advanced, error, skeleton)
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 04:53:54 +01:00
senke
089677321b
refactor(web): split VirtualizedChatMessages into module (item, empty, loading, scroll btn, skeleton)
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 04:44:26 +01:00
senke
3834583492
refactor(web): split LibraryPage into module (toolbar, empty, grid, list, skeleton)
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 04:31:06 +01:00
senke
e243e2c41e
refactor(web): split router into module (PublicRoute, ProtectedLayoutRoute, routeConfig)
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 04:16:37 +01:00
senke
43d0d7e129
refactor(web): split ChatView into chat-view module
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 03:59:32 +01:00
senke
bdda26ad08
refactor(web): split AuthView into auth-view module
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 03:53:59 +01:00
senke
c92c8d02a4
refactor(web): split AdminView into admin-view module
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 22:31:24 +01:00
senke
bb370397d2
refactor(web): split NotificationsView into notifications-view module
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 22:22:47 +01:00
senke
6833df9dc5
refactor(web): split EducationView into education-view module
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 22:11:13 +01:00
senke
b736de5dc7
refactor(web): split SettingsView into settings-view module
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 21:59:42 +01:00
senke
753191d88b
refactor(web): split CartView into cart-view module
...
- types: CartViewProps, CartDiscount
- useCartView: useCartStore, showPromo, discount, tax/finalTotal, handleApplyPromo
- CartViewEmpty, CartViewHeader, CartViewSummary, CartViewSecure, CartViewSkeleton
- PromoCodeModal in orchestrator; min-h-[60vh] -> min-h-layout-page-sm
- Stories: Default, Empty, Loading (Skeleton); decorator min-h-layout-page
- Re-export from CartView.tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 21:49:55 +01:00
senke
d7c462c8cc
refactor(web): split PurchasesView into purchases-view module
...
- types: PurchasesViewProps, Purchase
- usePurchasesView: commerceService.getPurchases, search, refund, download
- PurchasesViewHeader, PurchasesViewItem, PurchasesViewList, PurchasesViewSkeleton
- RefundRequestModal in orchestrator; Loading renders Skeleton
- Stories: Default, Empty (initialPurchases []), Loading (Skeleton)
- Re-export from PurchasesView.tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 21:42:35 +01:00
senke
0504810f29
refactor(web): split SocialView into social-view module
...
- types: SocialViewProps, SocialTabKey
- useSocialView: feedTracks (trackService.list), activeTab, playTrack
- SocialViewSidebar, SocialViewFeed, SocialViewFeedItem, SocialViewTrending, SocialViewSkeleton
- Loading renders Skeleton; decorator min-h-layout-page
- Re-export from SocialView.tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 21:34:18 +01:00
senke
c2c98ff535
refactor(web): split MarketplaceView into marketplace-view module
...
- types: MarketplaceViewProps, MarketplaceCategory; useMarketplaceView with marketplaceService/fallback
- MarketplaceViewHeader, MarketplaceViewCategories, MarketplaceViewSidebar, MarketplaceViewGrid, MarketplaceViewSkeleton
- allProducts for ProductDetailView similarProducts; min-h-screen -> min-h-layout-page
- Stories: Default, Loading (Skeleton); decorator min-h-layout-page
- Re-export from MarketplaceView.tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 18:42:16 +01:00
senke
6bdb66743e
refactor(web): split AnalyticsView into analytics-view module
...
- types: AnalyticsViewProps, DateRangeKey, GlobalStats, TopTrackRow, TrafficSource, DeviceStats, ChartHoverData
- useAnalyticsView: dateRange, stats, topTracks, trafficSources, deviceStats, loading, hoveredData, handleExport
- AnalyticsViewHeader, AnalyticsViewKpiGrid, AnalyticsViewChart, AnalyticsViewOrigins, AnalyticsViewPlatforms, AnalyticsViewTopTracks, AnalyticsViewSkeleton
- Data via analyticsService; loading renders Skeleton
- text-[10px] -> text-xs, tracking-[0.2em] -> tracking-wide
- Stories: Default, Loading (Skeleton); decorator min-h-layout-page
- Re-export from AnalyticsView.tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 18:33:42 +01:00
senke
937ec45660
refactor(web): split LiveView into live-view module
...
- types.ts: LiveViewProps, LiveViewChatMessage; mockData: FEATURED_STREAM, CHAT_MESSAGES
- useLiveView: stream, chatMessages, msgInput, handleSend, addToast
- 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-layout-page
- Re-export from LiveView.tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 18:15:41 +01:00
senke
e172d67292
refactor(web): split CheckoutView into checkout-view module
...
- types.ts: CheckoutViewProps, CheckoutFormState, INITIAL_CHECKOUT_FORM
- useCheckoutView: form state, cart/tax, handlePurchase, onComplete
- CheckoutViewHeader, CheckoutViewBillingCard, CheckoutViewPaymentCard,
CheckoutViewOrderSummary, CheckoutViewSkeleton
- CheckoutView orchestrator; re-export from CheckoutView.tsx
- Stories: Loading (Skeleton), Default, Processing, Success
- Decorator min-h-screen -> min-h-layout-page
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 18:04:13 +01:00
senke
fb3e5ceb5b
refactor(web): split AdminDashboardView into admin-dashboard-view module
...
- types: DashboardStats, UploadItem, AuditLogItem, StatCardProps, Report
- useAdminDashboardView: fetchData, handleAction, triggerProtocol
- Header, StatCard, TrafficCard, ProtocolsCard, NodeHealthCard, Tabs
- AdminDashboardSkeleton for Loading state
- max-w-layout-content, text-xs, gap-0.5 (no arbitrary values)
- Stories: Default, Loading (Skeleton). Decorator min-h-layout-page
- Re-export from AdminDashboardView.tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 17:54:02 +01:00
senke
4ef6ed9c3b
refactor(web): split AccountSettings (components/settings/account) into module
...
- account-settings/types: AccountSettingsUserMock, AccountSettingsToggles
- useAccountSettingsPage: view, modals, user, toggles, theme, setThemeOption
- IdentityCard, PreferencesCard, NotificationsCard, PrivacyCard, DangerCard
- AccountSettingsSkeleton for Loading state
- Privacy labels text-xs (no text-[10px])
- Theme selection: isOptionSelected(theme, variant)
- Stories: Default, Loading (Skeleton). Decorator min-h-layout-page
- Re-export from AccountSettings.tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 17:42:57 +01:00
senke
98f90c9863
refactor(web): split ChatInterface into chat-interface module
...
- types.ts: ChatInterfaceProps
- useChatInterface: state, wsService, loadMessages, loadChatStats, handleSendMessage, formatTimestamp
- ChatInterfaceHeader, ChatInterfaceMessages, ChatInterfaceInput
- ChatInterfaceSkeleton for Loading state
- Stories: Default, ProductionRoom, Loading (Skeleton)
- Decorator h-[600px] -> min-h-layout-page
- Re-export from ChatInterface.tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 14:24:41 +01:00
senke
a164ffa214
refactor(web): split CreateProductView into create-product-view module
...
- types.ts: LicenseConfig
- useCreateProductView: form state, updateLicense, handlePublish, handleSaveDraft
- CreateProductViewHeader, CoverCard, FilesCard, DetailsCard, PricingCard
- CreateProductViewSkeleton for Loading state
- Textarea min-h-24 (no arbitrary value)
- MSW: POST marketplace/products for Storybook
- Stories: Default, Loading (Skeleton)
- Re-export from CreateProductView.tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 14:16:38 +01:00
senke
162a3bf0a7
refactor(web): split FileDetailsView into file-details-view module
...
- types.ts: FileDetailsViewProps, ActivityItem, VersionItem
- mockData.ts: MOCK_ACTIVITY, MOCK_VERSIONS, getMockFile
- useFileDetailsView.ts: hook returning file, activity, versions
- FileDetailsViewHeader, Preview, Metadata, Activity, Versions, Storage
- FileDetailsViewSkeleton for Loading state
- Layout: min-h-layout-page-sm, badge text-xs
- Imports use @/ for Storybook resolution
- Stories: Default, Loading (Skeleton)
- Re-export from FileDetailsView.tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 14:05:44 +01:00
senke
9c58ff7818
refactor(web): split VirtualizedList into virtualized-list module
...
- virtualized-list/types.ts: VirtualizedListProps
- virtualized-list/useInfiniteScroll.ts: useInfiniteScroll hook
- virtualized-list/useScrollPosition.ts: useScrollPosition hook
- virtualized-list/VirtualizedList.tsx: main component
- Re-export from virtualized-list.tsx via ./virtualized-list/index
- Test mock extended with getTotalSize, measureElement, key on virtual items
- 4 tests pass
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 13:55:06 +01:00
senke
9d85485f30
refactor(web): split AudioContext into context/audio-context module
...
- types.ts: VisualizerSettings, AudioContextType
- mockTracks.ts: mock track data for initial state
- useAudioContextValue.ts: all state, effects, and actions
- AudioContext.tsx: createContext, useAudio, AudioProvider
- Re-export from context/AudioContext.tsx (useAudio, AudioProvider, VisualizerSettings)
- Fix toggleMute to toggle isMuted (was incorrectly toggling isPlaying)
- 12 tests pass
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 13:46:29 +01:00
senke
6aad6d7d03
refactor(player): decompose AudioPlayer into audio-player module
...
- Add audio-player/ with useAudioPlayerLifecycle, AudioPlayerCompact, AudioPlayerFull, AudioPlayerSkeleton
- Re-export and default export from AudioPlayer.tsx
- Story Loading uses AudioPlayerSkeleton; 20 tests pass
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 13:37:04 +01:00
senke
c8110d2ca2
refactor(library): decompose UploadModal into upload-modal module
...
- Add upload-modal/ with useLibraryUploadModal, UploadModalForm, UploadModalFooter, types
- Re-export UploadModal from UploadModal.tsx
- Form ids for a11y (library-upload-*); trigger role=button tabIndex=0
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 13:26:19 +01:00
senke
c17c975b59
refactor(views): decompose DiscoverView into discover-view module
...
- Add discover-view/ with useDiscoverView, Hero, Trending, NewReleases, Genres, Skeleton, Error
- Re-export DiscoverView from DiscoverView.tsx
- Loading: Skeleton instead of h-[50vh] spinner; Error: min-h-layout-page-sm
- Conformity: UPDATED badge text-[10px] -> text-xs
- Stories: Default, Loading (Skeleton), Error
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 13:19:25 +01:00
senke
1744fac6aa
refactor(profile): decompose UserProfilePage into user-profile-page module
...
- Add user-profile-page/ with useUserProfilePage, Hero, Header, Tabs, Skeleton, Error
- Re-export UserProfilePage from UserProfilePage.tsx
- Stories: Default (/u/demo), Loading (Skeleton), NotFound (/u/notfound)
- MSW: GET /api/v1/users/by-username/:username (404 for notfound)
- Tests: mock useUserProfilePage, ToastProvider; 7 tests pass
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 13:10:33 +01:00
senke
98f01e60fe
refactor(social): GroupDetailView module, useGroupDetailView, Header, Members, Events, Sidebar, Skeleton, stories
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 12:34:57 +01:00
senke
1b4caba44b
refactor(settings): EditProfile module, useEditProfile, ImagesCard, IdentityCard, Sidebar, Skeleton, cropUtils, stories
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 11:45:16 +01:00
senke
3811df2961
refactor(forms): FormBuilder module, useFormBuilder, FormBuilderFieldWidget, re-export, stories, a11y id
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 11:36:20 +01:00
senke
31b3c2e712
refactor(monitoring): MonitoringDashboardContent split into Header, Stats, ValidationCard, ErrorsCard, PerformanceCard
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 11:27:54 +01:00
senke
85c88c5143
refactor(data): Table module, useTable, TableHeadRow, TableBodyRows, re-export, stories, tests
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 11:22:47 +01:00
senke
eead265786
refactor(ui): tooltip module, useTooltip, re-export, tests
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 10:32:14 +01:00
senke
cb58101137
refactor(ui): tabs module, re-export
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 10:12:33 +01:00
senke
80cc76212a
refactor(ui): accordion module, re-export
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 02:33:10 +01:00
senke
9f78576389
refactor(ui): dropdown-menu module, dropdown controlled open, re-export
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 02:27:29 +01:00
senke
7b5796a3b6
refactor(views): StudioView module, re-export, stories
...
- Module studio-view: types, useStudioView, Header, Sidebar, NavButton,
Content, ProjectsSwitch, Skeleton, orchestrator StudioView
- Re-export from StudioView.tsx
- Stories: Default, Projects, Loading (Skeleton); decorator min-h-layout-main
- Fix: h-[calc(100vh-140px)] -> min-h-layout-main, w-[65%] -> w-2/3
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 02:17:36 +01:00
senke
38894d8a1d
refactor(studio): CloudSettingsView module, re-export, stories
...
- Module cloud-settings-view: types, useCloudSettingsView, Quota,
Preferences, Skeleton, orchestrator CloudSettingsView
- Re-export from CloudSettingsView.tsx
- Stories: Default, Loading (Skeleton); decorator min-h-layout-page
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 02:11:33 +01:00
senke
f724b63e38
refactor(studio): AIToolsView module, re-export, stories
...
- Module ai-tools-view: types, constants (AI_TOOLS), useAIToolsView,
ToolGrid, Workspace, Skeleton, orchestrator AIToolsView
- Re-export from AIToolsView.tsx
- Stories: Default, Loading (Skeleton); decorator min-h-layout-page,
no local ToastProvider (use StorybookDecorator)
- Fix: text-[10px] -> text-xs, min-h-[400px] -> min-h-layout-page-sm
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 02:07:05 +01:00
senke
e2f30ee28a
refactor(studio): ConnectivityView module, re-export, stories
...
- Module connectivity-view: types, useConnectivityView, WebDAV, Webhooks,
Skeleton, orchestrator ConnectivityView
- Re-export from ConnectivityView.tsx
- Stories: Default, Loading (Skeleton); decorator min-h-layout-page
- Fix: text-[10px] -> text-xs (Mount Password hint)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 02:02:00 +01:00
senke
bdcbf277e8
refactor(studio): GoLiveView module, re-export, stories
...
- Module go-live-view: types, useGoLiveView, Header, Preview, StreamInfo,
EncoderSetup, QuickInstructions, MicLevel, Skeleton, orchestrator
- Re-export from GoLiveView.tsx
- Stories: Default, Loading (Skeleton); decorator min-h-layout-main
- Fix: text-[10px] -> text-xs, w-[60%] -> w-3/5
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 01:57:22 +01:00
senke
946b6721b3
refactor(studio): CreateProjectModal module, re-export, stories
...
- Module create-project-modal: types, useCreateProjectModal, Header,
Form, Footer, Skeleton, orchestrator CreateProjectModal
- Re-export from projects/CreateProjectModal.tsx
- Stories: Default, Loading (Skeleton); decorator min-h-layout-story
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 01:51:25 +01:00
senke
41ba59a75f
refactor(studio): ProjectsManager module, re-export, stories
...
- Module projects-manager: types, useProjectsManager, Header, FilterBar,
Card, AddCard, Empty, Skeleton, orchestrator ProjectsManager
- Re-export from studio/ProjectsManager.tsx
- Stories: Default, Loading (Skeleton), Empty; decorator min-h-layout-main
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 01:44:40 +01:00
senke
1ea128b60d
refactor(tracks): TrackHistory module, re-export, stories, tests
...
- Module track-history: types, useTrackHistory, Header, Empty, ItemRow, Pagination, Skeleton, trackHistoryUtils
- Re-export from TrackHistory.tsx
- Stories: Default, Loading, Empty, Error (MSW)
- Tests: mock @/features/tracks/services/trackHistoryService, formatHistoryDate defensive, pagination/error tests fixed
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 01:34:58 +01:00
senke
3886061ec9
refactor(settings): TwoFactorSetup module, re-export, stories
...
- Module two-factor-setup: types, useTwoFactorSetup, Header, Step1/2/3, Skeleton
- Re-export from TwoFactorSetup.tsx
- Stories: Default, Step1, Step2, Loading (Skeleton), Error (MSW)
- Decorator: min-h-layout-page-sm
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 01:25:43 +01:00
senke
6fb8745efa
refactor(views): UploadView module, re-export, stories
...
- Module upload-view: types, useUploadView, Stepper, Step1/2/3, Skeleton
- Layout: min-h-layout-page, max-h-96 (no arbitrary values)
- Re-export from UploadView.tsx
- Stories: Default, Loading (Skeleton), Empty, Error
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 01:12:24 +01:00
senke
648cda6bf3
refactor(playlists): AddCollaboratorModal module, re-export, stories, tests
...
- Module add-collaborator-modal: types, useAddCollaboratorModal, Form, Skeleton
- Re-export from AddCollaboratorModal.tsx
- Stories: Default, Loading (Skeleton), Error (MSW)
- Tests: validation/mutation via ErrorDisplay, retry, no toast assertions
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 01:04:24 +01:00
senke
cf9bc76a03
refactor(playlists): découper SharePlaylistModal en module
...
- Module share-playlist-modal/ : useSharePlaylistModal, Content, Skeleton
- ErrorDisplay + retry (max 3), Spinner pour chargement
- Stories : Default, Loading, Error (MSW 500)
- Tests : useCreateShareLink mock, playlistId string
- Re-export depuis SharePlaylistModal.tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 00:57:48 +01:00
senke
b3b206dd2b
refactor(playlists): découper CreatePlaylistDialog en module
...
- Module create-playlist-dialog/ : schema zod, useCreatePlaylistDialog,
CreatePlaylistDialogForm, CreatePlaylistDialogSkeleton
- Bouton Créer avec Spinner (remplace Loader2)
- Stories : Default, Loading
- Tests : assertion createPlaylist(object), erreur avec Error
- Re-export depuis CreatePlaylistDialog.tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 00:52:51 +01:00
senke
40f43a9640
refactor(playlists): découper PlaylistSearch en module
...
- Module playlist-search/ : usePlaylistSearch, Bar, Filters, Results, Skeleton
- Chargement avec Spinner (remplace Loader2)
- PLAYLIST_SEARCH activé en Storybook (VITE_STORYBOOK)
- MSW : GET /api/v1/playlists/search
- Stories : Default, Loading, Empty, Error
- Tests : Vitest + mock playlistsApi, useToast stable
- Re-export depuis PlaylistSearch.tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 00:47:28 +01:00
senke
5f5275f6bb
refactor(playlists): découper PlaylistBatchActions en module
...
- Module playlist-batch-actions/ : usePlaylistBatchActions, exportUtils,
Bar, Buttons, DeleteDialog, Skeleton
- Boutons min-h-11 (remplace min-h-[44px])
- Stories : Default, SingleSelection, Loading
- Tests : mocks URL + Playlist id/user_id en string
- Re-export depuis PlaylistBatchActions.tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 00:37:06 +01:00
senke
157bda45e2
refactor(playlists): découper AddTrackToPlaylistModal en module
...
- Module add-track-to-playlist-modal/ : useAddTrackToPlaylistModal, Search,
List, TrackRow, Footer, Skeleton
- Liste max-h-96 (layout), Spinner pour chargement
- Stories : Default (useArgs), Loading (Skeleton)
- Re-export depuis AddTrackToPlaylistModal.tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 00:22:09 +01:00
senke
d1ad2639e4
refactor(playlists): PlaylistTrackList module with hook, subcomponents, skeleton
...
- Add playlist-track-list/ with usePlaylistTrackList, Empty, SortableItem, Skeleton, utils
- Prop isLoading for skeleton state
- Re-export from PlaylistTrackList.tsx and PlaylistTrackListSkeleton.tsx
- Stories: Default, Loading (Skeleton), Empty, Reordering (with mock data)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 00:14:19 +01:00
senke
01bca2fe08
refactor(notifications): NotificationMenu module with hook, subcomponents, skeleton
...
- Add notification-menu/ with useNotificationMenu, Trigger, Dropdown, List, Item, Skeleton
- Dropdown max-h-96 (no arbitrary max-h-[500px])
- Props notificationsOverride, isLoadingOverride, errorOverride for Storybook
- Re-export from NotificationMenu.tsx
- Stories: Default, Loading, Empty, Error, Skeleton
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 00:07:19 +01:00
senke
3232e77bcf
refactor(library): LibraryManager module with hook, subcomponents, skeleton
...
- Add library-manager/ with useLibraryManager, Header, Toolbar, Error, Empty, Content, Stats, Skeleton
- Layout min-h-layout-page (no arbitrary h-[600px])
- Props tracksOverride, errorOverride, isLoadingOverride for Storybook
- Re-export from LibraryManager.tsx
- Stories: Default, Loading (Skeleton), Empty, Error
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 00:00:35 +01:00
senke
423b9adb8e
refactor(education): CourseDetailView module with hook, subcomponents, skeleton
...
- Add course-detail-view/ with useCourseDetailView, Header, Tabs, Sidebar, Skeleton
- Stories: Default, Loading (Skeleton), Empty, Enrolled
- Re-export from CourseDetailView.tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 23:52:24 +01:00
senke
58cd96fe2e
refactor(education): CourseLearningView module with hook, subcomponents, skeleton
...
- Add course-learning-view/ with useCourseLearningView, Header, Player, Tabs, Sidebar, Skeleton
- Layout min-h-layout-main, no arbitrary values
- Re-export from CourseLearningView.tsx
- Stories: Default, Loading (Skeleton), Empty, Complete
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 23:45:58 +01:00
senke
ab67b3b256
refactor(marketplace): split ProductDetailView into module (Header, Gallery, Info, Licenses, Description, Reviews, Similar, Skeleton)
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 23:38:09 +01:00
senke
185fe03269
refactor(streaming): split PlaybackHeatmap into module (Header, Stats, Grid, Skeleton, Error, Empty)
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 23:31:06 +01:00
senke
9aa1549bc7
refactor(studio): split ProjectDetailView into module (Header, Tabs, Overview, Files, Settings, Sidebar, Skeleton)
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 23:24:39 +01:00
senke
3a991d85b6
refactor(auth): split SessionsPage into module (Header, Content, Skeleton, stories)
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 23:19:06 +01:00
senke
c5ffa235a2
refactor(tracks): split TrackSearchFilters into module (Basic, Advanced, Skeleton)
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 23:09:36 +01:00
senke
ea7faeb703
refactor(settings): extract AccountSettings into account-settings module
...
- Add account-settings/ with useAccountSettings, AccountSettingsErrorBanner,
AccountSettingsPasswordCard, AccountSettingsExportCard, AccountSettingsDeleteCard,
AccountSettingsSkeleton
- Re-export from AccountSettings.tsx for backward compatibility
- Stories: Default, Loading (skeleton, min-h-layout-story); remove ToastProvider
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 23:04:16 +01:00
senke
a056db91fe
refactor(ui): extract Dialog into dialog module
...
- Add dialog/ with types, Dialog, DialogHeader, DialogBody, DialogFooter,
DialogContent, DialogDescription, DialogTitle, DialogTrigger, DialogSkeleton
- Re-export from dialog.tsx via dialog/index for backward compatibility
- Stories: Default, Alert, Composition (max-w-md), Loading (DialogSkeleton)
- Test: assert Kodo destructive classes (text-kodo-red) for alert variant
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 22:59:48 +01:00
senke
a13555f58d
refactor(playlists): extract PlaylistList into playlist-list module
...
- Add playlist-list/ with usePlaylistList, PlaylistListToolbar, PlaylistListEmpty,
PlaylistListError, types; keep PlaylistListSkeleton at components level
- Re-export from PlaylistList.tsx for backward compatibility
- Stories: Default, Grid, Empty (MSW), Loading (skeleton, min-h-layout-story)
- Replace min-h-[44px] with min-h-11; no arbitrary values
- Tests: assert French labels and Pagination text; fix skeleton test
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 22:54:54 +01:00
senke
048393d266
refactor(tracks): extract TrackFilters into track-filters module
...
- Add track-filters/ with useTrackFilters, TrackFiltersHeader, TrackFiltersSearch,
TrackFiltersGrid, TrackFiltersClear, TrackFiltersSkeleton, types
- Re-export from TrackFilters.tsx for backward compatibility
- Stories: Default, Collapsible, Loading (skeleton)
- Layout primitive min-h-layout-story for skeleton; no arbitrary values
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 22:46:11 +01:00
senke
48ddd42182
refactor(player): extract AudioPlayer into audio-player module
...
- types, useAudioPlayerEffects, AudioPlayerTrackInfo, AudioPlayerControls
- AudioPlayerProgress, AudioPlayerVolume, AudioPlayerSkeleton
- Stories: Default (mock store), Skeleton
- Re-export from AudioPlayer.tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 22:40:06 +01:00
senke
44eb0e142f
refactor(ui): extract DataList into data-list module
...
- types, DataListSkeleton, DataListEmpty, DataListError, DataList
- Remove duplicate Modal/Dropdown from DataList.tsx (exist in modal.tsx/dropdown.tsx)
- Stories: Default, Loading, Empty, Error, Skeleton (min-h-layout-story)
- Re-export from DataList.tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 22:35:53 +01:00
senke
db39d87955
refactor(ui): extract OptimizedImage into optimized-image module
...
- types, generateImageSources, BlurPlaceholder, useImageFormatSupport
- OptimizedImage, OptimizedImageSkeleton, useImagePreloader, ResponsiveImage
- Stories: Default, WithPlaceholder, ErrorState, Loading (skeleton)
- Re-export from optimized-image.tsx; tests adapted to loading state
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 22:31:35 +01:00
senke
15d31cf793
fix(ui): call onAvatarUpdated('') after successful avatar delete
...
Ensures parents that rely on onAvatarUpdated get the empty URL when
avatar is removed. Aligns with profile feature test contract.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 22:24:50 +01:00
senke
c4111ac059
refactor(ui): extract AvatarUpload into avatar-upload module
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 22:21:02 +01:00
senke
38eab5c205
refactor(ui): extract DatePicker into date-picker module
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 22:15:11 +01:00
senke
c30049e215
refactor(share): extract ShareLinkManager into share-link-manager module
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 22:09:31 +01:00
senke
a74d51918c
refactor(streaming): extract PlaybackDashboard into playback-dashboard module
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 22:04:38 +01:00
senke
aec92086dd
refactor(monitoring): extract MonitoringDashboard into monitoring-dashboard module
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 21:57:39 +01:00
senke
f622fad9fc
refactor(auth): extract RegisterPage into register-page module
...
- Add register-page/ with useRegisterPage, RegisterPageForm,
RegisterPageVerificationNotice, RegisterPageSkeleton
- Layout primitives (min-h-layout-page-sm), tokens (success, destructive)
- Stories: Default, Loading, WithError; re-export from pages/RegisterPage
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 21:50:17 +01:00
senke
bc7eabdbbe
refactor(views): extract FileManagerView into file-manager-view module
...
- Add file-manager-view/ with useFileManagerView, Header, Toolbar, Table, Grid,
Empty, Skeleton; types and mockFiles
- Layout primitives (min-h-layout-page-sm), no arbitrary values
- Stories: Default, Loading, Empty
- Re-export from FileManagerView.tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 21:45:01 +01:00
senke
6f0677fc88
refactor(search): extract SearchPage into feature module
...
- Add features/search/components/search-page/ with useSearchPage, Header,
Discovery, Empty, Error, Results, Skeleton
- Layout primitives only (min-h-layout-page, max-w-6xl)
- Stories: Default, Loading, Empty, Error; MSW handler for SearchResults shape
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 21:39:31 +01:00
senke
796745f57f
fix(views): use layout primitive in NotificationsView loading state
...
Replace arbitrary h-[50vh] with min-h-layout-page-sm per .cursorrules
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 21:32:33 +01:00
senke
85abc9900f
refactor(notifications): extract NotificationsPage into feature module
...
- Add features/notifications/components/notifications-page/ with:
- useNotificationsPage (query + mark read / mark all read mutations)
- NotificationsPageHeader, NotificationsPageFilters, NotificationsPageItem
- NotificationsPageEmpty, NotificationsPageError, NotificationsPageSkeleton
- types (FilterType, NotificationTypeFilter, NOTIFICATION_TYPE_LABELS)
- Page re-exports from module; stories moved to component (Default, Loading, Error, Empty)
- MSW handler: notifications response shape aligned with notificationService (data.notifications)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 21:32:19 +01:00
senke
9dde2eec55
chore(studio): remove legacy CloudFileBrowser from components/studio
...
CloudFileBrowser lives in features/studio/components/cloud-file-browser/.
StudioView already imports from there.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 21:20:36 +01:00
senke
b20c9f4c6f
test(ui): add Select stories (Default, Empty, Disabled, Grouped, MultiSelect), fix tests for listbox/option
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 21:16:30 +01:00
senke
bf50ee4588
refactor(ui): decompose Select into select module
...
- Add select/ with useSelect, types, SelectTrigger, SelectDropdownContent,
SelectOptionItem; min-w-48 max-h-72 (no arbitrary values)
- Remove monolithic select.tsx; entry point is select/index.ts
- Backward compatible: imports from './select' resolve to module
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 21:16:19 +01:00
senke
53a97148e3
test(ui): add FileUpload stories (Default, Empty, Error, Disabled, etc.)
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 21:09:21 +01:00
senke
0eda9232df
refactor(ui): decompose FileUpload into file-upload module
...
- Add file-upload/ with useFileUpload, types, utils, and presentational
components: FileUploadDropzone, FileUploadErrorList, FileUploadFileList
- Remove monolithic file-upload.tsx; entry point is file-upload/index.ts
- Backward compatible: imports from './file-upload' resolve to module
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 21:09:08 +01:00
senke
f00c621bb4
test(upload): add UploadModal stories (Default, Open)
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 21:03:15 +01:00
senke
eadc2b7c65
refactor(upload): decompose UploadModal into upload-modal module
...
- Add upload-modal/ with useUploadModal, constants, and presentational
components: Dropzone, FileDisplay, Progress, ErrorAlert, MetadataForm
- Re-export from UploadModal.tsx for backward compatibility
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 21:03:07 +01:00
senke
1f2e59af8d
test(ui): add LazyErrorFallback and LazyComponent stories; fix LazyComponent tests for fallback text
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 20:49:17 +01:00
senke
df6c9c3d2b
refactor(ui): decompose LazyComponent into lazy-component module with LazyErrorFallback, LazyErrorBoundary, createLazyComponent
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 20:48:36 +01:00
senke
cc6b77aff4
test(views): add GearView stories Default, Loading, Empty, Error and GearViewSkeleton
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 20:38:59 +01:00
senke
260a787da6
refactor(views): decompose GearView into gear-view module with useGearView and sub-components
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 20:38:45 +01:00
senke
d1044b22d4
test(views): add ProfileView stories Default, Loading, Error and ProfileViewSkeleton
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 20:30:50 +01:00
senke
5485415113
refactor(views): decompose ProfileView into profile-view module with hook and sub-components
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 20:30:36 +01:00
senke
6f367717a3
test(user): add ProfileForm stories (Default, Loading, Error) and Skeleton; fix tests and MSW completion handler
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 20:21:05 +01:00
senke
8a8d2657f7
refactor(user): decompose ProfileForm into profile-form module with hook and sub-components
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 20:20:49 +01:00
senke
d8ae1d8761
test(chat): add stories and mocks for ChatSidebar
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 20:07:20 +01:00
senke
d88028a1d4
refactor(chat): decompose ChatSidebar into sub-components
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 20:07:09 +01:00
senke
b8f181c801
test(search): add stories Loading/Empty/Error and fix Search tests
...
- Stories: Loading, Empty, Error; decorator max-w-2xl min-h-layout-story
- SearchSkeleton.stories; fix tests: waitFor, Enter for history, keyboard nav query
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 19:45:52 +01:00
senke
6677455721
refactor(search): decompose Search into sub-components
...
- Add features/search/components/search: types, useSearchSuggestions,
SearchInput, SearchDropdown, SearchSkeleton
- Search.tsx orchestrator; re-export from components/search for GlobalSearchBar
- No console.log; logger only; layout primitives in stories
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 19:45:41 +01:00
senke
7255846083
fix(storybook): ignore net::ERR_ABORTED on iframe in audit (navigation false positive)
...
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 19:32:39 +01:00
senke
9ebaf9acb1
test(tracks): add stories and mocks for CommentThread
...
- Stories: EmptyReplies, LoadingReplies, ReplyError; decorator uses max-w-2xl, min-h-layout-story
- CommentThreadSkeleton.stories.tsx
- MSW: PUT */api/v1/comments/:id for update; useUser mock in CommentThread.test
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 19:20:58 +01:00
senke
f4b6ede605
refactor(tracks): decompose CommentThread into sub-components
...
- Add comment-thread module: types, useCommentReplies, useCommentActions
- Presentational components: CommentThreadHeader, CommentThreadContent,
CommentThreadActions, CommentReplyForm, CommentRepliesList
- CommentThreadSkeleton for Loading state
- CommentThread.tsx becomes orchestrator (~170 lines); re-export from module
- FE-COMP-012 preserved; no breaking change for CommentSection
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 19:20:47 +01:00
senke
7a0d45dbb1
feat(ui): implement skeleton-first loading and grid/list orchestration for CloudFileBrowser
2026-02-05 19:04:03 +01:00
senke
6f8a16359a
refactor(studio): modularize CloudFileBrowser with FileTable, FileGrid and FileToolbar
2026-02-05 19:04:00 +01:00
senke
7da61f9911
test(msw): add inventory gear handlers for deterministic story testing
2026-02-05 18:18:17 +01:00
senke
23bbcb1632
feat(ui): implement grid/list view orchestration with synchronized skeletons for GearView
2026-02-05 18:18:13 +01:00
senke
881321a9e6
refactor(ui): create atomic gear module with Header, Filters, Grid, and Modal
2026-02-05 18:18:09 +01:00
senke
b9f3906bca
refactor(ui): modularize ProfileView into Header, Stats, and Tabs components
2026-02-05 14:32:20 +01:00
senke
c8b640263d
chore(dx): add .cursorrules and design system audit documentation
2026-02-05 14:20:06 +01:00
senke
2a603e1ed0
refactor(ui): decompose ProfileForm into atomic sub-components (Avatar, Identity, Social, Actions, Security)
2026-02-05 14:16:01 +01:00
senke
4a0b809ed2
docs(storybook): final comparison 67%→0%, contract update, silent toasts in Storybook
2026-02-05 13:39:59 +01:00
senke
dc8dd90498
chore(storybook): add test:storybook script for local audit
2026-02-05 13:39:56 +01:00
senke
d45662ea22
ci(storybook): add audit workflow and exit 1 on audit failures
2026-02-05 13:39:53 +01:00
senke
1d244f9281
chore(storybook): set MSW onUnhandledRequest to 'error' to block unhandled network requests
2026-02-05 13:22:03 +01:00
senke
0c6c1685b8
chore(storybook): reclassify story hierarchy (App/Pages, Layouts, UI, Features, Docs/Failures) and enable autodocs
2026-02-05 13:21:54 +01:00
senke
f66aec4ac1
docs(storybook): clarify global decorator guarantees nav/auth context (Phase 3)
...
All stories run under AuthProvider and MemoryRouter; no story should
crash on missing useContext for auth or router.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 13:08:45 +01:00
senke
97c77a1925
refactor(storybook): remove duplicate providers from stories (Phase 2)
...
Stories no longer wrap with QueryClientProvider, ToastProvider,
ThemeProvider, or MemoryRouter; global StorybookDecorator provides them.
- Route-specific pages use parameters.router.initialEntries
(ResetPasswordPage, VerifyEmailPage) or minimal MemoryRouter+Route
where useParams is needed (TrackDetailPage, PlaylistDetailPage).
- Stories that seeded query cache use useQueryClient() from global
decorator (FollowButton, CollaboratorManagement, CommentSection).
- Navbar, AuthLayout, DashboardLayout, Header, and 25+ story files
simplified to layout divs only.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 13:08:17 +01:00
senke
64255e9133
feat(storybook): global StorybookDecorator in decorators.tsx (Phase 2)
...
Single decorator provides: I18nextProvider(i18n), ThemeProvider,
QueryClientProvider(retry:false), ToastProvider, AudioProvider,
AuthProvider, MemoryRouter. Stories can set parameters.router.initialEntries
for route-specific views. preview.tsx uses StorybookDecorator only.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 13:01:49 +01:00
senke
1eabdf5ade
chore(storybook): audit script filter sb-manager/sb-addons + comparison report
...
- Filter requestfailed to ignore /sb-manager/, /sb-addons/, /index.json,
/project.json so the audit counts only app/API failures.
- Add STORYBOOK_AUDIT_COMPARISON.md: before 641 stories / 1250 errors,
after 0 app errors (Phase 1 validated).
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 12:41:08 +01:00
senke
8b43574f15
docs(storybook): document MSW/same-origin contract in preview
...
Storybook must be run via npm run storybook so VITE_API_URL stays
relative and VITE_STORYBOOK is set; avoids accidental real API calls.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 12:28:04 +01:00
senke
c63d792bf0
fix(storybook): mark ErrorBoundary error stories for audit allowlist
...
WithError and WithCustomFallback set parameters.storybookAudit.expectConsoleErrors
so audit/CI can treat their console errors as intentional (failure demo).
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 12:17:50 +01:00
senke
843df44236
fix(storybook): mock dicebear and transparenttextures in MSW
...
Prevent external asset requests during Storybook so no network
dependency and deterministic rendering. Return 1x1 SVG placeholder.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 12:17:14 +01:00
senke
7f6b0d6f25
fix(storybook): fix auth/me shape and add dashboard, sessions, roles handlers
...
- auth/me: return data.user so authService.getCurrentUser() gets response.data.user
- Add GET /api/v1/dashboard for dashboardService (stats, recent_activity, library_preview)
- Add GET /api/v1/sessions/stats for sessionsApi
- Add GET /api/v1/roles and /roles/:id for admin views
- Remove console.log from audit/stats handler
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 12:16:56 +01:00
senke
bd8ef90ef6
fix(storybook): disable logger network send in Storybook
...
Set VITE_STORYBOOK=true for storybook dev/build so the logger never
sends POST to /logs/frontend in the isolated UI environment. Prevents
94+ failed network requests in audit and keeps Storybook hermetic.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 12:16:23 +01:00
senke
7b1ec1fb12
fix(storybook): remediate crashes and improve mock stability
...
- Add global AuthProvider and QueryClientProvider
- Fix Loader2 reference error in CommentThread
- Fix coverUrl crash in ProductCard
- Fix double-slash URL bug in logger
- Improve MSW handlers and environment config
2026-02-04 19:33:00 +01:00
senke
7314ea72c2
fix(frontend): remove redundant api version path in logger endpoint
2026-02-04 10:18:47 +01:00
senke
3f964e8fbe
fix(storybook): add global AuthProvider to preview.tsx
2026-02-04 10:17:19 +01:00
senke
557aa883f8
fix(storybook): update MSW handlers to be cookie-compatible and add missing logs endpoint
2026-02-04 10:15:11 +01:00
senke
9ea47201b5
feat(storybook): integrate msw for data mocking
2026-02-04 01:01:45 +01:00
senke
d2ae91ac25
chore(storybook): improve configuration and cleanup
2026-02-04 00:44:40 +01:00
senke
a2576c4eae
stabilisation: fix commit
2026-02-03 09:56:11 +01:00
senke
963fdf4f53
refactor(cart): migrate CheckoutView and MarketplaceView to useCartStore and fix stories
2026-02-03 09:50:51 +01:00
senke
3c30449a47
refactor(cart): migrate CartView and CartItem to useCartStore
2026-02-03 09:46:01 +01:00
senke
470c5a99df
refactor(cart): migrate Navbar to useCartStore and remove CartProvider decorator
2026-02-03 09:42:59 +01:00
senke
483710086b
refactor(cart): migrate WishlistView to useCartStore
2026-02-03 09:40:54 +01:00
senke
b8877c4ca3
chore(test): disable broken storybook plugin in vitest config
2026-02-03 09:37:16 +01:00
senke
19eff12641
docs(cart): list all CartContext consumers
2026-02-03 09:32:21 +01:00
senke
e810d67788
feat(storybook): complete comprehensive ui coverage for auth, player, tracks, and groups
2026-02-02 20:55:57 +01:00
senke
7ec9cb9cd6
feat(storybook): complete UI coverage with Batches 26-30
...
- Batch 26 (Tracks List/Grid): added stories for row, grid, sort, toggle, skeleton, empty states.
- Batch 27 (Dashboard): added stories for ActivityGraph, TrackList widget.
- Batch 28 (Education): added stories for CourseCard, MyCoursesView, QuizModal, CertificateModal.
- Batch 29 (Inventory): added stories for EquipmentCard, InventoryView.
- Batch 30 (Seller/Live): added stories for SellerDashboardView, FlashSaleModal, LiveStreamDetailView, TipStreamerModal.
- Verified build and fixed AudioProvider/service dependencies.
2026-02-02 20:47:47 +01:00
senke
962aff677f
feat(storybook): add stories for Auth, Player, Tracks, Dashboard (Batches 22-25)
...
- Batch 22 (Auth/Settings): OAuthButtons, PasswordStrengthIndicator, ThemeSwitcher, TwoFactorSettings
- Batch 23 (Player): TimeDisplay, RepeatShuffleButtons, NextPreviousButtons, QualitySelector
- Batch 24 (Tracks): LikeButton, TrackFilters, TrackStatsDisplay
- Batch 25 (Dashboard): StatCard
- Fixed build issues with sonner dependencies.
2026-02-02 20:42:51 +01:00
senke
2e8dbb74d5
feat(storybook): add stories for Feedback and Playlist components (Batches 20-21)
...
- Batch 20 (Feedback): Alert, Toast
- Batch 21 (Playlists): PlaylistCard, PlaylistHeader, AddTrackToPlaylistModal
- Verified successful build.
2026-02-02 20:38:52 +01:00
senke
d2601cf9ff
feat(storybook): add stories for Social, Notifications, and Modals (Batches 17-19)
...
- Batch 17 (Social): PostCard, CommentItem
- Batch 18 (Notifications): NotificationItem, NotificationBell, NotificationMenu
- Batch 19 (Modals): CreatorModal
- Fix: remove duplicate import in api.ts
- Verified successful build.
2026-02-02 20:33:45 +01:00
senke
535cf646ea
feat(storybook): achieve total UI coverage (Batches 13-16)
...
- Batch 13 (Library/Profile): UploadModal, FollowButton
- Batch 14 (Settings): AccountSettings, NotificationSettings
- Batch 15 (Layout): DashboardLayout, Header, Sidebar
- Batch 16 (Search): SearchBar, Search
- Verified successful build of all stories.
2026-02-02 20:29:46 +01:00
senke
fd0d7b3128
feat(storybook): expanded coverage for feature components (batches 10-12)
...
- Batch 10 (Auth): AuthButton, AuthInput, LoginForm, RegisterForm
- Batch 11 (Chat): ChatMessage, ChatInput, TypingIndicator
- Batch 12 (Player/Tracks): PlayPauseButton, VolumeControl, ProgressBar, TrackCard
- Achieved extensive functional component coverage.
2026-02-02 20:19:10 +01:00
senke
ba24e4c133
feat(storybook): complete UI component coverage (batches 6-9)
...
- Batch 6: FAB, FormField, FloatingInput, AvatarUpload
- Batch 7: Modal, ConfirmationDialog, ImageViewerModal, ErrorDisplay, LoadingState
- Batch 8: DataList, WaveformVisualizer, OptimizedImage, VirtualizedList
- Batch 9: ImageCropper, LoadingSpinner, FocusTrap
- Achieved total coverage for src/components/ui
2026-02-02 19:50:45 +01:00
senke
5024ff0e0b
feat(storybook): expanded coverage for visual and feedback components (batch 5)
...
- Added stories for: Spinner, KodoEmptyState, HelpText, AstralBackground
- Increased coverage for utility and visual components
2026-02-02 19:46:27 +01:00
senke
ba5b8a9abd
feat(storybook): expanded coverage for structural components (batch 4)
...
- Added stories for: Label, Skeleton, ScrollArea, Toast, Collapsible, Sidebar
- Covered layout and feedback components
2026-02-02 19:44:58 +01:00
senke
affc628722
feat(storybook): expanded coverage for complex form & data components (batch 3)
...
- Added stories for: DatePicker, Select, RadioGroup, FileUpload, Table
- Achieved high coverage for core UI components
2026-02-02 19:41:12 +01:00
senke
62683f1a17
feat(storybook): expanded coverage for complex UI components (batch 2)
...
- Added stories for: Accordion, Tabs, Textarea, Tooltip, Dialog, DropdownMenu
- Covered various interactive states and sub-components
2026-02-02 19:39:50 +01:00
senke
91055ee07b
feat(storybook): expanded coverage for core UI components (batch 1)
...
- Added stories for: Button, Avatar, Switch, Slider, Alert, Progress
- Consolidated Button component to src/components/ui/button.tsx
- Removed legacy src/components/Button.tsx
2026-02-02 19:37:52 +01:00
senke
ad60247f33
feat: global update including storybook setup and backend fixes
...
- Web: Setup Storybook, added addons, configured Tailwind, added stories for UI components.
- Backend: Updated API router, database, workers, and auth in common.
- Stream Server: Removed SQLx queries and updated auth.
- Docs & Scripts: Updated documentation and recovery scripts.
2026-02-02 19:34:14 +01:00
senke
efb5b19276
feat(auth): add centralized AuthProvider component
...
Created AuthProvider React component to centralize auth initialization
logic and eliminate race conditions.
Features:
- Single source of truth for auth initialization
- Checks for tokens on mount (TokenStorage.hasTokens())
- Calls refreshUser() if tokens exist
- Shows loading screen while auth initializing
- Always sets ready state (prevents stuck loading)
- Comprehensive error handling and logging
- Optional custom loading component prop
Benefits:
- Eliminates race condition: router no longer renders before auth ready
- Centralizes auth logic (was scattered in App.tsx, interceptors)
- Reusable across different app entry points
- Clean separation of concerns
Usage:
Impact: Reduces auth-related race conditions, improves code maintainability.
Fixes: P3.1 from audit AUDIT_TEMP_29_01_2026.md
2026-01-29 23:42:26 +01:00
senke
2628391e69
config(prod): add frontend production environment file
...
Created .env.production for frontend with absolute API URLs for
production deployment.
Configuration:
- VITE_API_URL: https://api.veza.com/api/v1
- VITE_WS_URL: wss://api.veza.com/ws
- VITE_STREAM_URL: https://api.veza.com/stream
- VITE_UPLOAD_URL: https://api.veza.com/upload
- VITE_API_VERSION: v1
Features:
- Absolute URLs (required for production, no Vite proxy)
- HTTPS/WSS for secure connections
- Validation alerting enabled
- Deployment notes included
Usage:
- Local testing: Update URLs to local domains, npm run build, npm run preview
- Production: Update to real domains, ensure CORS configured
Impact: Frontend can now be deployed to production with proper API URLs.
Fixes: P2.2 from audit AUDIT_TEMP_29_01_2026.md
2026-01-29 23:23:04 +01:00
senke
fa6f0bbda5
config(dev): add Vite proxy for API requests
...
Added proxy configuration to forward /api requests to backend
on localhost:8080 during development.
Benefits:
- Eliminates CORS errors in dev (requests are same-origin)
- No need for CORS_ALLOWED_ORIGINS in dev environment
- Matches production behavior (frontend and API on same domain)
- Simplifies local development setup
Configuration:
- Target: http://localhost:8080
- changeOrigin: true (modifies Host header)
- secure: false (allows self-signed certs in dev)
Impact: Dev environment more stable, no CORS configuration needed.
Fixes: P2.1 from audit AUDIT_TEMP_29_01_2026.md
2026-01-29 23:22:32 +01:00
senke
d44777b715
fix(auth): prevent race condition on app initialization
...
Added isAuthReady state to prevent router from rendering before auth
state is initialized. This eliminates login redirect loops and ensures
deterministic auth behavior.
Changes:
- Added isAuthReady state (default: false)
- New useEffect to initialize auth before rendering
- Waits for refreshUser() to complete if tokens exist
- Shows loading screen while auth is initializing
- Always sets isAuthReady=true in finally block
Loading screen:
- Simple centered spinner with "Chargement..." text
- Uses Tailwind classes for styling
- Matches app theme (bg-background, text-muted-foreground)
Behavior:
- App loads → Check for tokens → If yes, await refreshUser()
- Only after auth check completes, render router
- Prevents "flash of login page" for authenticated users
- Eliminates race condition: router no longer renders before auth ready
Impact: Fixes intermittent login loops, improves UX on page refresh.
Fixes: P1.2 from audit AUDIT_TEMP_29_01_2026.md
2026-01-29 23:19:01 +01:00
senke
75f61c05b2
fix(csrf): add retry mechanism for 403 CSRF errors
...
Added response interceptor to handle 403 errors caused by expired or
invalid CSRF tokens. When a mutation fails with 403, the interceptor:
1. Detects if error is CSRF-related (checks error message for csrf/token/forbidden)
2. Refreshes the CSRF token via csrfService.ensureToken()
3. Updates request headers with new token
4. Retries the request once
Features:
- Only retries once per request (via _csrfRetry flag)
- Skips retry for /csrf-token and /auth/* endpoints
- Logs all CSRF refresh attempts for debugging
- Falls through to original error if refresh fails
- Handles both error.error and error.message formats
TypeScript fixes:
- Cast originalRequest to any for _csrfRetry property
- Safely access error data with type checking
Impact: Eliminates 403 errors on POST/PUT/DELETE when CSRF token expires.
Users no longer need to manually refresh page to get new CSRF token.
Fixes: P1.3 from audit AUDIT_TEMP_29_01_2026.md
2026-01-29 23:18:08 +01:00
senke
2edf37557d
fix(auth): limit refresh token attempts to prevent infinite loops
...
Added refresh attempt counter with MAX_REFRESH_ATTEMPTS=3 to prevent
infinite refresh loops when token refresh repeatedly fails.
Changes:
- Added refreshAttempts counter and MAX_REFRESH_ATTEMPTS constant
- Check counter before attempting refresh, logout if max reached
- Increment counter on each refresh attempt
- Reset counter to 0 on successful refresh
- Log attempt number in all refresh-related logs
- Show user-friendly error message after max attempts
Behavior:
- After 3 failed refresh attempts, user is logged out automatically
- Prevents infinite 401 → refresh → 401 loops
- Uses logoutLocal() to avoid triggering another API call
- Displays clear error message: "Session expired after multiple attempts"
Impact: Eliminates infinite refresh loops, improves UX on persistent auth failures.
Fixes: P1.4 from audit AUDIT_TEMP_29_01_2026.md
2026-01-29 23:16:37 +01:00
senke
62a6b3a528
improving UI: improve audio player phase 1
2026-01-26 19:18:52 +01:00
senke
f61c0c3dcc
improving UI: adding API doc to Developer Page
2026-01-26 14:12:17 +01:00