Lock verified identity fields in profile and checkout

This commit is contained in:
2026-10-17 23:35:35 +03:30
parent 1ce33d9b74
commit c4c115ccfc
4 changed files with 39 additions and 16 deletions

View File

@@ -17,6 +17,7 @@ const ProfileDetails = ({
return (
<div className="relative z-[10] w-full min-h-32 max-md:min-h-20 flex flex-row-reverse max-[400px]:gap-3 justify-between flex-wrap-reverse glass items-center py-2 px-4">
<EditProfile
identityVerified={data?.result?.user_profile?.is_identity_verified}
nationalId={data?.result?.user_profile?.national_id}
email={data?.result?.user_profile?.email}
mobile={data?.result?.user_profile?.mobile}
@@ -36,11 +37,13 @@ const ProfileDetails = ({
export default ProfileDetails;
const EditProfile = ({
identityVerified,
nationalId,
email,
mobile,
cardNumber,
}: {
identityVerified?: boolean;
nationalId?: string | null;
email?: string | null;
mobile?: string | null;
@@ -53,6 +56,7 @@ const EditProfile = ({
<ModalEditProfile
isOpen={isOpen}
setIsOpen={setIsOpen}
identityVerified={identityVerified}
nationalId={nationalId}
email={email}
mobile={mobile}

View File

@@ -26,6 +26,7 @@ const ModalEditProfile = ({
isOpen,
setIsOpen,
nationalId,
identityVerified = false,
email,
mobile,
cardNumber,
@@ -33,6 +34,7 @@ const ModalEditProfile = ({
isOpen: boolean;
setIsOpen: Dispatch<SetStateAction<boolean>>;
nationalId?: string | null;
identityVerified?: boolean;
email?: string | null;
mobile?: string | null;
cardNumber?: string | null;
@@ -66,7 +68,7 @@ const ModalEditProfile = ({
mutationFn: async () => {
const requests = [];
if (nationalCode.trim() && nationalCode.trim() !== (nationalId ?? "")) {
if (!identityVerified && nationalCode.trim() && nationalCode.trim() !== (nationalId ?? "")) {
requests.push(
axios.post("/profile/national-id", {
national_id: nationalCode.trim(),
@@ -102,7 +104,7 @@ const ModalEditProfile = ({
});
const submitHandler = () => {
if (nationalCode.trim() && nationalCode.trim().length !== 10) {
if (!identityVerified && nationalCode.trim() && nationalCode.trim().length !== 10) {
toast.error("کد ملی باید ۱۰ رقم باشد");
return;
}
@@ -203,7 +205,11 @@ const ModalEditProfile = ({
value={mobile ?? ""}
disabled
/>
{mobileStep === "idle" ? (
{identityVerified ? (
<Alert type="info" extra="!mb-0 text-start">
شماره موبایل و کد ملی شما تأیید شده‌اند و قابل تغییر نیستند.
</Alert>
) : mobileStep === "idle" ? (
<div className="w-full flex flex-col gap-2">
<Input
type="text"
@@ -301,9 +307,11 @@ const ModalEditProfile = ({
}
/>
<Alert type="warning" extra="!mb-0 text-start">
کد ملی برای احراز هویت شاهکار در خریدهای با مبلغ بالا لازم است.
</Alert>
{!identityVerified && (
<Alert type="warning" extra="!mb-0 text-start">
کد ملی برای احراز هویت شاهکار در خریدهای با مبلغ بالا لازم است.
</Alert>
)}
<Input
type="text"
label="کد ملی :"
@@ -311,6 +319,7 @@ const ModalEditProfile = ({
extra="!w-full"
placeholder="کد ملی ۱۰ رقمی"
value={nationalCode}
disabled={identityVerified}
onChange={(e) =>
setNationalCode(e.target.value.replace(/[^0-9]/g, ""))
}

View File

@@ -47,6 +47,7 @@ const ModalBuy = ({ isOpen, setIsOpen, configId }: ModalBuyProps) => {
const [isInfoOpen, setIsInfoOpen] = useState(false);
const [needsShahkarVerification, setNeedsShahkarVerification] = useState(false);
const [nationalCode, setNationalCode] = useState("");
const identityVerified = Boolean(data?.data?.result?.is_identity_verified);
const [hasReadDescription, setHasReadDescription] = useState(false);
const payablePrice = toNumber(
price === 0 ? data?.data?.result?.price || 0 : price
@@ -113,6 +114,9 @@ const ModalBuy = ({ isOpen, setIsOpen, configId }: ModalBuyProps) => {
}, [isOpen, setFieldValue]);
const mutation = useMutation({
mutationKey: ["buyConfig"],
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ["profile"] });
},
mutationFn: (values: BuyConfigDataProps) => {
return axios.post(`home/config/${configId}/buy`, values);
},
@@ -205,7 +209,7 @@ const ModalBuy = ({ isOpen, setIsOpen, configId }: ModalBuyProps) => {
return;
}
if (needsShahkarVerification && nationalCode.trim().length !== 10) {
if (needsShahkarVerification && !identityVerified && nationalCode.trim().length !== 10) {
toast.error("لطفا کد ملی ۱۰ رقمی را به‌درستی وارد کنید");
return;
}
@@ -214,7 +218,7 @@ const ModalBuy = ({ isOpen, setIsOpen, configId }: ModalBuyProps) => {
...formik.values,
status: "buy",
...(hasExtraDescription ? { hasReadDescription: true } : {}),
...(needsShahkarVerification ? { nationalCode: nationalCode.trim() } : {}),
...(needsShahkarVerification && !identityVerified ? { nationalCode: nationalCode.trim() } : {}),
};
toast.promise(mutation.mutateAsync(payload), {
@@ -239,6 +243,9 @@ const ModalBuy = ({ isOpen, setIsOpen, configId }: ModalBuyProps) => {
}
const responseData = err.response?.data;
if (responseData && typeof responseData === "object" && "message" in responseData && typeof responseData.message === "string") {
errorMessage = responseData.message;
}
const isResponseObject =
responseData !== null && typeof responseData === "object";
const requiresAdvancedVerificationFromApi =
@@ -256,13 +263,14 @@ const ModalBuy = ({ isOpen, setIsOpen, configId }: ModalBuyProps) => {
(err.response?.status === 422 &&
errorMessage.includes("احراز هویت پیشرفته"));
const requiresShahkarVerificationFromApi =
isResponseObject &&
"requires_shahkar_verification" in responseData &&
Boolean(
(responseData as { requires_shahkar_verification?: boolean })
.requires_shahkar_verification
);
const shahkarError = responseData as {
requires_shahkar_verification?: boolean;
result?: { requires_shahkar_verification?: boolean };
} | undefined;
const requiresShahkarVerificationFromApi = Boolean(
shahkarError?.requires_shahkar_verification ||
shahkarError?.result?.requires_shahkar_verification
);
if (requiresShahkarVerificationFromApi) {
setNeedsShahkarVerification(true);
@@ -382,7 +390,7 @@ const ModalBuy = ({ isOpen, setIsOpen, configId }: ModalBuyProps) => {
{advancedVerificationMessage}
</Alert>
)}
{needsShahkarVerification && (
{needsShahkarVerification && !identityVerified && (
<div className="w-full flex flex-col gap-2">
<Alert type="warning" extra="!mb-0 text-start">
برای خریدهای با مبلغ بالا، احراز هویت شاهکار (تطبیق شماره

View File

@@ -219,6 +219,8 @@ type UserProfile = {
email: string;
mobile: string;
national_id?: string | null;
is_identity_verified?: boolean;
shahkar_verified_at?: string | null;
card_number?: string | null;
};