Remove multiple components related to multi-factor authentication setup

Removed personal account related multi-factor authentication setup modal and otp-input. Adjusted dependencies, exports, and imports to reflect the deletion. Various adjustments in other areas of the codebase were made to account for these deletions, including moving necessary components and adding the 'input-otp' library in the package.json under 'ui' directory.
This commit is contained in:
giancarlo
2024-03-28 01:30:43 +08:00
parent 500fea4bf8
commit 6048cc4759
21 changed files with 1078 additions and 630 deletions

View File

@@ -1,143 +0,0 @@
import type { FormEventHandler } from 'react';
import { useCallback, useEffect, useMemo } from 'react';
import { useFieldArray, useForm } from 'react-hook-form';
import { Input } from '../shadcn/input';
const DIGITS = 6;
export function OtpInput({
onValid,
onInvalid,
}: React.PropsWithChildren<{
onValid: (code: string) => void;
onInvalid: () => void;
}>) {
const digitsArray = useMemo(
() => Array.from({ length: DIGITS }, (_, i) => i),
[],
);
const { control, register, watch, setFocus, formState, setValue } = useForm({
mode: 'onChange',
reValidateMode: 'onChange',
defaultValues: {
values: digitsArray.map(() => ({ value: '' })),
},
});
useFieldArray({
control,
name: 'values',
shouldUnregister: true,
});
const { values } = watch();
const isFormValid = formState.isValid;
const code = (values ?? []).map(({ value }) => value).join('');
useEffect(() => {
if (!isFormValid) {
onInvalid();
return;
}
if (code.length === DIGITS) {
onValid(code);
return;
}
onInvalid();
}, [onInvalid, onValid, code, isFormValid]);
useEffect(() => {
setFocus('values.0.value');
}, [setFocus]);
const onInput: FormEventHandler<HTMLInputElement> = useCallback(
(target) => {
const element = target.currentTarget;
const isValid = element.reportValidity();
if (isValid) {
const nextIndex = Number(element.dataset.index) + 1;
if (nextIndex >= DIGITS) {
return;
}
setFocus(`values.${nextIndex}.value`);
}
},
[setFocus],
);
const onPaste = useCallback(
(event: React.ClipboardEvent<HTMLInputElement>) => {
const pasted = event.clipboardData.getData('text/plain');
// check if value is numeric
if (isNumeric(pasted)) {
const digits = getDigits(pasted, digitsArray);
digits.forEach((value, index) => {
setValue(`values.${index}.value`, value);
setFocus(`values.${index + 1}.value`);
});
}
},
[digitsArray, setFocus, setValue],
);
const handleKeyDown = useCallback(
(event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'Backspace') {
event.preventDefault();
const index = Number(event.currentTarget.dataset.inputIndex);
setValue(`values.${index}.value`, '');
setFocus(`values.${index - 1}.value`);
}
},
[setFocus, setValue],
);
return (
<div className={'flex justify-center space-x-2'}>
{digitsArray.map((digit, index) => {
const control = { ...register(`values.${digit}.value`) };
return (
<Input
autoComplete={'off'}
className={'w-10 text-center'}
data-index={digit}
pattern="[0-9]"
required
key={digit}
maxLength={1}
onInput={onInput}
onPaste={onPaste}
onKeyDown={handleKeyDown}
data-input-index={index}
{...control}
/>
);
})}
</div>
);
}
function isNumeric(pasted: string) {
const isNumericRegExp = /^-?\d+$/;
return isNumericRegExp.test(pasted);
}
function getDigits(pasted: string, digitsArray: number[]) {
return pasted.split('').slice(0, digitsArray.length);
}