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] 계좌번호 입력 제한 추가 #634

Merged
merged 5 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
1 change: 1 addition & 0 deletions client/src/constants/errorMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export const ERROR_MESSAGE = {
preventEmpty: '값은 비어있을 수 없어요',
invalidInput: '올바르지 않은 입력이에요.',
emptyBank: '계좌번호가 입력되지 않아서\n토스 송금 기능을 사용할 수 없어요',
invalidAccountNumber: '계좌번호는 8자에서 30자 사이로 입력 가능해요',
};

export const UNKNOWN_ERROR = 'UNKNOWN_ERROR';
1 change: 1 addition & 0 deletions client/src/constants/regExp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const REGEXP = {
eventUrl: /\/event\/([a-zA-Z0-9-]+)\//,
billTitle: /^([ㄱ-ㅎ가-힣a-zA-Z0-9ㆍᆢ]\s?)*$/,
memberName: /^([ㄱ-ㅎ가-힣a-zA-Zㆍᆢ]\s?)*$/,
accountNumber: /^[0-9\s\-]*$/,
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
accountNumber: /^[0-9\s\-]*$/,
accountNumber: ^\d+([\s\-]\d+)*[\s\-]?$,

로 사용하면 연속된 -나 공백을 걸러줄 수 있어요~

Copy link
Contributor Author

Choose a reason for hiding this comment

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

토다리는 정(규표현식의)신

};

export default REGEXP;
2 changes: 2 additions & 0 deletions client/src/constants/rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ const RULE = {
maxEventPasswordLength: 4,
maxMemberNameLength: 4,
maxPrice: 10000000,
minAccountNumberLength: 8,
maxAccountNumberLength: 30,
Comment on lines +6 to +7
Copy link
Contributor

Choose a reason for hiding this comment

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

상수화 굿굿

};

export default RULE;
40 changes: 36 additions & 4 deletions client/src/hooks/useAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@ import type {Event} from 'types/serviceType';

import {useEffect, useState} from 'react';

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

import RULE from '@constants/rule';

import useRequestPatchEvent from './queries/event/useRequestPatchEvent';
import useRequestGetEvent from './queries/event/useRequestGetEvent';

const useAccount = () => {
const {bankName, accountNumber} = useRequestGetEvent();

const [bankNameState, setBankName] = useState(bankName);
const [accountNumberState, setAccountNumber] = useState(accountNumber);
const [accountNumberErrorMessage, setAccountNumberErrorMessage] = useState<string | null>(null);
const [canSubmit, setCanSubmit] = useState(false);
const [isPasting, setIsPasting] = useState(false);

useEffect(() => {
setBankName(bankName);
Expand All @@ -24,7 +29,32 @@ const useAccount = () => {
};

const handleAccount = (event: React.ChangeEvent<HTMLInputElement>) => {
setAccountNumber(event.target.value);
if (isPasting) return;

const newValue = event.target.value;
const {isValid, errorMessage} = validateAccountNumber(newValue);
setAccountNumberErrorMessage(errorMessage);

const isValidMinLength = newValue.length >= RULE.minAccountNumberLength;

if (isValid) {
setAccountNumber(event.target.value);
} else if (!isValid && !isValidMinLength) {
setAccountNumber(event.target.value.replace(/[^0-9\s\-]/g, '').trim());
Copy link
Contributor

Choose a reason for hiding this comment

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

어차피 허용되는 문자인데 slice 를 사용하면 안되는 이유가 있었을까요?

Suggested change
setAccountNumber(event.target.value.replace(/[^0-9\s\-]/g, '').trim());
setAccountNumber(event.target.value.slice(0, RULE.maxAccountNumberLength).trim());

Copy link
Contributor Author

Choose a reason for hiding this comment

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

8자보다 작을 때 숫자 공백 하이픈 외의 문자가 허용되지 않도록 하기 위해서입니다!

}
};

const handleAccountOnPaste = (event: React.ClipboardEvent<HTMLInputElement>) => {
setIsPasting(true);

const value = `${accountNumberState}${event.clipboardData.getData('text')}`;
const newValue = value.replace(/[^0-9\s\-]/g, '').trim();
const {isValid, errorMessage} = validateAccountNumber(newValue);

setAccountNumberErrorMessage(errorMessage);
if (isValid) setAccountNumber(newValue);

setTimeout(() => setIsPasting(false), 0);
};

const getChangedField = () => {
Expand All @@ -49,15 +79,17 @@ const useAccount = () => {
const existEmptyField = bankName.trim() === '' && accountNumber.trim() === '';
const isChanged = bankName !== bankNameState || accountNumber !== accountNumberState;

setCanSubmit(!existEmptyField && isChanged);
}, [bankName, accountNumber, bankNameState, accountNumberState]);
setCanSubmit(!existEmptyField && isChanged && accountNumberErrorMessage === null);
}, [bankName, accountNumber, bankNameState, accountNumberState, accountNumberErrorMessage]);

return {
bankName: bankNameState,
accountNumber: accountNumberState,
accountNumberErrorMessage,
canSubmit,
selectBank,
handleAccount,
handleAccountOnPaste,
enrollAccount,
};
};
Expand Down
19 changes: 14 additions & 5 deletions client/src/pages/AccountPage/Account.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,16 @@ const Account = () => {

const [isBottomSheetOpen, setIsBottomSheetOpen] = useState(false);

const {bankName, accountNumber, canSubmit, selectBank, handleAccount, enrollAccount} = useAccount();
const {
bankName,
accountNumber,
accountNumberErrorMessage,
canSubmit,
selectBank,
handleAccount,
handleAccountOnPaste,
enrollAccount,
} = useAccount();

const enrollAccountAndNavigateAdmin = async () => {
await enrollAccount();
Expand All @@ -40,19 +49,19 @@ const Account = () => {
errorText={null}
autoFocus={false}
isAlwaysOnLabel
isAlwaysOnInputBorder
readOnly
onClick={() => setIsBottomSheetOpen(true)}
/>
<LabelInput
labelText="계좌번호"
placeholder="030302-04-191806"
errorText={null}
placeholder="ex) 030302-04-191806"
Copy link
Contributor

Choose a reason for hiding this comment

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

올바른 placeholder 최고

errorText={accountNumberErrorMessage}
isError={accountNumberErrorMessage !== null}
value={accountNumber ?? ''}
onChange={handleAccount}
onPaste={handleAccountOnPaste}
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.

저도 이번에 처음 알게 됐어요! 혹시나 있을까 해서 봤는데 진짜 있었던

Copy link
Contributor

Choose a reason for hiding this comment

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

ㄹㅇ 갓갓 onPaste

autoFocus={false}
isAlwaysOnLabel
isAlwaysOnInputBorder
/>
{isBottomSheetOpen && (
<BankSelectModal
Expand Down
23 changes: 23 additions & 0 deletions client/src/utils/validate/validateAccountNumber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {ERROR_MESSAGE} from '@constants/errorMessage';
import REGEXP from '@constants/regExp';
import RULE from '@constants/rule';

import {ValidateResult} from './type';

const validateAccountNumber = (accountNumber: string): ValidateResult => {
const isValidateType = () => {
return REGEXP.accountNumber.test(accountNumber);
};

const isValidateLength = () => {
return accountNumber.length >= RULE.minAccountNumberLength && accountNumber.length <= RULE.maxAccountNumberLength;
};

if (isValidateType() && isValidateLength()) {
return {isValid: true, errorMessage: null};
}

return {isValid: false, errorMessage: ERROR_MESSAGE.invalidAccountNumber};
};

export default validateAccountNumber;
Loading