This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

semble / src / webapp / features / profile / components / profileMenu / ProfileMenu.stories.tsx
2.8 kB 106 lines
1import type { Meta, StoryObj } from '@storybook/nextjs-vite'; 2import type { User } from '@semble/types'; 3import { Suspense, useEffect } from 'react'; 4import { useQueryClient } from '@tanstack/react-query'; 5import { Skeleton as MantineSkeleton } from '@mantine/core'; 6import ProfileMenu from './ProfileMenu'; 7import { profileKeys } from '../../lib/profileKeys'; 8import { AuthContext, type AuthContextType } from '@/hooks/useAuth'; 9 10const mockProfile: User = { 11 id: 'did:plc:abc123def456', 12 name: 'Elena Kowalski', 13 handle: 'elena.kowalski', 14 avatarUrl: 'https://i.pravatar.cc/150?u=elena', 15}; 16 17const mockAuthContext: AuthContextType = { 18 user: null, 19 isAuthenticated: true, 20 isLoading: false, 21 refreshAuth: async () => {}, 22 logout: async () => {}, 23}; 24 25function QueryCacheSeed({ 26 profile, 27 children, 28}: { 29 profile: User; 30 children: React.ReactNode; 31}) { 32 const queryClient = useQueryClient(); 33 34 useEffect(() => { 35 queryClient.setQueryData(profileKeys.mine(), profile); 36 }, [queryClient, profile]); 37 38 return <>{children}</>; 39} 40 41const meta: Meta<typeof ProfileMenu> = { 42 title: 'Features/Profile/ProfileMenu', 43 component: ProfileMenu, 44 decorators: [ 45 (Story) => ( 46 <AuthContext value={mockAuthContext}> 47 <QueryCacheSeed profile={mockProfile}> 48 <Suspense 49 fallback={<MantineSkeleton w={38} h={38} radius="md" ml={4} />} 50 > 51 <div style={{ maxWidth: 280 }}> 52 <Story /> 53 </div> 54 </Suspense> 55 </QueryCacheSeed> 56 </AuthContext> 57 ), 58 ], 59}; 60 61export default meta; 62 63type Story = StoryObj<typeof ProfileMenu>; 64 65/** Collapsed menu trigger shown in the navbar footer. Click to open. */ 66export const Default: Story = {}; 67 68/** Bot accounts show the robot icon next to the name. */ 69export const BotAccount: Story = { 70 decorators: [ 71 (Story) => ( 72 <AuthContext value={mockAuthContext}> 73 <QueryCacheSeed 74 profile={{ 75 ...mockProfile, 76 id: 'did:plc:bot999', 77 name: 'Semble Bot', 78 handle: 'bot.semble', 79 avatarUrl: 'https://i.pravatar.cc/150?u=bot', 80 labels: [ 81 { 82 val: 'bot', 83 src: 'did:plc:bot999', 84 uri: 'did:plc:bot999', 85 cts: '2024-01-01T00:00:00.000Z', 86 }, 87 ], 88 }} 89 > 90 <Suspense 91 fallback={<MantineSkeleton w={38} h={38} radius="md" ml={4} />} 92 > 93 <div style={{ maxWidth: 280 }}> 94 <Story /> 95 </div> 96 </Suspense> 97 </QueryCacheSeed> 98 </AuthContext> 99 ), 100 ], 101}; 102 103/** Skeleton shown while the profile data is loading. */ 104export const Skeleton: Story = { 105 render: () => <MantineSkeleton w={38} h={38} radius="md" ml={4} />, 106};