-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
80ca9c3
commit c730c13
Showing
8 changed files
with
368 additions
and
0 deletions.
There are no files selected for viewing
152 changes: 152 additions & 0 deletions
152
src/components/model/Work/components/WorkCard/index.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
import { WorkCard, WorkCardLoading } from './presentations'; | ||
|
||
import type { Meta, StoryObj } from '@storybook/react'; | ||
|
||
import { dateFormat } from '@/libs/dateFormat'; | ||
|
||
const meta: Meta<typeof WorkCard> = { | ||
component: WorkCard, | ||
parameters: { | ||
layout: 'centered', | ||
}, | ||
tags: ['autodocs'], | ||
}; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof WorkCard>; | ||
|
||
export const Default: Story = { | ||
args: { | ||
isPublic: true, | ||
title: 'title', | ||
tags: [ | ||
{ | ||
id: '1', | ||
name: 'name', | ||
color: '#000000', | ||
textColor: '#ffffff', | ||
}, | ||
{ | ||
id: '2', | ||
name: 'name', | ||
textColor: '#ffffff', | ||
color: '#000000', | ||
}, | ||
], | ||
createdAt: dateFormat(new Date().toString(), 'yyyy/MM/dd'), | ||
creator: { | ||
id: '1', | ||
displayName: 'name', | ||
avatarUrl: 'https://avatars.githubusercontent.com/u/94045195?v=4', | ||
}, | ||
thumbnailUrl: 'https://avatars.githubusercontent.com/u/94045195?v=4', | ||
}, | ||
}; | ||
|
||
export const Private: Story = { | ||
args: { | ||
isPublic: false, | ||
title: 'title', | ||
tags: [ | ||
{ | ||
id: '1', | ||
name: 'name', | ||
color: '#000000', | ||
textColor: '#ffffff', | ||
}, | ||
{ | ||
id: '2', | ||
name: 'name', | ||
color: '#000000', | ||
textColor: '#ffffff', | ||
}, | ||
], | ||
createdAt: dateFormat(new Date().toString(), 'yyyy/MM/dd'), | ||
creator: { | ||
id: '1', | ||
displayName: 'name', | ||
avatarUrl: 'https://avatars.githubusercontent.com/u/94045195?v=4', | ||
}, | ||
thumbnailUrl: 'https://avatars.githubusercontent.com/u/94045195?v=4', | ||
}, | ||
}; | ||
|
||
export const LongTitle: Story = { | ||
args: { | ||
isPublic: true, | ||
title: | ||
'とても長いタイトルですううううううううううううううううううううううううううううううううう', | ||
tags: [ | ||
{ | ||
id: '1', | ||
name: 'name', | ||
color: '#000000', | ||
textColor: '#ffffff', | ||
}, | ||
{ | ||
id: '2', | ||
name: 'name', | ||
color: '#000000', | ||
textColor: '#ffffff', | ||
}, | ||
], | ||
createdAt: dateFormat(new Date().toString(), 'yyyy/MM/dd'), | ||
creator: { | ||
id: '1', | ||
displayName: 'name', | ||
avatarUrl: 'https://avatars.githubusercontent.com/u/94045195?v=4', | ||
}, | ||
thumbnailUrl: 'https://avatars.githubusercontent.com/u/94045195?v=4', | ||
}, | ||
}; | ||
|
||
export const NumerousTags: Story = { | ||
args: { | ||
isPublic: true, | ||
title: 'title', | ||
tags: [ | ||
{ | ||
id: '1', | ||
name: 'name', | ||
color: '#000000', | ||
textColor: '#ffffff', | ||
}, | ||
{ | ||
id: '2', | ||
name: 'name', | ||
color: '#000000', | ||
textColor: '#ffffff', | ||
}, | ||
{ | ||
id: '3', | ||
name: 'name', | ||
color: '#000000', | ||
textColor: '#ffffff', | ||
}, | ||
{ | ||
id: '4', | ||
name: 'name', | ||
color: '#000000', | ||
textColor: '#ffffff', | ||
}, | ||
{ | ||
id: '5', | ||
name: 'name', | ||
color: '#000000', | ||
textColor: '#ffffff', | ||
}, | ||
], | ||
createdAt: dateFormat(new Date().toString(), 'yyyy/MM/dd'), | ||
creator: { | ||
id: '1', | ||
displayName: 'name', | ||
avatarUrl: 'https://avatars.githubusercontent.com/u/94045195?v=4', | ||
}, | ||
thumbnailUrl: 'https://avatars.githubusercontent.com/u/94045195?v=4', | ||
}, | ||
}; | ||
|
||
export const Loading: Story = { | ||
render: () => <WorkCardLoading />, | ||
}; |
72 changes: 72 additions & 0 deletions
72
src/components/model/Work/components/WorkCard/index.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import { render } from '@testing-library/react'; | ||
|
||
import '@testing-library/jest-dom'; | ||
import { WorkCard } from '.'; | ||
|
||
import type { ImageProps } from 'next/image'; | ||
|
||
jest.mock('next/image', () => ({ | ||
__esModule: true, | ||
default: (props: ImageProps & { src?: string }): JSX.Element => ( | ||
// eslint-disable-next-line @next/next/no-img-element | ||
<img src={props.src} alt={props.alt} /> | ||
), | ||
})); | ||
|
||
describe('model/WorkCard', () => { | ||
const mockProps = { | ||
isPublic: true, | ||
title: 'Sample Title', | ||
tags: [ | ||
{ id: '1', name: 'Tag 1', color: 'red', textColor: 'white' }, | ||
{ id: '2', name: 'Tag 2', color: 'blue', textColor: 'white' }, | ||
], | ||
creator: { | ||
id: '1', | ||
avatarUrl: '/mock.png', | ||
displayName: 'John Doe', | ||
}, | ||
createdAt: '2022-01-01', | ||
thumbnailUrl: '/mock.png', | ||
}; | ||
|
||
it('renders the WorkCard component', () => { | ||
const { container } = render(<WorkCard {...mockProps} />); | ||
expect(container.firstChild).toHaveClass('p-2 w-60 h-80'); | ||
}); | ||
|
||
it('renders the thumbnail image', () => { | ||
const { getByAltText } = render(<WorkCard {...mockProps} />); | ||
const thumbnailImage = getByAltText(`${mockProps.title}のサムネイル`); | ||
expect(thumbnailImage).toBeInTheDocument(); | ||
expect(thumbnailImage).toHaveAttribute('src', mockProps.thumbnailUrl); | ||
}); | ||
|
||
it('renders the title', () => { | ||
const { getByText } = render(<WorkCard {...mockProps} />); | ||
const titleElement = getByText(mockProps.title); | ||
expect(titleElement).toBeInTheDocument(); | ||
}); | ||
|
||
it('renders the tags', () => { | ||
const { getByText } = render(<WorkCard {...mockProps} />); | ||
mockProps.tags.forEach((tag) => { | ||
const tagElement = getByText(tag.name); | ||
expect(tagElement).toBeInTheDocument(); | ||
expect(tagElement).toHaveStyle(`background-color: ${tag.color}`); | ||
expect(tagElement).toHaveStyle('color: white'); | ||
}); | ||
}); | ||
|
||
it('renders the creator', () => { | ||
const { getByText } = render(<WorkCard {...mockProps} />); | ||
const creatorElement = getByText(mockProps.creator.displayName); | ||
expect(creatorElement).toBeInTheDocument(); | ||
}); | ||
|
||
it('renders the creation date', () => { | ||
const { getByText } = render(<WorkCard {...mockProps} />); | ||
const creationDateElement = getByText(mockProps.createdAt); | ||
expect(creationDateElement).toBeInTheDocument(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './presentations'; |
3 changes: 3 additions & 0 deletions
3
src/components/model/Work/components/WorkCard/presentations/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from './main'; | ||
|
||
export { WorkCardLoading } from './loading'; |
37 changes: 37 additions & 0 deletions
37
src/components/model/Work/components/WorkCard/presentations/loading.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import type { FC } from 'react'; | ||
|
||
import { Card, CardContent } from '@/components/ui/Card'; | ||
import { Skeleton } from '@/components/ui/Skeleton'; | ||
|
||
export const WorkCardLoading: FC = () => ( | ||
<Card className="p-2 w-60 h-80"> | ||
<Skeleton className="aspect-thumbnail rounded-sm" /> | ||
<CardContent className="flex p-0 gap-4 flex-col pt-4"> | ||
<Skeleton className="w-24 h-6" /> | ||
<TagLoading /> | ||
<div> | ||
<UserLoading /> | ||
<div className="flex-grow text-end float-end"> | ||
<Skeleton className="w-16 h-3" /> | ||
</div> | ||
</div> | ||
</CardContent> | ||
</Card> | ||
); | ||
|
||
const TagLoading: FC = () => ( | ||
<div className="flex flex-row gap-2 pb-2"> | ||
{Array.from({ length: 3 }, (_, i) => ( | ||
<Skeleton key={i} className="w-12 h-5" /> | ||
))} | ||
</div> | ||
); | ||
|
||
const UserLoading: FC = () => ( | ||
<div className="flex items-center gap-2"> | ||
<Skeleton className="w-6 h-6 rounded-full" /> | ||
<div className="flex flex-col"> | ||
<Skeleton className="w-20 h-4" /> | ||
</div> | ||
</div> | ||
); |
98 changes: 98 additions & 0 deletions
98
src/components/model/Work/components/WorkCard/presentations/main.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import type { FC } from 'react'; | ||
|
||
import { Globe, Lock } from 'lucide-react'; | ||
import Image from 'next/image'; | ||
import Link from 'next/link'; | ||
|
||
import { Avatar, AvatarImage } from '@/components/ui/Avatar'; | ||
import { Card, CardContent, CardTitle } from '@/components/ui/Card'; | ||
import { Typography } from '@/components/ui/Typography'; | ||
|
||
{ | ||
/* TODO:user domainが作成されたらそこからimportする */ | ||
} | ||
type User = { | ||
id: string; | ||
avatarUrl: string; | ||
displayName: string; | ||
}; | ||
|
||
{ | ||
/* TODO:tag domainが作成されたらそこからimportする */ | ||
} | ||
type Tag = { | ||
id: string; | ||
name: string; | ||
color: string; | ||
textColor: string; | ||
}; | ||
|
||
type Props = { | ||
isPublic: boolean; | ||
title: string; | ||
tags: Tag[]; | ||
creator: User; | ||
createdAt: string; | ||
thumbnailUrl: string; | ||
}; | ||
|
||
export const WorkCard: FC<Props> = ({ | ||
isPublic, | ||
title, | ||
tags, | ||
createdAt, | ||
creator, | ||
thumbnailUrl, | ||
}) => ( | ||
<Card className="p-2 w-60 h-80"> | ||
<div className="relative aspect-thumbnail rounded-sm overflow-hidden"> | ||
<Visibility isPublic={isPublic} /> | ||
<Image | ||
src={thumbnailUrl} | ||
alt={`${title}のサムネイル`} | ||
fill | ||
className="object-cover" | ||
/> | ||
</div> | ||
<CardContent className="flex p-0 gap-4 flex-col pt-4"> | ||
<CardTitle className="text-ellipsis overflow-hidden text-nowrap"> | ||
{title} | ||
</CardTitle> | ||
<div className="flex flex-row gap-2 overflow-scroll pb-2"> | ||
{/* TODO:tag domainが作成されたらそこからimportする */} | ||
{tags.map((tag) => ( | ||
<span | ||
key={tag.id} | ||
className="rounded-sm px-2 text-sm" | ||
style={{ backgroundColor: tag.color, color: tag.textColor }} | ||
> | ||
{tag.name} | ||
</span> | ||
))} | ||
</div> | ||
<div> | ||
{/* TODO:user domainが作成されたらそこからimportする */} | ||
<UserCard {...creator} /> | ||
<span className="flex-grow text-end float-end"> | ||
<Typography variant="caption">{createdAt}</Typography> | ||
</span> | ||
</div> | ||
</CardContent> | ||
</Card> | ||
); | ||
|
||
const UserCard: FC<User> = ({ id, avatarUrl, displayName }) => ( | ||
<div className="flex flex-row gap-2 relative"> | ||
<Link className="w-full h-full absolute" href={`/users/${id}`} /> | ||
<Avatar className="w-6 h-6 border-[0.5px] border-black"> | ||
<AvatarImage src={avatarUrl} /> | ||
</Avatar> | ||
<p className="font-bold">{displayName}</p> | ||
</div> | ||
); | ||
|
||
const Visibility: FC<{ isPublic: boolean }> = ({ isPublic }) => ( | ||
<span className="absolute z-50 left-1 top-1 text-green-light drop-shadow"> | ||
{isPublic ? <Globe className="w-8 h-8" /> : <Lock className="w-8 h-8" />} | ||
</span> | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
|
||
export * from './WorkCard'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters