ProPhoneInput: fix validation and value
This commit is contained in:
@@ -73,8 +73,6 @@ export function GiftBottomSheet({
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<ProPhoneInput
|
<ProPhoneInput
|
||||||
phone={giftForm.getFieldValue("receiverPhone")}
|
|
||||||
setPhone={(phone) => giftForm.setFieldValue("receiverPhone", phone)}
|
|
||||||
propName="receiverPhone"
|
propName="receiverPhone"
|
||||||
label={t("address.receiverPhone")}
|
label={t("address.receiverPhone")}
|
||||||
/>
|
/>
|
||||||
@@ -109,8 +107,6 @@ export function GiftBottomSheet({
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<ProPhoneInput
|
<ProPhoneInput
|
||||||
phone={giftForm.getFieldValue("senderPhone")}
|
|
||||||
setPhone={(phone) => giftForm.setFieldValue("senderPhone", phone)}
|
|
||||||
propName="senderPhone"
|
propName="senderPhone"
|
||||||
label={t("address.receiverPhone")}
|
label={t("address.receiverPhone")}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -5,15 +5,21 @@ import { useTranslation } from "react-i18next";
|
|||||||
import PhoneInput from "react-phone-input-2";
|
import PhoneInput from "react-phone-input-2";
|
||||||
import { useAppSelector } from "redux/hooks";
|
import { useAppSelector } from "redux/hooks";
|
||||||
import { ProBlack1 } from "ThemeConstants";
|
import { ProBlack1 } from "ThemeConstants";
|
||||||
|
import { PhoneNumberUtil } from "google-libphonenumber";
|
||||||
|
import useFormInstance from "antd/es/form/hooks/useFormInstance";
|
||||||
|
|
||||||
interface ProPhoneInput extends TitleProps {
|
interface ProPhoneInput extends TitleProps {
|
||||||
phone: string;
|
propName?: string;
|
||||||
setPhone: (phone: string) => void;
|
label?: string;
|
||||||
propName?: string
|
getValueCallback?: (value: string) => void;
|
||||||
label?: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProPhoneInput: FunctionComponent<ProPhoneInput> = ({ phone, setPhone, propName, label }) => {
|
const ProPhoneInput: FunctionComponent<ProPhoneInput> = ({
|
||||||
|
propName,
|
||||||
|
label,
|
||||||
|
getValueCallback,
|
||||||
|
}) => {
|
||||||
|
const form = useFormInstance();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { themeName } = useAppSelector((state) => state.theme);
|
const { themeName } = useAppSelector((state) => state.theme);
|
||||||
const { isRTL } = useAppSelector((state) => state.locale);
|
const { isRTL } = useAppSelector((state) => state.locale);
|
||||||
@@ -23,25 +29,30 @@ const ProPhoneInput: FunctionComponent<ProPhoneInput> = ({ phone, setPhone, prop
|
|||||||
name={propName}
|
name={propName}
|
||||||
label={label}
|
label={label}
|
||||||
rules={[
|
rules={[
|
||||||
{ required: true, message: "" },
|
{ required: true, message: t("validation.phoneRequired") },
|
||||||
{
|
{
|
||||||
validator: (_, value) => {
|
validator: (_, value) => {
|
||||||
if (!value || value.length <= 3) {
|
// Initialize the PhoneNumberUtil instance
|
||||||
return Promise.reject(new Error(""));
|
const phoneUtil = PhoneNumberUtil.getInstance();
|
||||||
}
|
if (
|
||||||
|
value &&
|
||||||
|
!phoneUtil.isValidNumber(
|
||||||
|
phoneUtil.parseAndKeepRawInput(`+${value}`),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return Promise.reject(new Error(t("validation.invalidPhone")));
|
||||||
|
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
normalize={(value) => {
|
|
||||||
if (value && setPhone) {
|
|
||||||
setPhone(value);
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<PhoneInputWrapper
|
<PhoneInputWrapper
|
||||||
phone={phone}
|
onChange={(value) => {
|
||||||
|
form.setFieldValue(propName, value);
|
||||||
|
getValueCallback?.(value);
|
||||||
|
}}
|
||||||
|
phone={form.getFieldValue(propName)}
|
||||||
themeName={themeName}
|
themeName={themeName}
|
||||||
isRTL={isRTL}
|
isRTL={isRTL}
|
||||||
placeholder={t("login.mobileNumber")}
|
placeholder={t("login.mobileNumber")}
|
||||||
@@ -52,8 +63,17 @@ const ProPhoneInput: FunctionComponent<ProPhoneInput> = ({ phone, setPhone, prop
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const PhoneInputWrapper = ({ phone, themeName, isRTL, placeholder, value, onChange, propName, label }: {
|
export const PhoneInputWrapper = ({
|
||||||
phone: string;
|
phone,
|
||||||
|
themeName,
|
||||||
|
isRTL,
|
||||||
|
placeholder,
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
propName,
|
||||||
|
label,
|
||||||
|
}: {
|
||||||
|
phone?: string;
|
||||||
themeName: string;
|
themeName: string;
|
||||||
isRTL: boolean;
|
isRTL: boolean;
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
@@ -106,7 +126,6 @@ export const PhoneInputWrapper = ({ phone, themeName, isRTL, placeholder, value,
|
|||||||
autoComplete: "tel",
|
autoComplete: "tel",
|
||||||
type: "tel",
|
type: "tel",
|
||||||
inputMode: "numeric",
|
inputMode: "numeric",
|
||||||
pattern: "[0-9]*",
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,23 +1,19 @@
|
|||||||
import ProInputCard from "components/ProInputCard/ProInputCard.tsx";
|
import ProInputCard from "components/ProInputCard/ProInputCard.tsx";
|
||||||
import ProPhoneInput from "components/ProPhoneInput";
|
import ProPhoneInput from "components/ProPhoneInput";
|
||||||
import { selectCart, updatePhone } from "features/order/orderSlice";
|
import { selectCart } from "features/order/orderSlice";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useAppDispatch, useAppSelector } from "redux/hooks";
|
import { useAppSelector } from "redux/hooks";
|
||||||
import { OrderType } from "pages/checkout/hooks/types.ts";
|
import { OrderType } from "pages/checkout/hooks/types.ts";
|
||||||
|
|
||||||
export default function PhoneCard() {
|
export default function PhoneCard() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const { orderType } = useAppSelector(selectCart);
|
||||||
const { phone, orderType } = useAppSelector(selectCart);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
orderType !== OrderType.Gift && (
|
orderType !== OrderType.Gift && (
|
||||||
<>
|
<>
|
||||||
<ProInputCard title={t("checkout.phoneNumber")}>
|
<ProInputCard title={t("checkout.phoneNumber")}>
|
||||||
<ProPhoneInput
|
<ProPhoneInput />
|
||||||
phone={phone}
|
|
||||||
setPhone={(phone) => dispatch(updatePhone(phone))}
|
|
||||||
/>
|
|
||||||
</ProInputCard>
|
</ProInputCard>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -23,19 +23,22 @@ export default function LoginPage() {
|
|||||||
const [sendOtp, { isLoading }] = useSendOtpMutation();
|
const [sendOtp, { isLoading }] = useSendOtpMutation();
|
||||||
const { subdomain } = useParams();
|
const { subdomain } = useParams();
|
||||||
|
|
||||||
const [phone, setPhone] = useState<string>("");
|
// const [phone, setPhone] = useState<string>("");
|
||||||
const [selectedDate, setSelectedDate] = useState<string>("");
|
const [selectedDate, setSelectedDate] = useState<string>("");
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const handleLogin = async () => {
|
const handleLogin = async () => {
|
||||||
|
form.validateFields().then(() => {
|
||||||
|
if (form.getFieldsValue()) {
|
||||||
localStorage.setItem("userPhone", form.getFieldValue("phone"));
|
localStorage.setItem("userPhone", form.getFieldValue("phone"));
|
||||||
if (form.getFieldsValue())
|
|
||||||
sendOtp(form.getFieldsValue()).then((response: any) => {
|
sendOtp(form.getFieldsValue()).then((response: any) => {
|
||||||
message.info(t("login.OTPSentToYourPhoneNumber"));
|
message.info(t("login.OTPSentToYourPhoneNumber"));
|
||||||
navigate(`/${subdomain}/otp`);
|
navigate(`/${subdomain}/otp`);
|
||||||
localStorage.setItem("otp", response.data.result.otp);
|
localStorage.setItem("otp", response.data.result.otp);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -94,7 +97,11 @@ export default function LoginPage() {
|
|||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item label={t("login.date")} name="date" required>
|
<Form.Item
|
||||||
|
label={t("login.date")}
|
||||||
|
name="date"
|
||||||
|
rules={[{ required: true, message: "" }]}
|
||||||
|
>
|
||||||
<Input
|
<Input
|
||||||
placeholder={t("login.DateOfBirth")}
|
placeholder={t("login.DateOfBirth")}
|
||||||
size="large"
|
size="large"
|
||||||
@@ -109,7 +116,7 @@ export default function LoginPage() {
|
|||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<ProPhoneInput phone={phone} setPhone={setPhone} />
|
<ProPhoneInput label={t("login.phone")} propName="phone" />
|
||||||
|
|
||||||
<Form.Item label={null}>
|
<Form.Item label={null}>
|
||||||
<Button
|
<Button
|
||||||
@@ -120,8 +127,7 @@ export default function LoginPage() {
|
|||||||
style={{
|
style={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
borderRadius: 1000,
|
borderRadius: 1000,
|
||||||
backgroundColor:
|
backgroundColor: isLoading
|
||||||
phone.length <= 3 || isLoading
|
|
||||||
? themeName === "light"
|
? themeName === "light"
|
||||||
? "rgba(233, 233, 233, 1)"
|
? "rgba(233, 233, 233, 1)"
|
||||||
: DisabledColor
|
: DisabledColor
|
||||||
@@ -132,7 +138,7 @@ export default function LoginPage() {
|
|||||||
marginTop: "2rem",
|
marginTop: "2rem",
|
||||||
boxShadow: "none",
|
boxShadow: "none",
|
||||||
}}
|
}}
|
||||||
disabled={phone.length <= 3 || isLoading}
|
disabled={isLoading}
|
||||||
htmlType="submit"
|
htmlType="submit"
|
||||||
>
|
>
|
||||||
{t("login.sendCode")}
|
{t("login.sendCode")}
|
||||||
|
|||||||
Reference in New Issue
Block a user