Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FE] 차등 정산 기능 구현 및 테스트 작성 #406

Merged
merged 28 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
ddeb93e
feat: 고정 가격을 설정했는지에 대한 isFixed 타입 추가
jinhokim98 Aug 19, 2024
e08b505
feat: 지출 상세 조회, 수정 api 함수 작성
jinhokim98 Aug 19, 2024
ee58547
feat: Get, Put query, mutation 작성
jinhokim98 Aug 19, 2024
d490740
feat: 고정값으로 수정할 때, 나머지 인원의 가격이 계산되는 기능 추가
jinhokim98 Aug 19, 2024
0e3d927
fix: isFixed field 추가로 반영되지 못한 테스트 수정
jinhokim98 Aug 19, 2024
cdeec00
test: useMemberReportListInAction 훅 텟트 작성
jinhokim98 Aug 19, 2024
efc5b57
fix: put body 형식 수정
jinhokim98 Aug 19, 2024
1034715
test: submit 함수 테스트 코드 작성
jinhokim98 Aug 19, 2024
c3e61c8
feat: 모든 인원의 가격을 고정시키려 했을 때 반영하지 않는 기능
jinhokim98 Aug 19, 2024
5a24a04
test: 모든 인원을 담을 때 테스트 작성
jinhokim98 Aug 19, 2024
9ec199d
fix: invalidate queries querykey actionId 명시
jinhokim98 Aug 19, 2024
1df1dfe
fix: 중복 인원이 들어왔을 때 잘못 계산되던 문제 해결
jinhokim98 Aug 19, 2024
ae6cf7d
test: 중복 인원일 때 테스트 코드 작성
jinhokim98 Aug 19, 2024
e6239f0
refactor: 지출상세 훅 리팩터링
jinhokim98 Aug 20, 2024
042b58b
test: 같은 멤버 다른 가격으로 변환 시 다시 계산되는 테스트 작성
jinhokim98 Aug 20, 2024
388bfa8
fix: isFixed 추가로 발생한 테스트 오류 수정
jinhokim98 Aug 20, 2024
ecda8ee
feat: 각 멤버 별 isFixed 추가 반영
jinhokim98 Aug 20, 2024
5a0ff8f
refactor: 서버의 isFixed 관리로 불필요한 상태 제거
jinhokim98 Aug 20, 2024
753e8ec
test: isFixed 필드 추가 테스트 반영
jinhokim98 Aug 20, 2024
c574f2d
feat: 계산값으로 값을 변경했을 때 isFixed를 해제하는 기능구현
jinhokim98 Aug 20, 2024
d8b3957
test: isFixed 해제 관련 테스트 작성
jinhokim98 Aug 20, 2024
e2d0aba
feat: member report validation 로직 작성
jinhokim98 Aug 20, 2024
0d5ec62
chore: 테스트를 위한 코드 작성 추후 삭제
jinhokim98 Aug 20, 2024
947b16a
chore: 테스트용 라우팅 삭제
jinhokim98 Aug 21, 2024
203922d
feat: 총 금액보다 큰지 검증하는 기능 추가
jinhokim98 Aug 21, 2024
46f88e7
feat: 차등 적용 input으로 handle하는 기능 추가
jinhokim98 Aug 21, 2024
ea9b6ce
remove: 사용하지 않는 파일 제거
jinhokim98 Aug 21, 2024
e63d3c1
Merge branch 'fe-dev' of https://github.com/woowacourse-teams/2024-ha…
jinhokim98 Aug 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 30 additions & 7 deletions client/src/apis/request/bill.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type {Bill} from 'types/serviceType';
import type {Bill, MemberReportInAction} from 'types/serviceType';

import {BASE_URL} from '@apis/baseUrl';
import {TEMP_PREFIX} from '@apis/tempPrefix';
import {requestDelete, requestPostWithoutResponse, requestPut} from '@apis/fetcher';
import {requestDelete, requestGet, requestPostWithoutResponse, requestPut} from '@apis/fetcher';
import {WithEventId} from '@apis/withEventId.type';

type RequestPostBillList = {
Expand All @@ -19,20 +19,18 @@ export const requestPostBillList = async ({eventId, billList}: WithEventId<Reque
});
};

