0 ? `${containerHeight}px` : undefined,
- }}
- >
- {allItems.map((item, index) => {
- const itemPosition = calculateItemPosition(index);
- return (
-
index && styles.done
+ {allItems.map((item, index) => (
+
index && styles.done
+ )}
+ >
+
+ {activeItemIndex > index && styles.done && (
+
)}
- style={{
- left: `${itemPosition}px`,
- transform: 'translateX(-50%)', // Центрируем относительно позиции
- }}
- >
-
- {activeItemIndex > index && styles.done && (
-
- )}
-
- {index + 1}
-
-
-
- {item}
+
+ {index + 1}
- );
- })}
+
+ {item}
+
+
+ ))}
0
- ? `linear-gradient(
- 90deg,
- #2866ed 0%,
- #2866ed ${((activeItemIndex) / (totalItems - 1)) * 100}%,
- #E2E8F0 ${((activeItemIndex) / (totalItems - 1)) * 100}%,
- #E2E8F0 100%
- )`
+ width: containerWidth - leftIndent - rightIndent,
+ left: leftIndent,
+ background: activeItemIndex
+ ? `
+ linear-gradient(
+ 90deg,
+ #2866ed 0%,
+ #2866ed ${((activeItemIndex - 1) / items.length) * 100}%,
+ #c4d9fc ${(activeItemIndex / items.length) * containerWidth + 16}px,
+ #E2E8F0 100%)
+ `
: "#E2E8F0",
}}
/>
-
-
+
);
}
diff --git a/src/components/domains/additional-purchases/ProgressLayout/ProgressLayout.tsx b/src/components/domains/additional-purchases/ProgressLayout/ProgressLayout.tsx
new file mode 100644
index 0000000..70021e8
--- /dev/null
+++ b/src/components/domains/additional-purchases/ProgressLayout/ProgressLayout.tsx
@@ -0,0 +1,27 @@
+"use client";
+
+import { IFunnelPaymentPlacement } from "@/entities/session/funnel/types";
+
+import { Progress, useMultiPageNavigationContext } from "..";
+
+interface IProgressLayoutProps {
+ children: React.ReactNode;
+}
+
+export default function ProgressLayout({ children }: IProgressLayoutProps) {
+ const { navigation } = useMultiPageNavigationContext();
+
+ const progressItems = navigation.data.map((item: IFunnelPaymentPlacement) => {
+ return item.title || item.type || "";
+ });
+
+ return (
+ <>
+
+ {children}
+ >
+ );
+}
diff --git a/src/components/domains/additional-purchases/VideoGuidesButton/VideoGuidesButton.tsx b/src/components/domains/additional-purchases/VideoGuidesButton/VideoGuidesButton.tsx
index d6b9a5a..febc548 100644
--- a/src/components/domains/additional-purchases/VideoGuidesButton/VideoGuidesButton.tsx
+++ b/src/components/domains/additional-purchases/VideoGuidesButton/VideoGuidesButton.tsx
@@ -23,16 +23,8 @@ export default function VideoGuidesButton() {
const { handleSingleCheckout, isLoading } = useSingleCheckout({
onSuccess: async () => {
- // Устанавливаем флаг навигации чтобы заблокировать повторные нажатия
setIsNavigating(true);
-
- // Переходим на следующую страницу или на главную
- if (navigation.hasNext) {
- await navigation.goToNext();
- } else {
- // Если это последний экран - переходим на дашборд
- window.location.href = ROUTES.home();
- }
+ await navigation.goToNext();
},
onError: _error => {
addToast({
@@ -67,7 +59,6 @@ export default function VideoGuidesButton() {
navigation.goToNext();
};
- // Блокируем кнопку во время загрузки ИЛИ навигации
const isButtonDisabled = isLoading || isNavigating;
return (
diff --git a/src/components/domains/additional-purchases/VideoGuidesOffer/VideoGuidesOffer.tsx b/src/components/domains/additional-purchases/VideoGuidesOffer/VideoGuidesOffer.tsx
index 9ff7d27..57481c7 100644
--- a/src/components/domains/additional-purchases/VideoGuidesOffer/VideoGuidesOffer.tsx
+++ b/src/components/domains/additional-purchases/VideoGuidesOffer/VideoGuidesOffer.tsx
@@ -86,9 +86,7 @@ export default function VideoGuidesOffer(props: VideoGuidesOfferProps) {
{!isFirstOffer && (
-
- {discount}% OFF
-
+
{discount}% OFF
)}
diff --git a/src/components/domains/additional-purchases/VideoGuidesOffers/VideoGuidesOffers.tsx b/src/components/domains/additional-purchases/VideoGuidesOffers/VideoGuidesOffers.tsx
index 7bc3d3c..8a25b33 100644
--- a/src/components/domains/additional-purchases/VideoGuidesOffers/VideoGuidesOffers.tsx
+++ b/src/components/domains/additional-purchases/VideoGuidesOffers/VideoGuidesOffers.tsx
@@ -23,7 +23,8 @@ export default function VideoGuidesOffers() {
const serverOffers = data?.variants ?? [];
return serverOffers.map((offer: IFunnelPaymentVariant, index: number) => {
// Первый товар имеет скидку 50%, остальные - 45%
- const discountPercent = index === 0 ? FIRST_PRODUCT_DISCOUNT : OTHER_PRODUCTS_DISCOUNT;
+ const discountPercent =
+ index === 0 ? FIRST_PRODUCT_DISCOUNT : OTHER_PRODUCTS_DISCOUNT;
// Рассчитываем oldPrice: если price это цена со скидкой X%, то oldPrice = price / (1 - X/100)
const oldPrice = Math.round(offer.price / (1 - discountPercent / 100));
return {
diff --git a/src/components/domains/additional-purchases/VideoGuidesPage/VideoGuidesPage.tsx b/src/components/domains/additional-purchases/VideoGuidesPage/VideoGuidesPage.tsx
index 14201e2..b3b9046 100644
--- a/src/components/domains/additional-purchases/VideoGuidesPage/VideoGuidesPage.tsx
+++ b/src/components/domains/additional-purchases/VideoGuidesPage/VideoGuidesPage.tsx
@@ -1,13 +1,9 @@
-"use client";
-
import { Suspense } from "react";
-import { useTranslations } from "next-intl";
+import { getTranslations } from "next-intl/server";
import {
AdditionalPurchaseBanner,
ProductSelectionProvider,
- Progress,
- useMultiPageNavigationContext,
VideoGuidesButton,
VideoGuidesOffers,
VideoGuidesOffersSkeleton,
@@ -16,21 +12,11 @@ import { Typography } from "@/components/ui";
import styles from "./VideoGuidesPage.module.scss";
-export default function VideoGuidesPage() {
- const t = useTranslations("AdditionalPurchases.video-guides");
- const { navigation } = useMultiPageNavigationContext();
-
- // Получаем названия всех страниц для прогресса
- const progressItems = navigation.data.map((item: any) => {
- return item.title || item.type || "";
- });
+export default async function VideoGuidesPage() {
+ const t = await getTranslations("AdditionalPurchases.video-guides");
return (