From cb4e144bcdea2d0bc0cf84325c688d8d3d0e9cda Mon Sep 17 00:00:00 2001 From: Doeun Kim Date: Thu, 22 Aug 2024 21:19:21 +0900 Subject: [PATCH] =?UTF-8?q?feat(web-domains):=20about=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=86=90=20=ED=9D=94=EB=93=A4=EA=B8=B0=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80=20(#121)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 타인 마이페이지에서 손흔들기 버튼 추가 * feat: 손흔들기 요청 처리 * fix: 버튼 상태 처리 수정 * fix: 버튼 상태 string 수정 * feat: 손 흔들기 상태 조회 처리 --- .../apis/mutates/useCreateHandWavings.ts | 20 ++++++++ .../apis/queries/useGetHandWavingsStatus.ts | 46 +++++++++++++++++++ .../apis/schema/HandWavingStatusResponse.ts | 4 ++ .../features/containers/ScreenContainer.tsx | 41 +++++++++++++++-- .../about-me/features/containers/styles.ts | 10 ++++ .../features/hooks/useGetFirstMeetingId.ts | 9 ++++ 6 files changed, 125 insertions(+), 5 deletions(-) create mode 100644 packages/web-domains/src/about-me/common/apis/mutates/useCreateHandWavings.ts create mode 100644 packages/web-domains/src/about-me/common/apis/queries/useGetHandWavingsStatus.ts create mode 100644 packages/web-domains/src/about-me/common/apis/schema/HandWavingStatusResponse.ts create mode 100644 packages/web-domains/src/about-me/features/hooks/useGetFirstMeetingId.ts diff --git a/packages/web-domains/src/about-me/common/apis/mutates/useCreateHandWavings.ts b/packages/web-domains/src/about-me/common/apis/mutates/useCreateHandWavings.ts new file mode 100644 index 00000000..654e0763 --- /dev/null +++ b/packages/web-domains/src/about-me/common/apis/mutates/useCreateHandWavings.ts @@ -0,0 +1,20 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query'; + +import { Http } from '@/common/apis/base.api'; + +import { HAND_WAVINGS_STATUS_QUERY_KEY } from '../queries/useGetHandWavingsStatus'; + +interface Request { + meetingId: number; + receiverMemberId: number; +} + +export const useCreateHandWavings = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: ({ meetingId, receiverMemberId }: Request) => + Http.POST(`/v1/meetings/${meetingId}/hand-wavings`, { receiverMemberId }), + onSuccess: (_, variable) => queryClient.invalidateQueries({ queryKey: [HAND_WAVINGS_STATUS_QUERY_KEY, variable] }), + }); +}; diff --git a/packages/web-domains/src/about-me/common/apis/queries/useGetHandWavingsStatus.ts b/packages/web-domains/src/about-me/common/apis/queries/useGetHandWavingsStatus.ts new file mode 100644 index 00000000..2f17e40c --- /dev/null +++ b/packages/web-domains/src/about-me/common/apis/queries/useGetHandWavingsStatus.ts @@ -0,0 +1,46 @@ +import { QueryClient, useQuery, UseQueryOptions } from '@tanstack/react-query'; + +import { Http } from '@/common/apis/base.api'; + +import { HandWavingStatusResponse } from '../schema/HandWavingStatusResponse'; + +interface Params { + meetingId: number; + receiverMemberId: number; +} + +interface QueryProps extends Params { + options?: UseQueryOptions; +} + +const queryFn = ({ meetingId, receiverMemberId }: Params) => + Http.GET(`/v1/meetings/${meetingId}/hand-wavings/receiver/${receiverMemberId}/status`); + +export const HAND_WAVINGS_STATUS_QUERY_KEY = 'HAND_WAVINGS_STATUS_QUERY_KEY '; + +export const useGetHandWavingsStatus = (props: QueryProps) => { + const { options, ...params } = props; + + return useQuery({ + queryKey: [HAND_WAVINGS_STATUS_QUERY_KEY, params], + queryFn: () => queryFn(params), + enabled: params.meetingId > 0, + staleTime: 1000 * 60 * 10, // 10분 + ...options, + }); +}; + +interface PrefetchProps extends Params { + queryClient: QueryClient; +} + +export const getHandWavingsStatusPrefetch = (props: PrefetchProps) => { + const { queryClient, ...params } = props; + + const prefetch = queryClient.prefetchQuery({ + queryKey: [HAND_WAVINGS_STATUS_QUERY_KEY, params], + queryFn: () => queryFn(params), + }); + + return prefetch; +}; diff --git a/packages/web-domains/src/about-me/common/apis/schema/HandWavingStatusResponse.ts b/packages/web-domains/src/about-me/common/apis/schema/HandWavingStatusResponse.ts new file mode 100644 index 00000000..710bf210 --- /dev/null +++ b/packages/web-domains/src/about-me/common/apis/schema/HandWavingStatusResponse.ts @@ -0,0 +1,4 @@ +export interface HandWavingStatusResponse { + HandWavingId: number; + status: 'REQUESTED' | 'ACCEPTED' | 'REJECTED'; +} diff --git a/packages/web-domains/src/about-me/features/containers/ScreenContainer.tsx b/packages/web-domains/src/about-me/features/containers/ScreenContainer.tsx index c3545d2c..9a419945 100644 --- a/packages/web-domains/src/about-me/features/containers/ScreenContainer.tsx +++ b/packages/web-domains/src/about-me/features/containers/ScreenContainer.tsx @@ -1,22 +1,53 @@ 'use client'; -import { colors, size } from '@sambad/sds/theme'; -import { Fragment } from 'react'; +import { colors, shadow, size } from '@sambad/sds/theme'; +import { Button } from '@sds/components'; +import { useCreateHandWavings } from '@/about-me/common/apis/mutates/useCreateHandWavings'; +import { useGetHandWavingsStatus } from '@/about-me/common/apis/queries/useGetHandWavingsStatus'; import { ActionBar } from '@/common/components/ActionBar/ActionBar'; +import { useGetFirstMeetingId } from '../hooks/useGetFirstMeetingId'; +import { useIsMyByParams } from '../hooks/useIsMyByParams'; + import { ProfileContainer } from './ProfileContainer'; import { SegmentedControlContainer } from './SegmentedControlContainer'; +import { handWavingButtonCss, screenRootCss } from './styles'; export const ScreenContainer = () => { + const { isMy, meetingMemberId } = useIsMyByParams(); + const { meetingId } = useGetFirstMeetingId(); + const { data: wavingStatusData, isSuccess: getWavingStatusSuccess } = useGetHandWavingsStatus({ + meetingId, + receiverMemberId: meetingMemberId, + }); + const { mutate, isSuccess: sendWavingSuccess } = useCreateHandWavings(); + + const isProgressHandWavings = sendWavingSuccess || wavingStatusData?.status === 'REQUESTED'; + + const handleHandWaving = () => { + mutate({ meetingId, receiverMemberId: meetingMemberId }); + }; + return ( - - +
+
- + {!isMy && getWavingStatusSuccess && ( + + )} +
); }; diff --git a/packages/web-domains/src/about-me/features/containers/styles.ts b/packages/web-domains/src/about-me/features/containers/styles.ts index 1cae13f4..df904b49 100644 --- a/packages/web-domains/src/about-me/features/containers/styles.ts +++ b/packages/web-domains/src/about-me/features/containers/styles.ts @@ -43,3 +43,13 @@ export const answerContentCss = css({ marginTop: size['7xs'], }, }); + +export const handWavingButtonCss = css({ + position: 'absolute', + bottom: size['xl'], +}); + +export const screenRootCss = css({ + position: 'relative', + height: '100dvh', +}); diff --git a/packages/web-domains/src/about-me/features/hooks/useGetFirstMeetingId.ts b/packages/web-domains/src/about-me/features/hooks/useGetFirstMeetingId.ts new file mode 100644 index 00000000..b0c07af0 --- /dev/null +++ b/packages/web-domains/src/about-me/features/hooks/useGetFirstMeetingId.ts @@ -0,0 +1,9 @@ +import { useGetMeetings } from '@/about-me/common/apis/queries/useGetMeetings'; + +export const useGetFirstMeetingId = () => { + const { data } = useGetMeetings(); + // NOTE: 하나의 모임에 참여할 수 있는 현재 스펙에서 첫 번째 meetingId를 가져옴 + const meetingId = data?.meetings[0]?.meetingId || -1; + + return { meetingId }; +};