- {t("title")}
+ {name}
- {subtitle && (
+ {description && (
- {subtitle}
+ {description}
)}
@@ -76,24 +76,18 @@ export default function VideoGuidesOffer(props: VideoGuidesOfferProps) {
- {t.rich("price", {
- price: () => (
-
- {getFormattedPrice(price, currency)}
-
- ),
- oldPrice: () => (
-
- {getFormattedPrice(oldPrice || 0, currency)}
-
- ),
- })}
-
-
- {t("discount", {
- discount: discount || 0,
- })}
+ {t("now")}{" "}
+
+ {getFormattedPrice(price, currency)}
+
+ {" "}
+
+ {getFormattedPrice(oldPrice || 0, currency)}
+
+ {!isFirstOffer && (
+ {discount}% OFF
+ )}
);
diff --git a/src/components/domains/additional-purchases/VideoGuidesOffers/VideoGuidesOffers.tsx b/src/components/domains/additional-purchases/VideoGuidesOffers/VideoGuidesOffers.tsx
index 867e083..8a25b33 100644
--- a/src/components/domains/additional-purchases/VideoGuidesOffers/VideoGuidesOffers.tsx
+++ b/src/components/domains/additional-purchases/VideoGuidesOffers/VideoGuidesOffers.tsx
@@ -10,42 +10,28 @@ import { useProductSelection } from "../ProductSelectionProvider";
import styles from "./VideoGuidesOffers.module.scss";
+// Зашитые проценты скидки: первый товар - 50%, остальные - 45%
+const FIRST_PRODUCT_DISCOUNT = 50;
+const OTHER_PRODUCTS_DISCOUNT = 45;
+
export default function VideoGuidesOffers() {
const { navigation } = useMultiPageNavigationContext();
const data = navigation.currentItem;
const offers = useMemo(() => {
- return [
- {
- id: "1",
- key: "main_ultra_pack",
- type: "sdv",
- price: 1939,
- oldPrice: 3499,
- },
- {
- id: "2",
- 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 ?? [];
+ // Используем данные с сервера и добавляем oldPrice на основе зашитого процента скидки
+ const serverOffers = data?.variants ?? [];
+ return serverOffers.map((offer: IFunnelPaymentVariant, index: number) => {
+ // Первый товар имеет скидку 50%, остальные - 45%
+ 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 {
+ ...offer,
+ oldPrice,
+ };
+ });
}, [data]);
const [activeOffer, setActiveOffer] = useState
("");
const { setSelectedProduct } = useProductSelection();
@@ -64,11 +50,12 @@ export default function VideoGuidesOffers() {
return (
- {offers.map(offer => (
+ {offers.map((offer, index) => (
handleOfferClick(offer)}
/>
))}
diff --git a/src/components/domains/additional-purchases/VideoGuidesPage/VideoGuidesPage.tsx b/src/components/domains/additional-purchases/VideoGuidesPage/VideoGuidesPage.tsx
index b1db972..b3b9046 100644
--- a/src/components/domains/additional-purchases/VideoGuidesPage/VideoGuidesPage.tsx
+++ b/src/components/domains/additional-purchases/VideoGuidesPage/VideoGuidesPage.tsx
@@ -1,10 +1,9 @@
import { Suspense } from "react";
-import { useTranslations } from "next-intl";
+import { getTranslations } from "next-intl/server";
import {
+ AdditionalPurchaseBanner,
ProductSelectionProvider,
- Progress,
- VideoGuidesBanner,
VideoGuidesButton,
VideoGuidesOffers,
VideoGuidesOffersSkeleton,
@@ -13,13 +12,12 @@ import { Typography } from "@/components/ui";
import styles from "./VideoGuidesPage.module.scss";
-export default function VideoGuidesPage() {
- const t = useTranslations("AdditionalPurchases.video-guides");
+export default async function VideoGuidesPage() {
+ const t = await getTranslations("AdditionalPurchases.video-guides");
return (
-
-
+
{t("title")}
diff --git a/src/components/domains/additional-purchases/index.ts b/src/components/domains/additional-purchases/index.ts
index d71789b..5b0b597 100644
--- a/src/components/domains/additional-purchases/index.ts
+++ b/src/components/domains/additional-purchases/index.ts
@@ -2,6 +2,7 @@ export { default as AddConsultantButton } from "./AddConsultantButton/AddConsult
export { default as AddConsultantPage } from "./AddConsultantPage/AddConsultantPage";
export { default as AddGuidesButton } from "./AddGuidesButton/AddGuidesButton";
export { default as AddGuidesPage } from "./AddGuidesPage/AddGuidesPage";
+export { default as AdditionalPurchaseBanner } from "./AdditionalPurchaseBanner/AdditionalPurchaseBanner";
export { default as Caution } from "./Caution/Caution";
export { default as ConsultationTable } from "./ConsultationTable/ConsultationTable";
export {
@@ -15,6 +16,7 @@ export {
useProductSelection,
} from "./ProductSelectionProvider";
export { default as Progress } from "./Progress/Progress";
+export { default as ProgressLayout } from "./ProgressLayout/ProgressLayout";
export { default as VideoGuidesBanner } from "./VideoGuidesBanner/VideoGuidesBanner";
export { default as VideoGuidesButton } from "./VideoGuidesButton/VideoGuidesButton";
export { default as VideoGuidesOffer } from "./VideoGuidesOffer/VideoGuidesOffer";
diff --git a/src/components/domains/chat/GlobalNewMessagesBanner/GlobalNewMessagesBanner.tsx b/src/components/domains/chat/GlobalNewMessagesBanner/GlobalNewMessagesBanner.tsx
index 03a7a43..c27063d 100644
--- a/src/components/domains/chat/GlobalNewMessagesBanner/GlobalNewMessagesBanner.tsx
+++ b/src/components/domains/chat/GlobalNewMessagesBanner/GlobalNewMessagesBanner.tsx
@@ -17,7 +17,7 @@ export default function GlobalNewMessagesBanner() {
const { unreadChats } = useChats();
const { balance } = useBalance();
- // Exclude banner on chat-related, settings (profile), retention funnel, and portraits pages
+ // Exclude banner on chat-related, settings (profile), retention funnel, portraits, and video guides pages
const pathname = usePathname();
const locale = useLocale();
const pathnameWithoutLocale = stripLocale(pathname, locale);
@@ -25,7 +25,8 @@ export default function GlobalNewMessagesBanner() {
pathnameWithoutLocale.startsWith(ROUTES.chat()) ||
pathnameWithoutLocale.startsWith(ROUTES.profile()) ||
pathnameWithoutLocale.startsWith("/retaining") ||
- pathnameWithoutLocale.startsWith("/portraits");
+ pathnameWithoutLocale.startsWith("/portraits") ||
+ pathnameWithoutLocale.startsWith("/video-guides");
const hasHydrated = useAppUiStore(state => state._hasHydrated);
const { isVisibleAll } = useAppUiStore(state => state.home.newMessages);
diff --git a/src/components/domains/chat/MessageInput/MessageInput.tsx b/src/components/domains/chat/MessageInput/MessageInput.tsx
index 621742f..435e101 100644
--- a/src/components/domains/chat/MessageInput/MessageInput.tsx
+++ b/src/components/domains/chat/MessageInput/MessageInput.tsx
@@ -82,7 +82,10 @@ export default function MessageInput({
aria-label="Send"
className={styles.sendButton}
>
-
+
diff --git a/src/components/domains/dashboard/cards/PortraitCard/PortraitCard.module.scss b/src/components/domains/dashboard/cards/PortraitCard/PortraitCard.module.scss
index 79be070..9b37602 100644
--- a/src/components/domains/dashboard/cards/PortraitCard/PortraitCard.module.scss
+++ b/src/components/domains/dashboard/cards/PortraitCard/PortraitCard.module.scss
@@ -8,7 +8,9 @@
display: flex;
flex-direction: column;
cursor: pointer;
- transition: transform 0.2s ease, box-shadow 0.2s ease;
+ transition:
+ transform 0.2s ease,
+ box-shadow 0.2s ease;
&:hover {
transform: translateY(-4px);
@@ -102,14 +104,14 @@
}
.statusDone {
- color: #16A34A;
+ color: #16a34a;
.statusText {
- color: #16A34A;
+ color: #16a34a;
}
.checkmark {
- color: #16A34A;
+ color: #16a34a;
}
}
@@ -158,7 +160,9 @@
align-items: center;
justify-content: center;
cursor: pointer;
- transition: background 0.2s ease, transform 0.1s ease;
+ transition:
+ background 0.2s ease,
+ transform 0.1s ease;
flex-shrink: 0;
svg {
diff --git a/src/components/domains/dashboard/cards/PortraitCard/PortraitCard.tsx b/src/components/domains/dashboard/cards/PortraitCard/PortraitCard.tsx
index cd7c3cc..ef6a83d 100644
--- a/src/components/domains/dashboard/cards/PortraitCard/PortraitCard.tsx
+++ b/src/components/domains/dashboard/cards/PortraitCard/PortraitCard.tsx
@@ -12,13 +12,22 @@ import styles from "./PortraitCard.module.scss";
type PortraitCardProps = PartnerPortrait;
const HeartCheckIcon = () => (
-