Skip to content

Commit

Permalink
Fix: #165 코드리뷰 반영 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
ice-bear98 committed Oct 10, 2024
1 parent 4b77d7b commit 1a85ca7
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 46 deletions.
33 changes: 13 additions & 20 deletions src/components/modal/team/UpdateModalTeam.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import useToast from '@hooks/useToast';
import type { Team, TeamForm } from '@/types/TeamType';
import type { TeamRoleName } from '@/types/RoleType';
import type { AllSearchCallback } from '@/types/SearchCallbackType';
import type { User } from '@/types/UserType';

type UpdateModalTeamProps = {
teamId: Team['teamId'];
Expand All @@ -33,13 +34,13 @@ export default function UpdateModalTeam({ teamId, onClose: handleClose }: Update
const updateTeamFormId = 'updateTeamForm';
const [keyword, setKeyword] = useState('');
const { toastInfo, toastWarn } = useToast();
const { loading, data: userList = [], clearData, fetchData } = useAxios(findUser);
const { loading: isSearching, data: userList = [], clearData, fetchData } = useAxios(findUser);

const { teamName, content, coworkers, isLoading, isError } = useReadTeam(teamId);
const { teamName, content, coworkers, isLoading: isTeamLoading, isError } = useReadTeam(teamId);

const { mutate: updateTeamMutation } = useUpdateTeamInfo();
const { mutate: addTeamCoworkerMutation } = useAddTeamCoworker(teamId);
const { mutate: deleteCoworkerMutation } = useDeleteTeamCoworker(teamId);
const { mutate: deleteCoworkerMutation } = useDeleteTeamCoworker();
const { mutate: updateTeamCoworkerRoleMutation } = useUpdateTeamCoworkerRole(teamId);

const searchCallbackInfo: AllSearchCallback = useMemo(
Expand All @@ -57,7 +58,7 @@ export default function UpdateModalTeam({ teamId, onClose: handleClose }: Update
} = methods;

useEffect(() => {
if (teamName && content) {
if (teamName && content && coworkers) {
reset({ teamName, content, coworkers });
}
}, [teamName, content, coworkers, reset]);
Expand All @@ -71,30 +72,24 @@ export default function UpdateModalTeam({ teamId, onClose: handleClose }: Update
handleClose();
};

const handleCoworkersClick = (userId: number, roleName: TeamRoleName) => {
const handleCoworkersClick = (userId: User['userId'], roleName: TeamRoleName) => {
const isIncludedUser = coworkers.find((coworker) => coworker.userId === userId);
if (isIncludedUser) return toastInfo('이미 포함된 팀원입니다');

const validRole = TEAM_ROLES.includes(roleName);
if (!validRole) {
return toastWarn('유효하지 않은 역할입니다.');
}

addTeamCoworkerMutation({ userId, roleName });
setKeyword('');
clearData();
};

const handleRemoveUser = (userId: number) => {
deleteCoworkerMutation(userId);
const handleRemoveUser = (userId: User['userId']) => {
deleteCoworkerMutation({ teamId, userId });
};

// 권한 변경 핸들러
const handleRoleChange = (userId: number, roleName: TeamRoleName) => {
const handleRoleChange = (userId: User['userId'], roleName: TeamRoleName) => {
updateTeamCoworkerRoleMutation({ userId, roleName });
};

if (isLoading || loading) {
if (isTeamLoading) {
return <Spinner />;
}

Expand All @@ -103,7 +98,6 @@ export default function UpdateModalTeam({ teamId, onClose: handleClose }: Update
<ModalLayout onClose={handleClose}>
<FormProvider {...methods}>
<form id="updateTeamForm" onSubmit={handleSubmit(handleFormSubmit)}>
{/* 팀명 불러오기 */}
<DuplicationCheckInput
id="teamName"
label="팀명"
Expand All @@ -112,7 +106,7 @@ export default function UpdateModalTeam({ teamId, onClose: handleClose }: Update
errors={errors.teamName?.message}
register={register('teamName', TEAM_VALIDATION_RULES.TEAM_NAME)}
/>
{/* 팀 설명 불러오기 */}

<DescriptionTextarea
id="teamDescription"
label="팀 설명"
Expand All @@ -123,18 +117,17 @@ export default function UpdateModalTeam({ teamId, onClose: handleClose }: Update
/>
</form>
</FormProvider>
{/* 팀명 및 팀 설명 수정 제출 */}

<ModalButton formId={updateTeamFormId} backgroundColor="bg-main">
수정
</ModalButton>

{/* 팀원 추가 , 팀원 삭제 , 권한 설정 즉시반영 */}
<div className="my-16">
<SearchUserInput
id="search"
label="팀원"
keyword={keyword}
loading={loading}
loading={isSearching}
userList={userList}
searchCallbackInfo={searchCallbackInfo}
onKeywordChange={handleKeywordChange}
Expand Down
25 changes: 12 additions & 13 deletions src/hooks/query/useTeamQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import {
} from '@services/teamService';
import useToast from '@hooks/useToast';
import { useMemo } from 'react';
import type { Team, TeamCoworker, TeamForm, TeamListWithApproval, TeamUpdateInfo } from '@/types/TeamType';
import type { Team, TeamCoworker, TeamForm, TeamListWithApproval, TeamInfoForm } from '@/types/TeamType';
import type { User } from '@/types/UserType';

// 전체 팀 목록 조회
export function useReadTeams() {
Expand Down Expand Up @@ -148,7 +149,7 @@ export function useUpdateTeamInfo() {
const teamsQueryKey = generateTeamsQueryKey();

const mutation = useMutation({
mutationFn: ({ teamId, teamInfo }: { teamId: Team['teamId']; teamInfo: TeamUpdateInfo }) =>
mutationFn: ({ teamId, teamInfo }: { teamId: Team['teamId']; teamInfo: TeamInfoForm }) =>
updateTeamInfo(teamId, teamInfo),
onError: () => {
toastError('팀 정보 수정에 실패했습니다. 다시 시도해 주세요.');
Expand Down Expand Up @@ -183,17 +184,18 @@ export function useAddTeamCoworker(teamId: Team['teamId']) {
}

// 팀원 삭제
export function useDeleteTeamCoworker(teamId: Team['teamId']) {
export function useDeleteTeamCoworker() {
const queryClient = useQueryClient();
const { toastSuccess, toastError } = useToast();
const teamCoworkersQueryKey = generateTeamCoworkersQueryKey(teamId);

const mutation = useMutation({
mutationFn: (userId: number) => removeTeamMember(teamId, userId),
mutationFn: ({ teamId, userId }: { teamId: Team['teamId']; userId: User['userId'] }) =>
removeTeamMember(teamId, userId),
onError: () => {
toastError('팀원 삭제에 실패했습니다. 다시 시도해 주세요.');
},
onSuccess: () => {
onSuccess: (_, { teamId }) => {
const teamCoworkersQueryKey = generateTeamCoworkersQueryKey(teamId);
toastSuccess('팀원을 삭제하였습니다.');
queryClient.invalidateQueries({ queryKey: teamCoworkersQueryKey });
},
Expand Down Expand Up @@ -223,7 +225,7 @@ export function useUpdateTeamCoworkerRole(teamId: Team['teamId']) {
return mutation;
}

// 팀원 목록 가져오기 훅
// 팀원 목록 조회
export function useReadTeamCoworkers(teamId: Team['teamId']) {
const {
data: coworkers = [] as TeamCoworker[],
Expand All @@ -235,15 +237,13 @@ export function useReadTeamCoworkers(teamId: Team['teamId']) {
const { data } = await findTeamCoworker(teamId);
return data;
},
enabled: !!teamId,
});

return { coworkers, isLoading, isError };
}

// 수정할 팀 목록 조회
// 팀 상세 조회
export function useReadTeam(teamId: Team['teamId']) {
// 팀 목록을 가져오기
const { joinedTeamList, invitedTeamList } = useReadTeams();

const teamList = useMemo(() => {
Expand All @@ -254,14 +254,13 @@ export function useReadTeam(teamId: Team['teamId']) {
return teamList.find((team) => team.teamId === teamId);
}, [teamList, teamId]);

// 팀원 목록 가져오기
const {
coworkers: teamCoworkers,
isLoading: isTeamCoworkersLoading,
isError: isTeamCoworkersError,
} = useReadTeamCoworkers(teamId);

const result = useMemo(
const team = useMemo(
() => ({
teamName: teamInfo?.teamName,
content: teamInfo?.content,
Expand All @@ -272,5 +271,5 @@ export function useReadTeam(teamId: Team['teamId']) {
[teamInfo, teamCoworkers, isTeamCoworkersError, isTeamCoworkersLoading],
);

return result;
return team;
}
19 changes: 14 additions & 5 deletions src/mocks/services/teamServiceHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ import {
ROLE_DUMMY,
USER_DUMMY,
} from '@mocks/mockData';
import { TeamForm } from '@/types/TeamType';
import { UserRole } from '@/types/UserType';
import type { TeamCoworker, TeamCoworkerInfo, TeamForm } from '@/types/TeamType';

const BASE_URL = import.meta.env.VITE_BASE_URL;

Expand Down Expand Up @@ -271,7 +270,7 @@ const teamServiceHandler = [
http.post(`${BASE_URL}/team/:teamId/invitation`, async ({ request, params }) => {
const accessToken = request.headers.get('Authorization');
const { teamId } = params;
const { userId, roleName } = (await request.json()) as UserRole;
const { userId, roleName } = (await request.json()) as TeamCoworkerInfo;

if (!accessToken) return new HttpResponse(null, { status: 401 });

Expand Down Expand Up @@ -312,19 +311,29 @@ const teamServiceHandler = [
TEAM_USER_DUMMY.length = 0;
TEAM_USER_DUMMY.push(...filteredTeamUsers);

const filteredProjectUsers = PROJECT_USER_DUMMY.filter((projectUser) => projectUser.userId !== Number(userId));

PROJECT_USER_DUMMY.length = 0;
PROJECT_USER_DUMMY.push(...filteredProjectUsers);

const filteredTaskUsers = TASK_USER_DUMMY.filter((taskUser) => taskUser.userId !== Number(userId));

TASK_USER_DUMMY.length = 0;
TASK_USER_DUMMY.push(...filteredTaskUsers);

return new HttpResponse(null, { status: 204 });
}),

// 팀원 권한 변경 API
http.patch(`${BASE_URL}/team/:teamId/user/:userId/role`, async ({ request, params }) => {
const accessToken = request.headers.get('Authorization');
const { teamId, userId } = params;
const { roleName } = (await request.json()) as UserRole;
const { roleName } = (await request.json()) as TeamCoworker;

if (!accessToken) {
return new HttpResponse(null, { status: 401 });
}
// 2. 유효한 역할인지 확인

const role = ROLE_DUMMY.find((role) => role.roleName === roleName);
if (!role) {
return HttpResponse.json({ message: '유효하지 않은 역할입니다.' }, { status: 400 });
Expand Down
5 changes: 3 additions & 2 deletions src/services/teamService.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { authAxios } from '@services/axiosProvider';
import type { AxiosRequestConfig } from 'axios';
import type { SearchUser, User } from '@/types/UserType';
import type { Team, TeamCoworker, TeamForm, TeamUpdateInfo } from '@/types/TeamType';
import type { Team, TeamCoworker, TeamForm, TeamInfoForm } from '@/types/TeamType';
import type { TeamRoleName } from '@/types/RoleType';

/**
Expand Down Expand Up @@ -130,6 +130,7 @@ export async function removeTeamMember(teamId: number, userId: number, axiosConf
* @param {number} userId
* @param {TeamRoleName} roleName
* @param {AxiosRequestConfig} [axiosConfig={}]
* @returns {Promise<AxiosResponse<void>>}
*/
export async function updateTeamRole(
teamId: number,
Expand Down Expand Up @@ -163,6 +164,6 @@ export async function findTeamCoworker(teamId: number, axiosConfig: AxiosRequest
* @param {AxiosRequestConfig} [axiosConfig={}]
* @returns {Promise<AxiosResponse<void>>}
*/
export async function updateTeamInfo(teamId: number, teamInfo: TeamUpdateInfo, axiosConfig: AxiosRequestConfig = {}) {
export async function updateTeamInfo(teamId: number, teamInfo: TeamInfoForm, axiosConfig: AxiosRequestConfig = {}) {
return authAxios.patch(`/team/${teamId}`, teamInfo, axiosConfig);
}
2 changes: 1 addition & 1 deletion src/types/TeamType.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export type TeamCoworker = {
roleName: TeamRoleName;
nickname?: string;
};
export type TeamUpdateInfo = Pick<Team, 'teamName' | 'content'>;
export type TeamInfoForm = Pick<Team, 'teamName' | 'content'>;

export type TeamCoworkerInfo = TeamCoworker & { nickname: User['nickname'] };

Expand Down
5 changes: 0 additions & 5 deletions src/types/UserType.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ export type User = {
profileImageName: string | null;
};

export type UserRole = {
userId: number;
roleName: string;
};

export type UserInfo = User & {
password: string;
};
Expand Down

0 comments on commit 1a85ca7

Please sign in to comment.