From 46901a62dd666f6e3669ebd351111061230998a0 Mon Sep 17 00:00:00 2001 From: hyeseon han Date: Fri, 23 Feb 2024 00:24:27 +0900 Subject: [PATCH 01/13] chore: eslint @typescript-eslint/no-floating-promises off --- .eslintrc.js | 1 + 1 file changed, 1 insertion(+) diff --git a/.eslintrc.js b/.eslintrc.js index fd9dec0..140164d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -20,5 +20,6 @@ module.exports = { '@typescript-eslint/strict-boolean-expressions': 'off', 'prettier/prettier': ['error', { endOfLine: 'auto' }], '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/no-floating-promises': 'off' }, }; From 37724936d03a847a291b2f85add4b7b6876c2101 Mon Sep 17 00:00:00 2001 From: hyeseon han Date: Fri, 23 Feb 2024 00:25:11 +0900 Subject: [PATCH 02/13] =?UTF-8?q?feat:=20CheckIcon=20=EC=B6=94=EA=B0=80,?= =?UTF-8?q?=20CheckBox=20component=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/icons/CheckIcon.tsx | 9 +++++++++ src/assets/icons/index.ts | 1 + src/components/atoms/CheckBox.tsx | 21 +++++++++++++++++++++ src/components/atoms/index.ts | 1 + 4 files changed, 32 insertions(+) create mode 100644 src/assets/icons/CheckIcon.tsx create mode 100644 src/components/atoms/CheckBox.tsx diff --git a/src/assets/icons/CheckIcon.tsx b/src/assets/icons/CheckIcon.tsx new file mode 100644 index 0000000..d2a4c4b --- /dev/null +++ b/src/assets/icons/CheckIcon.tsx @@ -0,0 +1,9 @@ +import React from 'react'; + +const CheckIcon: React.FC> = (props) => ( + + + +); +export default CheckIcon; + diff --git a/src/assets/icons/index.ts b/src/assets/icons/index.ts index c4b2dfe..3941f7f 100644 --- a/src/assets/icons/index.ts +++ b/src/assets/icons/index.ts @@ -27,3 +27,4 @@ export { default as DateIcon } from './DateIcon'; export { default as ClockIcon } from './ClockIcon'; export { default as CameraIcon } from './CameraIcon'; export { default as CircleCloseIcon } from './CircleCloseIcon'; +export { default as CheckIcon } from './CheckIcon'; diff --git a/src/components/atoms/CheckBox.tsx b/src/components/atoms/CheckBox.tsx new file mode 100644 index 0000000..45ece45 --- /dev/null +++ b/src/components/atoms/CheckBox.tsx @@ -0,0 +1,21 @@ +import { CheckIcon } from '@/assets/icons'; +import React from 'react'; + +const CheckBox: React.FC<{ active: boolean; onClick: () => void }> = ({ + active = false, + onClick, +}) => { + const commonStyle = + 'flex justify-center items-center w-[20px] h-[20px] rounded-full'; + return active ? ( + + ) : ( + + ); +}; + +export default CheckBox; diff --git a/src/components/atoms/index.ts b/src/components/atoms/index.ts index c7206d7..dce0bf4 100644 --- a/src/components/atoms/index.ts +++ b/src/components/atoms/index.ts @@ -16,3 +16,4 @@ export { default as RadioButtonField } from './RadioButtonField'; export { default as Input } from './Input'; export { default as MiniButton } from './MiniButton'; export { default as ExclamationAlertSpan } from './ExclamationAlertSpan'; +export { default as CheckBox } from './CheckBox'; From 0cc095bbb3ccfccbce240aed334ec7a6b0356898 Mon Sep 17 00:00:00 2001 From: hyeseon han Date: Fri, 23 Feb 2024 00:25:44 +0900 Subject: [PATCH 03/13] =?UTF-8?q?fix:=20Button=20component=20ButtonHTMLAtt?= =?UTF-8?q?ributes=20props=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/atoms/Button.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/atoms/Button.tsx b/src/components/atoms/Button.tsx index a728c37..76e4d15 100644 --- a/src/components/atoms/Button.tsx +++ b/src/components/atoms/Button.tsx @@ -6,11 +6,14 @@ interface ButtonProps { className?: string; } -const Button: React.FC = ({ text, className, onClick }) => { +const Button: React.FC< + ButtonProps & React.ButtonHTMLAttributes +> = ({ text, className, onClick, ...props }) => { return ( From 8c406fec9d7727d27d4b6789678f81e228dbd4b8 Mon Sep 17 00:00:00 2001 From: hyeseon han Date: Fri, 23 Feb 2024 00:26:51 +0900 Subject: [PATCH 04/13] =?UTF-8?q?chore:=20=EC=B9=9C=EA=B5=AC=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=ED=97=A4=EB=8D=94=20=EC=9A=B0=EC=B8=A1=20?= =?UTF-8?q?icon=20button=20component=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../molecules/FriendshipHeaderSettingButton.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/components/molecules/FriendshipHeaderSettingButton.tsx diff --git a/src/components/molecules/FriendshipHeaderSettingButton.tsx b/src/components/molecules/FriendshipHeaderSettingButton.tsx new file mode 100644 index 0000000..42c49a7 --- /dev/null +++ b/src/components/molecules/FriendshipHeaderSettingButton.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import { SettingIcon } from '@/assets/icons'; + +const FriendshipHeaderSettingButton: React.FC<{ onClick: () => void }> = ({ + onClick, +}) => { + return ( + + ); +}; + +export default FriendshipHeaderSettingButton; From 18b3904e59626495695df6c553337851d72500e2 Mon Sep 17 00:00:00 2001 From: hyeseon han Date: Fri, 23 Feb 2024 00:27:23 +0900 Subject: [PATCH 05/13] =?UTF-8?q?feat:=20=EC=B9=9C=EA=B5=AC=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20API=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/organisms/FriendListItem.tsx | 39 ++++--- .../templates/FriendListTemplate.tsx | 106 ++++++++++++++++-- src/hooks/queries/friendship/index.ts | 1 + .../queries/friendship/useDeleteFriendship.ts | 11 ++ src/hooks/queries/queryKeys.ts | 1 + src/pages/mypage/friendship/index.tsx | 17 ++- 6 files changed, 149 insertions(+), 26 deletions(-) create mode 100644 src/hooks/queries/friendship/useDeleteFriendship.ts diff --git a/src/components/organisms/FriendListItem.tsx b/src/components/organisms/FriendListItem.tsx index 0411bf9..852733c 100644 --- a/src/components/organisms/FriendListItem.tsx +++ b/src/components/organisms/FriendListItem.tsx @@ -1,38 +1,47 @@ import { AngleIcon } from '@/assets/icons'; -import { type ProfileEnum } from '@/types/common'; import { returnProfileImg } from '@/utils/returnProfileImg'; import Image from 'next/image'; import React from 'react'; +import { CheckBox } from '@/components/atoms'; +import { type FriendshipData } from '@/types/friendship'; const FriendListItem: React.FC<{ - name: string; - count: number; - profileEnum: ProfileEnum; -}> = ({ name, count, profileEnum }) => { + data: FriendshipData; + possibleDelete: boolean; + onClick: () => void; + active: boolean; +}> = ({ data, possibleDelete, onClick, active }) => { return (
+ {/* TODO profile img ENUM res 데이터로 교체 */} 친구 프로필
-

{name}

+

+ {data.nickname} +

- 냉장고 식자재 목록 {count}개 + 냉장고 식자재 목록 {data.ingredientCount}개

- + {possibleDelete ? ( + + ) : ( + + )}
); }; diff --git a/src/components/templates/FriendListTemplate.tsx b/src/components/templates/FriendListTemplate.tsx index 716734e..82a3bf2 100644 --- a/src/components/templates/FriendListTemplate.tsx +++ b/src/components/templates/FriendListTemplate.tsx @@ -6,11 +6,14 @@ import { useDisclosure, } from '@chakra-ui/react'; -import React, { useRef, useState } from 'react'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; import { type SortLabel } from '@/types/common'; -import { RadioButtonField, SortButton } from '../atoms'; +import { Button, RadioButtonField, SortButton } from '@/components/atoms'; import { FriendListItem } from '../organisms'; -import { useGetFriendships } from '@/hooks/queries/friendship'; +import { + useDeleteFriendship, + useGetFriendships, +} from '@/hooks/queries/friendship'; import type { FriendshipData, FriendshipSortType } from '@/types/friendship'; import { SuspenseFallback } from '.'; import { useObserver } from '@/hooks/useObserver'; @@ -20,29 +23,69 @@ const SORT_TYPES: SortLabel[] = [ { label: '등록순', value: 'createdAt' }, ]; -const FriendListTemplate: React.FC = () => { +const FriendListTemplate: React.FC<{ possibleDelete: boolean }> = ({ + possibleDelete, +}) => { const bottom = useRef(null); const { isOpen, onOpen, onClose } = useDisclosure(); + const { + isOpen: deleteIsOpen, + onOpen: deleteOnOpen, + onClose: deleteOnClose, + } = useDisclosure(); const [curSortType, setCurSortType] = useState(SORT_TYPES[0]); + const [selectedFriendIds, setSelectedFriendIds] = useState([]); const { data: friendsData, fetchNextPage: friendsNextPage, isFetchingNextPage: isFetchingfriendsNextPage, + refetch: friendsRefetch, } = useGetFriendships({ sort: curSortType.value as FriendshipSortType, }); + const deleteFriendship = useDeleteFriendship({ + onSuccess: () => { + deleteOnClose(); + friendsRefetch(); + }, + }); + const onIntersect: IntersectionObserverCallback = ([entry]) => { if (entry.isIntersecting) { void friendsNextPage(); } }; + const onClickDeleteFriends = useCallback(() => { + const friendIds: Array<{ friendId: number }> = []; + selectedFriendIds.forEach((ele) => friendIds.push({ friendId: ele })); + deleteFriendship.mutate(friendIds); + }, [selectedFriendIds]); + + const selectFriend = useCallback( + (id: number) => { + const tempSelectedFriendIds = selectedFriendIds.slice(); + const idx = tempSelectedFriendIds.indexOf(id); + if (idx === -1) { + tempSelectedFriendIds.push(id); + } else { + tempSelectedFriendIds.splice(idx, 1); + } + setSelectedFriendIds(tempSelectedFriendIds); + }, + [selectedFriendIds], + ); + useObserver({ target: bottom, onIntersect, }); + useEffect(() => { + setSelectedFriendIds([]); + }, [possibleDelete]); + if (!friendsData?.pages[0].content) { return ; } @@ -64,16 +107,63 @@ const FriendListTemplate: React.FC = () => { page.content.map((ele: FriendshipData) => ( { + selectFriend(ele.userId); + }} + active={selectedFriendIds.includes(ele.userId)} /> )), )} + {isFetchingfriendsNextPage ? :
} +
+
+ + + + + +

친구삭제

+

+ 삭제하기 버튼을 누르면 친구 목록에서 삭제됩니다. +

+
+
+
+
+
+ void }) => { + return useBaseMutation>( + queryKeys.DELETE_FRIENDSHIP(), + `/friendship/delete`, + onSuccess, + ); +}; +export default useDeleteFriendship; diff --git a/src/hooks/queries/queryKeys.ts b/src/hooks/queries/queryKeys.ts index e88a097..5a91d55 100644 --- a/src/hooks/queries/queryKeys.ts +++ b/src/hooks/queries/queryKeys.ts @@ -5,6 +5,7 @@ export const queryKeys = { KAKAO: () => ['kakao'], SHARES: () => ['shares'], FRIENDSHIPS: (sort: FriendshipSortType) => ['friendship', sort], + DELETE_FRIENDSHIP: () => ['deleteFriendship'], } as const; export type QueryKeys = (typeof queryKeys)[keyof typeof queryKeys]; diff --git a/src/pages/mypage/friendship/index.tsx b/src/pages/mypage/friendship/index.tsx index 139aadf..f397c4c 100644 --- a/src/pages/mypage/friendship/index.tsx +++ b/src/pages/mypage/friendship/index.tsx @@ -1,8 +1,8 @@ import { AddFriendTemplate, FriendListTemplate } from '@/components/templates'; +import FriendshipHeaderSettingButton from '@/components/molecules/FriendshipHeaderSettingButton'; import Header from '@/components/organisms/Header'; import type { NextPage } from 'next'; -import { SettingIcon } from '@/assets/icons'; import { TabButton } from '@/components/atoms'; import type { TabLabel } from '@/types/common'; import { useState } from 'react'; @@ -14,12 +14,19 @@ const TABS: TabLabel[] = [ const FriendShipPage: NextPage = () => { const [curTab, setCurTab] = useState(TABS[0]); + const [possibleDelete, setPossibleDelete] = useState(false); return (
} + headerRight={ + { + setPossibleDelete(!possibleDelete); + }} + /> + } backgroundColor="white" />
@@ -37,7 +44,11 @@ const FriendShipPage: NextPage = () => {
- {curTab.value === 'list' ? : } + {curTab.value === 'list' ? ( + + ) : ( + + )}
); }; From e0930eb435ded45bc0ff5aa71d1b6db1f2061959 Mon Sep 17 00:00:00 2001 From: hyeseon han Date: Fri, 23 Feb 2024 00:44:51 +0900 Subject: [PATCH 06/13] =?UTF-8?q?style:=20=EC=B9=9C=EA=B5=AC=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=8A=A4=ED=83=80=EC=9D=BC=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/pages/mypage/friendship/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/mypage/friendship/index.tsx b/src/pages/mypage/friendship/index.tsx index f397c4c..d5963bb 100644 --- a/src/pages/mypage/friendship/index.tsx +++ b/src/pages/mypage/friendship/index.tsx @@ -29,7 +29,7 @@ const FriendShipPage: NextPage = () => { } backgroundColor="white" /> -
+
{TABS.map((ele: TabLabel) => ( Date: Fri, 23 Feb 2024 00:45:31 +0900 Subject: [PATCH 07/13] =?UTF-8?q?feat:=20=EB=82=B4=20=EC=B4=88=EB=8C=80?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=A1=B0=ED=9A=8C=20API=20=EC=97=B0?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/AddFriendTemplate.tsx | 20 +++++++++---------- src/hooks/queries/queryKeys.ts | 1 + 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/components/templates/AddFriendTemplate.tsx b/src/components/templates/AddFriendTemplate.tsx index accb0a6..1bc095f 100644 --- a/src/components/templates/AddFriendTemplate.tsx +++ b/src/components/templates/AddFriendTemplate.tsx @@ -1,24 +1,22 @@ -import React, { useEffect, useState } from 'react'; - import { BulletNoticeBox } from '../organisms'; import { LabelRoundBox } from '../molecules'; import { MiniButton } from '@/components/atoms'; - -const MY_INVITATION_CODE = 'AB12CD3EF'; +import React from 'react'; +import { queryKeys } from '@/hooks/queries/queryKeys'; +import { useBaseQuery } from '@/hooks/queries/useBaseQuery'; const AddFriendTemplate: React.FC = () => { - const [myCode, setMyCode] = useState(''); - const onCopy: () => void = () => { navigator.clipboard - .writeText(myCode) + .writeText(myInviteCode?.data?.inviteCode ?? '') .then(() => null) .catch(() => null); }; - useEffect(() => { - setMyCode(MY_INVITATION_CODE); - }, []); + const { data: myInviteCode } = useBaseQuery<{ inviteCode: string }>( + queryKeys.MY_INVITE_CODE(), + '/users/me/invite-code', + ); return (
@@ -27,7 +25,7 @@ const AddFriendTemplate: React.FC = () => { content={ <> - {myCode} + {myInviteCode?.data?.inviteCode} diff --git a/src/hooks/queries/queryKeys.ts b/src/hooks/queries/queryKeys.ts index 5a91d55..ede5a80 100644 --- a/src/hooks/queries/queryKeys.ts +++ b/src/hooks/queries/queryKeys.ts @@ -6,6 +6,7 @@ export const queryKeys = { SHARES: () => ['shares'], FRIENDSHIPS: (sort: FriendshipSortType) => ['friendship', sort], DELETE_FRIENDSHIP: () => ['deleteFriendship'], + MY_INVITE_CODE: () => ['myInviteCode'], } as const; export type QueryKeys = (typeof queryKeys)[keyof typeof queryKeys]; From 50c2bd2d027a9975fccba6185af5126b58c322c2 Mon Sep 17 00:00:00 2001 From: hyeseon han Date: Fri, 23 Feb 2024 01:21:19 +0900 Subject: [PATCH 08/13] =?UTF-8?q?feat:=20WarningIcon=20=EC=B6=94=EA=B0=80,?= =?UTF-8?q?=20WarningLine=20component=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/icons/NotificationIcon.tsx | 2 +- src/assets/icons/WarningIcon.tsx | 9 +++++++++ src/assets/icons/index.ts | 1 + src/components/molecules/WarningLine.tsx | 13 +++++++++++++ src/components/molecules/index.ts | 1 + 5 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 src/assets/icons/WarningIcon.tsx create mode 100644 src/components/molecules/WarningLine.tsx diff --git a/src/assets/icons/NotificationIcon.tsx b/src/assets/icons/NotificationIcon.tsx index d445745..8eb31ad 100644 --- a/src/assets/icons/NotificationIcon.tsx +++ b/src/assets/icons/NotificationIcon.tsx @@ -2,7 +2,7 @@ import React from 'react'; const NotificationIcon: React.FC> = (props) => ( - + > = (props) => ( + + + +); + +export default WarningIcon; \ No newline at end of file diff --git a/src/assets/icons/index.ts b/src/assets/icons/index.ts index 3941f7f..ae1a479 100644 --- a/src/assets/icons/index.ts +++ b/src/assets/icons/index.ts @@ -28,3 +28,4 @@ export { default as ClockIcon } from './ClockIcon'; export { default as CameraIcon } from './CameraIcon'; export { default as CircleCloseIcon } from './CircleCloseIcon'; export { default as CheckIcon } from './CheckIcon'; +export { default as WarningIcon } from './WarningIcon'; diff --git a/src/components/molecules/WarningLine.tsx b/src/components/molecules/WarningLine.tsx new file mode 100644 index 0000000..945ec98 --- /dev/null +++ b/src/components/molecules/WarningLine.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import { WarningIcon } from '@/assets/icons'; + +const WarningLine: React.FC<{ text: string }> = ({ text }) => { + return ( +
+ +

{text}

+
+ ); +}; + +export default WarningLine; diff --git a/src/components/molecules/index.ts b/src/components/molecules/index.ts index 8d972b6..99e97e5 100644 --- a/src/components/molecules/index.ts +++ b/src/components/molecules/index.ts @@ -12,3 +12,4 @@ export { default as NavWhiteBoxItem } from './NavWhiteBoxItem'; export { default as VerticalLabelValue } from './VerticalLabelValue'; export { default as ShareInfoRowItem } from './ShareInfoRowItem'; export { default as LabelRoundBox } from './LabelRoundBox'; +export { default as WarningLine } from './WarningLine'; From f684513a5fdc170dcb67a2628c8d1bb97efbd895 Mon Sep 17 00:00:00 2001 From: hyeseon han Date: Fri, 23 Feb 2024 01:22:07 +0900 Subject: [PATCH 09/13] =?UTF-8?q?feat:=20=EC=B9=9C=EA=B5=AC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20API=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/molecules/LabelRoundBox.tsx | 2 +- .../templates/AddFriendTemplate.tsx | 58 +++++++++++++++---- src/hooks/queries/friendship/index.ts | 1 + .../queries/friendship/useAddFriendship.ts | 11 ++++ src/hooks/queries/queryKeys.ts | 1 + 5 files changed, 61 insertions(+), 12 deletions(-) create mode 100644 src/hooks/queries/friendship/useAddFriendship.ts diff --git a/src/components/molecules/LabelRoundBox.tsx b/src/components/molecules/LabelRoundBox.tsx index 87aaf4e..f47406a 100644 --- a/src/components/molecules/LabelRoundBox.tsx +++ b/src/components/molecules/LabelRoundBox.tsx @@ -7,7 +7,7 @@ const LabelRoundBox: React.FC<{ return (

{label}

-
{content}
+ {content}
); }; diff --git a/src/components/templates/AddFriendTemplate.tsx b/src/components/templates/AddFriendTemplate.tsx index 1bc095f..4da82e3 100644 --- a/src/components/templates/AddFriendTemplate.tsx +++ b/src/components/templates/AddFriendTemplate.tsx @@ -1,18 +1,40 @@ -import { BulletNoticeBox } from '../organisms'; -import { LabelRoundBox } from '../molecules'; +import { LabelRoundBox, WarningLine } from '@/components/molecules'; +import React, { useState } from 'react'; + +import { BulletNoticeBox } from '@/components/organisms'; import { MiniButton } from '@/components/atoms'; -import React from 'react'; import { queryKeys } from '@/hooks/queries/queryKeys'; +import { useAddFriendship } from '@/hooks/queries/friendship'; import { useBaseQuery } from '@/hooks/queries/useBaseQuery'; +import useToast from '@/hooks/useToast'; const AddFriendTemplate: React.FC = () => { + const [friendInviteCode, setFriendInviteCode] = useState(''); + const [warningVisible, setWarningVisible] = useState(false); + const { showToast } = useToast(); + const addFriendship = useAddFriendship({ + onSuccess: () => { + showToast('친구 추가가 완료되었습니다.', 'success'); + }, + }); + const onCopy: () => void = () => { navigator.clipboard .writeText(myInviteCode?.data?.inviteCode ?? '') - .then(() => null) + .then(() => { + showToast('초대 코드가 복사되었습니다.', 'success'); + }) .catch(() => null); }; + const onAddFriend = () => { + if (friendInviteCode.length < 9) { + setWarningVisible(true); + } else { + addFriendship.mutate({ inviteCode: friendInviteCode }); + } + }; + const { data: myInviteCode } = useBaseQuery<{ inviteCode: string }>( queryKeys.MY_INVITE_CODE(), '/users/me/invite-code', @@ -23,23 +45,37 @@ const AddFriendTemplate: React.FC = () => { +
{myInviteCode?.data?.inviteCode} - +
} /> - - +
+ { + setFriendInviteCode(e.target.value); + }} + maxLength={10} + /> + +
+ {warningVisible ? ( + + ) : null} } /> diff --git a/src/hooks/queries/friendship/index.ts b/src/hooks/queries/friendship/index.ts index 2c70a67..a69da17 100644 --- a/src/hooks/queries/friendship/index.ts +++ b/src/hooks/queries/friendship/index.ts @@ -1,2 +1,3 @@ export { default as useGetFriendships } from './useGetFriendships'; export { default as useDeleteFriendship } from './useDeleteFriendship'; +export { default as useAddFriendship } from './useAddFriendship'; diff --git a/src/hooks/queries/friendship/useAddFriendship.ts b/src/hooks/queries/friendship/useAddFriendship.ts new file mode 100644 index 0000000..8a497ca --- /dev/null +++ b/src/hooks/queries/friendship/useAddFriendship.ts @@ -0,0 +1,11 @@ +import { queryKeys } from '../queryKeys'; +import { useBaseMutation } from '../useBaseMutation'; + +const useAddFriendship = ({ onSuccess }: { onSuccess: () => void }) => { + return useBaseMutation<{ inviteCode: string }>( + queryKeys.ADD_FRIENDSHIP(), + `/friendship`, + onSuccess, + ); +}; +export default useAddFriendship; diff --git a/src/hooks/queries/queryKeys.ts b/src/hooks/queries/queryKeys.ts index ede5a80..0dbad20 100644 --- a/src/hooks/queries/queryKeys.ts +++ b/src/hooks/queries/queryKeys.ts @@ -7,6 +7,7 @@ export const queryKeys = { FRIENDSHIPS: (sort: FriendshipSortType) => ['friendship', sort], DELETE_FRIENDSHIP: () => ['deleteFriendship'], MY_INVITE_CODE: () => ['myInviteCode'], + ADD_FRIENDSHIP: () => ['addFriendship'], } as const; export type QueryKeys = (typeof queryKeys)[keyof typeof queryKeys]; From 7ea8153e4c5b04d56dc4024078d36a1449e233cc Mon Sep 17 00:00:00 2001 From: hyeseon han Date: Fri, 23 Feb 2024 22:40:59 +0900 Subject: [PATCH 10/13] =?UTF-8?q?fix:=20build=20error=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/atoms/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/atoms/index.ts b/src/components/atoms/index.ts index 38ebf49..7c06d92 100644 --- a/src/components/atoms/index.ts +++ b/src/components/atoms/index.ts @@ -17,4 +17,4 @@ export { default as Input } from './Input'; export { default as MiniButton } from './MiniButton'; export { default as ExclamationAlertSpan } from './ExclamationAlertSpan'; export { default as Lottie } from './Lottie'; -export { default as CheckBox } from './CheckBox'; \ No newline at end of file +export { default as CheckBox } from './CheckBox'; From 7876f5fea59771477de7d2dd070ca9c378b44bef Mon Sep 17 00:00:00 2001 From: hyeseon han Date: Fri, 23 Feb 2024 22:45:45 +0900 Subject: [PATCH 11/13] refactor: CheckBox refactoring --- src/components/atoms/CheckBox.tsx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/components/atoms/CheckBox.tsx b/src/components/atoms/CheckBox.tsx index 45ece45..9f8e388 100644 --- a/src/components/atoms/CheckBox.tsx +++ b/src/components/atoms/CheckBox.tsx @@ -7,13 +7,10 @@ const CheckBox: React.FC<{ active: boolean; onClick: () => void }> = ({ }) => { const commonStyle = 'flex justify-center items-center w-[20px] h-[20px] rounded-full'; - return active ? ( - - ) : ( - ); }; From b9f9fb7ee0e15966630c434cf65b456a4a163d94 Mon Sep 17 00:00:00 2001 From: hyeseon han Date: Fri, 23 Feb 2024 22:49:19 +0900 Subject: [PATCH 12/13] =?UTF-8?q?refactor:=20=EC=B9=9C=EA=B5=AC=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EC=84=B1=EA=B3=B5,=20=EC=B4=88=EB=8C=80=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EB=B3=B5=EC=82=AC=20=EC=84=B1=EA=B3=B5=EC=8B=9C=20?= =?UTF-8?q?=ED=86=A0=EC=8A=A4=ED=8A=B8=20=EB=A9=94=EC=84=B8=EC=A7=80=20?= =?UTF-8?q?=EC=83=81=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/templates/AddFriendTemplate.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/templates/AddFriendTemplate.tsx b/src/components/templates/AddFriendTemplate.tsx index 4da82e3..4d34801 100644 --- a/src/components/templates/AddFriendTemplate.tsx +++ b/src/components/templates/AddFriendTemplate.tsx @@ -8,13 +8,16 @@ import { useAddFriendship } from '@/hooks/queries/friendship'; import { useBaseQuery } from '@/hooks/queries/useBaseQuery'; import useToast from '@/hooks/useToast'; +const FRIEND_ADD_SUCCESS_MESSAGE = '친구 추가가 완료되었습니다.'; +const CODE_COPY_SUCCESS_MESSAGE = '초대 코드가 복사되었습니다.'; + const AddFriendTemplate: React.FC = () => { const [friendInviteCode, setFriendInviteCode] = useState(''); const [warningVisible, setWarningVisible] = useState(false); const { showToast } = useToast(); const addFriendship = useAddFriendship({ onSuccess: () => { - showToast('친구 추가가 완료되었습니다.', 'success'); + showToast(FRIEND_ADD_SUCCESS_MESSAGE, 'success'); }, }); @@ -22,7 +25,7 @@ const AddFriendTemplate: React.FC = () => { navigator.clipboard .writeText(myInviteCode?.data?.inviteCode ?? '') .then(() => { - showToast('초대 코드가 복사되었습니다.', 'success'); + showToast(CODE_COPY_SUCCESS_MESSAGE, 'success'); }) .catch(() => null); }; From 15203f32cb48496d079f73ab8e68e2ba6eee27e8 Mon Sep 17 00:00:00 2001 From: hyeseon han Date: Fri, 23 Feb 2024 23:03:52 +0900 Subject: [PATCH 13/13] =?UTF-8?q?refactor:=20=EB=82=B4=20=EC=B4=88?= =?UTF-8?q?=EB=8C=80=EC=BD=94=EB=93=9C=20=EC=A1=B0=ED=9A=8C=20query=20useG?= =?UTF-8?q?etMyInviteCode=20function=EC=9C=BC=EB=A1=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/templates/AddFriendTemplate.tsx | 16 +++++++--------- src/hooks/queries/friendship/index.ts | 1 + .../queries/friendship/useGetMyInviteCode.ts | 17 +++++++++++++++++ 3 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 src/hooks/queries/friendship/useGetMyInviteCode.ts diff --git a/src/components/templates/AddFriendTemplate.tsx b/src/components/templates/AddFriendTemplate.tsx index 4d34801..d4466fc 100644 --- a/src/components/templates/AddFriendTemplate.tsx +++ b/src/components/templates/AddFriendTemplate.tsx @@ -1,11 +1,12 @@ import { LabelRoundBox, WarningLine } from '@/components/molecules'; import React, { useState } from 'react'; +import { + useAddFriendship, + useGetMyInviteCode, +} from '@/hooks/queries/friendship'; import { BulletNoticeBox } from '@/components/organisms'; import { MiniButton } from '@/components/atoms'; -import { queryKeys } from '@/hooks/queries/queryKeys'; -import { useAddFriendship } from '@/hooks/queries/friendship'; -import { useBaseQuery } from '@/hooks/queries/useBaseQuery'; import useToast from '@/hooks/useToast'; const FRIEND_ADD_SUCCESS_MESSAGE = '친구 추가가 완료되었습니다.'; @@ -23,7 +24,7 @@ const AddFriendTemplate: React.FC = () => { const onCopy: () => void = () => { navigator.clipboard - .writeText(myInviteCode?.data?.inviteCode ?? '') + .writeText(myInviteCode ?? '') .then(() => { showToast(CODE_COPY_SUCCESS_MESSAGE, 'success'); }) @@ -38,10 +39,7 @@ const AddFriendTemplate: React.FC = () => { } }; - const { data: myInviteCode } = useBaseQuery<{ inviteCode: string }>( - queryKeys.MY_INVITE_CODE(), - '/users/me/invite-code', - ); + const { inviteCode: myInviteCode } = useGetMyInviteCode(); return (
@@ -50,7 +48,7 @@ const AddFriendTemplate: React.FC = () => { content={
- {myInviteCode?.data?.inviteCode} + {myInviteCode ?? ''}
diff --git a/src/hooks/queries/friendship/index.ts b/src/hooks/queries/friendship/index.ts index a69da17..baf19b4 100644 --- a/src/hooks/queries/friendship/index.ts +++ b/src/hooks/queries/friendship/index.ts @@ -1,3 +1,4 @@ export { default as useGetFriendships } from './useGetFriendships'; export { default as useDeleteFriendship } from './useDeleteFriendship'; export { default as useAddFriendship } from './useAddFriendship'; +export { default as useGetMyInviteCode } from './useGetMyInviteCode'; diff --git a/src/hooks/queries/friendship/useGetMyInviteCode.ts b/src/hooks/queries/friendship/useGetMyInviteCode.ts new file mode 100644 index 0000000..bf8c6ce --- /dev/null +++ b/src/hooks/queries/friendship/useGetMyInviteCode.ts @@ -0,0 +1,17 @@ +import { queryKeys } from '../queryKeys'; +import { useBaseQuery } from '../useBaseQuery'; + +const useGetMyInviteCode = () => { + const { data } = useBaseQuery<{ inviteCode: string }>( + queryKeys.MY_INVITE_CODE(), + '/users/me/invite-code', + ); + + if (!data?.data) { + return { inviteCode: '-' }; + } + + return data?.data; +}; + +export default useGetMyInviteCode;