Skip to content

Commit

Permalink
[#406] [모임 상세] 멤버 목록 컴포넌트 (#424)
Browse files Browse the repository at this point in the history
* chore: arrow-left.svg width, height 속성 제거

* feat: MemberItem 컴포넌트 구현

* feat: MemberItem 컴포넌트 스토리 작성

* feat: ShortMemberInfo 컴포넌트 작성

* feat: ShortMemberInfo 스토리북 작성

* style: 전체보기 버튼 size 수정

* fix: 멤버 전체보기 버튼 next/link 사용하도록 수정
  • Loading branch information
gxxrxn committed Jun 17, 2024
1 parent 9333f87 commit 199a234
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 1 deletion.
2 changes: 1 addition & 1 deletion public/icons/arrow-left.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions src/stories/bookgroup/detail/MemberItem.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Meta, StoryObj } from '@storybook/react';

import MemberItem from '@/ui/bookgroup/detail/MemberItem';

const meta: Meta<typeof MemberItem> = {
title: 'bookgroup/detail/MemberItem',
component: MemberItem,
tags: ['autodocs'],
};

export default meta;

type Story = StoryObj<typeof MemberItem>;

export const Default: Story = {
args: {
profileImageSrc: 'https://bit.ly/dan-abramov',
name: '댄',
job: { group: '개발', name: '프론트엔드 개발자' },
isOwner: true,
},
};
48 changes: 48 additions & 0 deletions src/stories/bookgroup/detail/ShortMemberInfo.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Meta, StoryObj } from '@storybook/react';

import ShortMemberInfo from '@/ui/bookgroup/detail/ShortMemberInfo';

const meta: Meta<typeof ShortMemberInfo> = {
title: 'bookgroup/detail/ShortMemberInfo',
component: ShortMemberInfo,
tags: ['autodocs'],
};

export default meta;

type Story = StoryObj<typeof ShortMemberInfo>;

export const Default: Story = {
args: {
members: [
{
id: 1,
profileImageSrc: 'https://bit.ly/dan-abramov',
name: '댄',
job: { group: '개발', name: '프론트엔드 개발자' },
isOwner: true,
},
{
id: 2,
profileImageSrc: 'https://bit.ly/kent-c-dodds',
name: '콜라',
job: { group: '개발', name: '백엔드 개발자' },
isOwner: false,
},
{
id: 3,
profileImageSrc: 'https://bit.ly/code-beast',
name: 'Code Beast',
job: { group: '디자인', name: 'UI/UX 디자이너' },
isOwner: false,
},
{
id: 4,
profileImageSrc: 'https://bit.ly/ryan-florence',
name: 'Ryan',
job: { group: '개발', name: '유니티 개발자' },
isOwner: false,
},
],
},
};
58 changes: 58 additions & 0 deletions src/ui/bookgroup/detail/MemberItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import Image from 'next/image';

interface MemberItemProps {
profileImageSrc: string;
name: string;
job: { group: string; name: string };
isOwner: boolean;
}

const MemberItem = ({
profileImageSrc,
name,
job,
isOwner,
}: MemberItemProps) => {
return (
<div className="flex gap-[0.8rem]">
<Avatar profileImageSrc={profileImageSrc} name={name} />
<div className="flex flex-col">
<Name text={name} isMarked={isOwner} />
<Job group={job.group} name={job.name} />
</div>
</div>
);
};

export default MemberItem;

// FIXME: Avatar Base 컴포넌트로 변경
const Avatar = ({
profileImageSrc,
name,
}: {
profileImageSrc: string;
name: string;
}) => (
<span
className={`relative h-[3.5rem] w-[3.5rem] ${
profileImageSrc ? 'bg-white' : 'bg-black-400'
}`}
>
{profileImageSrc && (
<Image alt={name} src={profileImageSrc} fill className="rounded-full" />
)}
</span>
);

const Name = ({ text, isMarked }: { text: string; isMarked: boolean }) => (
<p className="text-sm font-bold">
{text} {isMarked && ' 👑'}
</p>
);

const Job = ({ group, name }: { group: string; name: string }) => (
<p className="text-xs text-placeholder">
{group}{name}
</p>
);
58 changes: 58 additions & 0 deletions src/ui/bookgroup/detail/ShortMemberInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { IconArrowLeft } from '@public/icons';
import Button from '@/ui/Base/Button';
import MemberItem from './MemberItem';
import Link from 'next/link';
import { usePathname } from 'next/navigation';

type Member = {
id: number;
profileImageSrc: string;
name: string;
job: { group: string; name: string };
isOwner: boolean;
};

interface ShortMemberInfoProps {
members: Member[];
}

const MEMBER_SHOW_LIMIT = 3;

const ShortMemberInfo = ({ members }: ShortMemberInfoProps) => {
return (
<div className="flex flex-col gap-[2rem]">
<Heading text="멤버" />
<MemberList members={members.slice(0, MEMBER_SHOW_LIMIT)} />
<ViewAllButton />
</div>
);
};

export default ShortMemberInfo;

const Heading = ({ text }: { text: string }) => (
<p className="text-xl font-bold">{text}</p>
);

const MemberList = ({ members }: { members: Member[] }) => (
<div className="flex flex-col gap-[1rem]">
{members.map(({ id, ...memberItemProps }) => (
<MemberItem key={id} {...memberItemProps} />
))}
</div>
);

const ViewAllButton = () => {
const pathname = usePathname();

return (
<Link href={`${pathname}/members`}>
<Button size="full" colorScheme="main-light">
<span className="mr-[0.5rem] text-sm font-bold text-black-700">
전체보기
</span>
<IconArrowLeft className="inline-block h-[1rem] w-[1rem] rotate-180" />
</Button>
</Link>
);
};

0 comments on commit 199a234

Please sign in to comment.