Skip to content

Commit

Permalink
Feature/#256 팀원 목록 (#262)
Browse files Browse the repository at this point in the history
* feat: Member 타입 정의

#356

* chore: 팀원 목록 관련 mocks 데이터 추가

#256

* design: 팀원 목록 보는 ui 구현

#256

* api: 팀원 목록 조회 api 정의

#256

* chore: 나중에 할일 명시

#256

* feat: 팀장 위임하는 버튼 추가

#256

* fix: 틀린 경로명 고치기

#256

* fix: import 폴더 명 수정

#256
  • Loading branch information
llddang authored Jun 29, 2024
1 parent 5c41ab4 commit dfedd27
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 90 deletions.
3 changes: 3 additions & 0 deletions src/app/api/team.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ const postJoinTeam = (teamId: number, code: string) =>
body: code,
});

const getTeamMembers = (teamId: number) => teamFetcher(`/teams/${teamId}/members`);

const getMyTeams = (memberId: number) => teamFetcher(`/teams/members/${memberId}`);

const getMyTeamsWithStudy = (token: string, memberId: number) =>
Expand All @@ -57,4 +59,5 @@ export {
postJoinTeam,
getMyTeams,
getMyTeamsWithStudy,
getTeamMembers,
};
2 changes: 1 addition & 1 deletion src/app/team/[teamId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ const Page = ({ params }: { params: { teamId: number } }) => {
<Title isTeam imageUrl={teamInfo.imageUrl} name={teamInfo.name} description={teamInfo.description} />
{/* TODO 팀원 목록, 초대링크 버튼 */}
<Flex align="center" gap={{ base: '2', lg: '8' }}>
<TeamMember />
<TeamMember teamId={params.teamId} />
<Button color="white" bg="orange_dark" rightIcon={<BsLink45Deg size="24px" />} rounded="full" size="sm">
초대
</Button>
Expand Down
128 changes: 120 additions & 8 deletions src/containers/team/teamMember/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,126 @@
import { Avatar, AvatarGroup, useBreakpointValue } from '@chakra-ui/react';
'use client';

import teamMemberList from '@/mocks/teamMember';
import { Avatar, AvatarGroup, Box, Flex, IconButton, useBreakpointValue } from '@chakra-ui/react';
import { useEffect, useState } from 'react';
import { BiCrown, BiUserX } from 'react-icons/bi';

import ConfirmModal from '@/components/Modal/ConfirmModal';
import { teamMember } from '@/mocks/teamMember';
import { Member } from '@/types';

const TeamMember = ({ teamId }: { teamId: number }) => {
const [mandateModalOpen, setMandateModalOpen] = useState<boolean>(false);
const [firedModalOpen, setFiredModalOpen] = useState<boolean>(false);
const [modalMember, setModalMember] = useState<Member>({ id: -1, name: '', imageUrl: '' });
const [isHovering, setIsHovering] = useState<boolean>(false);

const handleMouseOut = () => {
setIsHovering(false);
};

const handleMouseOver = () => {
setIsHovering(true);
};

const handleFiredButtonClick = (member: Member) => {
setModalMember(member);
setFiredModalOpen(true);
};

const handleMandateButtonClick = (member: Member) => {
setModalMember(member);
setMandateModalOpen(true);
};

const handleModalCloseClick = () => {
setMandateModalOpen(false);
setFiredModalOpen(false);
setIsHovering(false);
};

const handleFiredMemberClick = () => {
// TODO: 팀원 퇴출 api 연결
handleModalCloseClick();
};

const handleMandateMemberClick = () => {
// TODO: 팀장 권한 위임 api 연결
handleModalCloseClick();
};

useEffect(() => {
// TODO: 팀원 목록 불러오기
}, [teamId]);

const TeamMember = () => {
return (
<AvatarGroup max={useBreakpointValue({ base: 3, lg: 4 })} size="md">
{teamMemberList.map((member) => {
return <Avatar key={member.googleId} name={member.name} src={member.imageUrl} />;
})}
</AvatarGroup>
<Box pos="relative" onMouseOut={handleMouseOut} onMouseOver={handleMouseOver}>
<AvatarGroup max={useBreakpointValue({ base: 3, lg: 4 })} size="md">
{teamMember.map((member) => {
return <Avatar key={member.id} name={member.name} src={member.imageUrl} />;
})}
</AvatarGroup>
{isHovering && (
<Box pos="absolute" zIndex="40" right="0" w="220px" h="400px">
<Box w="100%" h="100%" mt="2" p="4" pr="1" bg="white" borderRadius="xl" shadow="md">
<Box overflow="scroll" w="100%" h="100%">
{teamMember.map((member) => {
return (
<Flex align="center" justify="space-between" gap="2" p="2">
<Box>
<Avatar key={member.id} mr="2" name={member.name} size="sm" src={member.imageUrl} />
{member.name}
</Box>
{/* TODO: 팀장만 버튼 보이게 수정 */}
<Box>
<IconButton
fontSize="20px"
aria-label=""
icon={<BiCrown />}
isRound
onClick={() => {
handleMandateButtonClick(member);
}}
size="icon_md"
variant="icon_orange"
/>
<IconButton
fontSize="20px"
aria-label=""
icon={<BiUserX />}
isRound
onClick={() => {
handleFiredButtonClick(member);
}}
size="icon_md"
variant="icon_white"
/>
</Box>
</Flex>
);
})}
</Box>
</Box>
</Box>
)}
<ConfirmModal
isOpen={firedModalOpen}
onClose={handleModalCloseClick}
title="팀원 퇴출"
confirmButtonText="퇴출"
onConfirmButtonClick={handleFiredMemberClick}
>
{modalMember.name}을 퇴출하시겠습니까?
</ConfirmModal>
<ConfirmModal
isOpen={mandateModalOpen}
onClose={handleModalCloseClick}
title="팀장 위임"
confirmButtonText="위임"
onConfirmButtonClick={handleMandateMemberClick}
>
{modalMember.name}에게 팀장을 위임하겠습니까?
</ConfirmModal>
</Box>
);
};
export default TeamMember;
7 changes: 0 additions & 7 deletions src/containers/team/teamMember/types.ts

This file was deleted.

97 changes: 23 additions & 74 deletions src/mocks/teamMember.ts
Original file line number Diff line number Diff line change
@@ -1,76 +1,25 @@
import { TeamMemberProps } from '@/containers/team/teamMember/types';
/* eslint-disable import/prefer-default-export */
import { Member } from '@/types';

const teamMemberList: TeamMemberProps[] = [
{
name: '두레1',
googleId: '1',
email: 'email.com',
imageUrl: '',
isDeleted: false,
},
{
name: '두레2',
googleId: '2',
email: 'email.com',
imageUrl: 'https://bit.ly/ryan-florence',
isDeleted: false,
},
{
name: '두레3',
googleId: '3',
email: 'email.com',
imageUrl: '',
isDeleted: false,
},
{
name: '두레4',
googleId: '4',
email: 'email.com',
imageUrl: '',
isDeleted: false,
},
{
name: '두레5',
googleId: '5',
email: 'email.com',
imageUrl: '',
isDeleted: false,
},
{
name: '두레6',
googleId: '6',
email: 'email.com',
imageUrl: '',
isDeleted: false,
},
{
name: '두레7',
googleId: '7',
email: 'email.com',
imageUrl: '',
isDeleted: false,
},
{
name: '두레8',
googleId: '8',
email: 'email.com',
imageUrl: '',
isDeleted: false,
},
{
name: '두레9',
googleId: '9',
email: 'email.com',
imageUrl: '',
isDeleted: false,
},
{
name: '두레10',
googleId: '10',
email: 'email.com',
imageUrl: '',
isDeleted: false,
},
export const teamMember: Member[] = [
{ id: 1, name: '김철수1', imageUrl: '' },
{ id: 2, name: '김철수2', imageUrl: '' },
{ id: 3, name: '김철수3', imageUrl: '' },
{ id: 4, name: '김철수4', imageUrl: '' },
{ id: 5, name: '김철수5', imageUrl: '' },
{ id: 6, name: '김철수6', imageUrl: '' },
{ id: 7, name: '김철수7', imageUrl: '' },
{ id: 8, name: '김철수8', imageUrl: '' },
{ id: 9, name: '김철수9', imageUrl: '' },
{ id: 10, name: '김철수10', imageUrl: '' },
{ id: 11, name: '김철수11', imageUrl: '' },
{ id: 12, name: '김철수12', imageUrl: '' },
{ id: 13, name: '김철수13', imageUrl: '' },
{ id: 14, name: '김철수14', imageUrl: '' },
{ id: 15, name: '김철수15', imageUrl: '' },
{ id: 16, name: '김철수16', imageUrl: '' },
{ id: 17, name: '김철수17', imageUrl: '' },
{ id: 18, name: '김철수18', imageUrl: '' },
{ id: 19, name: '김철수19', imageUrl: '' },
{ id: 20, name: '김철수20', imageUrl: '' },
];

export default teamMemberList;
6 changes: 6 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ export interface TeamDetail extends Team {
attendanceRate: number;
}

export interface Member {
readonly id: number;
name: string;
imageUrl: string;
}

export interface Curriculum {
id: number;
participantId?: number;
Expand Down

0 comments on commit dfedd27

Please sign in to comment.