From 111e5167d48cd95f986247cc72de882fc80a7c00 Mon Sep 17 00:00:00 2001 From: gofnnp Date: Sat, 25 Oct 2025 21:19:32 +0400 Subject: [PATCH] additional-purchases-v2 add video guides additional purchase --- messages/en.json | 52 ++++++- public/emoji/heart_from_hands.webp | Bin 0 -> 3318 bytes public/emoji/ring.webp | Bin 0 -> 3840 bytes public/emoji/rose.webp | Bin 0 -> 2910 bytes .../ap/[pageType]/page.tsx | 3 + .../Progress/Progress.module.scss | 98 +++++++++++++ .../Progress/Progress.tsx | 81 +++++++++++ .../VideoGuidesBanner/HeartIcon.svg | 3 + .../VideoGuidesBanner.module.scss | 45 ++++++ .../VideoGuidesBanner/VideoGuidesBanner.tsx | 27 ++++ .../VideoGuidesButton.module.scss | 45 ++++++ .../VideoGuidesButton/VideoGuidesButton.tsx | 88 ++++++++++++ .../VideoGuidesOffer.module.scss | 131 ++++++++++++++++++ .../VideoGuidesOffer/VideoGuidesOffer.tsx | 100 +++++++++++++ .../VideoGuidesOffers.module.scss | 7 + .../VideoGuidesOffers/VideoGuidesOffers.tsx | 81 +++++++++++ .../VideoGuidesPage.module.scss | 23 +++ .../VideoGuidesPage/VideoGuidesPage.tsx | 38 +++++ .../domains/additional-purchases/index.ts | 9 ++ 19 files changed, 830 insertions(+), 1 deletion(-) create mode 100644 public/emoji/heart_from_hands.webp create mode 100644 public/emoji/ring.webp create mode 100644 public/emoji/rose.webp create mode 100644 src/components/domains/additional-purchases/Progress/Progress.module.scss create mode 100644 src/components/domains/additional-purchases/Progress/Progress.tsx create mode 100644 src/components/domains/additional-purchases/VideoGuidesBanner/HeartIcon.svg create mode 100644 src/components/domains/additional-purchases/VideoGuidesBanner/VideoGuidesBanner.module.scss create mode 100644 src/components/domains/additional-purchases/VideoGuidesBanner/VideoGuidesBanner.tsx create mode 100644 src/components/domains/additional-purchases/VideoGuidesButton/VideoGuidesButton.module.scss create mode 100644 src/components/domains/additional-purchases/VideoGuidesButton/VideoGuidesButton.tsx create mode 100644 src/components/domains/additional-purchases/VideoGuidesOffer/VideoGuidesOffer.module.scss create mode 100644 src/components/domains/additional-purchases/VideoGuidesOffer/VideoGuidesOffer.tsx create mode 100644 src/components/domains/additional-purchases/VideoGuidesOffers/VideoGuidesOffers.module.scss create mode 100644 src/components/domains/additional-purchases/VideoGuidesOffers/VideoGuidesOffers.tsx create mode 100644 src/components/domains/additional-purchases/VideoGuidesPage/VideoGuidesPage.module.scss create mode 100644 src/components/domains/additional-purchases/VideoGuidesPage/VideoGuidesPage.tsx diff --git a/messages/en.json b/messages/en.json index d9f7ffb..bcdcc8b 100644 --- a/messages/en.json +++ b/messages/en.json @@ -295,6 +295,56 @@ "emoji": "rised_hand.webp" } } + }, + "video-guides": { + "banner": { + "title": "Amazing!", + "description": "Your journey begins now" + }, + "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 ", + "emoji": "star_struck.webp" + }, + "main_numerology_analysis": { + "title": "Relationship plan", + "subtitle": "Discover the future without losing yourself", + "discount": "{discount}% OFF", + "price": "Now ", + "emoji": "ring.webp" + }, + "main_tarot_reading": { + "title": "Healthy compatibility", + "subtitle": "Balance between closeness and freedom", + "discount": "{discount}% OFF", + "price": "Now ", + "emoji": "rose.webp" + }, + "main_palmistry_guide": { + "title": "How to talk about feelings", + "subtitle": "Express your emotions and be understood", + "discount": "{discount}% OFF", + "price": "Now ", + "emoji": "heart_from_hands.webp" + } + } + }, + "Progress": { + "items": { + "1": "Your Soulmate Portrait", + "2": "Video Guides", + "3": "Add Consultation", + "4": "Access Your Results" + } } }, "Chat": { @@ -641,4 +691,4 @@ "month": "{count, plural, zero {#-months} one {#-month} two {#-months} few {#-months} many {#-months} other {#-months}}", "year": "{count, plural, zero {#-years} one {#-year} two {#-years} few {#-years} many {#-years} other {#-years}}" } -} \ No newline at end of file +} diff --git a/public/emoji/heart_from_hands.webp b/public/emoji/heart_from_hands.webp new file mode 100644 index 0000000000000000000000000000000000000000..be923a0146f1716a9c3aa738984222e19614a8c1 GIT binary patch literal 3318 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 AVE_OC literal 0 HcmV?d00001 diff --git a/public/emoji/ring.webp b/public/emoji/ring.webp new file mode 100644 index 0000000000000000000000000000000000000000..98f9fb81befc9c3ab7e375daa81fbee00fefd217 GIT binary patch literal 3840 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 C(Q&T; literal 0 HcmV?d00001 diff --git a/public/emoji/rose.webp b/public/emoji/rose.webp new file mode 100644 index 0000000000000000000000000000000000000000..01d5b96fe257c6458dbd1d5aac74be81d4804dee GIT binary patch literal 2910 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 literal 0 HcmV?d00001 diff --git a/src/app/[locale]/(additional-purchases)/ap/[pageType]/page.tsx b/src/app/[locale]/(additional-purchases)/ap/[pageType]/page.tsx index 9e7d979..a74b02a 100644 --- a/src/app/[locale]/(additional-purchases)/ap/[pageType]/page.tsx +++ b/src/app/[locale]/(additional-purchases)/ap/[pageType]/page.tsx @@ -3,6 +3,7 @@ import { redirect } from "next/navigation"; import { AddConsultantPage, AddGuidesPage, + VideoGuidesPage, } from "@/components/domains/additional-purchases"; import { ROUTES } from "@/shared/constants/client-routes"; @@ -20,6 +21,8 @@ export default async function AdditionalProductPage({ return ; case "add_guides": return ; + case "video_guides": + return ; default: return redirect(ROUTES.home()); } diff --git a/src/components/domains/additional-purchases/Progress/Progress.module.scss b/src/components/domains/additional-purchases/Progress/Progress.module.scss new file mode 100644 index 0000000..00f1217 --- /dev/null +++ b/src/components/domains/additional-purchases/Progress/Progress.module.scss @@ -0,0 +1,98 @@ +.container { + position: relative; + width: 100%; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + + & > * { + z-index: 1; + } + + & > .item { + display: flex; + flex-direction: column; + align-items: center; + gap: 12px; + + & > .marker { + width: 32px; + height: 32px; + border: 1px solid #e2e8f0; + border-radius: 50%; + background: f8fafc; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + background-color: #f8fafc; + + & > .number { + font-size: 12px; + font-weight: 500; + color: #9ca3af; + } + } + + & > .text { + font-size: 12px; + font-weight: 500; + line-height: 16px; + color: #9ca3af; + } + + &.active { + & > .marker { + position: relative; + box-shadow: 0px 2px 15px 0px #3b82f6f7; + background-color: #3b82f6; + border: 2px solid #ffffff; + + &::before { + content: ""; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 6px; + height: 6px; + border-radius: 50%; + background-color: #fff; + } + + & > .number { + display: none; + } + } + + & > .text { + color: #2866ed; + font-weight: 600; + } + } + + &.done { + & > .marker { + box-shadow: 0px 0px 0px 0px #3b82f626; + background-color: #2866ed; + border: none; + + & > .number { + display: none; + } + } + + & > .text { + color: #282828; + } + } + } + + .connector { + position: absolute; + top: 15px; + height: 2px; + z-index: 0; + } +} diff --git a/src/components/domains/additional-purchases/Progress/Progress.tsx b/src/components/domains/additional-purchases/Progress/Progress.tsx new file mode 100644 index 0000000..3679b54 --- /dev/null +++ b/src/components/domains/additional-purchases/Progress/Progress.tsx @@ -0,0 +1,81 @@ +"use client"; + +import { useTranslations } from "next-intl"; +import clsx from "clsx"; + +import { Icon, IconName, Typography } from "@/components/ui"; +import { useDynamicSize } from "@/hooks/DOM/useDynamicSize"; + +import styles from "./Progress.module.scss"; + +interface IProgressProps { + activeItemIndex: number; +} + +export default function Progress({ activeItemIndex }: IProgressProps) { + const t = useTranslations("AdditionalPurchases.Progress"); + const { width: containerWidth, elementRef } = useDynamicSize({ + defaultWidth: 327, + }); + + const items = Object.values(t.raw("items") as Record); + + const firstChild = elementRef.current?.childNodes[0] as HTMLElement; + const lastChild = elementRef.current?.childNodes[ + items.length - 1 + ] as HTMLElement; + const leftIndent = + ((firstChild?.getBoundingClientRect().width || 100) - 32) / 2; + const rightIndent = + ((lastChild?.getBoundingClientRect().width || 76) - 32) / 2; + + return ( +
+ {items.map((item, index) => ( +
index && styles.done + )} + > +
+ {activeItemIndex > index && styles.done && ( + + )} + + {index + 1} + +
+ + {item} + +
+ ))} +
+
+ ); +} diff --git a/src/components/domains/additional-purchases/VideoGuidesBanner/HeartIcon.svg b/src/components/domains/additional-purchases/VideoGuidesBanner/HeartIcon.svg new file mode 100644 index 0000000..78e1716 --- /dev/null +++ b/src/components/domains/additional-purchases/VideoGuidesBanner/HeartIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/domains/additional-purchases/VideoGuidesBanner/VideoGuidesBanner.module.scss b/src/components/domains/additional-purchases/VideoGuidesBanner/VideoGuidesBanner.module.scss new file mode 100644 index 0000000..5ecfd76 --- /dev/null +++ b/src/components/domains/additional-purchases/VideoGuidesBanner/VideoGuidesBanner.module.scss @@ -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; + } + } +} diff --git a/src/components/domains/additional-purchases/VideoGuidesBanner/VideoGuidesBanner.tsx b/src/components/domains/additional-purchases/VideoGuidesBanner/VideoGuidesBanner.tsx new file mode 100644 index 0000000..06e8d3a --- /dev/null +++ b/src/components/domains/additional-purchases/VideoGuidesBanner/VideoGuidesBanner.tsx @@ -0,0 +1,27 @@ +import { getTranslations } from "next-intl/server"; + +import { Typography } from "@/components/ui"; + +import HeartIcon from "./HeartIcon.svg"; + +import styles from "./VideoGuidesBanner.module.scss"; + +export default async function VideoGuidesBanner() { + const t = await getTranslations("AdditionalPurchases.video-guides.banner"); + + return ( +
+
+ +
+
+ + {t("title")} + + + {t("description")} + +
+
+ ); +} diff --git a/src/components/domains/additional-purchases/VideoGuidesButton/VideoGuidesButton.module.scss b/src/components/domains/additional-purchases/VideoGuidesButton/VideoGuidesButton.module.scss new file mode 100644 index 0000000..e2127ad --- /dev/null +++ b/src/components/domains/additional-purchases/VideoGuidesButton/VideoGuidesButton.module.scss @@ -0,0 +1,45 @@ +.container { + position: fixed; + bottom: calc(0dvh + 16px); + left: 50%; + transform: translateX(-50%); + width: 100%; + padding-inline: 24px; + max-width: 560px; + height: fit-content; + + & > .button { + 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%; + } + } + + & > .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; + } +} diff --git a/src/components/domains/additional-purchases/VideoGuidesButton/VideoGuidesButton.tsx b/src/components/domains/additional-purchases/VideoGuidesButton/VideoGuidesButton.tsx new file mode 100644 index 0000000..9227b80 --- /dev/null +++ b/src/components/domains/additional-purchases/VideoGuidesButton/VideoGuidesButton.tsx @@ -0,0 +1,88 @@ +"use client"; + +import { useTranslations } from "next-intl"; + +import { Button, Spinner, Typography } from "@/components/ui"; +import { BlurComponent } from "@/components/widgets"; +import { useSingleCheckout } from "@/hooks/payment/useSingleCheckout"; +import { useToast } from "@/providers/toast-provider"; +import { ROUTES } from "@/shared/constants/client-routes"; + +import { useMultiPageNavigationContext } from ".."; +import { useProductSelection } from "../ProductSelectionProvider"; + +import styles from "./VideoGuidesButton.module.scss"; + +export default function VideoGuidesButton() { + const t = useTranslations("AdditionalPurchases.video-guides"); + const { addToast } = useToast(); + const { selectedProduct } = useProductSelection(); + const { navigation } = useMultiPageNavigationContext(); + + const { handleSingleCheckout, isLoading } = useSingleCheckout({ + onSuccess: () => { + navigation.goToNext(); + }, + onError: _error => { + addToast({ + variant: "error", + message: t("payment_error"), + duration: 5000, + }); + }, + returnUrl: new URL( + navigation.getNextPageUrl() || ROUTES.home(), + process.env.NEXT_PUBLIC_APP_URL || "" + ).toString(), + }); + + const handlePurchase = () => { + if (!selectedProduct) { + addToast({ + variant: "error", + message: t("select_product_error"), + duration: 5000, + }); + return; + } + + handleSingleCheckout({ + productId: selectedProduct.id, + key: selectedProduct.key, + }); + }; + + const handleSkipOffer = () => { + navigation.goToNext(); + }; + + return ( + + + + + {t("copyright")} + + + ); +} diff --git a/src/components/domains/additional-purchases/VideoGuidesOffer/VideoGuidesOffer.module.scss b/src/components/domains/additional-purchases/VideoGuidesOffer/VideoGuidesOffer.module.scss new file mode 100644 index 0000000..67878d4 --- /dev/null +++ b/src/components/domains/additional-purchases/VideoGuidesOffer/VideoGuidesOffer.module.scss @@ -0,0 +1,131 @@ +.container.container { + position: relative; + width: 100%; + padding: 11px 18px 12px; + display: flex; + flex-direction: column; + box-shadow: 0px 0px 30px 0px #0000001f; + gap: 4px; + + & > .content { + display: grid; + grid-template-columns: 40px 1fr 20px; + gap: 12px; + + & > .emojiContainer { + width: 40px; + height: 40px; + border: 1px solid #cedfff; + background: linear-gradient(0deg, #e2ebff, #e2ebff); + border-radius: 16px; + display: flex; + align-items: center; + justify-content: center; + + & > .emoji { + width: 30px; + height: 30px; + background-position: center; + background-repeat: no-repeat; + background-size: contain; + } + } + + & > .textContainer { + display: flex; + flex-direction: column; + align-items: flex-start; + + & > .title { + font-size: 16px; + font-weight: 700; + line-height: 24px; + color: #262626; + } + + & > .subtitle { + font-size: 14px; + font-weight: 500; + line-height: 16px; + color: #737373; + } + } + + & > .checmarkContainer { + width: 20px; + height: 20px; + border: 2px solid #d4d4d4; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin-top: auto; + } + } + + & > .footer { + display: flex; + align-items: flex-start; + justify-content: space-between; + + & > .price { + font-size: 14px; + line-height: 20px; + color: #737373; + + & > .currentPrice { + font-size: 14px; + line-height: 20px; + color: #737373; + } + + & > .oldPrice { + font-size: 14px; + line-height: 20px; + color: #9ca3af; + text-decoration: line-through; + } + } + + & > .discount { + display: block; + padding: 6px 8px; + background: #ff6b6b1a; + border-radius: 9999; + font-size: 12px; + font-weight: 700; + color: #ff6b6b; + margin-right: 19px; + } + } + + &.active { + outline: 2px solid #9fbdff; + + & > .content { + & > .checmarkContainer { + background-color: #2866ed; + border: none; + } + } + } + + &.main_ultra_pack { + & > .footer { + & > .discount { + position: absolute; + top: -15px; + right: 49px; + background: #ff3737; + box-shadow: 0px 1px 11.98px 0px #ff44448c; + border: 2px solid #ffffff4d; + padding: 8px 12px; + color: #fff; + font-size: 14px; + font-weight: 800; + letter-spacing: 0.5px; + margin-right: 0; + } + } + } +} diff --git a/src/components/domains/additional-purchases/VideoGuidesOffer/VideoGuidesOffer.tsx b/src/components/domains/additional-purchases/VideoGuidesOffer/VideoGuidesOffer.tsx new file mode 100644 index 0000000..7974e46 --- /dev/null +++ b/src/components/domains/additional-purchases/VideoGuidesOffer/VideoGuidesOffer.tsx @@ -0,0 +1,100 @@ +import { useTranslations } from "next-intl"; +import clsx from "clsx"; + +import { Card, Icon, IconName, Typography } from "@/components/ui"; +import { IFunnelPaymentVariant } from "@/entities/session/funnel/types"; +import { getFormattedPrice } from "@/shared/utils/price"; +import { Currency } from "@/types"; + +import styles from "./VideoGuidesOffer.module.scss"; + +interface VideoGuidesOfferProps { + offer: IFunnelPaymentVariant; + isActive: boolean; + className?: string; + onClick: () => void; +} + +export default function VideoGuidesOffer(props: VideoGuidesOfferProps) { + const { offer, isActive, className, onClick } = props; + + const { key, price, oldPrice } = offer; + + const productKey = key.replaceAll(".", "_"); + + const t = useTranslations( + `AdditionalPurchases.video-guides.products.${productKey}` + ); + + const currency = Currency.USD; + + const subtitle = t.has("subtitle") ? t("subtitle") : undefined; + + const discount = Math.ceil( + (((oldPrice || 0) - price) / (oldPrice || 0)) * 100 + ); + + const emoji = t.has("emoji") ? t("emoji") : undefined; + + return ( + +
+
+ +
+
+ + {t("title")} + + {subtitle && ( + + {subtitle} + + )} +
+
+ +
+
+
+ + {t.rich("price", { + price: () => ( + + {getFormattedPrice(price, currency)} + + ), + oldPrice: () => ( + + {getFormattedPrice(oldPrice || 0, currency)} + + ), + })} + + + {t("discount", { + discount: discount || 0, + })} + +
+
+ ); +} diff --git a/src/components/domains/additional-purchases/VideoGuidesOffers/VideoGuidesOffers.module.scss b/src/components/domains/additional-purchases/VideoGuidesOffers/VideoGuidesOffers.module.scss new file mode 100644 index 0000000..f1812c0 --- /dev/null +++ b/src/components/domains/additional-purchases/VideoGuidesOffers/VideoGuidesOffers.module.scss @@ -0,0 +1,7 @@ +.container { + width: 100%; + display: flex; + flex-direction: column; + gap: 12px; + margin-top: 37px; +} diff --git a/src/components/domains/additional-purchases/VideoGuidesOffers/VideoGuidesOffers.tsx b/src/components/domains/additional-purchases/VideoGuidesOffers/VideoGuidesOffers.tsx new file mode 100644 index 0000000..867e083 --- /dev/null +++ b/src/components/domains/additional-purchases/VideoGuidesOffers/VideoGuidesOffers.tsx @@ -0,0 +1,81 @@ +"use client"; + +import { useEffect, useMemo, useState } from "react"; + +import { Skeleton } from "@/components/ui"; +import { IFunnelPaymentVariant } from "@/entities/session/funnel/types"; + +import { useMultiPageNavigationContext, VideoGuidesOffer } from ".."; +import { useProductSelection } from "../ProductSelectionProvider"; + +import styles from "./VideoGuidesOffers.module.scss"; + +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 ?? []; + }, [data]); + const [activeOffer, setActiveOffer] = useState(""); + const { setSelectedProduct } = useProductSelection(); + + useEffect(() => { + if (offers[0]) { + setActiveOffer(offers[0]?.id); + setSelectedProduct(offers[0]); + } + }, [offers, setSelectedProduct]); + + const handleOfferClick = (offer: IFunnelPaymentVariant) => { + setActiveOffer(offer.id); + setSelectedProduct(offer); + }; + + return ( +
+ {offers.map(offer => ( + handleOfferClick(offer)} + /> + ))} +
+ ); +} + +export function VideoGuidesOffersSkeleton() { + return ; +} diff --git a/src/components/domains/additional-purchases/VideoGuidesPage/VideoGuidesPage.module.scss b/src/components/domains/additional-purchases/VideoGuidesPage/VideoGuidesPage.module.scss new file mode 100644 index 0000000..e8a36d9 --- /dev/null +++ b/src/components/domains/additional-purchases/VideoGuidesPage/VideoGuidesPage.module.scss @@ -0,0 +1,23 @@ +.title { + font-size: 25px; + font-weight: 600; + line-height: 28px; + margin-top: 32px; + color: #000000; + max-width: 281px; + margin-inline: auto; +} + +.subtitle { + font-size: 16px; + font-weight: 500; + line-height: 24px; + color: #737373; +} + +.description { + font-size: 12px; + line-height: 16px; + color: #6b7280; + margin-top: 12px; +} diff --git a/src/components/domains/additional-purchases/VideoGuidesPage/VideoGuidesPage.tsx b/src/components/domains/additional-purchases/VideoGuidesPage/VideoGuidesPage.tsx new file mode 100644 index 0000000..b1db972 --- /dev/null +++ b/src/components/domains/additional-purchases/VideoGuidesPage/VideoGuidesPage.tsx @@ -0,0 +1,38 @@ +import { Suspense } from "react"; +import { useTranslations } from "next-intl"; + +import { + ProductSelectionProvider, + Progress, + VideoGuidesBanner, + VideoGuidesButton, + VideoGuidesOffers, + VideoGuidesOffersSkeleton, +} from "@/components/domains/additional-purchases"; +import { Typography } from "@/components/ui"; + +import styles from "./VideoGuidesPage.module.scss"; + +export default function VideoGuidesPage() { + const t = useTranslations("AdditionalPurchases.video-guides"); + + return ( + + + + + {t("title")} + + + {t("subtitle")} + + }> + + + + {t("description")} + + + + ); +} diff --git a/src/components/domains/additional-purchases/index.ts b/src/components/domains/additional-purchases/index.ts index 360f109..d71789b 100644 --- a/src/components/domains/additional-purchases/index.ts +++ b/src/components/domains/additional-purchases/index.ts @@ -14,3 +14,12 @@ export { ProductSelectionProvider, useProductSelection, } from "./ProductSelectionProvider"; +export { default as Progress } from "./Progress/Progress"; +export { default as VideoGuidesBanner } from "./VideoGuidesBanner/VideoGuidesBanner"; +export { default as VideoGuidesButton } from "./VideoGuidesButton/VideoGuidesButton"; +export { default as VideoGuidesOffer } from "./VideoGuidesOffer/VideoGuidesOffer"; +export { + default as VideoGuidesOffers, + VideoGuidesOffersSkeleton, +} from "./VideoGuidesOffers/VideoGuidesOffers"; +export { default as VideoGuidesPage } from "./VideoGuidesPage/VideoGuidesPage";