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 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | 1x 1x | import { maskEmail } from "@hooks/auth-api/useLoginOTP";
import { AtIcon, CheckIcon, LinkBreakIcon } from "@phosphor-icons/react";
import { useGetPublicForm } from "@sections/PayBuilder/components/hooks/useGetPublicForm";
import { useValidateAccount } from "@services/api/onboarding/user";
import { useAppTheme } from "@theme/v2/Provider";
import { useEffect } from "react";
import { useLocation, useNavigate, useSearchParams } from "react-router-dom";
import { showMessage } from "@common/Toast/ShowToast";
import { useCustomThemeV2 } from "@theme/hooks/useCustomThemeV2";
import {
RESEND_ERROR_MESSAGE,
TData,
useResendEmail,
} from "./api/useResendEmail";
import { ButtonWrapper } from "./common";
const PARAM_KEYS = [
"token",
"productID",
"email",
"orderID",
"merchantName",
] as const;
function useQueryParams<T extends readonly string[]>(
paramKeys: T,
): { [K in T[number]]: string | null } {
const [searchParams] = useSearchParams();
return paramKeys.reduce((acc, key) => {
(acc as any)[key] = searchParams.get(key) ?? null;
return acc;
}, {} as { [K in T[number]]: string | null });
}
const useEmailVerificationPageFactory = () => {
const navigate = useNavigate();
const { state } = useLocation();
const params = useQueryParams(PARAM_KEYS);
const {
status: tokenStatus,
isLoading: isTokenDataLoading,
mutateAsync: validateAccount,
} = useValidateAccount();
const { isLoading, sendEmailAsync } = useResendEmail();
const { isMobileView } = useCustomThemeV2();
const { data, isLoading: isPublicFormLoading } = useGetPublicForm(
state?.productID,
);
const { palette } = useAppTheme();
const handleBackToStore = () =>
navigate(`/${params.productID}?email=${encodeURIComponent(params.email!)}`);
useEffect(() => {
const handleValidation = async () => {
try {
await validateAccount({
token: params.token as string,
isFromCheckout: true,
});
} catch (error) {
return;
}
};
if (params.token) handleValidation();
}, [params.token]);
const internalMap = {
success: {
shouldShowPage: true,
icon: () => (
<CheckIcon size={25} fill={palette.icon?.["icon-secondary"]} />
),
title: "Email Verified",
message: () => (
<>
You can return to {data?.merchantName || params.merchantName} and
retry payment.
</>
),
action: () => (
<ButtonWrapper label="Back to Store" onClick={handleBackToStore} />
),
},
error: {
shouldShowPage: true,
icon: () => (
<LinkBreakIcon size={25} fill={palette.icon?.["icon-secondary"]} />
),
title: "Link is expired",
message: () => <>This page is no longer available.</>,
action: () => (
<ButtonWrapper label="Back to Store" onClick={handleBackToStore} />
),
},
pending: {
shouldShowPage: Boolean(state), // Hide if its not coming from pay now button, would be better to do a redirection.
icon: () => <AtIcon size={25} fill={palette.icon?.["icon-secondary"]} />,
title: "Confirm your email",
message: () => (
<>
You attempted to complete a purchase with{" "}
<strong>{data?.merchantName}</strong>. To proceed with the payment,
please
<br />
confirm your email address by clicking the link we sent to{" "}
<strong>{maskEmail(params.email || "", 5)}</strong>
</>
),
action: () => (
<ButtonWrapper
label="You can resend the email in"
onTimerEndLabel="Resend Email"
shouldHaveTimer
disabled={isLoading}
onClick={() => {
const _orderID = parseInt(params.orderID ?? "");
if (!_orderID) {
// Returning quietly would start the button's cooldown for a mail
// it never attempted, with nothing said to the buyer.
showMessage("Error", RESEND_ERROR_MESSAGE, !isMobileView);
return Promise.reject(new Error("no order to resend for"));
}
// Awaited by the button, which starts its cooldown only on a mail
// that actually went out.
return sendEmailAsync({ orderID: _orderID } as TData);
}}
/>
),
},
};
const tokenStatusComponent =
internalMap[tokenStatus as keyof typeof internalMap];
const currentStatus =
params.token && tokenStatusComponent
? tokenStatusComponent
: internalMap["pending"];
return {
currentStatus,
isLoading: isTokenDataLoading || isPublicFormLoading,
};
};
export { useEmailVerificationPageFactory };
|