From 99ace176e4a51be3ec86926e4c3d53d57383e4d3 Mon Sep 17 00:00:00 2001 From: Evgenij Ponomarev Date: Wed, 20 Mar 2024 00:59:03 +0300 Subject: [PATCH] Add new screens in palmistry --- .../discount-screen/discount-screen.css | 113 +++++++++++++ .../discount-screen/discount-screen.tsx | 78 +++++++++ .../palmistry-container.css | 7 + .../payment-screen/payment-screen.css | 53 +++++- .../payment-screen/payment-screen.tsx | 50 +++++- .../premium-bundle-screen.css | 139 ++++++++++++++++ .../premium-bundle-screen.tsx | 156 ++++++++++++++++++ .../palmistry/step-upload/step-upload.tsx | 8 + .../palmistry/steps-manager/steps-manager.tsx | 18 +- src/hooks/palmistry/use-steps.ts | 4 + src/routes.ts | 4 + 11 files changed, 610 insertions(+), 20 deletions(-) create mode 100644 src/components/palmistry/discount-screen/discount-screen.css create mode 100644 src/components/palmistry/discount-screen/discount-screen.tsx create mode 100644 src/components/palmistry/premium-bundle-screen/premium-bundle-screen.css create mode 100644 src/components/palmistry/premium-bundle-screen/premium-bundle-screen.tsx diff --git a/src/components/palmistry/discount-screen/discount-screen.css b/src/components/palmistry/discount-screen/discount-screen.css new file mode 100644 index 0000000..e120a92 --- /dev/null +++ b/src/components/palmistry/discount-screen/discount-screen.css @@ -0,0 +1,113 @@ +.discount-screen { + margin: 0 auto; + position: relative; + max-width: 428px; + width: 100%; + height: 100%; + display: flex; + flex-direction: column; +} + +.discount-screen__header { + display: flex; + width: 100%; + padding: 24px 0 11px; + justify-content: center; +} + +.discount-screen__content { + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + padding: 0 32px 32px; +} + +.discount-screen__content * { + font-family: OpenSans Regular; +} + +.discount-screen__title { + font-size: 20px; + margin-top: 23px; + font-weight: 600; + line-height: 24px; + text-align: center; + margin-bottom: 24px; +} + +.discount-screen__blocks { + gap: 7px; + display: flex; + align-items: flex-end; +} + +.discount-screen__block { + gap: 12px; + width: 160px; + display: flex; + padding: 16px; + overflow: hidden; + text-align: center; + align-items: center; + border-radius: 10px; + flex-direction: column; +} + +.discount-screen__block:first-child { + border: 2px solid #c7c7c7; +} + +.discount-screen__block:last-child { + padding-top: 0; + border: 2px solid #066fde; +} + +.discount-screen__price-block { + font-weight: 600; + line-height: 24px; +} + +.discount-screen__details { + display: flex; + flex-direction: column; +} + +.discount-screen__details-name { + color: #8e8e93; + font-size: 14px; + line-height: 18px; +} + +.discount-screen__details-value { + font-weight: 600; + line-height: 24px; +} + +.discount-screen__button { + position: relative; + display: flex; + justify-content: center; + align-items: center; + width: 132px; + height: fit-content; + min-height: 38px; + background: #066fde; + border-radius: 10px; + border: none; + font-weight: 600; + font-size: 14px; + line-height: 18px; + color: #fff; +} + +.discount-screen__header-block { + top: 0; + color: #fff; + height: 32px; + display: flex; + background: #066fde; + align-items: center; + width: calc(100% + 32px); + justify-content: center; +} diff --git a/src/components/palmistry/discount-screen/discount-screen.tsx b/src/components/palmistry/discount-screen/discount-screen.tsx new file mode 100644 index 0000000..19e2115 --- /dev/null +++ b/src/components/palmistry/discount-screen/discount-screen.tsx @@ -0,0 +1,78 @@ +import React from "react"; + +import { useNavigate } from 'react-router-dom'; + +import './discount-screen.css'; + +import routes from '@/routes'; +import HeaderLogo from '@/components/palmistry/header-logo/header-logo'; + +export default function DiscountScreen() { + const navigate = useNavigate(); + + const userHasWeeklySubscription = false; + + const goPremiumBundle = () => { + navigate(routes.client.palmistryPremiumBundle()); + }; + + React.useEffect(() => { + if (userHasWeeklySubscription) { + goPremiumBundle(); + } + }, [userHasWeeklySubscription]); + + return ( +
+
+ +
+ +
+ + Not planning on looking back? + + +
+
+ €19 for
1-week plan
+ +
+ Total savings + €0 +
+ +
+ 7-day trial + yes +
+ + +
+ +
+
save 33%
+ + €12.73 for
1-week plan
+ +
+ Total savings + €6.27 +
+ +
+ 3-day trial + no +
+ + +
+
+
+
+ ); +} diff --git a/src/components/palmistry/palmistry-container/palmistry-container.css b/src/components/palmistry/palmistry-container/palmistry-container.css index 07bf13f..cabe470 100644 --- a/src/components/palmistry/palmistry-container/palmistry-container.css +++ b/src/components/palmistry/palmistry-container/palmistry-container.css @@ -572,6 +572,13 @@ position: relative; } +.palmistry-container_type_payment { + padding-bottom: 0; +} + +.palmistry-container_type_discount { + width: 100%; +} @keyframes personal-statement-fade-in { 0% { diff --git a/src/components/palmistry/payment-screen/payment-screen.css b/src/components/palmistry/payment-screen/payment-screen.css index a3569ae..a88396e 100644 --- a/src/components/palmistry/payment-screen/payment-screen.css +++ b/src/components/palmistry/payment-screen/payment-screen.css @@ -26,15 +26,6 @@ font-family: OpenSans Regular; } -.payment-screen__widget { - background: #fff; - bottom: 0; - box-shadow: 0 -2px 16px rgba(18, 22, 32, .1); - max-width: 428px; - width: 100%; - padding: 40px; -} - .payment-screen__about-us { display: flex; text-align: center; @@ -191,3 +182,47 @@ font-size: 12px; line-height: 18px; } + +.payment-screen__widget { + background: #fff; + bottom: 0; + box-shadow: 0 -2px 16px rgba(18, 22, 32, .1); + max-width: 428px; + width: 100%; + padding: 40px; + position: relative; +} + +.payment-screen__widget_success { + height: 400px; +} + +.payment-screen__success { + width: 100%; + height: 100%; + position: absolute; + left: 0; + top: 0; + background: #fff; + z-index: 99; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 30px; + padding: 40px; +} + +.payment-screen__success-icon { + width: 100px; + height: 100px; + max-width: 50%; + flex-shrink: 0; +} + +.payment-screen__success-text { + font-size: 24px; + line-height: 32px; + text-align: center; + color: #121620; +} diff --git a/src/components/palmistry/payment-screen/payment-screen.tsx b/src/components/palmistry/payment-screen/payment-screen.tsx index ac39f88..d4912a4 100644 --- a/src/components/palmistry/payment-screen/payment-screen.tsx +++ b/src/components/palmistry/payment-screen/payment-screen.tsx @@ -1,9 +1,11 @@ import React from "react"; import { useSelector } from "react-redux"; +import { useNavigate } from 'react-router-dom'; import './payment-screen.css'; +import routes from '@/routes'; import useSteps, { Step } from '@/hooks/palmistry/use-steps'; import useTimer from '@/hooks/palmistry/use-timer'; import HeaderLogo from '@/components/palmistry/header-logo/header-logo'; @@ -15,11 +17,22 @@ const getFormattedPrice = (price: number) => { } export default function PaymentScreen() { + const navigate = useNavigate(); const time = useTimer(); const activeSubPlanFromStore = useSelector(selectors.selectActiveSubPlan); + // const subscriptionStatus = useSelector(selectors.selectStatus); + const subscriptionStatus = "subscribed"; const steps = useSteps(); + React.useEffect(() => { + if (subscriptionStatus === "subscribed") { + setTimeout(() => { + navigate(routes.client.palmistryDiscount()); + }, 1500); + } + }, [subscriptionStatus]); + React.useEffect(() => { if (!activeSubPlanFromStore) { steps.setFirstUnpassedStep(Step.SubscriptionPlan); @@ -40,8 +53,8 @@ export default function PaymentScreen() {
- The #1 Astrology app trusted by over{' '} - 25 million{' '} + The #1 Astrology app trusted by over{" "} + 25 million{" "} people. @@ -114,7 +127,9 @@ export default function PaymentScreen() {
Total today - ${getFormattedPrice(trialPrice)} + + ${getFormattedPrice(trialPrice)} +
@@ -144,11 +159,13 @@ export default function PaymentScreen() {
- You will be charged only ${getFormattedPrice(trialPrice)} for your 7-day trial. + You will be charged only{" "} + ${getFormattedPrice(trialPrice)} for your 7-day trial. - Then ${getFormattedPrice(fullPrice)} ${getFormattedPrice(trialPrice)} per week. Save $ + Then ${getFormattedPrice(fullPrice)} $ + {getFormattedPrice(trialPrice)} per week. Save $ {getFormattedPrice(fullPrice - trialPrice)} every week. @@ -224,8 +241,27 @@ export default function PaymentScreen() { {activeSubPlanFromStore && ( -
- +
+ {subscriptionStatus !== "subscribed" && } + + {subscriptionStatus === "subscribed" && ( +
+ + + + +
Payment success
+
+ )}
)}
diff --git a/src/components/palmistry/premium-bundle-screen/premium-bundle-screen.css b/src/components/palmistry/premium-bundle-screen/premium-bundle-screen.css new file mode 100644 index 0000000..b015746 --- /dev/null +++ b/src/components/palmistry/premium-bundle-screen/premium-bundle-screen.css @@ -0,0 +1,139 @@ +.premium-bundle-screen { + margin: 0 auto; + position: relative; + max-width: 428px; + width: 100%; + height: 100%; + display: flex; + flex-direction: column; +} + +.premium-bundle-screen__header { + display: flex; + width: 100%; + padding: 24px 0 11px; + justify-content: center; +} + +.premium-bundle-screen__content { + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + padding: 0 32px 32px; + padding-bottom: 20px; +} + +.premium-bundle-screen__button-skip { + height: 30px; + border: none; + display: flex; + padding: 0 8px; + color: #066fde; + margin-top: 12px; + font-weight: 600; + margin-left: auto; + align-items: center; + background: #eff2fd; + border-radius: 20px; +} + +.premium-bundle-screen__title { + margin: 8px 0; + font-size: 20px; + font-weight: 600; + line-height: 26px; + text-align: center; + letter-spacing: .2px; +} + +.premium-bundle-screen__subtitle { + font-size: 16px; + line-height: 18px; + text-align: center; +} + +.premium-bundle-screen__block-description { + width: 100%; + position: relative; + background: white; + z-index: 3; + display: flex; + flex-direction: column; + align-items: center; + box-shadow: 0 0 8px #0003; + border-radius: 8px; + padding: 16px; + text-align: center; + margin: 24px 0; + gap: 12px; +} + +.premium-bundle-screen__block-description p { + font-size: 14px; + line-height: 18px; +} + +.premium-bundle-screen__list-title { + font-size: 14px; + line-height: 18px; + font-weight: 700; +} + +.premium-bundle-screen__item { + display: flex; + align-items: center; + align-self: flex-start; +} + +.premium-bundle-screen__icon { + display: flex; + width: 40px; + height: 40px; + background: #ffeede; + border-radius: 20px; + margin-right: 16px; + align-items: center; + justify-content: center; +} + +.premium-bundle-screen__subsection { + width: 100%; + padding: 12px; + border-top: 2px solid #e0e3eb; + margin-bottom: -12px; +} + +.premium-bundle-screen__one-time-price { + color: #066fde; + font-weight: 600; + line-height: 24px; +} + +.premium-bundle-screen__button { + font-weight: 500; + background: #eff2fd; + justify-content: center; + align-items: center; + display: flex; + padding: 12px 16px; + max-width: 400px; + min-width: 250px; + width: 100%; + min-height: 60px; + border: none; + border-radius: 8px; + cursor: pointer; + font-size: 18px; + line-height: 20px; + color: #121620; + position: relative; + background: #066fde; + color: #fff!important; + position: relative; +} + +.premium-bundle-screen__button svg { + fill: #fff; + margin-right: 8px; +} diff --git a/src/components/palmistry/premium-bundle-screen/premium-bundle-screen.tsx b/src/components/palmistry/premium-bundle-screen/premium-bundle-screen.tsx new file mode 100644 index 0000000..bed1891 --- /dev/null +++ b/src/components/palmistry/premium-bundle-screen/premium-bundle-screen.tsx @@ -0,0 +1,156 @@ +import React from "react"; + +import { useNavigate } from 'react-router-dom'; + +import './premium-bundle-screen.css'; + +import routes from '@/routes'; +import HeaderLogo from '@/components/palmistry/header-logo/header-logo'; + +export default function PremiumBundleScreen() { + const navigate = useNavigate(); + + const userHasPremiumBundle = false; + + React.useEffect(() => { + if (userHasPremiumBundle) { + navigate(routes.client.home()); + } + }, [userHasPremiumBundle]); + + const goHome = () => { + navigate(routes.client.home()); + }; + + return ( +
+
+ +
+ +
+ + + Get extra insights with our Premium Bundle + + + Exclusive offer: recommended for get more insights about what future + holds for you. + + +
+ What your Premium Bundle will include: + +
+
+ + + + + + + + + + + + + + + +
+ +

Guide to Modern Astrology

+
+ +
+
+ + + + + + + + + + + + +
+ +

Annual Forecast for 2024

+
+ +
+ One-time price of €19! +

Original price is €45. Save 58%!

+
+ +
+

+ These plans are yours to keep even if you decide Hint isn’t + right for you. +

+
+
+ + +
+
+ ); +} diff --git a/src/components/palmistry/step-upload/step-upload.tsx b/src/components/palmistry/step-upload/step-upload.tsx index e20db97..55674ef 100644 --- a/src/components/palmistry/step-upload/step-upload.tsx +++ b/src/components/palmistry/step-upload/step-upload.tsx @@ -52,6 +52,14 @@ export default function StepUpload(props: Props) { React.useEffect(() => { if (palmPhoto) { + fetch( + 'https://palmistry.hint.app/api/processing', + { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ image: palmPhoto }), + }, + ); setIsUpladProcessing(false); steps.saveCurrent(palmPhoto); steps.goNext(); diff --git a/src/components/palmistry/steps-manager/steps-manager.tsx b/src/components/palmistry/steps-manager/steps-manager.tsx index 11b17e8..dfc43c1 100644 --- a/src/components/palmistry/steps-manager/steps-manager.tsx +++ b/src/components/palmistry/steps-manager/steps-manager.tsx @@ -29,6 +29,8 @@ import StepEmail from '@/components/palmistry/step-email/step-email'; import StepSubscriptionPlan from '@/components/palmistry/step-subscription-plan/step-subscription-plan'; import StepPaywall from '@/components/palmistry/step-paywall/step-paywall'; import PaymentScreen from '@/components/palmistry/payment-screen/payment-screen'; +import DiscountScreen from '@/components/palmistry/discount-screen/discount-screen'; +import PremiumBundleScreen from '@/components/palmistry/premium-bundle-screen/premium-bundle-screen'; const PalmistryContainerWrapper = (props: { children: React.ReactNode, currentStep: Step }) => { return ( @@ -62,7 +64,7 @@ export default function StepsManager() { }, [steps.isInited]); React.useEffect(() => { - if (subscriptionStatus === "subscribed") { + if (subscriptionStatus === "subscribed" && steps.current !== Step.Payment) { navigate(routes.client.home()); } }, [subscriptionStatus]); @@ -72,6 +74,12 @@ export default function StepsManager() { modalIsOpen ? 'steps-manager__motion-div_no-transform' : '', ]; + const nonSliderSteps = [ + Step.Payment, + Step.Discount, + Step.PremiumBundle, + ]; + return (
{steps.currentNumber >= steps.progressBarRange[0] && steps.currentNumber <= steps.progressBarRange[1] && ( @@ -79,13 +87,15 @@ export default function StepsManager() { )}
- {steps.current === Step.Payment && ( + {nonSliderSteps.includes(steps.current as Step) && ( - + {steps.current === Step.Payment && } + {steps.current === Step.Discount && } + {steps.current === Step.PremiumBundle && } )} - {steps.current !== Step.Payment && ( + {!nonSliderSteps.includes(steps.current as Step) && ( [host, "palmistry", "subscription-plan"].join("/"), palmistryPaywall: () => [host, "palmistry", "paywall"].join("/"), palmistryPayment: () => [host, "palmistry", "payment"].join("/"), + palmistryDiscount: () => [host, "palmistry", "discount"].join("/"), + palmistryPremiumBundle: () => [host, "palmistry", "premium-bundle"].join("/"), birthday: () => [host, "birthday"].join("/"), didYouKnow: () => [host, "did-you-know"].join("/"), freePeriodInfo: () => [host, "free-period"].join("/"), @@ -289,6 +291,8 @@ export const hasNavbarFooter = (path: string) => export const withoutHeaderRoutes = [ routes.client.palmistryPayment(), + routes.client.palmistryDiscount(), + routes.client.palmistryPremiumBundle(), routes.client.compatibility(), routes.client.subscription(), routes.client.paymentMethod(),