AW-483-484-485-fix-bugs

This commit is contained in:
Daniil Chemerkin 2025-07-01 15:22:35 +00:00
parent bf50dbaad4
commit 7e5329964e
11 changed files with 641 additions and 485 deletions

View File

@ -12,81 +12,83 @@ import { ELocalesPlacement } from "@/locales";
import { useFunnel } from "@/hooks/funnel/useFunnel";
function AnonymousPaymentPage() {
const dispatch = useDispatch();
const navigate = useNavigate();
const { products } = useFunnel({
funnel: ELocalesPlacement.EmailGenerator,
paymentPlacement: "TODO:FUNNEL"
});
const activeProduct = products[0];
const activeProductFromStore = useSelector(selectors.selectActiveProduct)
const { session, createSession } = useSession();
const utm = useSelector(selectors.selectUTM);
const feature = useSelector(selectors.selectFeature);
const [isParametersInitialized, setIsParametersInitialized] = useState(false);
const dispatch = useDispatch();
const navigate = useNavigate();
const { products } = useFunnel({
funnel: ELocalesPlacement.EmailGenerator,
paymentPlacement: "TODO:FUNNEL",
});
const activeProduct = products[0];
const activeProductFromStore = useSelector(selectors.selectActiveProduct);
const { session, createSession } = useSession();
const utm = useSelector(selectors.selectUTM);
const feature = useSelector(selectors.selectFeature);
const [isParametersInitialized, setIsParametersInitialized] = useState(false);
const location = useLocation();
const location = useLocation();
useEffect(() => {
const _feature = location.pathname.replace(
routes.client.anonymousPayment(),
""
);
dispatch(
actions.userConfig.setFeature(
_feature.includes("/v1/gender") ? "" : _feature
)
);
dispatch(actions.privacyPolicy.updateChecked(true))
}, [dispatch, location.pathname]);
useEffect(() => {
const _feature = location.pathname.replace(
routes.client.anonymousPayment(),
""
);
dispatch(
actions.userConfig.setFeature(
_feature.includes("/v1/gender") ? "" : _feature
)
);
dispatch(actions.privacyPolicy.updateChecked(true));
}, [dispatch, location.pathname]);
useEffect(() => {
if (!isParametersInitialized) {
return setIsParametersInitialized(true);
}
(async () => {
await createSession(ESourceAuthorization["aura.test.payment"])
})()
}, [utm, feature, isParametersInitialized])
useEffect(() => {
if (!!activeProduct) {
dispatch(actions.payment.update({
activeProduct
}))
}
}, [activeProduct]);
function onPaymentError(error?: string | undefined): void {
if (error === "Product not found") {
return navigate(routes.client.compatibilityV2TrialChoice());
}
useEffect(() => {
if (!isParametersInitialized) {
return setIsParametersInitialized(true);
}
(async () => {
await createSession(ESourceAuthorization["aura.test.payment"]);
})();
}, [utm, feature, isParametersInitialized]);
function onPaymentSuccess(): void {
setTimeout(() => {
navigate(routes.client.home());
}, 1500);
useEffect(() => {
if (!!activeProduct) {
dispatch(
actions.payment.update({
activeProduct,
})
);
}
}, [activeProduct]);
return (
<div className={styles.container}>
{!!activeProductFromStore && session?.["aura.test.payment"]?.length ?
<PaymentPage
// placementKey={EPlacementKeys["aura.placement.payment"]}
funnel={ELocalesPlacement.EmailGenerator}
paymentPlacement="TODO:FUNNEL"
onError={onPaymentError}
onSuccess={onPaymentSuccess}
isBackButtonVisible={false}
isAnonymous={true}
sessionId={session?.["aura.test.payment"]}
/>
:
<Loader color={LoaderColor.Black} />
}
</div>
)
function onPaymentError(error?: string | null): void {
if (error === "Product not found") {
return navigate(routes.client.compatibilityV2TrialChoice());
}
}
function onPaymentSuccess(): void {
setTimeout(() => {
navigate(routes.client.home());
}, 1500);
}
return (
<div className={styles.container}>
{!!activeProductFromStore && session?.["aura.test.payment"]?.length ? (
<PaymentPage
// placementKey={EPlacementKeys["aura.placement.payment"]}
funnel={ELocalesPlacement.EmailGenerator}
paymentPlacement="TODO:FUNNEL"
onError={onPaymentError}
onSuccess={onPaymentSuccess}
isBackButtonVisible={false}
isAnonymous={true}
sessionId={session?.["aura.test.payment"]}
/>
) : (
<Loader color={LoaderColor.Black} />
)}
</div>
);
}
export default AnonymousPaymentPage
export default AnonymousPaymentPage;

View File

@ -22,7 +22,7 @@ interface ICheckoutFormProps {
funnel: ELocalesPlacement;
paymentPlacement: string;
onSuccess?: () => void;
onError?: (error?: string) => void;
onError?: (error?: string | null) => void;
onModalClosed?: () => void;
}
@ -66,14 +66,15 @@ export default function CheckoutForm({
});
useEffect(() => {
if (error && onError) {
console.log(error);
if (error === "card_type_error") {
return setIsCardTypeError(true);
}
onError(error);
// if (error) {
console.log(error);
if (error === "card_type_error") {
return setIsCardTypeError(true);
} else {
setIsCardTypeError(false);
}
onError?.(error);
// }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [error]);

View File

@ -11,103 +11,109 @@ import { EPaymentMethod } from "@/data/paymentMethods";
import { IFunnelPaymentVariant } from "@/api/resources/Session";
const getPrice = (product: IFunnelPaymentVariant | null) => {
if (!product) {
return 0;
}
return (product.trialPrice || 0) / 100;
}
if (!product) {
return 0;
}
return (product.trialPrice || 0) / 100;
};
interface IPaymentFormProps {
isSinglePayment?: boolean;
className?: string;
funnel: ELocalesPlacement;
paymentPlacement: string;
trialInterval: number;
onPaymentError?: (error?: string) => void;
onPaymentSuccess?: () => void;
onModalClosed?: () => void;
isSinglePayment?: boolean;
className?: string;
funnel: ELocalesPlacement;
paymentPlacement: string;
trialInterval: number;
onPaymentError?: (error?: string | null) => void;
onPaymentSuccess?: () => void;
onModalClosed?: () => void;
}
function PaymentForm({
isSinglePayment = false,
className,
funnel,
paymentPlacement,
trialInterval,
onPaymentError,
onPaymentSuccess,
onModalClosed
isSinglePayment = false,
className,
funnel,
paymentPlacement,
trialInterval,
onPaymentError,
onPaymentSuccess,
onModalClosed,
}: IPaymentFormProps) {
const { translate } = useTranslations(ELocalesPlacement.V1);
const currency = useSelector(selectors.selectCurrency);
const activeProduct = useSelector(selectors.selectActiveProduct);
const { translate } = useTranslations(ELocalesPlacement.V1);
const currency = useSelector(selectors.selectCurrency);
const activeProduct = useSelector(selectors.selectActiveProduct);
const isLoading = false;
const isLoading = false;
const paymentMethodsButtons = [
{
id: EPaymentMethod.CREDIT_CARD,
icon: "/payment-form/credit-card.svg",
title: translate("payment_modal.credit_card")
}
]
const paymentMethodsButtons = [
{
id: EPaymentMethod.CREDIT_CARD,
icon: "/payment-form/credit-card.svg",
title: translate("payment_modal.credit_card"),
},
];
return (
<>
{isLoading && (
<div className={styles["payment-modal"]}>
<div className={styles["payment-loader"]}>
<Loader />
</div>
</div>
)}
<div
className={`${styles["payment-modal"]} ${isLoading ? styles.hide : ""} ${className}`}
>
{!isSinglePayment && <Title variant="h3" className={styles.title}>
{translate("payment_modal.title")}
</Title>}
<PaymentMethodsChoice
paymentMethods={paymentMethodsButtons}
selectedPaymentMethod={paymentMethodsButtons[0].id}
onSelectPaymentMethod={() => { }}
/>
{!isSinglePayment && activeProduct && (
<div>
<p className={styles["sub-plan-description"]}>
{translate("payment_modal.description", {
priceForDays: (
<b>
{translate("payment_modal.price_for_days", {
trialPrice: addCurrency(
getPrice(activeProduct),
currency
),
trialDuration: trialInterval,
})}
</b>
),
emailReminder: (
<b>{translate("payment_modal.email_reminder")}</b>
),
})}
</p>
</div>
)}
<div className={styles["payment-method-container"]}>
{!!activeProduct && <CheckoutForm
funnel={funnel}
paymentPlacement={paymentPlacement}
activeProduct={activeProduct}
onError={onPaymentError}
onSuccess={onPaymentSuccess}
onModalClosed={onModalClosed}
/>}
</div>
<p className={styles.address}>{translate("payment_modal.address")}</p>
</div>
</>
)
return (
<>
{isLoading && (
<div className={styles["payment-modal"]}>
<div className={styles["payment-loader"]}>
<Loader />
</div>
</div>
)}
<div
className={`${styles["payment-modal"]} ${
isLoading ? styles.hide : ""
} ${className}`}
>
{!isSinglePayment && (
<Title variant="h3" className={styles.title}>
{translate("payment_modal.title")}
</Title>
)}
<PaymentMethodsChoice
paymentMethods={paymentMethodsButtons}
selectedPaymentMethod={paymentMethodsButtons[0].id}
onSelectPaymentMethod={() => {}}
/>
{!isSinglePayment && activeProduct && (
<div>
<p className={styles["sub-plan-description"]}>
{translate("payment_modal.description", {
priceForDays: (
<b>
{translate("payment_modal.price_for_days", {
trialPrice: addCurrency(
getPrice(activeProduct),
currency
),
trialDuration: trialInterval,
})}
</b>
),
emailReminder: (
<b>{translate("payment_modal.email_reminder")}</b>
),
})}
</p>
</div>
)}
<div className={styles["payment-method-container"]}>
{!!activeProduct && (
<CheckoutForm
funnel={funnel}
paymentPlacement={paymentPlacement}
activeProduct={activeProduct}
onError={onPaymentError}
onSuccess={onPaymentSuccess}
onModalClosed={onModalClosed}
/>
)}
</div>
<p className={styles.address}>{translate("payment_modal.address")}</p>
</div>
</>
);
}
export default PaymentForm
export default PaymentForm;

View File

@ -28,7 +28,7 @@ interface IPaymentPageProps {
sessionId?: string;
funnel: ELocalesPlacement;
paymentPlacement: string;
onError?: (error?: string) => void;
onError?: (error?: string | null) => void;
onSuccess?: () => void;
onBack?: () => void;
onPopState?: () => void;
@ -89,13 +89,17 @@ function PaymentPage({
},
];
function onPaymentError(error?: string | undefined): void {
setIsPaymentError(true);
if (error !== "Product not found") {
metricService.reachGoal(EGoals.PAYMENT_ERROR, [
EMetrics.YANDEX,
EMetrics.KLAVIYO,
]);
function onPaymentError(error?: string | null): void {
if (error) {
setIsPaymentError(true);
if (error !== "Product not found") {
metricService.reachGoal(EGoals.PAYMENT_ERROR, [
EMetrics.YANDEX,
EMetrics.KLAVIYO,
]);
}
} else {
setIsPaymentError(false);
}
onError?.(error);
}

View File

@ -263,6 +263,7 @@ export const usePayment = ({
};
const submitInlineForm = (address?: AddressFields) => {
setError(null);
if (address) {
addressRef.current = address;
}

View File

@ -59,12 +59,12 @@ function CompatibilityV2Routes() {
const { setTheme } = useTheme();
const { isReady, variant: darkThemeCompatibilityV2Variant } = useUnleash({
flag: EUnleashFlags.darkThemeCompatibilityV2
})
flag: EUnleashFlags.darkThemeCompatibilityV2,
});
const { funnelData } = useFunnel({
funnel: ELocalesPlacement.CompatibilityV2,
paymentPlacement: ""
paymentPlacement: "",
});
const availablePaths = useMemo(() => {
@ -95,7 +95,7 @@ function CompatibilityV2Routes() {
dispatch(actions.compatibilityV2.update({ fromRedesign: true }));
}, [dispatch]);
function onPaymentError(error?: string | undefined): void {
function onPaymentError(error?: string | null): void {
if (error === "Product not found") {
return navigate(routes.client.compatibilityV2TrialChoice());
}
@ -115,14 +115,18 @@ function CompatibilityV2Routes() {
function onPopState(): void {
if (!availablePaths.main_secret_discount) return;
if (
document.location.toString() === `${window.location.origin}${routes.client.compatibilityV2Payment()}` ||
document.location.toString() === `${window.location.origin}${routes.client.compatibilityV2TrialPayment()}`
document.location.toString() ===
`${window.location.origin}${routes.client.compatibilityV2Payment()}` ||
document.location.toString() ===
`${
window.location.origin
}${routes.client.compatibilityV2TrialPayment()}`
) {
navigate(routes.client.compatibilityV2SaveOff());
}
}
function onPaymentErrorDiscount(error?: string | undefined): void {
function onPaymentErrorDiscount(error?: string | null): void {
if (error === "Product not found") {
return navigate(routes.client.compatibilityV2SecretDiscount());
}
@ -140,20 +144,22 @@ function CompatibilityV2Routes() {
}
return () => {
setTheme(ESiteTheme.Light);
}
}, [darkThemeCompatibilityV2Variant])
};
}, [darkThemeCompatibilityV2Variant]);
if (!isReady) {
return <div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100dvh"
}}
>
<Loader color={LoaderColor.Black} />
</div>
return (
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100dvh",
}}
>
<Loader color={LoaderColor.Black} />
</div>
);
}
return (
@ -171,19 +177,21 @@ function CompatibilityV2Routes() {
funnel={ELocalesPlacement.CompatibilityV2}
paymentPlacement="add_consultant"
nextRoute={
availablePaths.add_guides ?
routes.client.compatibilityV2AddGuides() :
`${routes.client.getInformationPartner()}?path=back`
availablePaths.add_guides
? routes.client.compatibilityV2AddGuides()
: `${routes.client.getInformationPartner()}?path=back`
}
/>
}
/>
<Route
path={removePrefix(routes.client.compatibilityV2AddGuides())}
element={<AddGuides
funnel={ELocalesPlacement.CompatibilityV2}
paymentPlacement="add_guides"
/>}
element={
<AddGuides
funnel={ELocalesPlacement.CompatibilityV2}
paymentPlacement="add_guides"
/>
}
/>
</Route>
</Route>
@ -196,23 +204,29 @@ function CompatibilityV2Routes() {
>
<Route
path={removePrefix(routes.client.compatibilityV2PaymentModal())}
element={<PaymentPage
funnel={ELocalesPlacement.CompatibilityV2}
paymentPlacement="main"
onError={onPaymentError}
onSuccess={onPaymentSuccess}
onBack={onBack}
onPopState={onPopState}
/>}
element={
<PaymentPage
funnel={ELocalesPlacement.CompatibilityV2}
paymentPlacement="main"
onError={onPaymentError}
onSuccess={onPaymentSuccess}
onBack={onBack}
onPopState={onPopState}
/>
}
/>
<Route
path={removePrefix(routes.client.compatibilityV2SecretDiscountPaymentModal())}
element={<PaymentPage
funnel={ELocalesPlacement.CompatibilityV2}
paymentPlacement="main_secret_discount"
onError={onPaymentErrorDiscount}
onSuccess={onPaymentSuccessDiscount}
/>}
path={removePrefix(
routes.client.compatibilityV2SecretDiscountPaymentModal()
)}
element={
<PaymentPage
funnel={ELocalesPlacement.CompatibilityV2}
paymentPlacement="main_secret_discount"
onError={onPaymentErrorDiscount}
onSuccess={onPaymentSuccessDiscount}
/>
}
/>
</Route>
<Route
@ -258,7 +272,9 @@ function CompatibilityV2Routes() {
element={<Birthdate />}
/>
<Route
path={removePrefix(routes.client.compatibilityV2BirthdatePartner())}
path={removePrefix(
routes.client.compatibilityV2BirthdatePartner()
)}
element={<BirthdatePartner />}
/>
<Route
@ -266,11 +282,15 @@ function CompatibilityV2Routes() {
element={<DateEvent />}
/>
<Route
path={removePrefix(routes.client.compatibilityV2PalmsInformation())}
path={removePrefix(
routes.client.compatibilityV2PalmsInformation()
)}
element={<PalmsInformation />}
/>
<Route
path={removePrefix(routes.client.compatibilityV2PalmsInformationPartner())}
path={removePrefix(
routes.client.compatibilityV2PalmsInformationPartner()
)}
element={<PalmsInformationPartner />}
/>
<Route
@ -296,11 +316,15 @@ function CompatibilityV2Routes() {
element={<CheckingPhone />}
/>
<Route
path={removePrefix(routes.client.compatibilityV2ElementResonates())}
path={removePrefix(
routes.client.compatibilityV2ElementResonates()
)}
element={<ElementResonates />}
/>
<Route
path={removePrefix(routes.client.compatibilityV2FavoriteColor())}
path={removePrefix(
routes.client.compatibilityV2FavoriteColor()
)}
element={<FavoriteColor />}
/>
<Route
@ -314,7 +338,9 @@ function CompatibilityV2Routes() {
element={<HeadOrHeartResult />}
/>
<Route
path={removePrefix(routes.client.compatibilityV2RelateFollowing())}
path={removePrefix(
routes.client.compatibilityV2RelateFollowing()
)}
element={<RelateFollowing />}
>
<Route path=":questionId" element={<RelateFollowing />} />
@ -329,7 +355,9 @@ function CompatibilityV2Routes() {
element={<LetScan />}
/>
<Route
path={removePrefix(routes.client.compatibilityV2ScanInstruction())}
path={removePrefix(
routes.client.compatibilityV2ScanInstruction()
)}
element={<ScanInstruction />}
/>
<Route
@ -342,7 +370,9 @@ function CompatibilityV2Routes() {
/>
<Route
path={removePrefix(routes.client.compatibilityV2TrialChoiceVideo())}
path={removePrefix(
routes.client.compatibilityV2TrialChoiceVideo()
)}
element={<TrialChoiceVideo />}
/>

View File

@ -57,7 +57,7 @@ function CompatibilityV3Routes() {
const { funnelData } = useFunnel({
funnel: ELocalesPlacement.CompatibilityV3,
paymentPlacement: ""
paymentPlacement: "",
});
const availablePaths = useMemo(() => {
@ -88,7 +88,7 @@ function CompatibilityV3Routes() {
dispatch(actions.compatibilityV3.update({ fromRedesign: true }));
}, [dispatch]);
function onPaymentError(error?: string | undefined): void {
function onPaymentError(error?: string | null): void {
if (error === "Product not found") {
return navigate(routes.client.compatibilityV3TrialChoice());
}
@ -108,14 +108,18 @@ function CompatibilityV3Routes() {
function onPopState(): void {
if (!availablePaths.main_secret_discount) return;
if (
document.location.toString() === `${window.location.origin}${routes.client.compatibilityV3Payment()}` ||
document.location.toString() === `${window.location.origin}${routes.client.compatibilityV3TrialPayment()}`
document.location.toString() ===
`${window.location.origin}${routes.client.compatibilityV3Payment()}` ||
document.location.toString() ===
`${
window.location.origin
}${routes.client.compatibilityV3TrialPayment()}`
) {
navigate(routes.client.compatibilityV3SaveOff());
}
}
function onPaymentErrorDiscount(error?: string | undefined): void {
function onPaymentErrorDiscount(error?: string | null): void {
if (error === "Product not found") {
return navigate(routes.client.compatibilityV3SecretDiscount());
}
@ -142,19 +146,21 @@ function CompatibilityV3Routes() {
funnel={ELocalesPlacement.CompatibilityV3}
paymentPlacement="add_consultant"
nextRoute={
availablePaths.add_guides ?
routes.client.compatibilityV3AddGuides() :
`${routes.client.getInformationPartner()}?path=back`
availablePaths.add_guides
? routes.client.compatibilityV3AddGuides()
: `${routes.client.getInformationPartner()}?path=back`
}
/>
}
/>
<Route
path={removePrefix(routes.client.compatibilityV3AddGuides())}
element={<AddGuides
funnel={ELocalesPlacement.CompatibilityV3}
paymentPlacement="add_guides"
/>}
element={
<AddGuides
funnel={ELocalesPlacement.CompatibilityV3}
paymentPlacement="add_guides"
/>
}
/>
</Route>
</Route>
@ -167,23 +173,29 @@ function CompatibilityV3Routes() {
>
<Route
path={removePrefix(routes.client.compatibilityV3PaymentModal())}
element={<PaymentPage
funnel={ELocalesPlacement.CompatibilityV3}
paymentPlacement="main"
onError={onPaymentError}
onSuccess={onPaymentSuccess}
onBack={onBack}
onPopState={onPopState}
/>}
element={
<PaymentPage
funnel={ELocalesPlacement.CompatibilityV3}
paymentPlacement="main"
onError={onPaymentError}
onSuccess={onPaymentSuccess}
onBack={onBack}
onPopState={onPopState}
/>
}
/>
<Route
path={removePrefix(routes.client.compatibilityV3SecretDiscountPaymentModal())}
element={<PaymentPage
funnel={ELocalesPlacement.CompatibilityV3}
paymentPlacement="main_secret_discount"
onError={onPaymentErrorDiscount}
onSuccess={onPaymentSuccessDiscount}
/>}
path={removePrefix(
routes.client.compatibilityV3SecretDiscountPaymentModal()
)}
element={
<PaymentPage
funnel={ELocalesPlacement.CompatibilityV3}
paymentPlacement="main_secret_discount"
onError={onPaymentErrorDiscount}
onSuccess={onPaymentSuccessDiscount}
/>
}
/>
</Route>
<Route
@ -225,7 +237,9 @@ function CompatibilityV3Routes() {
element={<Birthdate />}
/>
<Route
path={removePrefix(routes.client.compatibilityV3BirthdatePartner())}
path={removePrefix(
routes.client.compatibilityV3BirthdatePartner()
)}
element={<BirthdatePartner />}
/>
<Route
@ -233,11 +247,15 @@ function CompatibilityV3Routes() {
element={<DateEvent />}
/>
<Route
path={removePrefix(routes.client.compatibilityV3PalmsInformation())}
path={removePrefix(
routes.client.compatibilityV3PalmsInformation()
)}
element={<PalmsInformation />}
/>
<Route
path={removePrefix(routes.client.compatibilityV3PalmsInformationPartner())}
path={removePrefix(
routes.client.compatibilityV3PalmsInformationPartner()
)}
element={<PalmsInformationPartner />}
/>
<Route
@ -263,11 +281,15 @@ function CompatibilityV3Routes() {
element={<CheckingPhone />}
/>
<Route
path={removePrefix(routes.client.compatibilityV3ElementResonates())}
path={removePrefix(
routes.client.compatibilityV3ElementResonates()
)}
element={<ElementResonates />}
/>
<Route
path={removePrefix(routes.client.compatibilityV3FavoriteColor())}
path={removePrefix(
routes.client.compatibilityV3FavoriteColor()
)}
element={<FavoriteColor />}
/>
<Route
@ -281,7 +303,9 @@ function CompatibilityV3Routes() {
element={<HeadOrHeartResult />}
/>
<Route
path={removePrefix(routes.client.compatibilityV3RelateFollowing())}
path={removePrefix(
routes.client.compatibilityV3RelateFollowing()
)}
element={<RelateFollowing />}
>
<Route path=":questionId" element={<RelateFollowing />} />
@ -296,7 +320,9 @@ function CompatibilityV3Routes() {
element={<LetScan />}
/>
<Route
path={removePrefix(routes.client.compatibilityV3ScanInstruction())}
path={removePrefix(
routes.client.compatibilityV3ScanInstruction()
)}
element={<ScanInstruction />}
/>
<Route
@ -309,7 +335,9 @@ function CompatibilityV3Routes() {
/>
<Route
path={removePrefix(routes.client.compatibilityV3TrialChoiceVideo())}
path={removePrefix(
routes.client.compatibilityV3TrialChoiceVideo()
)}
element={<TrialChoiceVideo />}
/>

View File

@ -82,7 +82,7 @@ function CompatibilityV4Routes() {
const { funnelData } = useFunnel({
funnel: ELocalesPlacement.CompatibilityV4,
paymentPlacement: ""
paymentPlacement: "",
});
const availablePaths = useMemo(() => {
@ -113,7 +113,7 @@ function CompatibilityV4Routes() {
dispatch(actions.compatibilityV4.update({ fromRedesign: true }));
}, [dispatch]);
function onPaymentError(error?: string | undefined): void {
function onPaymentError(error?: string | null): void {
if (error === "Product not found") {
return navigate(routes.client.compatibilityV4TrialChoice());
}
@ -133,14 +133,18 @@ function CompatibilityV4Routes() {
function onPopState(): void {
if (!availablePaths.main_secret_discount) return;
if (
document.location.toString() === `${window.location.origin}${routes.client.compatibilityV4Payment()}` ||
document.location.toString() === `${window.location.origin}${routes.client.compatibilityV4TrialPayment()}`
document.location.toString() ===
`${window.location.origin}${routes.client.compatibilityV4Payment()}` ||
document.location.toString() ===
`${
window.location.origin
}${routes.client.compatibilityV4TrialPayment()}`
) {
navigate(routes.client.compatibilityV4SaveOff());
}
}
function onPaymentErrorDiscount(error?: string | undefined): void {
function onPaymentErrorDiscount(error?: string | null): void {
if (error === "Product not found") {
return navigate(routes.client.compatibilityV4SecretDiscount());
}
@ -167,19 +171,21 @@ function CompatibilityV4Routes() {
funnel={ELocalesPlacement.CompatibilityV4}
paymentPlacement="add_consultant"
nextRoute={
availablePaths.add_guides ?
routes.client.compatibilityV4AddGuides() :
`${routes.client.getInformationPartner()}?path=back`
availablePaths.add_guides
? routes.client.compatibilityV4AddGuides()
: `${routes.client.getInformationPartner()}?path=back`
}
/>
}
/>
<Route
path={removePrefix(routes.client.compatibilityV4AddGuides())}
element={<AddGuides
funnel={ELocalesPlacement.CompatibilityV4}
paymentPlacement="add_guides"
/>}
element={
<AddGuides
funnel={ELocalesPlacement.CompatibilityV4}
paymentPlacement="add_guides"
/>
}
/>
</Route>
</Route>
@ -192,23 +198,29 @@ function CompatibilityV4Routes() {
>
<Route
path={removePrefix(routes.client.compatibilityV4PaymentModal())}
element={<PaymentPage
funnel={ELocalesPlacement.CompatibilityV4}
paymentPlacement="main"
onError={onPaymentError}
onSuccess={onPaymentSuccess}
onBack={onBack}
onPopState={onPopState}
/>}
element={
<PaymentPage
funnel={ELocalesPlacement.CompatibilityV4}
paymentPlacement="main"
onError={onPaymentError}
onSuccess={onPaymentSuccess}
onBack={onBack}
onPopState={onPopState}
/>
}
/>
<Route
path={removePrefix(routes.client.compatibilityV4SecretDiscountPaymentModal())}
element={<PaymentPage
funnel={ELocalesPlacement.CompatibilityV4}
paymentPlacement="main_secret_discount"
onError={onPaymentErrorDiscount}
onSuccess={onPaymentSuccessDiscount}
/>}
path={removePrefix(
routes.client.compatibilityV4SecretDiscountPaymentModal()
)}
element={
<PaymentPage
funnel={ELocalesPlacement.CompatibilityV4}
paymentPlacement="main_secret_discount"
onError={onPaymentErrorDiscount}
onSuccess={onPaymentSuccessDiscount}
/>
}
/>
</Route>
<Route
@ -271,34 +283,44 @@ function CompatibilityV4Routes() {
element={<HeadOrHeartResult />}
/>
<Route
path={removePrefix(
routes.client.compatibilityV4Loading()
)}
path={removePrefix(routes.client.compatibilityV4Loading())}
element={<Loading />}
/>
<Route element={<StepperLayout />}>
<Route
path={removePrefix(routes.client.compatibilityV4WhatAddToAnalysis())}
path={removePrefix(
routes.client.compatibilityV4WhatAddToAnalysis()
)}
element={<WhatAddToAnalysis />}
/>
<Route
path={removePrefix(routes.client.compatibilityV4PotentialPartnerName())}
path={removePrefix(
routes.client.compatibilityV4PotentialPartnerName()
)}
element={<PotentialPartnerName />}
/>
<Route
path={removePrefix(routes.client.compatibilityV4PotentialPartnerBirthdate())}
path={removePrefix(
routes.client.compatibilityV4PotentialPartnerBirthdate()
)}
element={<PotentialPartnerBirthdate />}
/>
<Route
path={removePrefix(routes.client.compatibilityV4FormerPartnerName())}
path={removePrefix(
routes.client.compatibilityV4FormerPartnerName()
)}
element={<FormerPartnerName />}
/>
<Route
path={removePrefix(routes.client.compatibilityV4FormerPartnerBirthdate())}
path={removePrefix(
routes.client.compatibilityV4FormerPartnerBirthdate()
)}
element={<FormerPartnerBirthdate />}
/>
<Route
path={removePrefix(routes.client.compatibilityV4GenderPartner())}
path={removePrefix(
routes.client.compatibilityV4GenderPartner()
)}
element={<GenderPartner />}
/>
<Route
@ -310,7 +332,9 @@ function CompatibilityV4Routes() {
element={<Birthplace />}
/>
<Route
path={removePrefix(routes.client.compatibilityV4BirthplacePartner())}
path={removePrefix(
routes.client.compatibilityV4BirthplacePartner()
)}
element={<BirthplacePartner />}
/>
<Route
@ -322,15 +346,21 @@ function CompatibilityV4Routes() {
element={<YourAnalysis />}
/>
<Route
path={removePrefix(routes.client.compatibilityV4PartnerAnalysis())}
path={removePrefix(
routes.client.compatibilityV4PartnerAnalysis()
)}
element={<PartnerAnalysis />}
/>
<Route
path={removePrefix(routes.client.compatibilityV4ResultAnalysis())}
path={removePrefix(
routes.client.compatibilityV4ResultAnalysis()
)}
element={<ResultAnalysis />}
/>
<Route
path={removePrefix(routes.client.compatibilityV4PartnerSimilarity())}
path={removePrefix(
routes.client.compatibilityV4PartnerSimilarity()
)}
element={<PartnerSimilarity />}
/>
<Route
@ -338,7 +368,9 @@ function CompatibilityV4Routes() {
element={<ReviewPage />}
/>
<Route
path={removePrefix(routes.client.compatibilityV4BirthdatePartner())}
path={removePrefix(
routes.client.compatibilityV4BirthdatePartner()
)}
element={<BirthdatePartner />}
/>
<Route
@ -346,11 +378,15 @@ function CompatibilityV4Routes() {
element={<DateEvent />}
/>
<Route
path={removePrefix(routes.client.compatibilityV4PalmsInformation())}
path={removePrefix(
routes.client.compatibilityV4PalmsInformation()
)}
element={<PalmsInformation />}
/>
<Route
path={removePrefix(routes.client.compatibilityV4PalmsInformationPartner())}
path={removePrefix(
routes.client.compatibilityV4PalmsInformationPartner()
)}
element={<PalmsInformationPartner />}
/>
<Route
@ -370,9 +406,7 @@ function CompatibilityV4Routes() {
element={<CalculateInAdvance />}
/>
<Route
path={removePrefix(
routes.client.compatibilityV4AlmostThere()
)}
path={removePrefix(routes.client.compatibilityV4AlmostThere())}
element={<AlmostThere />}
/>
<Route
@ -400,9 +434,7 @@ function CompatibilityV4Routes() {
element={<YourInclination />}
/>
<Route
path={removePrefix(
routes.client.compatibilityV4YourFear()
)}
path={removePrefix(routes.client.compatibilityV4YourFear())}
element={<YourFear />}
/>
<Route
@ -418,11 +450,15 @@ function CompatibilityV4Routes() {
element={<StressResponse />}
/>
<Route
path={removePrefix(routes.client.compatibilityV4ElementResonates())}
path={removePrefix(
routes.client.compatibilityV4ElementResonates()
)}
element={<ElementResonates />}
/>
<Route
path={removePrefix(routes.client.compatibilityV4FavoriteColor())}
path={removePrefix(
routes.client.compatibilityV4FavoriteColor()
)}
element={<FavoriteColor />}
/>
<Route
@ -430,7 +466,9 @@ function CompatibilityV4Routes() {
element={<HeadOrHeart />}
/>
<Route
path={removePrefix(routes.client.compatibilityV4RelateFollowing())}
path={removePrefix(
routes.client.compatibilityV4RelateFollowing()
)}
element={<RelateFollowing />}
>
<Route path=":questionId" element={<RelateFollowing />} />
@ -445,7 +483,9 @@ function CompatibilityV4Routes() {
element={<LetScan />}
/>
<Route
path={removePrefix(routes.client.compatibilityV4ScanInstruction())}
path={removePrefix(
routes.client.compatibilityV4ScanInstruction()
)}
element={<ScanInstruction />}
/>
<Route
@ -458,7 +498,9 @@ function CompatibilityV4Routes() {
/>
<Route
path={removePrefix(routes.client.compatibilityV4TrialChoiceVideo())}
path={removePrefix(
routes.client.compatibilityV4TrialChoiceVideo()
)}
element={<TrialChoiceVideo />}
/>

View File

@ -19,119 +19,138 @@ import { ELocalesPlacement } from "@/locales";
const removePrefix = (path: string) => path.replace(emailMarketingV1Prefix, "");
function MarketingLandingV1Routes() {
const navigate = useNavigate();
const navigate = useNavigate();
function onPaymentError(error?: string | undefined): void {
if (error === "Product not found") {
return navigate(routes.client.emailMarketingV1SpecialOffer());
function onPaymentError(error?: string | null): void {
if (error === "Product not found") {
return navigate(routes.client.emailMarketingV1SpecialOffer());
}
}
function onPaymentSuccess(): void {
setTimeout(() => {
navigate(routes.client.emailMarketingV1SkipTrial());
}, 1500);
}
function onBack(): void {
navigate(routes.client.emailMarketingV1SaveOff());
}
function onPopState(): void {
if (
document.location.toString() ===
`${window.location.origin}${routes.client.emailMarketingV1SpecialOffer()}`
) {
navigate(routes.client.emailMarketingV1SaveOff());
}
}
function onPaymentErrorDiscount(error?: string | null): void {
if (error === "Product not found") {
return navigate(routes.client.emailMarketingV1SecretDiscount());
}
}
function onPaymentSuccessDiscount(): void {
setTimeout(() => {
navigate(routes.client.emailMarketingV1SkipTrial());
}, 1500);
}
return (
<Routes>
<Route
path={removePrefix(routes.client.emailMarketingV1Onboarding())}
element={<OnboardingPage />}
/>
<Route element={<PrivateOutlet />}>
<Route element={<AdditionalPurchasesPalmistry />}>
<Route
path={removePrefix(routes.client.emailMarketingV1SkipTrial())}
element={<SkipTrial />}
/>
<Route
path={removePrefix(routes.client.emailMarketingV1AddConsultant())}
element={
<AddConsultant
funnel={ELocalesPlacement.EmailMarketingCompatibilityV1}
paymentPlacement="add_consultant"
/>
}
/>
<Route
path={removePrefix(routes.client.emailMarketingV1AddGuides())}
element={
<AddGuides
funnel={ELocalesPlacement.EmailMarketingCompatibilityV1}
paymentPlacement="add_guides"
/>
}
/>
</Route>
</Route>
<Route
element={
<CheckSubscriptionOutlet
subscribedReturnUrl={routes.client.compatibilityV2SkipTrial()}
/>
}
}
function onPaymentSuccess(): void {
setTimeout(() => {
navigate(routes.client.emailMarketingV1SkipTrial());
}, 1500);
}
function onBack(): void {
navigate(routes.client.emailMarketingV1SaveOff());
}
function onPopState(): void {
if (document.location.toString() === `${window.location.origin}${routes.client.emailMarketingV1SpecialOffer()}`) {
navigate(routes.client.emailMarketingV1SaveOff());
}
}
function onPaymentErrorDiscount(error?: string | undefined): void {
if (error === "Product not found") {
return navigate(routes.client.emailMarketingV1SecretDiscount());
}
}
function onPaymentSuccessDiscount(): void {
setTimeout(() => {
navigate(routes.client.emailMarketingV1SkipTrial());
}, 1500);
}
return (
<Routes>
<Route
path={removePrefix(routes.client.emailMarketingV1Onboarding())}
element={<OnboardingPage />}
>
<Route
path={removePrefix(routes.client.emailMarketingV1PaymentModal())}
element={
<PaymentPage
funnel={ELocalesPlacement.EmailMarketingCompatibilityV1}
paymentPlacement="main"
onError={onPaymentError}
onSuccess={onPaymentSuccess}
onBack={onBack}
onPopState={onPopState}
/>
<Route element={<PrivateOutlet />}>
<Route element={<AdditionalPurchasesPalmistry />}>
<Route
path={removePrefix(routes.client.emailMarketingV1SkipTrial())}
element={<SkipTrial />}
/>
<Route
path={removePrefix(routes.client.emailMarketingV1AddConsultant())}
element={<AddConsultant
funnel={ELocalesPlacement.EmailMarketingCompatibilityV1}
paymentPlacement="add_consultant"
/>}
/>
<Route
path={removePrefix(routes.client.emailMarketingV1AddGuides())}
element={<AddGuides
funnel={ELocalesPlacement.EmailMarketingCompatibilityV1}
paymentPlacement="add_guides"
/>}
/>
</Route>
</Route>
<Route
element={
<CheckSubscriptionOutlet
subscribedReturnUrl={routes.client.compatibilityV2SkipTrial()}
/>
}
>
<Route
path={removePrefix(routes.client.emailMarketingV1PaymentModal())}
element={<PaymentPage
funnel={ELocalesPlacement.EmailMarketingCompatibilityV1}
paymentPlacement="main"
onError={onPaymentError}
onSuccess={onPaymentSuccess}
onBack={onBack}
onPopState={onPopState}
/>}
/>
<Route
path={removePrefix(routes.client.emailMarketingV1SecretDiscountPaymentModal())}
element={<PaymentPage
funnel={ELocalesPlacement.EmailMarketingCompatibilityV1}
paymentPlacement="main_secret_discount"
onError={onPaymentErrorDiscount}
onSuccess={onPaymentSuccessDiscount}
/>}
/>
</Route>
<Route element={<div className={styles.container}><Outlet /></div>}>
<Route
path={removePrefix(routes.client.emailMarketingV1Landing())}
element={<MarketingLanding />}
/>
<Route
path={removePrefix(routes.client.emailMarketingV1SpecialOffer())}
element={<SpecialOffer />}
/>
<Route
path={removePrefix(routes.client.emailMarketingV1SaveOff())}
element={<SaveOff />}
/>
<Route
path={removePrefix(routes.client.emailMarketingV1SecretDiscount())}
element={<SecretDiscount />}
/>
<Route path="*" element={<NotFoundPage />} />
</Route>
</Routes>
);
}
/>
<Route
path={removePrefix(
routes.client.emailMarketingV1SecretDiscountPaymentModal()
)}
element={
<PaymentPage
funnel={ELocalesPlacement.EmailMarketingCompatibilityV1}
paymentPlacement="main_secret_discount"
onError={onPaymentErrorDiscount}
onSuccess={onPaymentSuccessDiscount}
/>
}
/>
</Route>
<Route
element={
<div className={styles.container}>
<Outlet />
</div>
}
>
<Route
path={removePrefix(routes.client.emailMarketingV1Landing())}
element={<MarketingLanding />}
/>
<Route
path={removePrefix(routes.client.emailMarketingV1SpecialOffer())}
element={<SpecialOffer />}
/>
<Route
path={removePrefix(routes.client.emailMarketingV1SaveOff())}
element={<SaveOff />}
/>
<Route
path={removePrefix(routes.client.emailMarketingV1SecretDiscount())}
element={<SecretDiscount />}
/>
<Route path="*" element={<NotFoundPage />} />
</Route>
</Routes>
);
}
export default MarketingLandingV1Routes;

View File

@ -62,19 +62,19 @@ const availableUrlsDarkTheme = [
routes.client.palmistryV1Camera(),
routes.client.palmistryV1ScannedPhoto(),
routes.client.palmistryV1Email(),
]
];
function PalmistryV1Routes() {
const navigate = useNavigate();
const dispatch = useDispatch();
const { isReady, variant: darkThemePalmistryV1Variant } = useUnleash({
flag: EUnleashFlags.darkThemePalmistryV1
})
flag: EUnleashFlags.darkThemePalmistryV1,
});
const { funnelData } = useFunnel({
funnel: ELocalesPlacement.PalmistryV1,
paymentPlacement: ""
paymentPlacement: "",
});
const availablePaths = useMemo(() => {
@ -105,7 +105,7 @@ function PalmistryV1Routes() {
dispatch(actions.palmistry.update({ fromRedesign: true }));
}, [dispatch]);
function onPaymentError(error?: string | undefined): void {
function onPaymentError(error?: string | null): void {
if (error === "Product not found") {
return navigate(routes.client.palmistryV1TrialChoice());
}
@ -125,14 +125,16 @@ function PalmistryV1Routes() {
function onPopState(): void {
if (!availablePaths.main_secret_discount) return;
if (
document.location.toString() === `${window.location.origin}${routes.client.palmistryV1Payment()}` ||
document.location.toString() === `${window.location.origin}${routes.client.palmistryV1TrialPayment()}`
document.location.toString() ===
`${window.location.origin}${routes.client.palmistryV1Payment()}` ||
document.location.toString() ===
`${window.location.origin}${routes.client.palmistryV1TrialPayment()}`
) {
navigate(routes.client.palmistryV1SaveOff());
}
}
function onPaymentErrorDiscount(error?: string | undefined): void {
function onPaymentErrorDiscount(error?: string | null): void {
if (error === "Product not found") {
return navigate(routes.client.palmistryV1SecretDiscount());
}
@ -157,19 +159,21 @@ function PalmistryV1Routes() {
} else {
document.body.classList.remove("dark-theme");
}
}, [window.location.pathname])
}, [window.location.pathname]);
if (!isReady) {
return <div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100dvh"
}}
>
<Loader color={LoaderColor.Black} />
</div>
return (
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100dvh",
}}
>
<Loader color={LoaderColor.Black} />
</div>
);
}
return (
@ -187,19 +191,21 @@ function PalmistryV1Routes() {
funnel={ELocalesPlacement.PalmistryV1}
paymentPlacement="add_consultant"
nextRoute={
availablePaths.add_guides ?
routes.client.palmistryV1AddGuides() :
`${routes.client.getInformationPartner()}?path=back`
availablePaths.add_guides
? routes.client.palmistryV1AddGuides()
: `${routes.client.getInformationPartner()}?path=back`
}
/>
}
/>
<Route
path={removePrefix(routes.client.palmistryV1AddGuides())}
element={<AddGuides
funnel={ELocalesPlacement.PalmistryV1}
paymentPlacement="add_guides"
/>}
element={
<AddGuides
funnel={ELocalesPlacement.PalmistryV1}
paymentPlacement="add_guides"
/>
}
/>
</Route>
</Route>
@ -212,23 +218,29 @@ function PalmistryV1Routes() {
>
<Route
path={removePrefix(routes.client.palmistryV1PaymentModal())}
element={<PaymentPage
funnel={ELocalesPlacement.PalmistryV1}
paymentPlacement="main"
onError={onPaymentError}
onSuccess={onPaymentSuccess}
onBack={onBack}
onPopState={onPopState}
/>}
element={
<PaymentPage
funnel={ELocalesPlacement.PalmistryV1}
paymentPlacement="main"
onError={onPaymentError}
onSuccess={onPaymentSuccess}
onBack={onBack}
onPopState={onPopState}
/>
}
/>
<Route
path={removePrefix(routes.client.palmistryV1SecretDiscountPaymentModal())}
element={<PaymentPage
funnel={ELocalesPlacement.PalmistryV1}
paymentPlacement="main_secret_discount"
onError={onPaymentErrorDiscount}
onSuccess={onPaymentSuccessDiscount}
/>}
path={removePrefix(
routes.client.palmistryV1SecretDiscountPaymentModal()
)}
element={
<PaymentPage
funnel={ELocalesPlacement.PalmistryV1}
paymentPlacement="main_secret_discount"
onError={onPaymentErrorDiscount}
onSuccess={onPaymentSuccessDiscount}
/>
}
/>
</Route>
<Route

View File

@ -28,7 +28,7 @@ function PalmistryV2Routes() {
dispatch(actions.palmistry.update({ fromRedesign: true }));
}, [dispatch]);
function onPaymentError(error?: string | undefined): void {
function onPaymentError(error?: string | null): void {
if (error === "Product not found") {
return navigate(routes.client.palmistryV2TrialPayment());
}
@ -41,7 +41,10 @@ function PalmistryV2Routes() {
}
function onPopState(): void {
if (document.location.toString() === `${window.location.origin}${routes.client.palmistryV2TrialPayment()}`) {
if (
document.location.toString() ===
`${window.location.origin}${routes.client.palmistryV2TrialPayment()}`
) {
navigate(routes.client.palmistryV2SaveOff());
}
}
@ -50,7 +53,7 @@ function PalmistryV2Routes() {
navigate(routes.client.palmistryV2SaveOff());
}
function onPaymentErrorDiscount(error?: string | undefined): void {
function onPaymentErrorDiscount(error?: string | null): void {
if (error === "Product not found") {
return navigate(routes.client.palmistryV2SecretDiscount());
}
@ -85,10 +88,12 @@ function PalmistryV2Routes() {
/>
<Route
path={removePrefix(routes.client.palmistryV2AddGuides())}
element={<AddGuides
funnel={ELocalesPlacement.EmailMarketingPalmistryV2}
paymentPlacement="add_guides"
/>}
element={
<AddGuides
funnel={ELocalesPlacement.EmailMarketingPalmistryV2}
paymentPlacement="add_guides"
/>
}
/>
</Route>
</Route>
@ -101,23 +106,29 @@ function PalmistryV2Routes() {
>
<Route
path={removePrefix(routes.client.palmistryV2PaymentModal())}
element={<PaymentPage
funnel={ELocalesPlacement.EmailMarketingPalmistryV2}
paymentPlacement="main"
onError={onPaymentError}
onSuccess={onPaymentSuccess}
onBack={onBack}
onPopState={onPopState}
/>}
element={
<PaymentPage
funnel={ELocalesPlacement.EmailMarketingPalmistryV2}
paymentPlacement="main"
onError={onPaymentError}
onSuccess={onPaymentSuccess}
onBack={onBack}
onPopState={onPopState}
/>
}
/>
<Route
path={removePrefix(routes.client.palmistryV2SecretDiscountPaymentModal())}
element={<PaymentPage
funnel={ELocalesPlacement.EmailMarketingPalmistryV2}
paymentPlacement="main_secret_discount"
onError={onPaymentErrorDiscount}
onSuccess={onPaymentSuccessDiscount}
/>}
path={removePrefix(
routes.client.palmistryV2SecretDiscountPaymentModal()
)}
element={
<PaymentPage
funnel={ELocalesPlacement.EmailMarketingPalmistryV2}
paymentPlacement="main_secret_discount"
onError={onPaymentErrorDiscount}
onSuccess={onPaymentSuccessDiscount}
/>
}
/>
</Route>
<Route