2026-02-03 08:56:11 +00:00
|
|
|
import type { Meta, StoryObj } from '@storybook/react';
|
feat(release): v0.202 — Lots G, H, F, C, D
- Lot G: Recherche avancée (musical_key, tri pertinence, autocomplete, facettes, historique)
- Lot H: Analytics créateur (stats, charts, completion rate, export CSV/JSON)
- Lot F: Seller dashboard (GET /sell/stats, liste produits)
- Lot C: Player (crossfade, gapless preload, PiP)
- Lot D2: Autoplay (GET /tracks/recommendations, section À écouter ensuite)
Backend: GetRecommendations handler, route /tracks/recommendations
Frontend: PlayerQueue recommendations, fix TS errors (GlobalPlayer, AnalyticsViewKpiGrid, etc.)
Docs: FEATURE_STATUS, PROJECT_STATE, CHANGELOG, SCOPE_CONTROL
2026-02-20 17:16:17 +00:00
|
|
|
import { useEffect } from 'react';
|
2026-02-03 08:56:11 +00:00
|
|
|
import { PlayerQueue } from './PlayerQueue';
|
|
|
|
|
import { usePlayerStore } from '../store/playerStore';
|
feat(release): v0.202 — Lots G, H, F, C, D
- Lot G: Recherche avancée (musical_key, tri pertinence, autocomplete, facettes, historique)
- Lot H: Analytics créateur (stats, charts, completion rate, export CSV/JSON)
- Lot F: Seller dashboard (GET /sell/stats, liste produits)
- Lot C: Player (crossfade, gapless preload, PiP)
- Lot D2: Autoplay (GET /tracks/recommendations, section À écouter ensuite)
Backend: GetRecommendations handler, route /tracks/recommendations
Frontend: PlayerQueue recommendations, fix TS errors (GlobalPlayer, AnalyticsViewKpiGrid, etc.)
Docs: FEATURE_STATUS, PROJECT_STATE, CHANGELOG, SCOPE_CONTROL
2026-02-20 17:16:17 +00:00
|
|
|
import { useAuthStore } from '@/features/auth/store/authStore';
|
2026-02-03 08:56:11 +00:00
|
|
|
|
|
|
|
|
const meta: Meta<typeof PlayerQueue> = {
|
2026-02-05 13:20:06 +00:00
|
|
|
title: 'Components/Features/Player/PlayerQueue',
|
2026-02-03 08:56:11 +00:00
|
|
|
component: PlayerQueue,
|
|
|
|
|
parameters: {
|
|
|
|
|
layout: 'padded',
|
|
|
|
|
},
|
|
|
|
|
tags: ['autodocs'],
|
|
|
|
|
argTypes: {
|
|
|
|
|
onClose: { action: 'onClose' },
|
|
|
|
|
onPlay: { action: 'onPlay' },
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default meta;
|
|
|
|
|
type Story = StoryObj<typeof PlayerQueue>;
|
|
|
|
|
|
|
|
|
|
const mockTracks = [
|
|
|
|
|
{ id: '1', title: 'Start Me Up', artist: 'The Rolling Stones', cover: 'https://picsum.photos/200', duration: 200, url: '' },
|
|
|
|
|
{ id: '2', title: 'Bohemian Rhapsody', artist: 'Queen', cover: 'https://picsum.photos/201', duration: 354, url: '' },
|
|
|
|
|
{ id: '3', title: 'Hotel California', artist: 'Eagles', cover: 'https://picsum.photos/202', duration: 391, url: '' },
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const StoreInitializer = ({ tracks, currentIndex = 0 }: { tracks: any[], currentIndex?: number }) => {
|
2026-02-12 23:32:08 +00:00
|
|
|
const { addToQueue, clearQueue } = usePlayerStore();
|
2026-02-03 08:56:11 +00:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
clearQueue();
|
|
|
|
|
// We add tracks one by one or batch if supported, here we simluate adding
|
|
|
|
|
// Note: usePlayerStore actions might need adjustment if they don't support direct manipulation for stories
|
|
|
|
|
// But addToQueue takes Track[].
|
|
|
|
|
|
|
|
|
|
// We clear first
|
|
|
|
|
usePlayerStore.setState({ queue: [], currentIndex: -1 });
|
|
|
|
|
|
|
|
|
|
// Set state directly for storybook purposes to ensure consistency
|
|
|
|
|
usePlayerStore.setState({
|
|
|
|
|
queue: tracks,
|
chore(v0.102): consolidate remaining changes — docs, frontend, backend
- docs: SCOPE_CONTROL, CONTRIBUTING, README, .github templates
- frontend: DeveloperDashboardView, Player components, MSW handlers, auth, reactQuerySync
- backend: playback_analytics, playlist_service, testutils, integration README
Excluded (artifacts): .auth, playwright-report, test-results, storybook_audit_detailed.json
2026-02-20 12:02:12 +00:00
|
|
|
currentIndex,
|
2026-02-03 08:56:11 +00:00
|
|
|
currentTrack: tracks[currentIndex]
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
}, [tracks, currentIndex, addToQueue, clearQueue]);
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const Default: Story = {
|
|
|
|
|
args: {
|
|
|
|
|
isOpen: true,
|
|
|
|
|
},
|
|
|
|
|
decorators: [
|
|
|
|
|
(Story) => (
|
|
|
|
|
<>
|
|
|
|
|
<StoreInitializer tracks={mockTracks} currentIndex={0} />
|
2026-02-17 16:03:57 +00:00
|
|
|
<div className="h-[600px] w-full relative bg-background overflow-hidden">
|
2026-02-03 08:56:11 +00:00
|
|
|
<Story />
|
|
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
};
|
|
|
|
|
|
feat(release): v0.202 — Lots G, H, F, C, D
- Lot G: Recherche avancée (musical_key, tri pertinence, autocomplete, facettes, historique)
- Lot H: Analytics créateur (stats, charts, completion rate, export CSV/JSON)
- Lot F: Seller dashboard (GET /sell/stats, liste produits)
- Lot C: Player (crossfade, gapless preload, PiP)
- Lot D2: Autoplay (GET /tracks/recommendations, section À écouter ensuite)
Backend: GetRecommendations handler, route /tracks/recommendations
Frontend: PlayerQueue recommendations, fix TS errors (GlobalPlayer, AnalyticsViewKpiGrid, etc.)
Docs: FEATURE_STATUS, PROJECT_STATE, CHANGELOG, SCOPE_CONTROL
2026-02-20 17:16:17 +00:00
|
|
|
const AuthInitializer = ({ authenticated }: { authenticated: boolean }) => {
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
useAuthStore.setState({ isAuthenticated: authenticated });
|
|
|
|
|
return () => useAuthStore.setState({ isAuthenticated: false });
|
|
|
|
|
}, [authenticated]);
|
|
|
|
|
return null;
|
|
|
|
|
};
|
|
|
|
|
|
2026-02-03 08:56:11 +00:00
|
|
|
export const Empty: Story = {
|
|
|
|
|
args: {
|
|
|
|
|
isOpen: true,
|
|
|
|
|
},
|
|
|
|
|
decorators: [
|
|
|
|
|
(Story) => (
|
|
|
|
|
<>
|
|
|
|
|
<StoreInitializer tracks={[]} />
|
2026-02-17 16:03:57 +00:00
|
|
|
<div className="h-[600px] w-full relative bg-background overflow-hidden">
|
2026-02-03 08:56:11 +00:00
|
|
|
<Story />
|
|
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
};
|
feat(release): v0.202 — Lots G, H, F, C, D
- Lot G: Recherche avancée (musical_key, tri pertinence, autocomplete, facettes, historique)
- Lot H: Analytics créateur (stats, charts, completion rate, export CSV/JSON)
- Lot F: Seller dashboard (GET /sell/stats, liste produits)
- Lot C: Player (crossfade, gapless preload, PiP)
- Lot D2: Autoplay (GET /tracks/recommendations, section À écouter ensuite)
Backend: GetRecommendations handler, route /tracks/recommendations
Frontend: PlayerQueue recommendations, fix TS errors (GlobalPlayer, AnalyticsViewKpiGrid, etc.)
Docs: FEATURE_STATUS, PROJECT_STATE, CHANGELOG, SCOPE_CONTROL
2026-02-20 17:16:17 +00:00
|
|
|
|
|
|
|
|
export const EmptyWithRecommendations: Story = {
|
|
|
|
|
args: {
|
|
|
|
|
isOpen: true,
|
|
|
|
|
},
|
|
|
|
|
decorators: [
|
|
|
|
|
(Story) => (
|
|
|
|
|
<>
|
|
|
|
|
<AuthInitializer authenticated />
|
|
|
|
|
<StoreInitializer tracks={[]} />
|
|
|
|
|
<div className="h-[600px] w-full relative bg-background overflow-hidden">
|
|
|
|
|
<Story />
|
|
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
};
|