diff --git a/src/components/Group/GroupProfile/GroupProfile.jsx b/src/components/Group/GroupProfile/GroupProfile.jsx index 4bf1601e..d4525860 100644 --- a/src/components/Group/GroupProfile/GroupProfile.jsx +++ b/src/components/Group/GroupProfile/GroupProfile.jsx @@ -14,6 +14,7 @@ const GroupProfile = ({ isGroupLeader, isManaging, groupMemberList, + isGroupRequest, }) => { return ( @@ -37,6 +38,7 @@ const GroupProfile = ({ isGroupMember={isGroupMember} isGroupLeader={isGroupLeader} isManaging={isManaging} + isGroupRequest={isGroupRequest} /> ); diff --git a/src/components/Group/GroupProfile/GroupProfile.styles.js b/src/components/Group/GroupProfile/GroupProfile.styles.js index 1c843dd5..fea5701b 100644 --- a/src/components/Group/GroupProfile/GroupProfile.styles.js +++ b/src/components/Group/GroupProfile/GroupProfile.styles.js @@ -114,6 +114,16 @@ export const ProfileButton = styled.button` position: relative; cursor: pointer; + &.disabledButton { + background-color: ${({ theme: { colors } }) => colors.btn_02}; + border: none; + cursor: not-allowed; + + &:hover { + background-color: ${({ theme: { colors } }) => colors.btn_02}; + } + } + &:hover { background-color: ${({ theme: { colors } }) => colors.btn_04}; } diff --git a/src/components/Group/GroupProfile/GroupProfileButton.jsx b/src/components/Group/GroupProfile/GroupProfileButton.jsx index 09a128c1..01db6be4 100644 --- a/src/components/Group/GroupProfile/GroupProfileButton.jsx +++ b/src/components/Group/GroupProfile/GroupProfileButton.jsx @@ -5,6 +5,7 @@ import { useNavigate } from "react-router-dom"; import GroupDelegateModal from "@/components/Common/GroupModal/GroupDelegateModal/GroupDelegateModal"; import { AddIcon } from "@/constants/iconConstants"; import { UI_TYPE } from "@/constants/uiConstants"; +import { changeRequestGroupJoin } from "@/features/group/group-service"; import { openDelegateGroupModal } from "@/features/ui/ui-slice"; import { @@ -19,6 +20,7 @@ const GroupProfileButton = ({ isGroupMember, isGroupLeader, isManaging, + isGroupRequest, // eslint-disable-next-line consistent-return }) => { const dispatch = useDispatch(); @@ -93,10 +95,12 @@ const GroupProfileButton = ({ } // 그룹 멤버가 아닐떄 - if (!isGroupMember) { + if (!isGroupMember && !isGroupRequest) { return ( - + dispatch(changeRequestGroupJoin(groupId))} + > <> 그룹 참여 요청 @@ -105,6 +109,19 @@ const GroupProfileButton = ({ ); } + + if (isGroupRequest) { + return ( + + 수락 대기 중 + dispatch(changeRequestGroupJoin(groupId))} + > + 요청 취소 + + + ); + } }; export default GroupProfileButton; diff --git a/src/features/group/group-service.js b/src/features/group/group-service.js index a5c528ab..cc1a40ad 100644 --- a/src/features/group/group-service.js +++ b/src/features/group/group-service.js @@ -198,24 +198,11 @@ export const changeGroupOption = createAsyncThunk( }, ); -export const cancelGroupJoin = createAsyncThunk( - "group/cancelGroupJoin", - async (groupId, thunkAPI) => { - const data = await commonThunk( - { - method: "POST", - url: `/api/group/${groupId}/members/request`, - successCode: 200, - }, - thunkAPI, - ); - return data; - }, -); - export const changeRequestGroupJoin = createAsyncThunk( "group/changeRequestGroupJoin", async (groupId, thunkAPI) => { + const { user } = thunkAPI.getState().auth; + const data = await commonThunk( { method: "POST", @@ -224,7 +211,7 @@ export const changeRequestGroupJoin = createAsyncThunk( }, thunkAPI, ); - return data; + return { data, user }; }, ); diff --git a/src/features/group/group-slice.js b/src/features/group/group-slice.js index 8ed4d782..9b689396 100644 --- a/src/features/group/group-slice.js +++ b/src/features/group/group-slice.js @@ -15,7 +15,6 @@ import { approveGroupJoin, rejectGroupJoin, deleteGroupMember, - cancelGroupJoin, changeRequestGroupJoin, changeGroupPublicOption, updateGroupProfile, @@ -125,8 +124,29 @@ const groupSlice = createSlice({ .addCase(getGroupInfo.fulfilled, (state, { payload }) => { state.groupInfo = payload; }) - .addCase(changeRequestGroupJoin.fulfilled, () => { - toast.success("그룹 신청 취소 완료"); + .addCase(changeRequestGroupJoin.fulfilled, (state, { payload }) => { + if (payload.data.message === "성공적으로 신청되었습니다.") { + const { userId, nickname, profileImage } = payload.user; + + const requestUserInfo = { + accessLevel: "viewer", + member: { + userId, + nickname, + image: profileImage, + isPendingMember: 1, + }, + }; + + state.groupRequestMemberList.push(requestUserInfo); + + toast.success("그룹 신청 완료"); + } else { + state.groupRequestMemberList = state.groupRequestMemberList.filter( + (prev) => prev.member.userId !== payload.user.userId, + ); + toast.success("그룹 신청 취소 완료"); + } }) .addCase(changeGroupPublicOption.fulfilled, ({ payload }) => { toast.error(payload.error); @@ -138,9 +158,6 @@ const groupSlice = createSlice({ toast.success("그룹 정보가 수정되었습니다"); }, ) - .addCase(cancelGroupJoin.fulfilled, () => { - toast.success("그룹 신청 취소 완료"); - }) .addCase(changeGroupOption.fulfilled, () => {}) .addCase(delegateGroup.fulfilled, () => { toast.success("그룹장 위임이 완료되었습니다."); diff --git a/src/pages/GroupPage/GroupPage.jsx b/src/pages/GroupPage/GroupPage.jsx index 0e5185d8..3b35c883 100644 --- a/src/pages/GroupPage/GroupPage.jsx +++ b/src/pages/GroupPage/GroupPage.jsx @@ -15,6 +15,7 @@ import { UI_TYPE } from "@/constants/uiConstants"; import { getGroupInfo, getGroupMemberList, + getGroupRequestMemberList, } from "@/features/group/group-service"; import { resetGroupStateForGroupPage } from "@/features/group/group-slice"; import { resetPostStateForGroupPage } from "@/features/post/post-slice"; @@ -26,7 +27,9 @@ const GroupPage = () => { const dispatch = useDispatch(); const { user } = useSelector((state) => state.auth); - const { groupInfo, groupMemberList } = useSelector((state) => state.group); + const { groupInfo, groupMemberList, groupRequestMemberList } = useSelector( + (state) => state.group, + ); const { openedModal } = useSelector((state) => state.ui); @@ -43,6 +46,7 @@ const GroupPage = () => { useEffect(() => { dispatch(getGroupMemberList(groupId)); + dispatch(getGroupRequestMemberList(groupId)); try { dispatch(getGroupInfo(groupId)).unwrap(); @@ -71,7 +75,7 @@ const GroupPage = () => { } }, [searchParams]); - if (isLoading || !groupInfo) { + if (isLoading || !groupInfo || !groupRequestMemberList) { return
그룹 정보 불러오는 중...
; } @@ -80,6 +84,10 @@ const GroupPage = () => { const leaderName = groupInfo.information.leaderInfo.nickname; const isGroupLeader = groupInfo.accessLevel === "owner"; const isGroupMember = groupInfo.accessLevel !== null; + const isGroupRequest = + groupRequestMemberList.findIndex( + (data) => data.member.userId === user.userId, + ) !== -1; return ( @@ -89,6 +97,7 @@ const GroupPage = () => { isGroupMember={isGroupMember} isManaging={isManaging} groupMemberList={groupMemberList} + isGroupRequest={isGroupRequest} /> {isManaging ? (