Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | 149x 149x 2x 13x 224x 224x 224x 102x 224x 224x 224x 224x 68x 68x 68x 68x 68x 4x 4x 68x 224x 68x 224x 38x 224x 68x | import React, { useState } from "react";
import { useFormContext } from "react-hook-form";
import { formatCardNumber } from "@utils/index";
import { GiveInput, InputProps } from "@shared/GiveInputs/GiveInput";
import { InputAdornment } from "@mui/material";
import { getCardBrandIcon } from "@sections/Checkout/Payment/inputs/CardNumberInput";
import { isEmpty } from "lodash";
export const CARD_LENGTHS = {
AMEX: 17,
OTHERS: 19,
};
type ICardNumberFieldProps = InputProps & {
handleCardNumberCheck?: (value: string) => void;
onCardTypeChange?: (cardType: string) => void;
};
const CardNumberField = ({
sx,
handleCardNumberCheck = () => null,
onCardTypeChange = () => null,
...rest
}: ICardNumberFieldProps) => {
const { setValue, clearErrors, watch } = useFormContext();
const inputVal = watch("payment.cardNumber");
const derivedCard = React.useMemo(
() => formatCardNumber(inputVal || ""),
[inputVal],
);
const cardType = derivedCard?.cardType || "";
const maxCardNumberLength =
cardType && cardType === "AMEX" ? CARD_LENGTHS.AMEX : CARD_LENGTHS.OTHERS;
const type = isEmpty(inputVal) ? "hide" : cardType?.toUpperCase() ?? "hide";
const normalizeInput = (value: string) => {
Iif (!value) return value;
const card = formatCardNumber(value);
const allowedLength =
card?.cardType && card?.cardType === "AMEX"
? CARD_LENGTHS.AMEX
: CARD_LENGTHS.OTHERS;
const isApprovedLength = card?.formattedNumber?.length === allowedLength;
if (isApprovedLength) {
clearErrors("payment.cardNumber");
handleCardNumberCheck(value);
}
return card.formattedNumber;
};
const handleChange = (value: string) => {
setValue("payment.cardNumber", normalizeInput(value));
};
React.useEffect(() => {
onCardTypeChange(cardType);
}, [cardType]);
return (
<GiveInput
{...rest}
onChange={(event) => handleChange(event.target.value)}
maxLength={maxCardNumberLength}
sx={{
letterSpacing: "2px",
"& .MuiFormHelperText-root": {
letterSpacing: "0px",
},
...sx,
}}
InputProps={{
endAdornment: (
<InputAdornment position="start" sx={{ alignItems: "center" }}>
{getCardBrandIcon(type)}
</InputAdornment>
),
inputMode: "numeric",
}}
/>
);
};
export default CardNumberField;
|