From 8486739b8b069181b74a1f398311961ce078c1b2 Mon Sep 17 00:00:00 2001 From: Seojisoo20191941 Date: Sun, 28 Jan 2024 14:23:33 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=EB=82=B4=20=EB=AA=A8=EC=9E=84=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/endpoint/meetings/getMeetings.ts | 53 ++++++++++++++ .../members/detail/MemberDetail.tsx | 32 +++++++-- .../members/detail/MemberMeetingCard.tsx | 69 ++++++++++++++++++- src/components/members/detail/types.ts | 11 +++ src/constants/links.ts | 1 + 5 files changed, 159 insertions(+), 7 deletions(-) create mode 100644 src/api/endpoint/meetings/getMeetings.ts diff --git a/src/api/endpoint/meetings/getMeetings.ts b/src/api/endpoint/meetings/getMeetings.ts new file mode 100644 index 000000000..c034e918a --- /dev/null +++ b/src/api/endpoint/meetings/getMeetings.ts @@ -0,0 +1,53 @@ +import axios from 'axios'; +import { z } from 'zod'; + +// FIXME: 1/28 데모데이 due date가 얼마 남지 않은 이슈로 크루 api와 바로 통신했습니다. +// 플그 서버와 통신하도록 수정 + zod, createEndPoint 사용하도록 변경 필요합니다. 담당자: FE 서지수, BE 이승헌 +// 무한스크롤 적용해야합니다. + +const MeetingSchema = z.object({ + id: z.number(), + isMeetingLeader: z.boolean(), + title: z.string(), + imageUrl: z.string(), + category: z.string(), + isActiveMeeting: z.boolean(), + mstartDate: z.string(), + mendDate: z.string(), +}); + +const MetaSchema = z.object({ + page: z.number(), + take: z.number(), + itemCount: z.number(), + pageCount: z.number(), + hasPreviousPage: z.boolean(), + hasNextPage: z.boolean(), +}); + +export const CREW_ORIGIN = + process.env.NODE_ENV === 'development' ? `https://crew.api.dev.sopt.org` : `https://crew.api.prod.sopt.org`; + +// export const getMeetings = createEndpoint({ +// request: (orgUserId: number) => ({ +// method: 'GET', +// url: `${CREW_ORIGIN}/meeting/v2/org-user?orgUserId=${orgUserId}`, +// }), +// serverResponseScheme: z.object({ +// meetings: z.array(MeetingSchema), +// meta: MetaSchema, +// }), +// }); + +// export const getMeetings = async (orgUserId: number) => { +// await axios.request({ +// method: 'GET', +// baseURL: `${CREW_ORIGIN}/meeting/v2/org-user?orgUserId=${orgUserId}`, +// }); +// }; + +export async function getMeetings(orgUserId: number) { + const data = await axios.get(`https://crew.api.dev.sopt.org/meeting/v2/org-user?orgUserId=${orgUserId}`); + + return data.data?.meetings; +} diff --git a/src/components/members/detail/MemberDetail.tsx b/src/components/members/detail/MemberDetail.tsx index 5cff09db8..8f642381e 100644 --- a/src/components/members/detail/MemberDetail.tsx +++ b/src/components/members/detail/MemberDetail.tsx @@ -1,5 +1,6 @@ import styled from '@emotion/styled'; import { colors } from '@sopt-makers/colors'; +import { useQuery } from '@tanstack/react-query'; import dayjs from 'dayjs'; import { uniq } from 'lodash-es'; import Link from 'next/link'; @@ -10,6 +11,7 @@ import MailIcon from 'public/icons/icon-mail.svg'; import ProfileIcon from 'public/icons/icon-profile.svg'; import { FC, useMemo } from 'react'; +import { getMeetings } from '@/api/endpoint/meetings/getMeetings'; import { useGetMemberOfMe } from '@/api/endpoint/members/getMemberOfMe'; import { useGetMemberProfileById } from '@/api/endpoint_LEGACY/hooks'; import { isProjectCategory } from '@/api/endpoint_LEGACY/projects/type'; @@ -21,9 +23,11 @@ import EmptyProfile from '@/components/members/detail/EmptyProfile'; import InfoItem from '@/components/members/detail/InfoItem'; import InterestSection from '@/components/members/detail/InterestSection'; import MemberDetailSection from '@/components/members/detail/MemberDetailSection'; +import MemberMeetingCard from '@/components/members/detail/MemberMeetingCard'; import MemberProjectCard from '@/components/members/detail/MemberProjectCard'; import MessageSection from '@/components/members/detail/MessageSection'; import PartItem from '@/components/members/detail/PartItem'; +import { MeetingType } from '@/components/members/detail/types'; import { DEFAULT_DATE } from '@/components/members/upload/constants'; import { Category } from '@/components/projects/types'; import { playgroundLink } from '@/constants/links'; @@ -51,7 +55,11 @@ const MemberDetail: FC = ({ memberId }) => { const router = useRouter(); const { data: profile, isLoading, error } = useGetMemberProfileById(safeParseInt(memberId) ?? undefined); const { data: me } = useGetMemberOfMe(); - + const { data: meetingList } = useQuery({ + queryKey: ['getMeetings'], + queryFn: () => getMeetings(Number(memberId) ?? undefined), + }); + console.log(meetingList); const sortedSoptActivities = useMemo(() => { if (!profile?.soptActivities) { return []; @@ -253,6 +261,20 @@ const MemberDetail: FC = ({ memberId }) => { )} + + {profile.name}님이 참여한 모임 + {meetingList && meetingList?.length > 0 && ( + <> + {meetingList.length}개의 프로젝트에 참여 + + {meetingList.map((meeting: MeetingType) => ( + + ))} + + + )} + {meetingList?.length === 0 && 아직 참여한 프로젝트가 없어요} + ); @@ -505,14 +527,14 @@ const ProjectSub = styled.div` const ProjectDisplay = styled.div` display: grid; grid-template-columns: repeat(2, 1fr); - row-gap: 64px; + row-gap: 20px; column-gap: 29px; - margin-top: 60px; + margin-top: 32px; @media ${MOBILE_MEDIA_QUERY} { display: flex; flex-direction: column; - gap: 26px; - margin-top: 26px; + gap: 24px; + margin-top: 24px; } `; diff --git a/src/components/members/detail/MemberMeetingCard.tsx b/src/components/members/detail/MemberMeetingCard.tsx index de1cc7918..357b5c719 100644 --- a/src/components/members/detail/MemberMeetingCard.tsx +++ b/src/components/members/detail/MemberMeetingCard.tsx @@ -1,3 +1,68 @@ -export default function MemberMeetingCard() { - return
MemberGroupCard
; +import styled from '@emotion/styled'; +import { colors } from '@sopt-makers/colors'; +import dayjs from 'dayjs'; +import Link from 'next/link'; + +import ContentsCard from '@/components/common/ContentsCard'; +import { playgroundLink } from '@/constants/links'; + +interface Meeting { + id: number; + isMeetingLeader: boolean; + title: string; + category: string; + imageUrl: string; + isActiveMeeting: boolean; + mstartDate: string; + mendDate: string; } + +interface MeetingProps extends Meeting { + userName: string; +} + +export default function MemberMeetingCard({ + id, + isMeetingLeader, + title, + category, + imageUrl, + mstartDate, + mendDate, + isActiveMeeting, + userName, +}: MeetingProps) { + const meetingCategory = isMeetingLeader ? `${category} | ${userName}님이 만든 모임` : category; + const startDate = dayjs(mstartDate).format('YYYY.MM.DD'); + const endDate = dayjs(mendDate).format('YYYY.MM.DD'); + const date = startDate === endDate ? startDate : `${startDate} - ${endDate}`; + + return ( + + + + {date} + + } + /> + + ); +} + +const Circle = styled.div<{ isActiveMeeting: boolean }>` + border-radius: 50%; + background-color: ${({ isActiveMeeting }) => (isActiveMeeting ? '#CDF47C' : colors.gray300)}; + width: 6px; + height: 6px; +`; + +const Bottom = styled.footer` + display: flex; + gap: 8px; + align-items: center; +`; diff --git a/src/components/members/detail/types.ts b/src/components/members/detail/types.ts index 1739d145f..ec5b1b187 100644 --- a/src/components/members/detail/types.ts +++ b/src/components/members/detail/types.ts @@ -15,3 +15,14 @@ export type Career = endDate: string; isCurrent: false; }; + +export type MeetingType = { + id: number; + isMeetingLeader: boolean; + title: string; + imageUrl: string; + category: string; + isActiveMeeting: boolean; + mstartDate: string; + mendDate: string; +}; diff --git a/src/constants/links.ts b/src/constants/links.ts index 150ef45bc..59d81dda5 100644 --- a/src/constants/links.ts +++ b/src/constants/links.ts @@ -17,6 +17,7 @@ export const playgroundLink = { projectUpload: () => `/projects/upload`, projectEdit: (id: string | number) => `/projects/edit/${id}`, groupList: () => '/group', + groupDetail: (id: string | number) => `/group/detail?id=${id}`, intro: () => `/intro`, login: () => `/auth/login`, register: () => `/auth/verify`, From dc13ab49c4f9e021999453370dac3d60927b03e1 Mon Sep 17 00:00:00 2001 From: Seojisoo20191941 Date: Sun, 28 Jan 2024 14:35:09 +0900 Subject: [PATCH 2/4] =?UTF-8?q?refactor:=20meetingList=20undefined=20?= =?UTF-8?q?=EC=95=84=EB=8B=90=20=EB=95=8C=EC=97=90=20length=20=EA=B5=AC?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/members/detail/MemberDetail.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/members/detail/MemberDetail.tsx b/src/components/members/detail/MemberDetail.tsx index 575115dbe..f1ac34e67 100644 --- a/src/components/members/detail/MemberDetail.tsx +++ b/src/components/members/detail/MemberDetail.tsx @@ -59,7 +59,7 @@ const MemberDetail: FC = ({ memberId }) => { queryKey: ['getMeetings'], queryFn: () => getMeetings(Number(memberId) ?? undefined), }); - console.log(meetingList); + const sortedSoptActivities = useMemo(() => { if (!profile?.soptActivities) { return []; @@ -263,7 +263,7 @@ const MemberDetail: FC = ({ memberId }) => { {profile.name}님이 참여한 모임 - {meetingList && meetingList?.length > 0 && ( + {meetingList && meetingList.length > 0 && ( <> {meetingList.length}개의 프로젝트에 참여 @@ -273,7 +273,7 @@ const MemberDetail: FC = ({ memberId }) => { )} - {meetingList?.length === 0 && 아직 참여한 프로젝트가 없어요} + {meetingList && meetingList.length === 0 && 아직 참여한 프로젝트가 없어요} @@ -530,7 +530,7 @@ const ProjectDisplay = styled.div` row-gap: 20px; column-gap: 29px; margin-top: 32px; - + @media ${MOBILE_MEDIA_QUERY} { display: flex; flex-direction: column; From 20e417918973ad7c75973b1922ed025fd8df45c3 Mon Sep 17 00:00:00 2001 From: Seojisoo20191941 Date: Sun, 28 Jan 2024 14:41:02 +0900 Subject: [PATCH 3/4] =?UTF-8?q?refactor:=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/endpoint/meetings/getMeetings.ts | 2 +- src/components/members/detail/MemberDetail.tsx | 6 ++++-- src/components/members/detail/MemberProjectCard.tsx | 2 -- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/api/endpoint/meetings/getMeetings.ts b/src/api/endpoint/meetings/getMeetings.ts index c034e918a..d94eda5d5 100644 --- a/src/api/endpoint/meetings/getMeetings.ts +++ b/src/api/endpoint/meetings/getMeetings.ts @@ -46,7 +46,7 @@ export const CREW_ORIGIN = // }); // }; -export async function getMeetings(orgUserId: number) { +export async function getMeetings(orgUserId: string) { const data = await axios.get(`https://crew.api.dev.sopt.org/meeting/v2/org-user?orgUserId=${orgUserId}`); return data.data?.meetings; diff --git a/src/components/members/detail/MemberDetail.tsx b/src/components/members/detail/MemberDetail.tsx index f1ac34e67..9765cd74a 100644 --- a/src/components/members/detail/MemberDetail.tsx +++ b/src/components/members/detail/MemberDetail.tsx @@ -1,6 +1,7 @@ import styled from '@emotion/styled'; import { colors } from '@sopt-makers/colors'; import { useQuery } from '@tanstack/react-query'; +import { Spacing } from '@toss/emotion-utils'; import dayjs from 'dayjs'; import { uniq } from 'lodash-es'; import Link from 'next/link'; @@ -56,8 +57,8 @@ const MemberDetail: FC = ({ memberId }) => { const { data: profile, isLoading, error } = useGetMemberProfileById(safeParseInt(memberId) ?? undefined); const { data: me } = useGetMemberOfMe(); const { data: meetingList } = useQuery({ - queryKey: ['getMeetings'], - queryFn: () => getMeetings(Number(memberId) ?? undefined), + queryKey: ['getMeetings', memberId], + queryFn: () => getMeetings(memberId), }); const sortedSoptActivities = useMemo(() => { @@ -276,6 +277,7 @@ const MemberDetail: FC = ({ memberId }) => { {meetingList && meetingList.length === 0 && 아직 참여한 프로젝트가 없어요} + ); }; diff --git a/src/components/members/detail/MemberProjectCard.tsx b/src/components/members/detail/MemberProjectCard.tsx index a9445cd6e..34bd1013b 100644 --- a/src/components/members/detail/MemberProjectCard.tsx +++ b/src/components/members/detail/MemberProjectCard.tsx @@ -20,8 +20,6 @@ const MemberProjectCard: FC = ({ ? `${serviceType} | ${generation}기 ${PROJECT_CATEGORY_LABEL[category]}` : PROJECT_CATEGORY_LABEL[category]; - console.log(id); - return ( Date: Sun, 28 Jan 2024 14:47:27 +0900 Subject: [PATCH 4/4] =?UTF-8?q?chore:=20=EB=AA=A8=EC=9E=84=20=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=EA=B2=BD=EC=9A=B0=20=EC=9B=8C=EB=94=A9=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/members/detail/MemberDetail.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/members/detail/MemberDetail.tsx b/src/components/members/detail/MemberDetail.tsx index 9765cd74a..b3ee538a7 100644 --- a/src/components/members/detail/MemberDetail.tsx +++ b/src/components/members/detail/MemberDetail.tsx @@ -274,7 +274,7 @@ const MemberDetail: FC = ({ memberId }) => { )} - {meetingList && meetingList.length === 0 && 아직 참여한 프로젝트가 없어요} + {meetingList && meetingList.length === 0 && 아직 참여한 모임이 없어요}