video guide
This commit is contained in:
parent
b98096bb7c
commit
042bb25057
@ -222,6 +222,13 @@
|
|||||||
"required_field": "This field is required"
|
"required_field": "This field is required"
|
||||||
},
|
},
|
||||||
"AdditionalPurchases": {
|
"AdditionalPurchases": {
|
||||||
|
"banner": {
|
||||||
|
"title": "Amazing!",
|
||||||
|
"description": "Your journey begins now"
|
||||||
|
},
|
||||||
|
"Progress": {
|
||||||
|
"final_step": "Access Your Results"
|
||||||
|
},
|
||||||
"caution": {
|
"caution": {
|
||||||
"title": "Caution!",
|
"title": "Caution!",
|
||||||
"description": "To prevent double charges please don`t close the page and don`t go back."
|
"description": "To prevent double charges please don`t close the page and don`t go back."
|
||||||
@ -238,7 +245,8 @@
|
|||||||
"save": "Save {discount}%",
|
"save": "Save {discount}%",
|
||||||
"get_my_consultation": "Get my consultation",
|
"get_my_consultation": "Get my consultation",
|
||||||
"skip_this_offer": "Skip this offer",
|
"skip_this_offer": "Skip this offer",
|
||||||
"payment_error": "Something went wrong. Please try again later."
|
"payment_error": "Something went wrong. Please try again later.",
|
||||||
|
"copyright": "© 2025, Wit Lab LLC, California, US"
|
||||||
},
|
},
|
||||||
"add-guides": {
|
"add-guides": {
|
||||||
"title": "Choose your sign-up offer 🔥",
|
"title": "Choose your sign-up offer 🔥",
|
||||||
@ -248,6 +256,7 @@
|
|||||||
"payment_error": "Something went wrong. Please try again later.",
|
"payment_error": "Something went wrong. Please try again later.",
|
||||||
"select_product_error": "Please select a product",
|
"select_product_error": "Please select a product",
|
||||||
"skip_offer": "Skip offer",
|
"skip_offer": "Skip offer",
|
||||||
|
"copyright": "© 2025, Wit Lab LLC, California, US",
|
||||||
"products": {
|
"products": {
|
||||||
"main_ultra_pack": {
|
"main_ultra_pack": {
|
||||||
"title": "ULTRA PACK",
|
"title": "ULTRA PACK",
|
||||||
@ -288,6 +297,53 @@
|
|||||||
"emoji": "rised_hand.webp"
|
"emoji": "rised_hand.webp"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"video-guides": {
|
||||||
|
"title": "Choose your sign-up offer 🔥",
|
||||||
|
"subtitle": "Available only now",
|
||||||
|
"description": "* You will be charged for the add-on services or offers selected at the time of purchase. This is a non-recuring payment.",
|
||||||
|
"button": "Continue",
|
||||||
|
"skip_button": "Skip this offer and proceed further",
|
||||||
|
"copyright": "© 2025, Wit Lab LLC, California, US",
|
||||||
|
"products": {
|
||||||
|
"main_ultra_pack": {
|
||||||
|
"title": "Ultra Pack",
|
||||||
|
"subtitle": "3 in 1+2 secret bonus readings",
|
||||||
|
"discount": "{discount}% OFF",
|
||||||
|
"price": "Now <price></price> <oldPrice></oldPrice>",
|
||||||
|
"emoji": "star_struck.webp"
|
||||||
|
},
|
||||||
|
"main_numerology_analysis": {
|
||||||
|
"title": "Relationship plan",
|
||||||
|
"subtitle": "Discover the future without losing yourself",
|
||||||
|
"discount": "{discount}% OFF",
|
||||||
|
"price": "Now <price></price> <oldPrice></oldPrice>",
|
||||||
|
"emoji": "ring.webp"
|
||||||
|
},
|
||||||
|
"main_tarot_reading": {
|
||||||
|
"title": "Healthy compatibility",
|
||||||
|
"subtitle": "Balance between closeness and freedom",
|
||||||
|
"discount": "{discount}% OFF",
|
||||||
|
"price": "Now <price></price> <oldPrice></oldPrice>",
|
||||||
|
"emoji": "rose.webp"
|
||||||
|
},
|
||||||
|
"main_palmistry_guide": {
|
||||||
|
"title": "How to talk about feelings",
|
||||||
|
"subtitle": "Express your emotions and be understood",
|
||||||
|
"discount": "{discount}% OFF",
|
||||||
|
"price": "Now <price></price> <oldPrice></oldPrice>",
|
||||||
|
"emoji": "heart_from_hands.webp"
|
||||||
|
},
|
||||||
|
"main_money_reading": {
|
||||||
|
"title": "How to talk about feelings",
|
||||||
|
"subtitle": "Express your emotions and be understood",
|
||||||
|
"discount": "{discount}% OFF",
|
||||||
|
"price": "Now <price></price> <oldPrice></oldPrice>",
|
||||||
|
"emoji": "heart_from_hands.webp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"payment_error": "Something went wrong. Please try again later.",
|
||||||
|
"select_product_error": "Please select a product"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Chat": {
|
"Chat": {
|
||||||
|
|||||||
@ -229,6 +229,13 @@
|
|||||||
"required_field": "This field is required"
|
"required_field": "This field is required"
|
||||||
},
|
},
|
||||||
"AdditionalPurchases": {
|
"AdditionalPurchases": {
|
||||||
|
"banner": {
|
||||||
|
"title": "Amazing!",
|
||||||
|
"description": "Your journey begins now"
|
||||||
|
},
|
||||||
|
"Progress": {
|
||||||
|
"final_step": "Access Your Results"
|
||||||
|
},
|
||||||
"caution": {
|
"caution": {
|
||||||
"title": "Caution!",
|
"title": "Caution!",
|
||||||
"description": "To prevent double charges please don`t close the page and don`t go back."
|
"description": "To prevent double charges please don`t close the page and don`t go back."
|
||||||
@ -245,7 +252,8 @@
|
|||||||
"save": "Save {discount}%",
|
"save": "Save {discount}%",
|
||||||
"get_my_consultation": "Get my consultation",
|
"get_my_consultation": "Get my consultation",
|
||||||
"skip_this_offer": "Skip this offer",
|
"skip_this_offer": "Skip this offer",
|
||||||
"payment_error": "Something went wrong. Please try again later."
|
"payment_error": "Something went wrong. Please try again later.",
|
||||||
|
"copyright": "© 2025, Wit Lab LLC, California, US"
|
||||||
},
|
},
|
||||||
"add-guides": {
|
"add-guides": {
|
||||||
"title": "Choose your sign-up offer 🔥",
|
"title": "Choose your sign-up offer 🔥",
|
||||||
@ -255,6 +263,7 @@
|
|||||||
"payment_error": "Something went wrong. Please try again later.",
|
"payment_error": "Something went wrong. Please try again later.",
|
||||||
"select_product_error": "Please select a product",
|
"select_product_error": "Please select a product",
|
||||||
"skip_offer": "Skip offer",
|
"skip_offer": "Skip offer",
|
||||||
|
"copyright": "© 2025, Wit Lab LLC, California, US",
|
||||||
"products": {
|
"products": {
|
||||||
"main_ultra_pack": {
|
"main_ultra_pack": {
|
||||||
"title": "ULTRA PACK",
|
"title": "ULTRA PACK",
|
||||||
@ -297,10 +306,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"video-guides": {
|
"video-guides": {
|
||||||
"banner": {
|
|
||||||
"title": "Amazing!",
|
|
||||||
"description": "Your journey begins now"
|
|
||||||
},
|
|
||||||
"title": "Choose your sign-up offer 🔥",
|
"title": "Choose your sign-up offer 🔥",
|
||||||
"subtitle": "Available only now",
|
"subtitle": "Available only now",
|
||||||
"description": "* You will be charged for the add-on services or offers selected at the time of purchase. This is a non-recuring payment.",
|
"description": "* You will be charged for the add-on services or offers selected at the time of purchase. This is a non-recuring payment.",
|
||||||
@ -335,16 +340,15 @@
|
|||||||
"discount": "{discount}% OFF",
|
"discount": "{discount}% OFF",
|
||||||
"price": "Now <price></price> <oldPrice></oldPrice>",
|
"price": "Now <price></price> <oldPrice></oldPrice>",
|
||||||
"emoji": "heart_from_hands.webp"
|
"emoji": "heart_from_hands.webp"
|
||||||
|
},
|
||||||
|
"main_money_reading": {
|
||||||
|
"title": "How to talk about feelings",
|
||||||
|
"subtitle": "Express your emotions and be understood",
|
||||||
|
"discount": "{discount}% OFF",
|
||||||
|
"price": "Now <price></price> <oldPrice></oldPrice>",
|
||||||
|
"emoji": "heart_from_hands.webp"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"Progress": {
|
|
||||||
"items": {
|
|
||||||
"1": "Your Soulmate Portrait",
|
|
||||||
"2": "Video Guides",
|
|
||||||
"3": "Add Consultation",
|
|
||||||
"4": "Access Your Results"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Chat": {
|
"Chat": {
|
||||||
|
|||||||
@ -222,6 +222,13 @@
|
|||||||
"required_field": "This field is required"
|
"required_field": "This field is required"
|
||||||
},
|
},
|
||||||
"AdditionalPurchases": {
|
"AdditionalPurchases": {
|
||||||
|
"banner": {
|
||||||
|
"title": "Amazing!",
|
||||||
|
"description": "Your journey begins now"
|
||||||
|
},
|
||||||
|
"Progress": {
|
||||||
|
"final_step": "Access Your Results"
|
||||||
|
},
|
||||||
"caution": {
|
"caution": {
|
||||||
"title": "Caution!",
|
"title": "Caution!",
|
||||||
"description": "To prevent double charges please don`t close the page and don`t go back."
|
"description": "To prevent double charges please don`t close the page and don`t go back."
|
||||||
@ -238,7 +245,8 @@
|
|||||||
"save": "Save {discount}%",
|
"save": "Save {discount}%",
|
||||||
"get_my_consultation": "Get my consultation",
|
"get_my_consultation": "Get my consultation",
|
||||||
"skip_this_offer": "Skip this offer",
|
"skip_this_offer": "Skip this offer",
|
||||||
"payment_error": "Something went wrong. Please try again later."
|
"payment_error": "Something went wrong. Please try again later.",
|
||||||
|
"copyright": "© 2025, Wit Lab LLC, California, US"
|
||||||
},
|
},
|
||||||
"add-guides": {
|
"add-guides": {
|
||||||
"title": "Choose your sign-up offer 🔥",
|
"title": "Choose your sign-up offer 🔥",
|
||||||
@ -248,6 +256,7 @@
|
|||||||
"payment_error": "Something went wrong. Please try again later.",
|
"payment_error": "Something went wrong. Please try again later.",
|
||||||
"select_product_error": "Please select a product",
|
"select_product_error": "Please select a product",
|
||||||
"skip_offer": "Skip offer",
|
"skip_offer": "Skip offer",
|
||||||
|
"copyright": "© 2025, Wit Lab LLC, California, US",
|
||||||
"products": {
|
"products": {
|
||||||
"main_ultra_pack": {
|
"main_ultra_pack": {
|
||||||
"title": "ULTRA PACK",
|
"title": "ULTRA PACK",
|
||||||
@ -288,6 +297,53 @@
|
|||||||
"emoji": "rised_hand.webp"
|
"emoji": "rised_hand.webp"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"video-guides": {
|
||||||
|
"title": "Choose your sign-up offer 🔥",
|
||||||
|
"subtitle": "Available only now",
|
||||||
|
"description": "* You will be charged for the add-on services or offers selected at the time of purchase. This is a non-recuring payment.",
|
||||||
|
"button": "Continue",
|
||||||
|
"skip_button": "Skip this offer and proceed further",
|
||||||
|
"copyright": "© 2025, Wit Lab LLC, California, US",
|
||||||
|
"products": {
|
||||||
|
"main_ultra_pack": {
|
||||||
|
"title": "Ultra Pack",
|
||||||
|
"subtitle": "3 in 1+2 secret bonus readings",
|
||||||
|
"discount": "{discount}% OFF",
|
||||||
|
"price": "Now <price></price> <oldPrice></oldPrice>",
|
||||||
|
"emoji": "star_struck.webp"
|
||||||
|
},
|
||||||
|
"main_numerology_analysis": {
|
||||||
|
"title": "Relationship plan",
|
||||||
|
"subtitle": "Discover the future without losing yourself",
|
||||||
|
"discount": "{discount}% OFF",
|
||||||
|
"price": "Now <price></price> <oldPrice></oldPrice>",
|
||||||
|
"emoji": "ring.webp"
|
||||||
|
},
|
||||||
|
"main_tarot_reading": {
|
||||||
|
"title": "Healthy compatibility",
|
||||||
|
"subtitle": "Balance between closeness and freedom",
|
||||||
|
"discount": "{discount}% OFF",
|
||||||
|
"price": "Now <price></price> <oldPrice></oldPrice>",
|
||||||
|
"emoji": "rose.webp"
|
||||||
|
},
|
||||||
|
"main_palmistry_guide": {
|
||||||
|
"title": "How to talk about feelings",
|
||||||
|
"subtitle": "Express your emotions and be understood",
|
||||||
|
"discount": "{discount}% OFF",
|
||||||
|
"price": "Now <price></price> <oldPrice></oldPrice>",
|
||||||
|
"emoji": "heart_from_hands.webp"
|
||||||
|
},
|
||||||
|
"main_money_reading": {
|
||||||
|
"title": "How to talk about feelings",
|
||||||
|
"subtitle": "Express your emotions and be understood",
|
||||||
|
"discount": "{discount}% OFF",
|
||||||
|
"price": "Now <price></price> <oldPrice></oldPrice>",
|
||||||
|
"emoji": "heart_from_hands.webp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"payment_error": "Something went wrong. Please try again later.",
|
||||||
|
"select_product_error": "Please select a product"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Chat": {
|
"Chat": {
|
||||||
|
|||||||
@ -1,26 +1,45 @@
|
|||||||
.container.container {
|
.container {
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
-webkit-box-align: center;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
height: fit-content;
|
|
||||||
max-width: 560px;
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 0dvh;
|
bottom: calc(0dvh + 16px);
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
margin-top: 0px;
|
width: 100%;
|
||||||
padding-bottom: 20px;
|
padding-inline: 24px;
|
||||||
padding-inline: 15px;
|
max-width: 560px;
|
||||||
z-index: 5;
|
height: fit-content;
|
||||||
}
|
|
||||||
|
|
||||||
.button.button {
|
& > .button {
|
||||||
padding-block: 16px;
|
padding-block: 20px;
|
||||||
}
|
background: linear-gradient(90deg, #3b82f6 0%, #2563eb 100%);
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow:
|
||||||
|
0px 5px 14px 0px #3b82f666,
|
||||||
|
0px 4px 6px 0px #3b82f61a;
|
||||||
|
|
||||||
.skipButton.skipButton {
|
& > .text {
|
||||||
background-color: transparent;
|
font-size: 19px;
|
||||||
text-decoration: underline;
|
font-weight: 500;
|
||||||
|
line-height: 125%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .skipButton {
|
||||||
|
padding: 0;
|
||||||
|
min-height: none;
|
||||||
|
margin-top: 13px;
|
||||||
|
|
||||||
|
& > .text {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 24px;
|
||||||
|
color: #1f2937;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .copyright {
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 16px;
|
||||||
|
color: #9ca3af;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -67,20 +67,24 @@ export default function AddConsultantButton() {
|
|||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<Spinner />
|
<Spinner />
|
||||||
) : (
|
) : (
|
||||||
<Typography weight="semiBold" color="white">
|
<Typography color="white" className={styles.text}>
|
||||||
{t("get_my_consultation")}
|
{t("get_my_consultation")}
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
className={styles.skipButton}
|
className={styles.skipButton}
|
||||||
|
variant="ghost"
|
||||||
onClick={handleSkipOffer}
|
onClick={handleSkipOffer}
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
>
|
>
|
||||||
<Typography size="sm" color="black">
|
<Typography as="p" className={styles.text}>
|
||||||
{t("skip_this_offer")}
|
{t("skip_this_offer")}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Button>
|
</Button>
|
||||||
|
<Typography as="p" className={styles.copyright}>
|
||||||
|
{t("copyright")}
|
||||||
|
</Typography>
|
||||||
</BlurComponent>
|
</BlurComponent>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AddConsultantButton,
|
AddConsultantButton,
|
||||||
Caution,
|
|
||||||
ConsultationTable,
|
ConsultationTable,
|
||||||
|
Progress,
|
||||||
|
useMultiPageNavigationContext,
|
||||||
} from "@/components/domains/additional-purchases";
|
} from "@/components/domains/additional-purchases";
|
||||||
import { Card, Typography } from "@/components/ui";
|
import { Card, Typography } from "@/components/ui";
|
||||||
|
|
||||||
@ -11,10 +14,19 @@ import styles from "./AddConsultantPage.module.scss";
|
|||||||
|
|
||||||
export default function AddConsultantPage() {
|
export default function AddConsultantPage() {
|
||||||
const t = useTranslations("AdditionalPurchases.add-consultant");
|
const t = useTranslations("AdditionalPurchases.add-consultant");
|
||||||
|
const { navigation } = useMultiPageNavigationContext();
|
||||||
|
|
||||||
|
// Получаем названия всех страниц для прогресса
|
||||||
|
const progressItems = navigation.data.map((item: any) => {
|
||||||
|
return item.title || item.type || "";
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Caution />
|
<Progress
|
||||||
|
items={progressItems}
|
||||||
|
activeItemIndex={navigation.currentIndex}
|
||||||
|
/>
|
||||||
<Typography as="h2" size="xl" weight="semiBold" className={styles.title}>
|
<Typography as="h2" size="xl" weight="semiBold" className={styles.title}>
|
||||||
{t("title")}
|
{t("title")}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|||||||
@ -7,8 +7,26 @@
|
|||||||
padding-inline: 24px;
|
padding-inline: 24px;
|
||||||
max-width: 560px;
|
max-width: 560px;
|
||||||
height: fit-content;
|
height: fit-content;
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
& > .button {
|
||||||
padding-block: 16px;
|
padding-block: 20px;
|
||||||
|
background: linear-gradient(90deg, #3b82f6 0%, #2563eb 100%);
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow:
|
||||||
|
0px 5px 14px 0px #3b82f666,
|
||||||
|
0px 4px 6px 0px #3b82f61a;
|
||||||
|
|
||||||
|
& > .text {
|
||||||
|
font-size: 19px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 125%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .copyright {
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 16px;
|
||||||
|
color: #9ca3af;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -68,11 +68,14 @@ export default function AddGuidesButton() {
|
|||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<Spinner />
|
<Spinner />
|
||||||
) : (
|
) : (
|
||||||
<Typography weight="semiBold" color="white">
|
<Typography color="white" className={styles.text}>
|
||||||
{isSkipOffer ? t("skip_offer") : t("button")}
|
{isSkipOffer ? t("skip_offer") : t("button")}
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
|
<Typography as="p" className={styles.copyright}>
|
||||||
|
{t("copyright")}
|
||||||
|
</Typography>
|
||||||
</BlurComponent>
|
</BlurComponent>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,15 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
import { Suspense } from "react";
|
import { Suspense } from "react";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AddGuidesButton,
|
AddGuidesButton,
|
||||||
Caution,
|
|
||||||
Offers,
|
Offers,
|
||||||
OffersSkeleton,
|
OffersSkeleton,
|
||||||
ProductSelectionProvider,
|
ProductSelectionProvider,
|
||||||
|
Progress,
|
||||||
|
useMultiPageNavigationContext,
|
||||||
} from "@/components/domains/additional-purchases";
|
} from "@/components/domains/additional-purchases";
|
||||||
import { Typography } from "@/components/ui";
|
import { Typography } from "@/components/ui";
|
||||||
|
|
||||||
@ -14,10 +17,19 @@ import styles from "./AddGuidesPage.module.scss";
|
|||||||
|
|
||||||
export default function AddGuidesPage() {
|
export default function AddGuidesPage() {
|
||||||
const t = useTranslations("AdditionalPurchases.add-guides");
|
const t = useTranslations("AdditionalPurchases.add-guides");
|
||||||
|
const { navigation } = useMultiPageNavigationContext();
|
||||||
|
|
||||||
|
// Получаем названия всех страниц для прогресса
|
||||||
|
const progressItems = navigation.data.map((item: any) => {
|
||||||
|
return item.title || item.type || "";
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ProductSelectionProvider>
|
<ProductSelectionProvider>
|
||||||
<Caution />
|
<Progress
|
||||||
|
items={progressItems}
|
||||||
|
activeItemIndex={navigation.currentIndex}
|
||||||
|
/>
|
||||||
<Typography as="h2" size="xl" weight="semiBold" className={styles.title}>
|
<Typography as="h2" size="xl" weight="semiBold" className={styles.title}>
|
||||||
{t("title")}
|
{t("title")}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|||||||
@ -0,0 +1,45 @@
|
|||||||
|
.container {
|
||||||
|
width: 100%;
|
||||||
|
padding: 18px 20px 25px 25px;
|
||||||
|
background: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
rgba(78, 205, 196, 0.1) 0%,
|
||||||
|
rgba(102, 126, 234, 0.1) 100%
|
||||||
|
);
|
||||||
|
border: 1px solid #4ecdc433;
|
||||||
|
border-radius: 32px;
|
||||||
|
margin-top: 34px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 48px 1fr;
|
||||||
|
gap: 16px;
|
||||||
|
|
||||||
|
& > .iconContainer {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #4ecdc433;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .textContainer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
& > .title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 28px;
|
||||||
|
color: #262626;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .description {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 24px;
|
||||||
|
color: #525252;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
|
import { Typography } from "@/components/ui";
|
||||||
|
|
||||||
|
import HeartIcon from "./HeartIcon.svg";
|
||||||
|
|
||||||
|
import styles from "./AdditionalPurchaseBanner.module.scss";
|
||||||
|
|
||||||
|
export default function AdditionalPurchaseBanner() {
|
||||||
|
const t = useTranslations("AdditionalPurchases.banner");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.iconContainer}>
|
||||||
|
<HeartIcon />
|
||||||
|
</div>
|
||||||
|
<div className={styles.textContainer}>
|
||||||
|
<Typography as="h4" align="left" className={styles.title}>
|
||||||
|
{t("title")}
|
||||||
|
</Typography>
|
||||||
|
<Typography as="p" align="left" className={styles.description}>
|
||||||
|
{t("description")}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
<svg width="20" height="18" viewBox="0 0 20 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M1.85938 10.0879L8.91797 16.6777C9.21094 16.9511 9.59766 17.1035 10 17.1035C10.4023 17.1035 10.7891 16.9511 11.082 16.6777L18.1406 10.0879C19.3281 8.98239 20 7.43161 20 5.81051V5.58395C20 2.85348 18.0273 0.525356 15.3359 0.0761369C13.5547 -0.220738 11.7422 0.361293 10.4688 1.63473L10 2.10348L9.53125 1.63473C8.25781 0.361293 6.44531 -0.220738 4.66406 0.0761369C1.97266 0.525356 0 2.85348 0 5.58395V5.81051C0 7.43161 0.671875 8.98239 1.85938 10.0879Z" fill="#4ECDC4"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 581 B |
@ -19,7 +19,7 @@
|
|||||||
& > .marker {
|
& > .marker {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
border: 1px solid #e2e8f0;
|
border: 2px solid #e2e8f0;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: f8fafc;
|
background: f8fafc;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -76,7 +76,7 @@
|
|||||||
& > .marker {
|
& > .marker {
|
||||||
box-shadow: 0px 0px 0px 0px #3b82f626;
|
box-shadow: 0px 0px 0px 0px #3b82f626;
|
||||||
background-color: #2866ed;
|
background-color: #2866ed;
|
||||||
border: none;
|
border: 2px solid #2866ed;
|
||||||
|
|
||||||
& > .number {
|
& > .number {
|
||||||
display: none;
|
display: none;
|
||||||
@ -91,7 +91,7 @@
|
|||||||
|
|
||||||
.connector {
|
.connector {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 15px;
|
top: 16px;
|
||||||
height: 2px;
|
height: 2px;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,20 +9,23 @@ import { useDynamicSize } from "@/hooks/DOM/useDynamicSize";
|
|||||||
import styles from "./Progress.module.scss";
|
import styles from "./Progress.module.scss";
|
||||||
|
|
||||||
interface IProgressProps {
|
interface IProgressProps {
|
||||||
|
items: string[];
|
||||||
activeItemIndex: number;
|
activeItemIndex: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Progress({ activeItemIndex }: IProgressProps) {
|
export default function Progress({ items, activeItemIndex }: IProgressProps) {
|
||||||
const t = useTranslations("AdditionalPurchases.Progress");
|
const t = useTranslations("AdditionalPurchases.Progress");
|
||||||
const { width: containerWidth, elementRef } = useDynamicSize<HTMLDivElement>({
|
const { width: containerWidth, elementRef } = useDynamicSize<HTMLDivElement>({
|
||||||
defaultWidth: 327,
|
defaultWidth: 327,
|
||||||
});
|
});
|
||||||
|
|
||||||
const items = Object.values(t.raw("items") as Record<string, string>);
|
// Всегда добавляем финальный пункт в конец
|
||||||
|
const finalStep = t("final_step");
|
||||||
|
const allItems = [...items, finalStep];
|
||||||
|
|
||||||
const firstChild = elementRef.current?.childNodes[0] as HTMLElement;
|
const firstChild = elementRef.current?.childNodes[0] as HTMLElement;
|
||||||
const lastChild = elementRef.current?.childNodes[
|
const lastChild = elementRef.current?.childNodes[
|
||||||
items.length - 1
|
allItems.length - 1
|
||||||
] as HTMLElement;
|
] as HTMLElement;
|
||||||
const leftIndent =
|
const leftIndent =
|
||||||
((firstChild?.getBoundingClientRect().width || 100) - 32) / 2;
|
((firstChild?.getBoundingClientRect().width || 100) - 32) / 2;
|
||||||
@ -31,7 +34,7 @@ export default function Progress({ activeItemIndex }: IProgressProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container} ref={elementRef}>
|
<div className={styles.container} ref={elementRef}>
|
||||||
{items.map((item, index) => (
|
{allItems.map((item, index) => (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
@ -69,8 +72,8 @@ export default function Progress({ activeItemIndex }: IProgressProps) {
|
|||||||
? `
|
? `
|
||||||
linear-gradient(
|
linear-gradient(
|
||||||
90deg, #2866ed 0%,
|
90deg, #2866ed 0%,
|
||||||
#2866ed ${((activeItemIndex - 1) / items.length) * 100}%,
|
#2866ed ${((activeItemIndex - 1) / allItems.length) * 100}%,
|
||||||
#c4d9fc ${(activeItemIndex / items.length) * containerWidth + 16}px,
|
#c4d9fc ${(activeItemIndex / allItems.length) * containerWidth + 16}px,
|
||||||
#E2E8F0 100%)
|
#E2E8F0 100%)
|
||||||
`
|
`
|
||||||
: "#E2E8F0",
|
: "#E2E8F0",
|
||||||
|
|||||||
@ -30,7 +30,7 @@ export default function VideoGuidesOffer(props: VideoGuidesOfferProps) {
|
|||||||
|
|
||||||
const subtitle = t.has("subtitle") ? t("subtitle") : undefined;
|
const subtitle = t.has("subtitle") ? t("subtitle") : undefined;
|
||||||
|
|
||||||
const discount = Math.ceil(
|
const discount = Math.round(
|
||||||
(((oldPrice || 0) - price) / (oldPrice || 0)) * 100
|
(((oldPrice || 0) - price) / (oldPrice || 0)) * 100
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -10,42 +10,27 @@ import { useProductSelection } from "../ProductSelectionProvider";
|
|||||||
|
|
||||||
import styles from "./VideoGuidesOffers.module.scss";
|
import styles from "./VideoGuidesOffers.module.scss";
|
||||||
|
|
||||||
|
// Зашитые проценты скидки: первый товар - 50%, остальные - 45%
|
||||||
|
const FIRST_PRODUCT_DISCOUNT = 50;
|
||||||
|
const OTHER_PRODUCTS_DISCOUNT = 45;
|
||||||
|
|
||||||
export default function VideoGuidesOffers() {
|
export default function VideoGuidesOffers() {
|
||||||
const { navigation } = useMultiPageNavigationContext();
|
const { navigation } = useMultiPageNavigationContext();
|
||||||
const data = navigation.currentItem;
|
const data = navigation.currentItem;
|
||||||
|
|
||||||
const offers = useMemo(() => {
|
const offers = useMemo(() => {
|
||||||
return [
|
// Используем данные с сервера и добавляем oldPrice на основе зашитого процента скидки
|
||||||
{
|
const serverOffers = data?.variants ?? [];
|
||||||
id: "1",
|
return serverOffers.map((offer: IFunnelPaymentVariant, index: number) => {
|
||||||
key: "main_ultra_pack",
|
// Первый товар имеет скидку 50%, остальные - 45%
|
||||||
type: "sdv",
|
const discountPercent = index === 0 ? FIRST_PRODUCT_DISCOUNT : OTHER_PRODUCTS_DISCOUNT;
|
||||||
price: 1939,
|
// Рассчитываем oldPrice: если price это цена со скидкой X%, то oldPrice = price / (1 - X/100)
|
||||||
oldPrice: 3499,
|
const oldPrice = Math.round(offer.price / (1 - discountPercent / 100));
|
||||||
},
|
return {
|
||||||
{
|
...offer,
|
||||||
id: "2",
|
oldPrice,
|
||||||
key: "main_numerology_analysis",
|
};
|
||||||
type: "sdv",
|
});
|
||||||
price: 938,
|
|
||||||
oldPrice: 1999,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "3",
|
|
||||||
key: "main_tarot_reading",
|
|
||||||
type: "sdv",
|
|
||||||
price: 937,
|
|
||||||
oldPrice: 1999,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "4",
|
|
||||||
key: "main_palmistry_guide",
|
|
||||||
type: "sdv",
|
|
||||||
price: 936,
|
|
||||||
oldPrice: 1999,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
return data?.variants ?? [];
|
|
||||||
}, [data]);
|
}, [data]);
|
||||||
const [activeOffer, setActiveOffer] = useState<string>("");
|
const [activeOffer, setActiveOffer] = useState<string>("");
|
||||||
const { setSelectedProduct } = useProductSelection();
|
const { setSelectedProduct } = useProductSelection();
|
||||||
|
|||||||
@ -1,13 +1,16 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
import { Suspense } from "react";
|
import { Suspense } from "react";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
AdditionalPurchaseBanner,
|
||||||
ProductSelectionProvider,
|
ProductSelectionProvider,
|
||||||
Progress,
|
Progress,
|
||||||
VideoGuidesBanner,
|
|
||||||
VideoGuidesButton,
|
VideoGuidesButton,
|
||||||
VideoGuidesOffers,
|
VideoGuidesOffers,
|
||||||
VideoGuidesOffersSkeleton,
|
VideoGuidesOffersSkeleton,
|
||||||
|
useMultiPageNavigationContext,
|
||||||
} from "@/components/domains/additional-purchases";
|
} from "@/components/domains/additional-purchases";
|
||||||
import { Typography } from "@/components/ui";
|
import { Typography } from "@/components/ui";
|
||||||
|
|
||||||
@ -15,11 +18,20 @@ import styles from "./VideoGuidesPage.module.scss";
|
|||||||
|
|
||||||
export default function VideoGuidesPage() {
|
export default function VideoGuidesPage() {
|
||||||
const t = useTranslations("AdditionalPurchases.video-guides");
|
const t = useTranslations("AdditionalPurchases.video-guides");
|
||||||
|
const { navigation } = useMultiPageNavigationContext();
|
||||||
|
|
||||||
|
// Получаем названия всех страниц для прогресса
|
||||||
|
const progressItems = navigation.data.map((item: any) => {
|
||||||
|
return item.title || item.type || "";
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ProductSelectionProvider>
|
<ProductSelectionProvider>
|
||||||
<Progress activeItemIndex={1} />
|
<Progress
|
||||||
<VideoGuidesBanner />
|
items={progressItems}
|
||||||
|
activeItemIndex={navigation.currentIndex}
|
||||||
|
/>
|
||||||
|
<AdditionalPurchaseBanner />
|
||||||
<Typography as="h1" className={styles.title}>
|
<Typography as="h1" className={styles.title}>
|
||||||
{t("title")}
|
{t("title")}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|||||||
@ -2,6 +2,7 @@ export { default as AddConsultantButton } from "./AddConsultantButton/AddConsult
|
|||||||
export { default as AddConsultantPage } from "./AddConsultantPage/AddConsultantPage";
|
export { default as AddConsultantPage } from "./AddConsultantPage/AddConsultantPage";
|
||||||
export { default as AddGuidesButton } from "./AddGuidesButton/AddGuidesButton";
|
export { default as AddGuidesButton } from "./AddGuidesButton/AddGuidesButton";
|
||||||
export { default as AddGuidesPage } from "./AddGuidesPage/AddGuidesPage";
|
export { default as AddGuidesPage } from "./AddGuidesPage/AddGuidesPage";
|
||||||
|
export { default as AdditionalPurchaseBanner } from "./AdditionalPurchaseBanner/AdditionalPurchaseBanner";
|
||||||
export { default as Caution } from "./Caution/Caution";
|
export { default as Caution } from "./Caution/Caution";
|
||||||
export { default as ConsultationTable } from "./ConsultationTable/ConsultationTable";
|
export { default as ConsultationTable } from "./ConsultationTable/ConsultationTable";
|
||||||
export {
|
export {
|
||||||
|
|||||||
@ -35,6 +35,7 @@ export const FunnelPaymentPlacementSchema = z.object({
|
|||||||
variants: z.array(FunnelPaymentVariantSchema).optional(),
|
variants: z.array(FunnelPaymentVariantSchema).optional(),
|
||||||
paymentUrl: z.string().optional(),
|
paymentUrl: z.string().optional(),
|
||||||
type: z.string().optional(),
|
type: z.string().optional(),
|
||||||
|
title: z.string().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const FunnelSchema = z.object({
|
export const FunnelSchema = z.object({
|
||||||
|
|||||||
@ -16,6 +16,7 @@ interface PageNavigationOptions<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface PageNavigationReturn<T> {
|
interface PageNavigationReturn<T> {
|
||||||
|
data: T[];
|
||||||
currentItem: T | undefined;
|
currentItem: T | undefined;
|
||||||
currentIndex: number;
|
currentIndex: number;
|
||||||
isFirst: boolean;
|
isFirst: boolean;
|
||||||
@ -124,6 +125,7 @@ export function useMultiPageNavigation<T>({
|
|||||||
|
|
||||||
return useMemo(
|
return useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
|
data,
|
||||||
currentItem,
|
currentItem,
|
||||||
nextItem,
|
nextItem,
|
||||||
currentIndex,
|
currentIndex,
|
||||||
@ -141,6 +143,7 @@ export function useMultiPageNavigation<T>({
|
|||||||
totalPages,
|
totalPages,
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
|
data,
|
||||||
currentItem,
|
currentItem,
|
||||||
nextItem,
|
nextItem,
|
||||||
currentIndex,
|
currentIndex,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user