From 1b46d994e5055f26b824992f8caed93b6c8cf831 Mon Sep 17 00:00:00 2001 From: HiHoi Date: Mon, 11 Mar 2024 14:14:31 +0900 Subject: [PATCH] feat: team member list ver pc and mobile is added --- .../teams/[id]/panel/TeamInfoContainer.tsx | 157 ++++++------- src/app/teams/[id]/panel/TeamMemberList.tsx | 217 ++++++++++++++++++ 2 files changed, 290 insertions(+), 84 deletions(-) create mode 100644 src/app/teams/[id]/panel/TeamMemberList.tsx diff --git a/src/app/teams/[id]/panel/TeamInfoContainer.tsx b/src/app/teams/[id]/panel/TeamInfoContainer.tsx index d1d405d0b..0d4de90d2 100644 --- a/src/app/teams/[id]/panel/TeamInfoContainer.tsx +++ b/src/app/teams/[id]/panel/TeamInfoContainer.tsx @@ -1,7 +1,7 @@ import { useRouter } from 'next/navigation' import useSWR from 'swr' -import { MouseEvent, useEffect, useState } from 'react' -import { Button, Card, Popover, Stack, Typography } from '@mui/material' +import { useEffect } from 'react' +import { Stack, Typography } from '@mui/material' import useAxiosWithAuth from '@/api/config' import CuCircularProgress from '@/components/CuCircularProgress' import CuAvatar from '@/components/CuAvatar' @@ -10,44 +10,87 @@ import { ITeamInfo } from '@/types/ITeamInfo' import { StatusIcon, IconInfo } from './TeamInfoComponent' import * as style from './TeamInfoContainer.style' import { isAxiosError } from 'axios' -import OthersProfile from '@/app/panel/OthersProfile' -import { AccountBox } from '@/icons' +import useMedia from '@/hook/useMedia' +import { TeamMemberListMobile, TeamMemberListPc } from './TeamMemberList' -interface ITeamMemberInfo { +export interface ITeamMemberInfo { id: number name: string role: string } const TeamInfoContainer = ({ id }: { id: number }) => { + const { isPc } = useMedia() const axiosInstance = useAxiosWithAuth() // 팀의 정보를 불러오는 API 호출 const { data, error, isLoading } = useSWR( `${process.env.NEXT_PUBLIC_CSR_API}/api/v1/team/main/${id}`, (url: string) => axiosInstance(url).then((res) => res.data), ) - // 팀원의 정보를 불러오는 API 호출 -> 추후 API 통합이 필요 - const { data: memberData, isLoading: memberIsLoading } = useSWR< - Array - >( - `${process.env.NEXT_PUBLIC_CSR_API}/api/v1/team/main/member/${id}`, - (url: string) => axiosInstance(url).then((res) => res.data), - ) - const { setHeaderTitle } = useHeaderStore() - const router = useRouter() - // 멤버 리스트를 보여주기 위한 popover 관련 객체 - const [popOverAnchorEl, setPopOverAnchorEl] = - useState(null) + // // 팀원의 정보를 불러오는 API 호출 -> 추후 API 통합이 필요 + // const { data: memberData, isLoading: memberIsLoading } = useSWR< + // Array + // >( + // `${process.env.NEXT_PUBLIC_CSR_API}/api/v1/team/main/member/${id}`, + // (url: string) => axiosInstance(url).then((res) => res.data), + // ) - const handlePopoverOpen = (event: MouseEvent) => { - setPopOverAnchorEl(event.currentTarget) - } + // 테스트용 데이터 + const mockData: Array = [ + { + id: 1, + name: '테스트1', + role: 'LEADER', + }, + { + id: 2, + name: '테스트2', + role: 'MEMBER', + }, + { + id: 3, + name: '테스트3', + role: 'MEMBER', + }, + { + id: 4, + name: '테스트4', + role: 'MEMBER', + }, + { + id: 5, + name: '테스트5', + role: 'MEMBER', + }, + { + id: 6, + name: '테스트6', + role: 'MEMBER', + }, + { + id: 7, + name: '테스트7', + role: 'MEMBER', + }, + { + id: 8, + name: '테스트8', + role: 'MEMBER', + }, + { + id: 9, + name: '테스트9', + role: 'MEMBER', + }, + { + id: 10, + name: '테스트10테스트10테스트10테스트10테스트10테스트10', + role: 'MEMBER', + }, + ] - const handlePopoverClose = () => { - setPopOverAnchorEl(null) - } - - const open = Boolean(popOverAnchorEl) + const { setHeaderTitle } = useHeaderStore() + const router = useRouter() // set header useEffect(() => { @@ -102,65 +145,11 @@ const TeamInfoContainer = ({ id }: { id: number }) => { - - - - - - 멤버 리스트 - - - - {memberIsLoading || !memberData ? ( - - ) : ( - memberData.map((member) => ( - - - - {member.role === 'LEADER' && ( - - )} - - {member.name} - - - - - - )) - )} - - - + {isPc ? ( + + ) : ( + + )} diff --git a/src/app/teams/[id]/panel/TeamMemberList.tsx b/src/app/teams/[id]/panel/TeamMemberList.tsx new file mode 100644 index 000000000..299117a61 --- /dev/null +++ b/src/app/teams/[id]/panel/TeamMemberList.tsx @@ -0,0 +1,217 @@ +'use client' + +import { Button, Card, Popover, Stack, Typography } from '@mui/material' +import { ITeamMemberInfo } from './TeamInfoContainer' +import CuCircularProgress from '@/components/CuCircularProgress' +import { AccountBox } from '@/icons' +import { MouseEvent, useState } from 'react' +import useNicknameStore from '@/states/useNicknameStore' +import { useRouter } from 'next/navigation' +import ReportModal from '@/components/ReportModal' +import ExternalMessageModal from '@/app/panel/ExternalMessageModal' +import CuModal from '@/components/CuModal' + +// 팀원 리스트를 보여주는 컴포넌트의 props interface +interface ITeamMemberListProps { + members: Array +} + +// 공통으로 사용되는 컴포넌트 +// 1. 프로필 보기 버튼, 쪽지 보내기 버튼, 신고하기 버튼을 보여주는 컴포넌트 +const MemberButtonGroup = ({ + userId, + name, +}: { + userId: string + name: string +}) => { + const router = useRouter() + const myNickname = useNicknameStore.getState().nickname + + // 쪽지와 신고를 보내기 위한 모달 + const [modalType, setModalType] = useState('' as string) + const messageOpen = () => { + setModalType('message') + } + const reportOpen = () => { + setModalType('report') + } + const handleModalClose = () => { + setModalType('') + } + + // 남의 프로필 보기 + const goOthersProfile = () => { + router.push(`/profile/${userId}`) + } + // 자기 자신의 프로필 보기 + const goMypage = () => { + router.push('/my-page') + } + + // 유령 회원 처리 + if (Number(userId) === -1) return <> + + return ( + <> + {myNickname !== name ? ( + <> + + + + + ) : ( + + )} + + + + ) +} + +// 2. 팀원의 이름과 역할, 프로필 보기 버튼을 보여주는 컴포넌트 +const MemberInfo = ({ member }: { member: ITeamMemberInfo }) => { + return ( + + + + + {member.name} + + {member.role === 'LEADER' && ( + + )} + + + + + + + ) +} + +// 모바일에선 버튼을 클릭하여 모달을 통해 멤버 리스트를 보여준다. +const TeamMemberListMobile = ({ members }: ITeamMemberListProps) => { + const [open, setOpen] = useState(false) + + // 모달 관련 함수 + const handleOpen = () => { + setOpen(true) + } + const handleClose = () => { + setOpen(false) + } + return ( + <> + + + + {!members ? ( + + ) : ( + members.map((member) => ( + + )) + )} + + + + ) +} + +// PC에선 popover를 사용하여 멤버 리스트를 보여준다. +const TeamMemberListPc = ({ members }: ITeamMemberListProps) => { + // 멤버 리스트를 보여주기 위한 popover 관련 객체 + // mui의 기본 예제 참고 + const [popOverAnchorEl, setPopOverAnchorEl] = + useState(null) + + const handlePopoverOpen = (event: MouseEvent) => { + setPopOverAnchorEl(event.currentTarget) + } + + const handlePopoverClose = () => { + setPopOverAnchorEl(null) + } + + const open = Boolean(popOverAnchorEl) + + return ( + <> + + + + + 멤버 리스트 + + + {!members ? ( + + ) : ( + members.map((member) => ( + + )) + )} + + + + + ) +} + +export { TeamMemberListPc, TeamMemberListMobile }