type RequestDeleteBillAction = {
type RequestBillAction = {
actionId: number;
};

export const requestDeleteBillAction = async ({eventId, actionId}: WithEventId<RequestDeleteBillAction>) => {
export const requestDeleteBillAction = async ({eventId, actionId}: WithEventId<RequestBillAction>) => {
await requestDelete({
baseUrl: BASE_URL.HD,
endpoint: `${TEMP_PREFIX}/${eventId}/bill-actions/${actionId}`,
});
};

type RequestPutBillAction = Bill & {
actionId: number;
};
type RequestPutBillAction = Bill & RequestBillAction;

export const requestPutBillAction = async ({eventId, actionId, title, price}: WithEventId<RequestPutBillAction>) => {
await requestPut({
Expand All @@ -44,3 +42,28 @@ export const requestPutBillAction = async ({eventId, actionId, title, price}: Wi
},
});
};

type MemberReportList = {members: MemberReportInAction[]};

export const requestGetMemberReportListInAction = async ({eventId, actionId}: WithEventId<RequestBillAction>) => {
return requestGet<MemberReportList>({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

흠... 확실히 우리가 쓰던 이름들을 생각하면 뭔지 이해는 되는데
너무 길기도 하고 바로 알수가 없어서
정말 더 좋은 이름이 있을지 고민해봐야 하긴 하겠네요

실제로 "엥...? 멤버별 지출내역을 왜 또 만들었지?" 라고 생각했어요... 😢😢

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

흐음;;; 그렇긴 해요;; 이 부분 이름 짓는 거 진짜 어려웠는데 어떻게 바꾸면 좋을지 감이 안 와요ㅜㅜ

baseUrl: BASE_URL.HD,
endpoint: `${TEMP_PREFIX}/${eventId}/bill-actions/${actionId}/fixed`,
});
};

type RequestPutMemberReportList = RequestBillAction & MemberReportList;

export const requestPutMemberReportListInAction = async ({
eventId,
actionId,
members,
}: WithEventId<RequestPutMemberReportList>) => {
return requestPut({
baseUrl: BASE_URL.HD,
endpoint: `${TEMP_PREFIX}/${eventId}/bill-actions/${actionId}/fixed`,
body: {
members,
},
});
};
1 change: 1 addition & 0 deletions client/src/constants/queryKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const QUERY_KEYS = {
allMemberList: 'allMemberList',
currentInMember: 'currentInMember',
memberReport: 'memberReport',
memberReportInAction: 'memberReportInAction',
};

export default QUERY_KEYS;
24 changes: 24 additions & 0 deletions client/src/hooks/queries/useRequestGetMemberReportListInAction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {useQuery} from '@tanstack/react-query';

import {requestGetMemberReportListInAction} from '@apis/request/bill';

import getEventIdByUrl from '@utils/getEventIdByUrl';

import QUERY_KEYS from '@constants/queryKeys';

const useRequestGetMemberReportListInAction = (actionId: number) => {
const eventId = getEventIdByUrl();

const {data, ...queryResult} = useQuery({
queryKey: [QUERY_KEYS.memberReportInAction, actionId],
queryFn: () => requestGetMemberReportListInAction({eventId, actionId}),
select: data => data.members,
});

return {
memberReportListInActionFromServer: data ?? [],
queryResult,
};
};

export default useRequestGetMemberReportListInAction;
29 changes: 29 additions & 0 deletions client/src/hooks/queries/useRequestPutMemberReportListInAction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {useMutation, useQueryClient} from '@tanstack/react-query';

import {requestPutMemberReportListInAction} from '@apis/request/bill';
import {MemberReportInAction} from 'types/serviceType';

import getEventIdByUrl from '@utils/getEventIdByUrl';

import QUERY_KEYS from '@constants/queryKeys';

const useRequestPutMemberReportListInAction = (actionId: number) => {
const eventId = getEventIdByUrl();
const queryClient = useQueryClient();

const {mutate, ...mutationProps} = useMutation({
mutationFn: (members: MemberReportInAction[]) => requestPutMemberReportListInAction({eventId, actionId, members}),
onSuccess: () => {
queryClient.invalidateQueries({queryKey: [QUERY_KEYS.stepList]});
queryClient.invalidateQueries({queryKey: [QUERY_KEYS.memberReport]});
queryClient.invalidateQueries({queryKey: [QUERY_KEYS.memberReportInAction, actionId]});
},
});

return {
putMemberReportListInAction: mutate,
mutationProps,
};
};

export default useRequestPutMemberReportListInAction;
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ describe('useDeleteMemberAction', () => {
name: '망쵸',
price: null,
sequence: 1,
isFixed: false,
};

result.current.deleteMemberActionList.addDeleteMemberAction(memberAction);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import type {MemberReportInAction} from 'types/serviceType';

import {useEffect, useState} from 'react';

import validateMemberReportInAction from '@utils/validate/validateMemberReportInAction';

type MemberReportInput = MemberReportInAction & {
index: number;
};

type UseMemberReportProps = {
data: MemberReportInAction[];
addAdjustedMember: (memberReport: MemberReportInAction) => void;
totalPrice: number;
};

const useMemberReportInput = ({data, addAdjustedMember, totalPrice}: UseMemberReportProps) => {
const [inputList, setInputList] = useState<MemberReportInput[]>(data.map((item, index) => ({...item, index})));
const [canSubmit, setCanSubmit] = useState<boolean>(false);

const onChange = (event: React.ChangeEvent<HTMLInputElement>, index: number) => {
const {value} = event.target;

validateAndAddAdjustedMember(value, index);
};

const validateAndAddAdjustedMember = (price: string, index: number) => {
const {isValid, errorMessage} = validateMemberReportInAction(price, totalPrice);
setCanSubmit(errorMessage === null);

if (isValid) {
const newInputList = [...inputList];
newInputList[index].price = Number(price);
setInputList(newInputList);

const memberReportData: MemberReportInAction = {
name: newInputList[index].name,
price: newInputList[index].price,
isFixed: newInputList[index].isFixed,
};
addAdjustedMember(memberReportData);
}
};

// addAdjustedMember로 인해 data가 변했을 때 input list의 값을 맞춰주기 위함
useEffect(() => {
setInputList(data.map((item, index) => ({...item, index})));
}, [data]);

return {
inputList,
onChange,
canSubmit,
};
};

export default useMemberReportInput;
Loading
Loading