video guide

This commit is contained in:
dev.daminik00 2025-10-27 23:13:45 +01:00
parent b98096bb7c
commit 042bb25057
20 changed files with 355 additions and 89 deletions

View File

@ -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": {

View File

@ -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": {

View File

@ -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": {

View File

@ -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;
}
} }

View File

@ -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>
); );
} }

View File

@ -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>

View File

@ -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;
}
} }

View File

@ -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>
); );
} }

View File

@ -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>

View File

@ -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;
}
}
}

View File

@ -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>
);
}

View File

@ -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

View File

@ -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;
} }

View File

@ -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",

View File

@ -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
); );

View File

@ -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();

View File

@ -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>

View File

@ -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 {

View File

@ -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({

View File

@ -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,