veza/apps/web/src/features/player/components/PlayerQueue.stories.tsx

109 lines
3.2 KiB
TypeScript
Raw Normal View History

2026-02-03 08:56:11 +00:00
import type { Meta, StoryObj } from '@storybook/react';
import { useEffect } from 'react';
2026-02-03 08:56:11 +00:00
import { PlayerQueue } from './PlayerQueue';
import { usePlayerStore } from '../store/playerStore';
import { useAuthStore } from '@/features/auth/store/authStore';
2026-02-03 08:56:11 +00:00
const meta: Meta<typeof PlayerQueue> = {
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 }) => {
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,
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} />
<div className="h-[600px] w-full relative bg-background overflow-hidden">
2026-02-03 08:56:11 +00:00
<Story />
</div>
</>
),
],
};
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={[]} />
<div className="h-[600px] w-full relative bg-background overflow-hidden">
2026-02-03 08:56:11 +00:00
<Story />
</div>
</>
),
],
};
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>
</>
),
],
};