Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
โ€ฆeng-dong into feature/#410
  • Loading branch information
pakxe committed Aug 21, 2024
2 parents fbff55e + 78d20a3 commit e276dca
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,32 @@ type MemberReportInput = MemberReportInAction & {
type UseMemberReportProps = {
data: MemberReportInAction[];
addAdjustedMember: (memberReport: MemberReportInAction) => void;
getOnlyOneNotAdjustedRemainMemberIndex: () => number | null;
getIsSamePriceStateAndServerState: () => boolean;
totalPrice: number;
};

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

const [canEditList, setCanEditList] = useState<boolean[]>(new Array(data.length).fill(true));

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);
const {isValid} = validateMemberReportInAction(price, totalPrice);
setCanSubmit(isValid);

if (isValid) {
const newInputList = [...inputList];
Expand All @@ -44,12 +54,22 @@ const useMemberReportInput = ({data, addAdjustedMember, totalPrice}: UseMemberRe

// addAdjustedMember๋กœ ์ธํ•ด data๊ฐ€ ๋ณ€ํ–ˆ์„ ๋•Œ input list์˜ ๊ฐ’์„ ๋งž์ถฐ์ฃผ๊ธฐ ์œ„ํ•จ
useEffect(() => {
setCanSubmit(!getIsSamePriceStateAndServerState());
setInputList(data.map((item, index) => ({...item, index})));

// ๋‚จ์€ ์ธ์›์ด 1๋ช…์ผ ๋•Œ ์ˆ˜์ •์„ ๋ถˆ๊ฐ€๋Šฅํ•˜๋„๋ก ์„ค์ •
const onlyOneIndex = getOnlyOneNotAdjustedRemainMemberIndex();
if (onlyOneIndex !== null) {
const newCanEditList = new Array(data.length).fill(true);
newCanEditList[onlyOneIndex] = false;
setCanEditList(newCanEditList);
}
}, [data]);

return {
inputList,
onChange,
canEditList,
canSubmit,
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,27 @@ describe('useMemberReportListInActionTest', () => {
const targetMemberReset = result.current.memberReportListInAction.find(member => member.name === '๋ง์ตธ');
expect(targetMemberReset?.isFixed).toBe(false);
});

it('์•„๋ฌด๋„ ์กฐ์ •๋œ ๊ฐ’์ด ์—†๋‹ค๋ฉด ์กฐ์ •๊ฐ’์ด ์žˆ๋Š”์ง€ ํ™•์ธ ๊ฒฐ๊ณผ false๋‹ค.', async () => {
const {result} = initializeProvider(actionId, totalPrice);

await waitFor(() => expect(result.current.queryResult.isSuccess).toBe(true));

expect(result.current.isExistAdjustedPrice()).toBe(false);
});

it('๋ง์ตธ์˜ ๊ฐ€๊ฒฉ์„ 100์›์œผ๋กœ ๋ฐ”๊พผ ํ›„ ๋ฆฌ์ŠคํŠธ ์ค‘ ์กฐ์ •๊ฐ’์ด ์žˆ๋Š”์ง€ ํ™•์ธ ๊ฒฐ๊ณผ true๋‹ค.', async () => {
const {result} = initializeProvider(actionId, totalPrice);
const adjustedMemberMangcho: MemberReportInAction = {name: '๋ง์ตธ', price: 100, isFixed: false};

await waitFor(() => expect(result.current.queryResult.isSuccess).toBe(true));

act(() => {
result.current.addAdjustedMember(adjustedMemberMangcho);
});

expect(result.current.isExistAdjustedPrice()).toBe(true);
});
});

// last
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,51 @@ const useMemberReportListInAction = (actionId: number, totalPrice: number) => {
memberReportListInActionFromServer,
);

// isFixed๋ฅผ ๋ชจ๋‘ ํ’€๊ณ  ๊ณ„์‚ฐ๊ฐ’์œผ๋กœ ๋ชจ๋‘ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ธฐ๋Šฅ
const reCalculatePriceByTotalPriceChange = () => {
const {divided, remainder} = calculateDividedPrice(memberReportListInAction.length, 0);

const resetMemberReportList = [...memberReportListInAction];
resetMemberReportList.forEach((member, index) => {
if (index !== resetMemberReportList.length - 1) {
member.price = divided;
} else {
member.price = divided + remainder;
}
member.isFixed = false;
});

setMemberReportListInAction(resetMemberReportList);
};

// ์ด ๊ธˆ์•ก์ด ๋ณ€๋™๋์„ ๋•Œ (์„œ๋ฒ„์—์„œ ์˜จ ๊ฐ’๊ณผ ๋‹ค๋ฅผ ๋•Œ) ์žฌ๊ณ„์‚ฐ ์‹คํ–‰
useEffect(() => {
const totalPriceFromServer = memberReportListInActionFromServer.reduce((acc, cur) => acc + cur.price, 0);

if (totalPriceFromServer !== totalPrice) {
reCalculatePriceByTotalPriceChange();
}
}, [totalPrice]);

useEffect(() => {
if (queryResult.isSuccess) {
setMemberReportListInAction(memberReportListInActionFromServer);
}
}, [memberReportListInActionFromServer, queryResult.isSuccess]);

const isExistAdjustedPrice = () => {
return memberReportListInAction.some(member => member.isFixed === true);
};

// ์กฐ์ •๋˜์ง€ ์•Š์€ ์ธ์›์ด ๋‹จ 1๋ช…์ธ ๊ฒฝ์šฐ์˜ index
const getOnlyOneNotAdjustedRemainMemberIndex = (): number | null => {
const adjustedPriceCount = getAdjustedMemberCount(memberReportListInAction);

if (adjustedPriceCount < memberReportListInAction.length - 1) return null;

return memberReportListInAction.findIndex(member => member.isFixed === false);
};

// ์กฐ์ •๊ฐ’ ๋ฉค๋ฒ„์˜ ์ˆ˜๋ฅผ ๊ตฌํ•˜๋Š” ํ•จ์ˆ˜
const getAdjustedMemberCount = (memberReportListInAction: MemberReportInAction[]) => {
return memberReportListInAction.filter(member => member.isFixed === true).length;
Expand Down Expand Up @@ -89,10 +128,29 @@ const useMemberReportListInAction = (actionId: number, totalPrice: number) => {
putMemberReportListInAction(memberReportListInAction);
};

const getIsSamePriceStateAndServerState = () => {
const serverStatePriceList = memberReportListInActionFromServer.map(({price}) => price);
const clientStatePriceList = memberReportListInAction.map(({price}) => price);

let isSame = true;

// isArrayEqual์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ์ด์œ ๋Š” ์ •๋ ฌ์ด ์˜ํ–ฅ์„ ๋ฐ›์œผ๋ฉด ์•ˆ ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค
for (let i = 0; i < serverStatePriceList.length; i++) {
if (serverStatePriceList[i] !== clientStatePriceList[i]) {
isSame = false;
}
}

return isSame;
};

return {
memberReportListInAction,
addAdjustedMember,
isExistAdjustedPrice,
onSubmit,
getOnlyOneNotAdjustedRemainMemberIndex,
getIsSamePriceStateAndServerState,
queryResult,
};
};
Expand Down
10 changes: 1 addition & 9 deletions client/src/utils/validate/validateMemberReportInAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,13 @@ const validateMemberReportInAction = (price: string, totalPrice: number): Valida
return true;
};

const validateEmpty = () => {
if (!price.trim().length) {
errorMessage = ERROR_MESSAGE.preventEmpty;
return false;
}
return true;
};

const validateUnderTotalPrice = () => {
if (numberTypePrice > totalPrice) return false;

return true;
};

if (validateOnlyNaturalNumber() && validatePrice() && validateEmpty() && validateUnderTotalPrice()) {
if (validateOnlyNaturalNumber() && validatePrice() && validateUnderTotalPrice()) {
return {isValid: true, errorMessage: null};
}

Expand Down

0 comments on commit e276dca

Please sign in to comment.