From 0f949466c40cba2bd30d68c0cb9cd67f5a1d7226 Mon Sep 17 00:00:00 2001 From: Daniil Chemerkin Date: Tue, 28 Jan 2025 00:45:05 +0000 Subject: [PATCH] develop --- .../email-marketing-comp-v1/en/male_en.json | 62 ++++++++++ .../en/male_en.json | 80 +++++++++++++ .../de/female_de.json | 0 .../de/male_de.json | 0 .../en/female_en.json | 0 .../en/male_en.json | 0 .../es/female_es.json | 0 .../es/male_es.json | 0 .../fr/female_fr.json | 0 .../fr/male_fr.json | 0 .../hi/female_hi.json | 0 .../hi/male_hi.json | 0 .../pt-br/female_pt-br.json | 0 .../pt-br/male_pt-br.json | 0 .../pt-pt/female_pt-pt.json | 0 .../pt-pt/male_pt-pt.json | 0 .../ru/female_ru.json | 0 .../ru/male_ru.json | 0 .../v1/email-marketing/circular-text-en.png | Bin 0 -> 52634 bytes public/v1/email-marketing/fire.png | Bin 0 -> 1722 bytes public/v1/email-marketing/gift.png | Bin 0 -> 2143 bytes public/v1/email-marketing/gift.svg | 23 ++++ src/api/resources/Paywall.ts | 3 +- src/auth/AuthContext.ts | 3 +- src/auth/AuthProvider.tsx | 17 ++- src/components/App/index.tsx | 18 +-- .../ChatsPath/pages/ExpertChat/index.tsx | 1 + .../pages/ExpertChat/styles.module.scss | 12 +- .../components/AdviceFromAstrologer/index.tsx | 15 ++- .../v1/components/CustomerCounter/index.tsx | 6 +- .../v1/components/FindingPartner/index.tsx | 9 +- .../components/GivePersonalizedPlan/index.tsx | 9 +- .../GuaranteedSecurityPayments/index.tsx | 6 +- .../components/InsightsRelationship/index.tsx | 6 +- .../components/MoneyBackGuarantee/index.tsx | 16 +-- .../v1/components/PriceComparison/index.tsx | 8 +- .../v1/components/PricingSummary/index.tsx | 20 +++- .../v1/components/Reviews/index.tsx | 8 +- .../components/SecretDiscountTable/index.tsx | 67 +++++++++++ .../SecretDiscountTable/styles.module.scss | 110 ++++++++++++++++++ .../v1/components/StatisticsBanner/index.tsx | 6 +- .../UnderstandingYourself/index.tsx | 6 +- .../v1/images/SVG/Blob/index.tsx | 18 +++ .../v1/images/SVG/Blob2/index.tsx | 17 +++ .../v1/images/SVG/Blob3/index.tsx | 18 +++ .../v1/images/SVG/Blob4/index.tsx | 21 ++++ .../v1/pages/MarketingLanding/index.tsx | 52 +++++---- .../EmailMarketing/v1/pages/SaveOff/index.tsx | 71 +++++++++++ .../v1/pages/SaveOff/styles.module.scss | 85 ++++++++++++++ .../v1/pages/SecretDiscount/index.tsx | 109 +++++++++++++++++ .../pages/SecretDiscount/styles.module.scss | 75 ++++++++++++ .../v1/pages/SpecialOffer/index.tsx | 20 +++- .../components/PalmIsReady/index.tsx | 8 +- .../components/PalmIsReady/styles.module.scss | 6 + src/components/PalmistryV1/data/index.tsx | 2 +- .../PalmistryV1/pages/Birthdate/index.tsx | 4 +- .../pages/ElementResonates/index.tsx | 2 +- .../PalmistryV1/pages/Email/index.tsx | 2 +- .../PalmistryV1/pages/FavoriteColor/index.tsx | 2 +- .../pages/GenderPalmistry/index.tsx | 29 ++++- .../pages/GenderPalmistry/styles.module.scss | 7 ++ .../PalmistryV1/pages/HeadOrHeart/index.tsx | 2 +- .../pages/RelateFollowing/index.tsx | 2 +- .../pages/RelationshipStatus/index.tsx | 2 +- .../pages/TrialPayment/styles.module.scss | 2 +- .../PalmistryV1/pages/WhatAspects/index.tsx | 2 +- .../PalmistryV2/components/Address/index.tsx | 10 +- .../components/Address/styles.module.scss | 1 + .../components/DiscountExpires/index.tsx | 8 +- .../components/GuardPayments/index.tsx | 4 +- .../components/MoneyBackGuarantee/index.tsx | 10 +- .../components/PalmsSayAbout/index.tsx | 43 +++---- .../components/PaymentTable/index.tsx | 24 ++-- .../components/PaymentTable/styles.module.css | 1 + .../components/PersonalInformation/index.tsx | 14 +-- .../PalmistryV2/components/Reviews/index.tsx | 14 +-- .../components/SecretDiscountTable/index.tsx | 18 +-- .../WithPartnerInformation/index.tsx | 26 ++--- .../PalmistryV2/images/SVG/Blob4/index.tsx | 8 +- .../PalmistryV2/pages/SaveOff/index.tsx | 27 +++-- .../pages/SecretDiscount/index.tsx | 36 ++++-- .../pages/SecretDiscount/styles.module.scss | 30 ++++- .../PalmistryV2/pages/TrialPayment/index.tsx | 27 ++--- .../pages/TrialPayment/styles.module.scss | 4 + .../Payment/nmi/PaymentForm/index.tsx | 9 +- .../v1/components/PrivacyPolicy/index.tsx | 5 +- .../TrialPayment/components/Header/index.tsx | 6 +- .../components/Header/styles.module.css | 6 +- src/components/pages/Auth/index.tsx | 22 +++- .../authentication/use-authentication.ts | 20 ++-- src/hooks/chatsSocket/useChatsSocket.ts | 48 ++++++-- src/hooks/paywall/defaultPaywalls.ts | 58 +++++++++ src/locales/index.ts | 38 ++++-- .../ABDesign/v1/LayoutSession/index.tsx | 4 +- .../MarketingLanding/v1/index.tsx | 10 ++ src/routerComponents/Palmistry/v2/index.tsx | 32 ++--- src/routes.ts | 2 + src/store/paywalls.ts | 2 + 98 files changed, 1342 insertions(+), 294 deletions(-) create mode 100644 public/locales/email-marketing-comp-v1/en/male_en.json create mode 100644 public/locales/email-marketing-palmistry-v2/en/male_en.json rename public/locales/{palmistry-v1.1 => palmistry-v1_1}/de/female_de.json (100%) rename public/locales/{palmistry-v1.1 => palmistry-v1_1}/de/male_de.json (100%) rename public/locales/{palmistry-v1.1 => palmistry-v1_1}/en/female_en.json (100%) rename public/locales/{palmistry-v1.1 => palmistry-v1_1}/en/male_en.json (100%) rename public/locales/{palmistry-v1.1 => palmistry-v1_1}/es/female_es.json (100%) rename public/locales/{palmistry-v1.1 => palmistry-v1_1}/es/male_es.json (100%) rename public/locales/{palmistry-v1.1 => palmistry-v1_1}/fr/female_fr.json (100%) rename public/locales/{palmistry-v1.1 => palmistry-v1_1}/fr/male_fr.json (100%) rename public/locales/{palmistry-v1.1 => palmistry-v1_1}/hi/female_hi.json (100%) rename public/locales/{palmistry-v1.1 => palmistry-v1_1}/hi/male_hi.json (100%) rename public/locales/{palmistry-v1.1 => palmistry-v1_1}/pt-br/female_pt-br.json (100%) rename public/locales/{palmistry-v1.1 => palmistry-v1_1}/pt-br/male_pt-br.json (100%) rename public/locales/{palmistry-v1.1 => palmistry-v1_1}/pt-pt/female_pt-pt.json (100%) rename public/locales/{palmistry-v1.1 => palmistry-v1_1}/pt-pt/male_pt-pt.json (100%) rename public/locales/{palmistry-v1.1 => palmistry-v1_1}/ru/female_ru.json (100%) rename public/locales/{palmistry-v1.1 => palmistry-v1_1}/ru/male_ru.json (100%) create mode 100644 public/v1/email-marketing/circular-text-en.png create mode 100644 public/v1/email-marketing/fire.png create mode 100644 public/v1/email-marketing/gift.png create mode 100644 public/v1/email-marketing/gift.svg create mode 100644 src/components/EmailMarketing/v1/components/SecretDiscountTable/index.tsx create mode 100644 src/components/EmailMarketing/v1/components/SecretDiscountTable/styles.module.scss create mode 100644 src/components/EmailMarketing/v1/images/SVG/Blob/index.tsx create mode 100644 src/components/EmailMarketing/v1/images/SVG/Blob2/index.tsx create mode 100644 src/components/EmailMarketing/v1/images/SVG/Blob3/index.tsx create mode 100644 src/components/EmailMarketing/v1/images/SVG/Blob4/index.tsx create mode 100644 src/components/EmailMarketing/v1/pages/SaveOff/index.tsx create mode 100644 src/components/EmailMarketing/v1/pages/SaveOff/styles.module.scss create mode 100644 src/components/EmailMarketing/v1/pages/SecretDiscount/index.tsx create mode 100644 src/components/EmailMarketing/v1/pages/SecretDiscount/styles.module.scss diff --git a/public/locales/email-marketing-comp-v1/en/male_en.json b/public/locales/email-marketing-comp-v1/en/male_en.json new file mode 100644 index 0000000..bc527a1 --- /dev/null +++ b/public/locales/email-marketing-comp-v1/en/male_en.json @@ -0,0 +1,62 @@ +{ + "marketing-landing": { + "title": "Special Offer!", + "description": "Everything for free. Trial include!", + "title-hey": "Hey, Sun 👋", + "description-hey": "Your wellness and happiness are key for us!", + "title-highlights": "Highlights of your plan:", + "button-continue": "Continue", + "plan-includes-title": "Your plan also includes:", + "plan-includes-unlimited-horoscopes": "Unlimited daily / weekly / monthly / yearly horoscopes", + "plan-includes-astrology-lessons": "Astrology lessons and articles inside the app", + "plan-includes-lifestyle-calendars": "Beauty / health / travel and more calendars", + "plan-includes-compatibility-check": "Compatibility check with zodiac signs inside the app", + "personalized-plan-title": "So we decided to give you your personalized plan and access to the trial of our app", + "personalized-plan-free": "FOR FREE!", + "personal-astrologer-advice": "1:1 Advice from your personal astrologer", + "finding-compatible-partner": "Finding the most compatible partner", + "relationship-patterns-insights": "Insights into your relationship patterns, and emotional and sexual needs", + "better-understanding-yourself": "Better understanding of yourself and your needs", + "old-price-label": "OLD PRICE", + "new-price-label": "NEW PRICE", + "review-1": "Horoscope tells realistic facts about day to day life, which can be easily relatable. It shows direction.", + "review-2": "It makes me feel safe, seeing, warm and smart.", + "review-3": "I love that we have the \"my profile\" option. I love learning about myself.", + "circular-text-image": "circular-text-en.png", + "statistics-banner-text": "Last week alone got this relationship guide", + "statistics-banner-count": "+ people", + "money-back-guarantee-title": "Money-back guarantee", + "money-back-guarantee-text": "We are convinced that we will help you get a deeper understanding of your partner and how you can improve your relationship. After all of our stellar customer reviews, we are ready to return your money if you feel that this report doesn't provide any value. Find more about applicable limitations in our Money-back policy.", + "guaranteed-security-payments": "Guaranteed security payments" + }, + "special-offer": { + "title": "Special Offer!", + "start-trial": "Start your -day trial", + "cancel-anytime": "No pressure. Cancel anytime", + "policy": "By continuing you agree that if you don't cancel prior to the end of the -days trial, you will automatically be charged every 2 weeks until you cancel in settings. Learn more about cancellation and refund policy in Subscription terms", + "button-continue": "Continue", + "pricing-summary-total-today": "Total today:", + "pricing-summary-code-applied": "Code applied!", + "pricing-summary-cost-after-trial": "Your cost per 2 weeks after trial", + "pricing-summary-trial-description": "You will be charged only for your -day trial. Subscription renews automatically until cancelled. You can cancel at any time before the end of the trial." + }, + "save-off": { + "title": "SAVE % OFF!", + "instead": " instead ", + "instead-old-price": "of ", + "trial-duration": "-day trial", + "discount-offer": "% off on your personalized plan", + "button-trial": "GET -day trial" + }, + "secret-discount": { + "title": "You get a secret discount!", + "button-trial": "GET -DAY TRIAL", + "policy": "By continuing you agree that if you don't cancel prior to the end of the -days trial, you will automatically be charged for the introductory period of 14 days thereafter the standard rate of every 14 days until you cancel in settings. Learn more about cancellation and refund policy in Subscription terms.", + "secret-discount-table_title": "You get a secret discount!", + "secret-discount-table_subtitle": "No pressure. Cancel anytime.", + "secret-discount-table_discount-applied": "Secret discount applied!", + "secret-discount-table_cost-after-trial": "Your cost per days after trial:", + "secret-discount-table_you-save": "You save ", + "secret-discount-table_total-today": "Total today" + } +} \ No newline at end of file diff --git a/public/locales/email-marketing-palmistry-v2/en/male_en.json b/public/locales/email-marketing-palmistry-v2/en/male_en.json new file mode 100644 index 0000000..c28a80c --- /dev/null +++ b/public/locales/email-marketing-palmistry-v2/en/male_en.json @@ -0,0 +1,80 @@ +{ + "trial-payment": { + "transform_your_life": "Transform your\nlife with the Power\nof Palmistry — Get your\npersonalized plan today", + "get_trial_days": "GET -day trial", + "personalized_reading_ready": "Personalized Palmistry\nReading is ready!", + "hands_reveal_title": "What your hands and fingers can reveal about you", + "hands_reveal_description": "Your hands and fingers are like a personal storybook, with each line representing a chapter of your life.", + "prepare_personalized_plan": "We will prepare your\npersonalized plan", + "aura_users_stories": "Here are a few stories from\nAURA Users", + "as_featured_in": "As featured in", + "discount_expires": "Discount expires", + "min": "min", + "sec": "sec", + "payment_table_special_offer": "Special offer", + "payment_table_title": "Personalized plan for ", + "payment_table_total_today": "Total today", + "payment_table_cost": "Including 1-week trial personal reading", + "guaranteed_security_payments": "Guaranteed security payments", + "policy_link": "Subscription policy", + "subscription_policy": "You are enrolling in 1 week subscription. By continuing you agree that if you don't cancel prior to the end of the -day trial for the you will automatically be charged every 1 week until you cancel in settings. Learn more about cancellation and refund policy in ", + "money_back_guarantee_title": "100% Money-back Guarantee", + "money_back_guarantee_text": "We are convinced that we will help you get a deeper understanding of your partner and how you can improve your relationship. After all of our stellar customer reviews, we are ready to return your money if you feel that this report doesn't provide any value. Find more about applicable limitations in our Money-back policy.", + "palms_say_about_point5": " is a symbol of vitality, holds clues about your health, energy, and passion for life", + "palms_say_about_point5_color": "Life line", + "palms_say_about_point3": " reflects intellectual pursuits and mental strengths", + "palms_say_about_point3_color": "Head line", + "palms_say_about_point7": " reveals insights into your financial potential and approach towards wealth", + "palms_say_about_point7_color": "Fate line", + "palms_say_about_point1": " can reveal insights into your romantic journey, mapping your heart's desires", + "palms_say_about_point1_color": "Love line", + "palms_say_about_point9": "Each finger is a pillar of your personality, from leadership and ambition to creativity and self- expression", + "zodiac_sign": "Zodiac sign", + "zodiac_signs_aries": "Aries", + "zodiac_signs_taurus": "Taurus", + "zodiac_signs_gemini": "Gemini", + "zodiac_signs_cancer": "Cancer", + "zodiac_signs_leo": "Leo", + "zodiac_signs_virgo": "Virgo", + "zodiac_signs_libra": "Libra", + "zodiac_signs_scorpio": "Scorpio", + "zodiac_signs_sagittarius": "Sagittarius", + "zodiac_signs_capricorn": "Capricorn", + "zodiac_signs_aquarius": "Aquarius", + "zodiac_signs_pisces": "Pisces", + "gender": "Gender", + "male": "Male", + "female": "Female", + "date_of_birth": "Date of birth", + "place_of_birth": "Place of birth", + "reviews_username1": "Rebecca Bauman", + "reviews_tagline1": "\"It’s changed my life!\"", + "reviews_text1": "I'm thankful for this app and Akho! She's an excellent palm reader and astrologer—clear, thorough, and reassuring. I eagerly look forward to more sessions with her!", + "reviews_username2": "Mika Ryan", + "reviews_tagline2": "\"After years of seeking, I’ve finally found a true love.\"", + "reviews_text2": "I was hesitant about whether it was really worth trying, but now I have no regrets and I'm enjoying my new relationships!", + "reviews_username3": "Amanda Holmes", + "reviews_tagline3": "\"I’ve found a job I really enjoy.\"", + "reviews_text3": "Thanks to Vladana, I've finally discovered a clue about what my life's purpose really is and what kind of job resonates with me better!", + "copyright": ", Wit Apps LLC,
2108 N ST STE 5446 SACRAMENTO, CA 95816, US" + }, + "save-off": { + "title": "SAVE % OFF!", + "instead": " instead ", + "instead-old-price": "of ", + "trial-duration": "-day trial", + "discount-offer": "% off on your personalized plan", + "button-trial": "GET -day trial" + }, + "secret-discount": { + "title": "You get a secret discount!", + "button-trial": "GET -DAY TRIAL", + "policy": "By continuing you agree that if you don't cancel prior to the end of the -days trial, you will automatically be charged for the introductory period of 14 days thereafter the standard rate of every 14 days until you cancel in settings. Learn more about cancellation and refund policy in Subscription terms.", + "secret-discount-table_title": "You get a secret discount!", + "secret-discount-table_subtitle": "No pressure. Cancel anytime.", + "secret-discount-table_discount-applied": "Secret discount applied!", + "secret-discount-table_cost-after-trial": "Your cost per days after trial:", + "secret-discount-table_you-save": "You save ", + "secret-discount-table_total-today": "Total today" + } +} \ No newline at end of file diff --git a/public/locales/palmistry-v1.1/de/female_de.json b/public/locales/palmistry-v1_1/de/female_de.json similarity index 100% rename from public/locales/palmistry-v1.1/de/female_de.json rename to public/locales/palmistry-v1_1/de/female_de.json diff --git a/public/locales/palmistry-v1.1/de/male_de.json b/public/locales/palmistry-v1_1/de/male_de.json similarity index 100% rename from public/locales/palmistry-v1.1/de/male_de.json rename to public/locales/palmistry-v1_1/de/male_de.json diff --git a/public/locales/palmistry-v1.1/en/female_en.json b/public/locales/palmistry-v1_1/en/female_en.json similarity index 100% rename from public/locales/palmistry-v1.1/en/female_en.json rename to public/locales/palmistry-v1_1/en/female_en.json diff --git a/public/locales/palmistry-v1.1/en/male_en.json b/public/locales/palmistry-v1_1/en/male_en.json similarity index 100% rename from public/locales/palmistry-v1.1/en/male_en.json rename to public/locales/palmistry-v1_1/en/male_en.json diff --git a/public/locales/palmistry-v1.1/es/female_es.json b/public/locales/palmistry-v1_1/es/female_es.json similarity index 100% rename from public/locales/palmistry-v1.1/es/female_es.json rename to public/locales/palmistry-v1_1/es/female_es.json diff --git a/public/locales/palmistry-v1.1/es/male_es.json b/public/locales/palmistry-v1_1/es/male_es.json similarity index 100% rename from public/locales/palmistry-v1.1/es/male_es.json rename to public/locales/palmistry-v1_1/es/male_es.json diff --git a/public/locales/palmistry-v1.1/fr/female_fr.json b/public/locales/palmistry-v1_1/fr/female_fr.json similarity index 100% rename from public/locales/palmistry-v1.1/fr/female_fr.json rename to public/locales/palmistry-v1_1/fr/female_fr.json diff --git a/public/locales/palmistry-v1.1/fr/male_fr.json b/public/locales/palmistry-v1_1/fr/male_fr.json similarity index 100% rename from public/locales/palmistry-v1.1/fr/male_fr.json rename to public/locales/palmistry-v1_1/fr/male_fr.json diff --git a/public/locales/palmistry-v1.1/hi/female_hi.json b/public/locales/palmistry-v1_1/hi/female_hi.json similarity index 100% rename from public/locales/palmistry-v1.1/hi/female_hi.json rename to public/locales/palmistry-v1_1/hi/female_hi.json diff --git a/public/locales/palmistry-v1.1/hi/male_hi.json b/public/locales/palmistry-v1_1/hi/male_hi.json similarity index 100% rename from public/locales/palmistry-v1.1/hi/male_hi.json rename to public/locales/palmistry-v1_1/hi/male_hi.json diff --git a/public/locales/palmistry-v1.1/pt-br/female_pt-br.json b/public/locales/palmistry-v1_1/pt-br/female_pt-br.json similarity index 100% rename from public/locales/palmistry-v1.1/pt-br/female_pt-br.json rename to public/locales/palmistry-v1_1/pt-br/female_pt-br.json diff --git a/public/locales/palmistry-v1.1/pt-br/male_pt-br.json b/public/locales/palmistry-v1_1/pt-br/male_pt-br.json similarity index 100% rename from public/locales/palmistry-v1.1/pt-br/male_pt-br.json rename to public/locales/palmistry-v1_1/pt-br/male_pt-br.json diff --git a/public/locales/palmistry-v1.1/pt-pt/female_pt-pt.json b/public/locales/palmistry-v1_1/pt-pt/female_pt-pt.json similarity index 100% rename from public/locales/palmistry-v1.1/pt-pt/female_pt-pt.json rename to public/locales/palmistry-v1_1/pt-pt/female_pt-pt.json diff --git a/public/locales/palmistry-v1.1/pt-pt/male_pt-pt.json b/public/locales/palmistry-v1_1/pt-pt/male_pt-pt.json similarity index 100% rename from public/locales/palmistry-v1.1/pt-pt/male_pt-pt.json rename to public/locales/palmistry-v1_1/pt-pt/male_pt-pt.json diff --git a/public/locales/palmistry-v1.1/ru/female_ru.json b/public/locales/palmistry-v1_1/ru/female_ru.json similarity index 100% rename from public/locales/palmistry-v1.1/ru/female_ru.json rename to public/locales/palmistry-v1_1/ru/female_ru.json diff --git a/public/locales/palmistry-v1.1/ru/male_ru.json b/public/locales/palmistry-v1_1/ru/male_ru.json similarity index 100% rename from public/locales/palmistry-v1.1/ru/male_ru.json rename to public/locales/palmistry-v1_1/ru/male_ru.json diff --git a/public/v1/email-marketing/circular-text-en.png b/public/v1/email-marketing/circular-text-en.png new file mode 100644 index 0000000000000000000000000000000000000000..8605ac0b4658c718668adbdf9ace53117906df6f GIT binary patch literal 52634 zcmV)?K!U%CP)z$K0g*!lfpz~yH{ zV#f$4#vpJ3Oz2=FQ49zRB!TLw-sw)#-RbV$+y8uKXLe_1XSTfe?sSsg_q2Muv(t8W z_OstM-yx(-Whzsd%2cK@jXb%o>+oNZV1^^uU}^wFw0b?LzyH|(iep# zkdQ$z1bkXwZL8_%=%}4N zdv>+lJ_!I;{F=a%U6;mT%G@v^!H0sBsZ3=$_(^Es!qxNgsSXo}Ds84KY6X02oe(-+z z04jl}iR)CjOxzD0C?(OHkTPdkrZOFnY7;=>4iSaaZB|IEN=VIRQX2;0b`k z?|8mVpxeZTh6eV_w@LN&^^@>Rx5@fO&rLR^Yvm?N+XPcA-j zrU1=aNe#fjQo2{V?$RWFmpRIVh{_M~z$fJy(ihgb`R1DyJ(-r*-zW#@bar+U3WQEB zm&@$fv4ga=wK-i~T?#iuL5B47^!NZk0m<33XOB{6U0t2i*Vl(%DCL;mvcJFIvGmia zsj0!SE2j?(3=p11a306>*QLL1ZEY=~_2~*f7ww@fN_pBo((?F^_R-~ibVZ%w96x6J zl;b4b-Q6q?1xt7P_U*2e$Fvdsm)>)i-g9x?=!`2}b6H7w08$wk4@_c40r~<8AY^I$ z8~}_^vCvt$a-~RDfD%Bsb?erUuOR@C`wX%=cJJPu5p@dSqX5O~5}=1;x}TBzCi)<^ ziJj`|YL>8X-#**86X~wVPxBHfO$HfuOo0=C>T)2>Yk5N(<&FAw~6nv^E zXjW1ntQJJ~Yv_-#0{fz9RaI5BwqH#_u7;Mc(elchVqK>BtL3`rZ>=~d(kK|#@L$#k z^hNXszvwgFeB%oRMc=SQuajLX-Pk>#*Iz-eJLGmm?^y-qq<#NO3W!;3{CQ+3C^9E? z{tR@dcBnSWy2t~J$`5Pok2TD=XPG4Gj%ppWqjn zun(fg{>Ah2L?fSburA~{Q= zww^rYCRrWy-n#VOvVE$OaH&cHoMfJJk%SmTa0-wFBDdi7UEwd~lwZTKM&&0mMo7FY zL=%&dz(r-j-Lo`shVofSKn2>gyAU3XpkepB)1*Axd+Q^z+dVNFL%h1<5=GNd;^vH|bIxr4GWTc3o-& zV?g-JU;fgh7AVsgqB1a!0pi93aTwwRDThcnhv-nQLR)VQzH)R3Q_fqEH8haCS#7iU#9&;Wndfw z#DP&4LqUv70~k^fje(OUCTFO4=TPy^2Q?W8>5H7@Mv@E%#0o+}Gh6_E843=p4E86s z9o2O7oXh9e)s34{S2J!-U2W?L*{lkF#P4j(SKF|llsgvH(bj0EBp3~AiV{SwJqTaozu& zF=Ixaa{M7TB8b{t%qCKL*^<2> zm7yY>5e)fOA&J8b6gd!P0fe&;zi@8*_~Xv3scD*1UEO$stkq5eZGEAK1YBZX+j3k#sQ@JhNyb$+H#g_0)tiCi zgb5S!6%`fWB7OHC;rc_zg9|YmzLDt1O*h@-O82x3kfTIpU>sr6I3dMa%XLjUcj!nC z*RrUb;f~dQcrVJaWVyaj5B;Tt<9gR|*UW97eB6T8rfFwXRMgJNP{W6*uVx@L50PX5 zD7z)f`Ss(Gq-5@ccA)gi?;G6xLie8aPi)!xr{&MRaK|db!HJN zCkhu>S67#XgEjH|4rLI`O5$;rbA`>|3a3su?#%ke_KPx(XZ;O#&M|d2oG%sx3lpUa z5uf9zaIxC8)~6Fh@BV>ZFKp~w@xaq7ZdoCWHzWW*owLkQkjzt%l+Wp+HcRX1=x{e~ z+?c1*gS&F&N*y2-SD&(*&&W~v&W;da+)^=!%}N0vQY$69*TT9?w+wv=9QqR205K~W zQotQ%C>J6ewH1yKzlTkl-#p{+bLUQ*bmF4g`thghV3OHp6njwg2PT=m%Rp8Vot+~N(egI-bqA=6PxI?0^SMK(4z=63Jiou`rk zGuY5EAdEE(6seev88!+xDf}U0J6fiKsSJ#zCB>M+2QcFXF>MSMV(1Vd{=)FVr{#r= zD3m*_0Cz}VqzW!7GZ3VlVV0Kn!4MqcDGNS%VmdHP!xa{)OOyd`tWlvNwYjX!p)!!{ z-}(54&gBn2v*Om}oRd^GZrL_*mOh6`Kava}`LRolH7?ajx;j7-;`@mE-6?aCrJ?d& zEFB3>&_9-Ds3=xt;sG5?Z)$2nII9fh8vMYp5_hNsi{+wn=B$%Gd*Y;V$DZBPJmo#i zN!l@WCS>pqj#6-h@!ViEc#ed)TnHr-t^C(4EX3^&WM>QB+MNu z;xIR+nAS&Odc${~aNVNjhN)*&S5Zr{qjx4=Ul<0c(s7T;0nlcU83~HVhf;{sQF)PX zXt@8)tzEC*{mLsp``^tw|I{OMl9YoS=I%ekTo1{>Q;66^vVO}VHnAINK>4xqK{`;W zeCLWFZN`c+&lnrkAu1wsb8~aHrw3jiAw6LT2*v)HCw*oiGomz1zBuDhYqIpjN(F|c z6Qh$4C;h8pgGp1m&50)+6$+YeLHU@dP4c^;k9=X}e^4%RDY!_XhZMj5MmfV_s!s8Z zH;DX0$Bt~!VO%9O(hwMFgtIsa08y1KGqezd5ZL`+Vf$DS{`jC^J+X&Dnb?L?nV2$bQx z;XDKTdSBSG{ZGGmy&4s^y10u<@S_5q4iTyBB5+}eEDqRMRT z5k%BX;<>{p&aikOEDQi0uTtDR?{|L?Z`BsZia2TO6@tc$Yf9*G46Q-a<|2bplwNRAdAV_MEK zsW@#rKb+gw*}3D@AFo~izsuiT``ZnIi{v^;wr|iu`l9uuNt5zaWy3^lDqiQg52U_{ zM&p_1L!8RMXeY-28iE@n{MX@Jq6qGwuVXCx9m;ElRKmhMvF)gqQx{S|Y@&b&R~rp= zY=Bq{cbJqbj2sv-K$r;loTMjouFJLOOZcjbux60}nhG$J1E4uiu%F8fZrRnd@qt&@ z{A%gSRrhZso`{VAl|ui>ILi9^`e95#g>)WCj(fm2_@4PGowLve7BT z3W5SyoG^RqkxNo@lBFe`w{_KI*H+4Q!T@fT8iFEjMBhw#WDat$vuF3l2cKU4-T&IO z<>g&SqT^>6Za&~50g7}R=Cf&Jzer^h+#}{-V@(@57Gznxwo@4xH8KQ@)wx9I5()hx z`}2~i#V|uHhFKmFTX2YM`2a~|1|YWDMCK?RVsddg`8jinU(k@(XaOn+0LPRlEdyrK zdJ=P!$vH(EmpPmt?CjkB%8ws-_=cq<07u3_QUlE}*F_G~v6tgfeVC}tx15+_h+|AL zm^pK1UIIsqamH1a4Kym1?*=D5SS+8lBCN`6<35SDpbfI9T%m6lp7xbqZ=TMO=Gs z!#M!tmhG>?NOM0`!!T}903=aee*CG3)Owv0)@vT>Om_7lQUo6s-mJ_$22=({k4#7+ zI7Rl$xkM#+LqkIYvnW{OlYnFtZyBeHG@Yk9$j&EMeDC_#-*{jH3G|N)3^@lW zxJSl0QbS-4)@#W)1I{tOV#NxZVWv#v5C=wyOLX}H>i+sFh>eIHu?ioNI7Dg@%<`4x z#1uZvX;xO=n?C7;*3(b=#~T{zCtmC~7^6qjLNyxF{@{w&eun9WK0tB{w$3>U(OM3BrU%j$6}x4tWOZEXcrd<(-0;}GG8hW+=Q|ASBXdPGqZNdkz; z(j&_djiSWl2(HiyU51$7l`` z3x)0KS+``#16Tckj=kZbp&{9VJuGdyfrbGj{rDpsnhWj`(Zlb#=bpS46xSh#C>ME1 zbBrX=ANu>?6eTWEcDq5K*la$Zui!q3!XFV%xm9eo%1NJj=d5XG-B4Lsr#NSOyJ2py zI6&07KmE!gxI@QO-ezSkfP>U>jtxroey6iayT%&yrhEHl?`v_R^ndm?XU) z;XWAa@t=`00{l%pZ__i^uL%adv)*~*y?=Gt-JhN}_x*=qOj41$nu20A@y02}E|Y91 zKr+`cZOd%iwoT~M<(XZq5!XHRu+brh7)g3X{S67lMWmpZ?d|Plx!&XEYbS)H(IY0eGCSH?Ka-S02gERUV=HSsubs7@atbLm>XhiM zE+7P1w3uuGQHPj8GBrR3=X8MF-M96@KfU&gAHKeJ>3T``s93QL;5f`H$caU{L<5If zK#D^R80G7gxkIEgk%EJw?~lkM;8ar4#5b})muTV=(^#96fuey+jMN>b2g9&lF+B(- z8AP>pS#sKt{a^fa14%`)F({?jm!7k<+awACN!xi5 z{6VWFI33SH=JNYGSFe5etB*eS&F7(aq)9`<_mO_^2c=mvM$0wVJ06lQJy~)H5MR2~ zdHnImZDO+zgc1NUJtDP4S3$Rk{lg|NXnW7O-~RiKNee!gak7mv)SAG>q$4ux5$!r9 z1Qq^WWJ@rcSRVZR4xRwk`YAa#H!>VV8X1;LmI9mjrkbX;fXN8h1f~L#|J(I&$Ws zj)m{I`r9Vsiq;(AZ7ON0b&Et!RzXd=GNN9rV=NOoC#4cgJEmL!wJFnT$+D-r7#P0y z%BhSK6x6k2kbM8!Ye?75L1TTdzSv8q((<$CHc(KlApLzg{~Xdl%bxCz1;c2upD0`~ z_R+_-aaHUWZEo7ouN82u*X-3njMw9pQ*-KlW1OJG&BmSg+I9@(f)^PB;S*yvZZ68c2KxkfsGD&P0++y9Dwd9P05ml&^0G^I)D zN|FH(qtdl=#`6il&;~mfUN)Hl3^Kg)ls1+Ikr*5x(((JZpP5Cz_K$xymVe@r9pu7G zC$as7r?j$T5I|7?>?;&JNeu9*WCFFI{F&!XU~TFE{`>p4lINf4;sp$VCmE6)TZ4;QUS7)S-I}`v(Hk-}u+O-Son-i>RNcHao;7Ga0jHY+=+dkOnpmf&}L1ei*PKGZ^ z#W+MPH$Ws#ksDdSDS|VsOOx}8D$`Q9t1D4ZgG(Z>&b zd>XqBqkE2HzE7qWLwQ5Fg0W(JW`vmAk9hu$R=Yf|qTIkTnQX(P3G+UA`9*hr8e4@66BwX6s(_ms43U&$#4^7yQfBzVZbV35g2+Kg2cwQrd`7cErziqHw70is zHgDeS$48|46odiu{Sv9(MeJA4oqf?^=bZe7pVZd0p5)i+HxLFuwRvJqGY(uoTS`Do zqQ|m=Ct+gkRoBiSSA3X)#Q77Ls9aZ{C9B`q8+y@E@9ZNRSQ*eyzW+AazGcuqyMApy zIpxeYQdyayIxCmFw5*31V3q;j!c$urI6d*mPBKjMzMFD%IDTnaFIn~49wO^olWg++ z7HI%OfFFJV=>PUFYsjO&-9fkQq=u%=m{~^-quaBOcdmu9`Iy-=&c9&qz^L#e@bBMV zO}_HEmF!m-O`wwlSn2h4Nn&noZAQ61M-sKsP82PBW*7Sfc+KLVgR+}9%3xc}MwpRE z)C(|{`#R8{rz(KA$WOn&p0#P>SV$DTao*tld zFaV?fMgSDK8v%48>=)@&Pr@Fmh>8P!Vt;=>141?upii9ij&UEn?4B==Z<+nqO3j35 z06{`uVv#0yM-}xPy-I$df}B@0>ZNeB{t%)Af(Z}>t&w~O;WzlZ`?rv_tNO^Uox|)G z7G?RoUc=@M1OEOjDpu=&A{#iOfJ<}(Gqafi3f6V00wYjrPe=n%X$+BQ5!=tt0Wykvl#il6 z*sxm9y!ylM|DT(v-fl^!+ol4%#7@r^qg>L*<6*J=Pob%05oi2Pt0Krx0( zG!6Jry51hIGxQQl=lc8eiet45MxgE;!@hB3AqNI=eb@jHLJU5W8CZhW+QwHh4iF^j z&`H#@_KiLY(tRxLm=iq49AK&I3=7>r;0i%1Sj+d#ws~A)Al~l^ee{k!zL}i|XN~(| z#ifuc?KZD^2|@+H!DTj&Qj4?#80f$wyJrv zE}8bu6Rx@4KG)gy@zX&v7-&SRC+Vk{|)$OM(`2TLF zpOWidS#|GvuL_p|AHtJmG8wXKm!}44Yin~59h@6tP*GkuecyD`O=9WR19l4GfeMV` zDYJ*h-En+wky@W&Rm;)`$8;jlDN6o{czdBwsXX(f&%JZb%nQD0_fM3-Ndr9lu~sgq zK&?A9AcnaS=nA1Tl(`~+-ZAr=nbkO4hxanWg#`qz=hYW?D}5K7maW}2lpAb2rNz@H z(o>gRIaxUm!^ZMwdm`%qfot^Z^!J^ZUsHYNJkVpFe(pGSZ*Kg;EOOsHTbNi4P`u!h z2`mqcGIC!9NG?3Z6Ys(KcJCY}GN{NOl_wtFNzDC<05-27rGy(g7Y5r%Uq`=LGeA22 z^gzvO$`rJ34qwf(bM8#)^f}?-4^ZC5|#mq?y#0ie&fSy-< zpaP@ME^?<+0g7xJ8XC%QP{f+fm2lifAP9&DaL)ln4cbIDi4A~u z|B@}_(#4ZWD;4uUdi^xzJUB`nz;T`6FvUGs&W%L;Ec;)8CeuB34TU&k!HI$EMm@}0 zPq}bm*itw;egO)chQO197ST9S4IqOwFN#kHOby(l=zG9DdTC%3=FVPpTXW0I@80{n zYkn>+o`NGdN91w9IW{*p5BK!+uqyld`UnL_GI65!T=^`Sph(#wm*E zIE0JNJ9g~AdMt3qVL@f9tE*WM2pC!D`O5cQ_=9U&n-0HPt}PlA?cGQMim~8ld8NJkzHLwetuIOQ51E4`ExyF z&6|DXv~yd@)Q(!F2laqzH+kYw%zDuayJX7rTK@=Y1o`?~CD4505xsoy5xMeX9sYd; zfkTHY5}uO+kn#n%+GM{N5!)nQyF#tt5MrEFV-c+b3cwLyIeGlN8>q#)@mIgU`gY1} zund?&h#51;NI_8)%!&EboNLU%m4^bQi_m3KWO629lLLSbC}5PAHkFnk04Oq$q7vI z03_kcBXlwV!vk&=!UF;rg`q_TMZ{7Br#L)3?7)2h)0Y5>!X<|OlZwV>KezseHV?=#|V@JIw zENrG4aiZgv^97L40N+phTA001Ey$gq(n~L~eJWo2KnURFk-^6_B^_1!i;oU0#>0KBWz*h3u*SakO3(Y~_tZ)(#A5jxPd~SfT(;P= zD1ZH*R)^ejoY;|(eCRkS@{R<#1u-ZtbN89jQO!UQT<+qJde;2#{Zi|{V9^9}!KI!K z7$AuI4{p45d<8k?xF)JX*hySV5M1$0pMScG{Cde|&u`SUfR-&#t=t#i8tp2_rZhtf zq16g;+_QV*lK;Bz1K**CP?iD(hihtTh6V-(aICCKNX6Tj>V0tDuBfQ+mmDA-m&k(4!r1bc7vK4*=KA*cDYX&tvYG(T z&N<3yrmwjCH8ygNblcN2%wDn?v+CKl`pR^ z*7g~>CNbw3R!`Z&`jKm1F8u8LVW=+!Tt(r)KRjdWxPH`FK$anYT=zZ?@dgKIS4A1cT&&*`c{EYL*`-Uw9yf9s_L-c!-kbC5uV1qf6CUYC-mbigwmn+AxZ0-_Fz(g5|+!XUYB?Ot-~SrZs= zwN0p|Twyo4_QqN4WdKmZ6$CE{&f~>;>G_@@%8S$wFWOBFd$D%+<`}2>0csJ22>m}l z>tyu-6jeQ=R~8~IbdqpS86L`$mshB>VC1|uAWQ@}j`pHPZF2soa!Km4BYb4v!`I+l zKR!@zP!apJm-mFa1v=+F}V9C?gtb!z?7kE^R1=FFJN#OjwQQv$Kt%)Zins%K;_ zJcl2CIHB*ZIL|5@%Odqy1xEjAKzyb*Rt_DOg&PhD#Akmg0!q~a6k%x5b&B4u3GfIp z4TM;IBGCtz_Hvm9B?l$w=3pEFsMXeI$x+8Nk$Zo!iTwA^H<1^Y?IM4EbvHTToh_c8 ziyAq+m&#H41+c`_Jpd?PE^K%S;bi^fquq>)6dX!u*gKxZb{Wm{*zdcPYt-|~*ANSW zHjs+|sS%|Vpy`-^MayBlH}nu6BUq%NlYEZrb@8!+PLX|p=yQIGTH%L>!}Y=7g=ZmV z)PUfJDfE+JP}AW{uT#Aq)5qCEMk&o9B+NYq?}Yvy)YZ1l2ROdI`hMsfSsE3o!96Nn z>h0}ysP)=iwQ3cD-3o9N+@fQ=gfT#485r3OJNoFOo!|WCH@;4hf}#jCE4V}vB1x>B zTm8Ow|KQqj&9g#=mMBovImJ}|iM*WYOReOS#sD0Q!SUgRnK84TafxCPDC7rl0`TB= zgFN0W4Al~fmk0WW(5 z>U}kxmG2v(^c+XI!zTJ+g6KTJ0^(MZlh15rA1jE~4?VzLtDNxo`uN{Y_XFyB&)wr5 z|NQEnP=EZsOFc;|TI=hh}gEa6U`hNPRx$GDQ6hy?9%hXcq@~6H$oB1qu?-(Mte04Ps;-EgZup_!13}f@f z4T%JtALFY#)()?&iLaavnE@1zO1w1&%rpn$lt|*1`V9&J|zz-4ma=kB&*oyA1B*mTIWCGhwg7|M)toe-Jx;mzzW}t|5 zS}0Xut!Ez;{YnZ2MFW|1G$bJ?Dmosbq+#ZY;0iwQvFVIUl=}X9yoscwT-1vWn&2#GvE|&y6GnN91!OX3-Dl_79RgC z+tbs7pb(hV!frYOLm()`5i{RCea_(*ek*vuaj-ivnR6V_Kzo1-%nBz-~fEQG&zj*rfCk8`HnON}9>oI}iXj97mL|$vck40FG z5`In#Pigi;wL#PtzLDk+AMr!Mc|mwpuv03RODTPIl)lRORe&Y-`Xn&ab@E5fy6Brn z%v=OtF*)X`07!oUIud{*QCf1GF%!peOc-DI>=p-$SJ91qN%(T7us~-J920Ii_4V~^ zW(yXr;uh%YW9Po_u#-=?{`PF9(sRo5u~8iiX1$_gJXWzs14Uy0%1VW_bC&w}-nK1+ zY+kcB=xf=cQ2qURzdry^%u0c^Gnh4^fmh7OAoeA95|*)*O$mH5fE4nlmrX?`aE$18 zqI*Eh*QVDbKbyrLo5~Dlh9UO=H6}COvMFSnAW?8;>$hrg~cY!ZQbRy-#i1{%2T?%6iF;7 z65DydbUIKJbT_p~i}}k}er#%}f8C)F{XvyBP>khzG%|rtIFmz?fL~HzE0pxIN!p9A z)FB0P%`xTl-eVI1E4sS|tG>Nqul zsnStJ#-s9>D&8+N7C1)6KA(N| z+5YNd_@yR(|0Zh7oHF(toa1HZ|KESEu4e#eScAQg;A%$i?rU#Lj`BYesP0U*EHZxpQH@`)n3C#G4%z z1&*RdlW1)MN4c*$fQGKjQTv>s(%aO@CysydwO>5Jmu7Xjk0Ua<+6EUM_mM{)5w*BV z=k^orH;z#(xrp^4DCrC92weozP4Hz-EBM!kx#s-EML)W>K4SiJSWgoMN#$ISNv+GV zgNG3m_1X!;BEU4M4I(&7V>vA!2-fO5ZduO)MyxRyXy7o8Iqe|mmv6si9a;NkKU1wd z`A8S@QUF2BcA~(}u{>j2eyOis`EXfnREFNQ#`;MYFJ5%lwR9H&qM1E_c!pE5hzKJl;wch!W((sMv)L@>Kv!OH`d81LI_db& z5mAzuK_`4H1B^Z}NF*rw$5EUjF@s|8GB}3*1*I?}W(9p&RIxeKv{Xi_&-P*}B@({) z1~Qh5B-1!2#0-2RLB#=QVvaItSqne{6rcJ-H(B>qKYRXi_RFrA#Aeh$2l=xfZ}j!c z{@8K6NIq}~U-nG5zfhSzCgi>CerZ)n=PZL&F5txEF;^Zc6AciKp z$407aN;q9UE{@UxWaRye;UYu%wLGAKzQEWfsFknJ4VSH8hLWhpTZTc9h_-HYNizao z=t9DIu3R6q9EV>;(p>_aY?_6IPs zi{)-P?3gdXC<9^^H?Fp}R@^*xLnk)RYdvM*-`y@RUgZ!Q=*h?47CHBsBm+e`H>UJ` z=H?^G`##W76ewB;v||Frps&W4)k&Dg0G_6Ot)TR4+P9OqKKa+Q>1CpfWw!FBx*~dJ z*-SYTd@L*g8I>nopVtT9IK!rb%I64QzQPMyf$603Du}V*=tyH<>5FNchs%fFIikKz za{JU$-FW(me}6lSF+_6T!8%NYgCZjDOVuzOz^pgE9Ba}CSyCExU=*ApH_NjN=N2gj zid6T&z8=&9UD4m)uPk|b`l+9}Mz%mZ+RJGcpG_n`MnX(nlj$p~mj@t%*wUp`fgbwG zYJJg-JtAGNH{7f`KCCaAk*hW5k?V3uM7dD=$;PP-u;ky7AQOnD14_R%(eHaWM+`v5 z<+T8$$hZ6%Z_Yc`-bO@m862;?YO3!8`Q#&ATA$_dCc~B!>R4gqYxawWsD%BOrr*j!q~zO#g{=WcPeJKRKSUw z1RnDh{6<#1_rlvg*jzt#u_&F4Qw*B4a*B>L82Lkv{9+PMd~O?G?FE!Ykl1gnCS6@a z#=POasV{Dj76pnyy`jM!$$1znRDjS<(ZG;|a~o@9<5J@RJLX%TkP_c?t0k?sB}eL?=DAWgLNa9X$z zp^WA{mVDN{{7f8;RnRLn#m~SsPajq84hGf+PD?DjWqGRba$wVTi8?ogxQC--#Q6AP|5S%M=J;#P*jL z{rH-?n(=3PHP}Eg?l>M4{bT*ST+;F4ByQWXkIa9kw_@C+$u;D~=XZss>goLmr^)HW zoUVhSL`eZL@+Gys*av`EJem}LALRR({yD{o*BDz^y%5pZ|M&Mhc>v-8KbzW*pwF0h z|Cb+{!WQUaYk<>oLqox0eU6bCAjD8HaiTCO0XT|%IDb!>a9s6^E0;V+BuI06Z%Erk|T@I)sUen`(1s?f=`}wufJz?xn@p;+zbO%=~k7xP{6 z=Qo#L|LAkye3k@@Y7O!Iq1M*cVG5MF?c28x&zm=av9R==CH*lD&$ELnSrAKXg8>OUV9Ca`@)l@rY zm?Tg5`8s|UL0J7!EOZ7i1gD97Sb-4BCx|JhO8JPfPSg}FpH$AV)f0Y4TU!sGzh&Et zzumoet5}CN4^f&*i!M0EzCO0Fxl6&(`!4 zick4t+#>Nr=;{w%cF)ZX^}&=sGbnn;iS&vk1VuUD1(!}D?`9MEi4i%#XDb8op!2E~911jQgX-zg0! zg0S$En6uhCzLH%3>BIe*FmlUU6Hd%!E`=?Ew za7<_+E5A}3Yaeb}d8lbX5rgc^3nnt_GYC4wWlwjpWll|E%tK3q$^1378McK*YFi&8 zxVjiF(p-LIxx~={Je|7|$D-}haeDgo2#&89j#92utwZjAaE;;_`dpSMFY8r_qn?+} zVZ7e(g&DrXH;gP;6iuCV>oQ}EAaIjn@hz{9`aKWY@z40}dMSRN{Cw)Mu@1(}1o!5M z!!P*asx=ROXw%j|VL_ZcWs-6f69i|7mng&cnT49-h_7E1oc~DBNR4tGJ>-Zvx^A(G zZxExaue{`EpJ{HKx>)&0vIF@mFYoglHcn9nz678M{mb8d_6YW?)3T?#$*-4ewobn~ z{oHZnwU>AMqKlbRRKNI!3}ȰNm*)na1>4CNP3-zP)`zBHtlD;;Q-Qq;DK*rwDJ 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 literal 0 HcmV?d00001 diff --git a/public/v1/email-marketing/fire.png b/public/v1/email-marketing/fire.png new file mode 100644 index 0000000000000000000000000000000000000000..1966e9a766e663a43a0315e3671c5d567c5be6b4 GIT binary patch literal 1722 zcmV;r21WUaP)3~K-MhVB&tAE<&{kSRBUWlu1jQJ|XyW59eEy{&1|QMH#Hi6k8WSbahz5N8 zrT+^WiHX1;Bxp!LqrpcI6aZdo$yAZd-z;^x%k-%+BrX%zS?DIidzz ze(BQZ&i3`qrORlX8f*F89W&`>iIPCL@6bn8>O~<66gWfgaZ*-c4#8{o6(qwdal;#&+H2(2txI1t+}OT7CIj*Q^!w?7 zfjBQ0TFC_E3W~rkMo&jLi~MgJ+C1nOE09CdsNP$C@SaZo*(YybJlrdPXr@GV`aL#0 z9K)%MV)`Qj%K<#8!PxEt7Du-<7{b{J;?#7=fVPB0r{M4c*4vZteF0yCnz0mTH_QsBfdQXHrALHAznTT?9h1xMm z%o)cd4zN8G75Fo&)69$nu&qdQo$pm03wVgBx}uBB80Mvb=2C|$$sn|8HlHU~tjH@7 zAF0A(q67_^ibTCI;Z-=e7l$=rc?^IAu2MHa%0>Fd{aQWOw^}XubjeN8RMo2jENj)5 zcx+@=I9t6sG%RbgK!%3HkXQyVXBh{=j|m76hX4s<3Ot9T*MmL}-yuYk9mN4|SxSL6 z3E?Ru5lX6-bl&sbv%+;VtoR0LnpGWR)w0l68O#_&KGZ=4t(BWaO5=~KeHE$L0tnCr z?Lm#{OrU68HYC*?P`Q>6W>w6)W^G-#|I@L(b~5#fc4K)2zGqn( zmpDTm;+>?d9tZ&oBvJb1v^L; z4v{!epx`h9Rr=oxBl(oI;hUWof-|bq&c3jCnVA@T$LyH6)#^6MTx64Kc^36#CA8Mp z^duS8&18(cM{;jjg+umEnQ!~pd-=fU_0FyfpKg<%-nG>92A^OVaT}jMr&A`McO+X- zqF`jy%D=vk9XYj)^4;6m${!BW|JBy4QG8}k&*+>=q-`3<&z01!HG2w)@h Q%>V!Z07*qoM6N<$f`&m#y8r+H literal 0 HcmV?d00001 diff --git a/public/v1/email-marketing/gift.png b/public/v1/email-marketing/gift.png new file mode 100644 index 0000000000000000000000000000000000000000..bf585603b57ecf178976f693ae87b32eccf9904d GIT binary patch literal 2143 zcmV-l2%z_gP)FjS-QT+bT~1nXTOAtKj#z_Gft21T>?W+)ysO+g}|gA4aI+UEZQH@Na} zT6l1M2~I$qK~WXtE({`Xa5&tD!5SDU4q-qPAXEl&4_ZQlqHw6y##i22_g)^PQ$O5v z=+MlSFqHU4h@E^(zgY9dJJXLnx+U{skBxg1MiLFvh8qN63WJ_hk<6q~?CpiHXiY-{ z4>e?RX&|Y!a_ITdnkloUSAFLrrIhidEuSi$+?QPAu z$Nuq`v5`L?_|b zi-f&d4Oqrv%t7sF05!)jH2*H-PGoVeG>y}9vp8ioks!*~_hhk>1XmzdN)+*gE-;{I zxIs-~WhMoSIDe%yfj&j%ULapDVnyAl0K+`5Rm>xutGi`7Vm;)m< z2Mtiv2C|k}QBd_f z+D%|M+ly5mfgZMSDrZnCBUwwCfvHL}0@nvNT=42AplYp-!xAAZirB8zFf=@j-sL%5 z>^}>=;G>vVC^7{_nivwTW>#Q!nSfbkNdGH|;uOaarKU=HF#-ouzJTKR$P-&E;zM2( zx$oMM;BMLe{Kbix%yXtCn+A)T2Q?RjB(UnG2~=}cj6TWn{)aW>hKQXEL!Bzi$_Y56 zWPOlf_|6d7FPpe9#BnBcG2=P#!**w7ov)U{<*neAPLnD0CnH5kl(}KSgK< zFpme|y$s7fsh~L?qBc%G>QvhK5Vq;z)MNmwDKL*FIiBdQW#0Og6-31VUnI(Qe)Bhg zm%!WZR8q92H?P81eTc|wAv+H>4Hh*RQ5P@{gy1B~;wDmwXXDsO8|Tk?k%$lxy3}NM zG@BtB9qxB&anL-!f8a)^79@gS#SW3Bjf7Oz98d1tBPYa2j$*3(^-=&J-;N z5OyDiam=D?to5amfK}dJC*2g>jgQ)h_5iCI1Z79Fd!huj@)QzX^8x<)s)c!@%?4Wv zOx13QF)LrjCiBzoKCIsv`>9r zAbv%Vxt3Mp5RpEm$Mr9xTso_XF2#%BGH@Lm2^prx^N+3XGah zhfRRGDbqrSjn0uuw(`olNspXliI|G^u%fzM;5R?;fJYuRqKAabatk?BA%()C`jl7y zfQDkfiVQg;)yt(&C>4sG`_W2pq8U?NQxSRvvw10Gp{Ww!$=Z}*%i4o-w8@FHqVI;?edclN@wwvECS>0_KfbP zCTVX)-d@hRy#%~ePJO*qLa7wUUIJF zQf({&ziaHw@v{5TJ1&(H-*Q!M#rw$hx=<18Auc7+VFs;D<1$>#PFwAAuIn?y_EXPR zFgg}L?s|c|`-xx4e0=Ah4{hArr#AOecge~P)R1Hq28ak)6nU#1v|Wq@DY}5=9{{1edmU*RB(Nk3W8^uW2v%E|aAg0e4DPh<4s%HMi=X&|UIn zx3+rtLl6G@_&xW2^}Cg;VO;ee%VK-^p-me`?wEe8ug7~-rB}?r3F+O=ZacuDHtdC| zBb7a=zb_lO>F1w*?X|bAXW#1rk8S_6w>>h{GyQ#y2ZP5iHQ{?99Fac|isaMVzW4Ua z_#ch6{);TMi~nZ3zPWCAMb3KR?5w4Rtnl$C&xRq{{Wnz V-u4}ka_|5E002ovPDHLkV1lc|2Cx7C literal 0 HcmV?d00001 diff --git a/public/v1/email-marketing/gift.svg b/public/v1/email-marketing/gift.svg new file mode 100644 index 0000000..1bfccec --- /dev/null +++ b/public/v1/email-marketing/gift.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/api/resources/Paywall.ts b/src/api/resources/Paywall.ts index 16a1cfe..605e948 100644 --- a/src/api/resources/Paywall.ts +++ b/src/api/resources/Paywall.ts @@ -19,7 +19,8 @@ export enum EPlacementKeys { "aura.placement.palmistry.redesign" = "aura.placement.palmistry.redesign", "aura.placement.chat" = "aura.placement.chat", "aura.placement.email.palmistry" = "aura.placement.email.palmistry", - "aura.placement.email.palmistry.discount" = "aura.placement.email.palmistry.discount" + "aura.placement.email.palmistry.discount" = "aura.placement.email.palmistry.discount", + "aura.placement.email.compatibility.discount" = "aura.placement.email.compatibility.discount" } export interface ResponseGetSuccess { diff --git a/src/auth/AuthContext.ts b/src/auth/AuthContext.ts index e7c16f6..35af7a7 100644 --- a/src/auth/AuthContext.ts +++ b/src/auth/AuthContext.ts @@ -1,11 +1,12 @@ import { createContext } from 'react' import { AuthToken, User } from '../api' +import { IUser } from '@/api/resources/User' export interface AuthContextValue { user: User.User | null token: AuthToken logout: () => void - signUp: (token: AuthToken, user: User.User) => AuthToken + signUp: (token: AuthToken, user: User.User, newUser?: IUser) => AuthToken } export const AuthContext = createContext({} as AuthContextValue) diff --git a/src/auth/AuthProvider.tsx b/src/auth/AuthProvider.tsx index 3e85add..9d87b99 100644 --- a/src/auth/AuthProvider.tsx +++ b/src/auth/AuthProvider.tsx @@ -3,6 +3,7 @@ import { useDispatch, useSelector } from "react-redux"; import { actions, selectors } from "../store"; import { AuthToken, User } from "../api"; import { AuthContext } from "./AuthContext"; +import { IUser } from "@/api/resources/User"; export function AuthProvider({ children, @@ -11,7 +12,7 @@ export function AuthProvider({ const token = useSelector(selectors.selectToken); const user = useSelector(selectors.selectUser); const signUp = useCallback( - (token: AuthToken, user: User.User): AuthToken => { + (token: AuthToken, user: User.User, newUser?: IUser): AuthToken => { dispatch(actions.token.update(token)); dispatch(actions.user.update(user)); dispatch(actions.form.addEmail(user.email)); @@ -23,6 +24,20 @@ export function AuthProvider({ ) ); } + if (newUser) { + dispatch(actions.questionnaire.update({ + gender: newUser.profile.gender ?? undefined, + birthPlace: newUser.profile.birthplace?.address ?? undefined, + birthdate: newUser.profile.birthdate ?? undefined, + partnerBirthPlace: newUser.partner?.birthplace?.address ?? undefined, + partnerBirthdate: newUser.partner?.birthdate ?? undefined, + partnerGender: newUser.partner?.gender ?? undefined, + })) + + dispatch(actions.user.update({ + username: newUser.profile.name ?? undefined, + })); + } return token; }, [dispatch] diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index 386a128..926b591 100755 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -242,21 +242,7 @@ function App(): JSX.Element { const { token } = await api.getRealToken({ token: jwtToken }); const { user } = await api.getUser({ token }); const { user: userMe } = await api.getMe({ token }); - signUp(token, user); - - dispatch(actions.questionnaire.update({ - gender: userMe.profile.gender ?? undefined, - birthPlace: userMe.profile.birthplace?.address ?? undefined, - birthdate: userMe.profile.birthdate ?? undefined, - partnerBirthPlace: userMe.partner?.birthplace?.address ?? undefined, - partnerBirthdate: userMe.partner?.birthdate ?? undefined, - partnerGender: userMe.partner?.gender ?? undefined, - })) - - dispatch(actions.user.update({ - username: userMe.profile.name ?? undefined, - })); - + signUp(token, user, userMe); } catch (error) { console.log("Error of get real token or get user: "); console.error(error); @@ -331,7 +317,7 @@ function App(): JSX.Element { } > - } /> + } /> } /> } /> diff --git a/src/components/ChatsPath/pages/ExpertChat/styles.module.scss b/src/components/ChatsPath/pages/ExpertChat/styles.module.scss index 1b87453..dcfa415 100644 --- a/src/components/ChatsPath/pages/ExpertChat/styles.module.scss +++ b/src/components/ChatsPath/pages/ExpertChat/styles.module.scss @@ -13,10 +13,14 @@ .modal { max-height: calc(100dvh - 32px); - height: 100%; - top: auto; - bottom: 0; - transform: translate(-50%, 0); + // height: 100%; + // top: auto; + // bottom: 0; + // transform: translate(-50%, 0); +} + +.modal-title { + color: #2f2e37; } .header-container { diff --git a/src/components/EmailMarketing/v1/components/AdviceFromAstrologer/index.tsx b/src/components/EmailMarketing/v1/components/AdviceFromAstrologer/index.tsx index 56f4a55..9196b35 100644 --- a/src/components/EmailMarketing/v1/components/AdviceFromAstrologer/index.tsx +++ b/src/components/EmailMarketing/v1/components/AdviceFromAstrologer/index.tsx @@ -1,12 +1,23 @@ import { images } from "../../data"; import TextWithEmoji from "../TextWithEmoji"; import styles from "./styles.module.scss"; +import { useTranslations } from "@/hooks/translations"; +import { ELocalesPlacement } from "@/locales"; function AdviceFromAstrologer() { + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1); + return (
- - messages + + messages
) } diff --git a/src/components/EmailMarketing/v1/components/CustomerCounter/index.tsx b/src/components/EmailMarketing/v1/components/CustomerCounter/index.tsx index 98ff065..37804ee 100644 --- a/src/components/EmailMarketing/v1/components/CustomerCounter/index.tsx +++ b/src/components/EmailMarketing/v1/components/CustomerCounter/index.tsx @@ -1,11 +1,15 @@ +import { useTranslations } from '@/hooks/translations'; import { images } from '../../data'; import styles from './styles.module.scss'; +import { ELocalesPlacement } from '@/locales'; interface CustomerCounterProps { count: number; } function CustomerCounter({ count }: CustomerCounterProps) { + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1); + return (
{/*
@@ -27,7 +31,7 @@ function CustomerCounter({ count }: CustomerCounterProps) {
*/} - +
{count}
); diff --git a/src/components/EmailMarketing/v1/components/FindingPartner/index.tsx b/src/components/EmailMarketing/v1/components/FindingPartner/index.tsx index 7a816a7..c9f8095 100644 --- a/src/components/EmailMarketing/v1/components/FindingPartner/index.tsx +++ b/src/components/EmailMarketing/v1/components/FindingPartner/index.tsx @@ -1,11 +1,18 @@ import { images } from "../../data"; import TextWithEmoji from "../TextWithEmoji"; import styles from "./styles.module.scss"; +import { useTranslations } from "@/hooks/translations"; +import { ELocalesPlacement } from "@/locales"; function FindingPartner() { + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1); + return (
- + smartphone
) diff --git a/src/components/EmailMarketing/v1/components/GivePersonalizedPlan/index.tsx b/src/components/EmailMarketing/v1/components/GivePersonalizedPlan/index.tsx index 650277f..ed86046 100644 --- a/src/components/EmailMarketing/v1/components/GivePersonalizedPlan/index.tsx +++ b/src/components/EmailMarketing/v1/components/GivePersonalizedPlan/index.tsx @@ -1,14 +1,17 @@ import Title from "@/components/Title"; import styles from "./styles.module.scss"; import { images } from "../../data"; +import { useTranslations } from "@/hooks/translations"; +import { ELocalesPlacement } from "@/locales"; function GivePersonalizedPlan() { + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1); + return (
- So we decided to give you your - personalized plan and access to - the trial of our app <span>FOR FREE!</span> + {translate("marketing-landing.personalized-plan-title")} + <span> {translate("marketing-landing.personalized-plan-free")}</span> stars stars diff --git a/src/components/EmailMarketing/v1/components/GuaranteedSecurityPayments/index.tsx b/src/components/EmailMarketing/v1/components/GuaranteedSecurityPayments/index.tsx index 9169882..42d7e56 100644 --- a/src/components/EmailMarketing/v1/components/GuaranteedSecurityPayments/index.tsx +++ b/src/components/EmailMarketing/v1/components/GuaranteedSecurityPayments/index.tsx @@ -1,11 +1,15 @@ import { images } from "../../data"; import styles from "./styles.module.scss"; +import { useTranslations } from "@/hooks/translations"; +import { ELocalesPlacement } from "@/locales"; function GuaranteedSecurityPayments() { + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1); + return (
guaranteed -

Guaranteed security payments

+

{translate("marketing-landing.guaranteed-security-payments")}

) } diff --git a/src/components/EmailMarketing/v1/components/InsightsRelationship/index.tsx b/src/components/EmailMarketing/v1/components/InsightsRelationship/index.tsx index 6116232..d2ac48d 100644 --- a/src/components/EmailMarketing/v1/components/InsightsRelationship/index.tsx +++ b/src/components/EmailMarketing/v1/components/InsightsRelationship/index.tsx @@ -1,12 +1,16 @@ import { images } from "../../data"; import TextWithEmoji from "../TextWithEmoji"; import styles from "./styles.module.scss"; +import { useTranslations } from "@/hooks/translations"; +import { ELocalesPlacement } from "@/locales"; function InsightsRelationship() { + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1); + return (
relationships diff --git a/src/components/EmailMarketing/v1/components/MoneyBackGuarantee/index.tsx b/src/components/EmailMarketing/v1/components/MoneyBackGuarantee/index.tsx index b3abb35..5975ebb 100644 --- a/src/components/EmailMarketing/v1/components/MoneyBackGuarantee/index.tsx +++ b/src/components/EmailMarketing/v1/components/MoneyBackGuarantee/index.tsx @@ -1,22 +1,22 @@ import TextWithEmoji from "../TextWithEmoji"; import styles from "./styles.module.scss"; +import { useTranslations } from "@/hooks/translations"; +import { ELocalesPlacement } from "@/locales"; -function UnderstandingYourself() { +function MoneyBackGuarantee() { + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1); + return (

- We are convinced that we will help you get a deeper understanding of - your partner and how you can improve your relationship. - After all of our stellar customer reviews, we are ready to return your money - if you feel that this report doesn’t provide any value. Find more - about applicable limitations in our Money-back policy. + {translate("marketing-landing.money-back-guarantee-text")}

) } -export default UnderstandingYourself \ No newline at end of file +export default MoneyBackGuarantee \ No newline at end of file diff --git a/src/components/EmailMarketing/v1/components/PriceComparison/index.tsx b/src/components/EmailMarketing/v1/components/PriceComparison/index.tsx index 9de0e74..44fa738 100644 --- a/src/components/EmailMarketing/v1/components/PriceComparison/index.tsx +++ b/src/components/EmailMarketing/v1/components/PriceComparison/index.tsx @@ -1,5 +1,7 @@ import { combineStyles } from "@/services/styles"; import styles from "./styles.module.scss"; +import { useTranslations } from "@/hooks/translations"; +import { ELocalesPlacement } from "@/locales"; interface PriceComparisonProps { oldPrice: number | string; @@ -7,11 +9,13 @@ interface PriceComparisonProps { } function PriceComparison({ oldPrice, newPrice }: PriceComparisonProps) { + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1); + return (
- OLD PRICE + {translate("marketing-landing.old-price-label")}
{oldPrice}
@@ -20,7 +24,7 @@ function PriceComparison({ oldPrice, newPrice }: PriceComparisonProps) {
- NEW PRICE + {translate("marketing-landing.new-price-label")}
${newPrice}
diff --git a/src/components/EmailMarketing/v1/components/PricingSummary/index.tsx b/src/components/EmailMarketing/v1/components/PricingSummary/index.tsx index 22c92a1..d4a6533 100644 --- a/src/components/EmailMarketing/v1/components/PricingSummary/index.tsx +++ b/src/components/EmailMarketing/v1/components/PricingSummary/index.tsx @@ -1,6 +1,9 @@ import { combineStyles } from '@/services/styles'; import CountdownTimer from '../CountdownTimer'; import styles from './styles.module.scss'; +import { useTranslations } from "@/hooks/translations"; +import { addCurrency, ELocalesPlacement } from "@/locales"; +import { Currency } from '@/components/PaymentTable'; interface PricingSummaryProps { totalToday: number | string; @@ -8,6 +11,7 @@ interface PricingSummaryProps { discountedPrice: number | string; trialDuration: number | string; saveText: string; + currency: Currency; } function PricingSummary({ @@ -15,21 +19,24 @@ function PricingSummary({ originalPrice, discountedPrice, trialDuration, - saveText + saveText, + currency }: PricingSummaryProps) { + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1); + return (
- Total today: + {translate("special-offer.pricing-summary-total-today")} ${totalToday}
- Code applied! + {translate("special-offer.pricing-summary-code-applied")}
- Your cost per 2 weeks after trial + {translate("special-offer.pricing-summary-cost-after-trial")}
${originalPrice} ${discountedPrice} @@ -40,7 +47,10 @@ function PricingSummary({

- You will be charged only ${totalToday} for your {trialDuration}-day trial. Subscription renews automatically until cancelled. You can cancel at any time before the end of the trial. + {translate("special-offer.pricing-summary-trial-description", { + totalToday: addCurrency(totalToday, currency), + trialDuration: trialDuration + })}

); diff --git a/src/components/EmailMarketing/v1/components/Reviews/index.tsx b/src/components/EmailMarketing/v1/components/Reviews/index.tsx index 16083c0..9b08275 100644 --- a/src/components/EmailMarketing/v1/components/Reviews/index.tsx +++ b/src/components/EmailMarketing/v1/components/Reviews/index.tsx @@ -6,7 +6,7 @@ import { ELocalesPlacement } from "@/locales"; import { images } from "../../data"; function Reviews() { - const { translate } = useTranslations(ELocalesPlacement.PalmistryV1); + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1); const reviews: IReviewProps[] = useMemo( () => [ { @@ -14,21 +14,21 @@ function Reviews() { username: "@andi36_11", date: "06/05/2024", gender: "male", - text: "Horoscope tells realistic facts about day to day life, which can be easily relatable. It shows direction.", + text: translate("marketing-landing.review-1"), }, { avatar: images("aramaska.png"), username: "@aramaska", date: "04/17/2024", gender: "female", - text: "It makes me feel safe, seeing, warm and smart.", + text: translate("marketing-landing.review-2"), }, { avatar: images("patterso.png"), username: "@patterso", date: "03/01/2024", gender: "female", - text: "I love that we have the “my profile” option. I love learning about myself.", + text: translate("marketing-landing.review-3"), }, ], [translate] diff --git a/src/components/EmailMarketing/v1/components/SecretDiscountTable/index.tsx b/src/components/EmailMarketing/v1/components/SecretDiscountTable/index.tsx new file mode 100644 index 0000000..62657f5 --- /dev/null +++ b/src/components/EmailMarketing/v1/components/SecretDiscountTable/index.tsx @@ -0,0 +1,67 @@ +import Title from "@/components/Title"; +import styles from "./styles.module.scss"; +import { images } from "../../data"; +import { usePaywall } from "@/hooks/paywall/usePaywall"; +import { addCurrency, ELocalesPlacement } from "@/locales"; +import { EPlacementKeys } from "@/api/resources/Paywall"; +import { Currency } from "@/components/PaymentTable"; +import { useTranslations } from "@/hooks/translations"; + +const placementKey = EPlacementKeys["aura.placement.email.compatibility.discount"] + +const getPrice = (price: number, currency: Currency) => { + if (price % 100 === 0) { + return addCurrency(price / 100, currency); + } + return addCurrency( + (price / 100).toFixed(2), + currency + ); +} + +function SecretDiscountTable() { + const { products, currency, getText } = usePaywall({ + placementKey, + localesPlacement: ELocalesPlacement.EmailMarketingCompatibilityV1, + }); + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1); + + const activeProduct = products[0]; + const price = activeProduct?.price || 0; + const trialPrice = activeProduct?.trialPrice || 0; + const trialDuration = activeProduct?.trialDuration || 7; + + return ( +
+ + {translate("secret-discount.secret-discount-table_title")} + +

+ {translate("secret-discount.secret-discount-table_subtitle")} +

+
+ Gift + + {translate("secret-discount.secret-discount-table_discount-applied")} + + {getText("old.discount")} + {getText("new.discount")} +
+
+

{translate("secret-discount.secret-discount-table_cost-after-trial", { days: trialDuration })}

+ {addCurrency(Number(getText("old.price")), currency)} + {getPrice(price, currency)} +
+
+

{translate("secret-discount.secret-discount-table_you-save", { amount: addCurrency(Number(getText("save")), currency) })}

+
+
+
+

{translate("secret-discount.secret-discount-table_total-today")}

+ {getPrice(trialPrice, currency)} +
+
+ ) +} + +export default SecretDiscountTable \ No newline at end of file diff --git a/src/components/EmailMarketing/v1/components/SecretDiscountTable/styles.module.scss b/src/components/EmailMarketing/v1/components/SecretDiscountTable/styles.module.scss new file mode 100644 index 0000000..b3d981e --- /dev/null +++ b/src/components/EmailMarketing/v1/components/SecretDiscountTable/styles.module.scss @@ -0,0 +1,110 @@ +.container { + background-color: #fff; + border-radius: 13px; + width: calc(100% + 24px); + padding: 16px 0 22px; + box-shadow: 2px 11px 17px -1px rgba(0, 0, 0, 0.13); + margin-top: 42px; + color: #363636; +} + +.title { + font-size: 20px; + font-weight: 600; + line-height: 24px; + margin-bottom: 0; +} + +.subtitle { + font-size: 13px; + font-weight: 400; + line-height: 16px; + margin-top: 5px; + text-align: center; +} + +.applied { + width: 100%; + background-color: #293D68; + padding: 7px 10px; + margin-top: 12px; + display: flex; + align-items: center; + justify-content: start; + gap: 10px; + color: #fff; + + &>img { + width: 17px; + } + + &>.title { + font-size: 15px; + font-weight: 500; + line-height: 19px; + } + + &>.old-discount { + font-size: 15px; + color: #B2B2B2; + text-decoration: line-through; + margin-left: 4px; + } + + &>.new-discount { + color: #fff; + font-size: 20px; + font-weight: 600; + line-height: 19px; + margin-left: 4px; + } +} + +.grid-line { + display: grid; + grid-template-columns: 1fr 22px 22px; + align-items: center; + gap: 28px; + margin-top: 8px; + padding: 0 24px 0 10px; + + &>p { + font-size: 12px; + font-weight: 400; + line-height: 130%; + margin-bottom: 0; + } + + &.days-14>span { + font-size: 12px; + font-weight: 400; + line-height: 130%; + + &.old-price { + text-decoration: line-through; + } + } + + &.save { + margin-top: 2px; + } + + &.total-today { + + &>p, + span { + font-size: 16px; + font-weight: 500; + line-height: 130%; + margin-top: 8px; + } + } +} + +hr { + display: block; + width: 100%; + margin: 0; + background-color: #363636; + margin-top: 6px; +} \ No newline at end of file diff --git a/src/components/EmailMarketing/v1/components/StatisticsBanner/index.tsx b/src/components/EmailMarketing/v1/components/StatisticsBanner/index.tsx index 4732fe0..28bc253 100644 --- a/src/components/EmailMarketing/v1/components/StatisticsBanner/index.tsx +++ b/src/components/EmailMarketing/v1/components/StatisticsBanner/index.tsx @@ -1,15 +1,19 @@ import styles from './styles.module.scss'; +import { useTranslations } from "@/hooks/translations"; +import { ELocalesPlacement } from "@/locales"; interface StatisticsBannerProps { count: number; } function StatisticsBanner({ count }: StatisticsBannerProps) { + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1); + return (
- Last week alone {count}+ people got this relationship guide + {translate("marketing-landing.statistics-banner-text", { b: {translate("marketing-landing.statistics-banner-count", { count })} })}
diff --git a/src/components/EmailMarketing/v1/components/UnderstandingYourself/index.tsx b/src/components/EmailMarketing/v1/components/UnderstandingYourself/index.tsx index 509dd64..90c0fcf 100644 --- a/src/components/EmailMarketing/v1/components/UnderstandingYourself/index.tsx +++ b/src/components/EmailMarketing/v1/components/UnderstandingYourself/index.tsx @@ -1,12 +1,16 @@ import { images } from "../../data"; import TextWithEmoji from "../TextWithEmoji"; import styles from "./styles.module.scss"; +import { useTranslations } from "@/hooks/translations"; +import { ELocalesPlacement } from "@/locales"; function UnderstandingYourself() { + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1); + return (
hand with eye diff --git a/src/components/EmailMarketing/v1/images/SVG/Blob/index.tsx b/src/components/EmailMarketing/v1/images/SVG/Blob/index.tsx new file mode 100644 index 0000000..6273fff --- /dev/null +++ b/src/components/EmailMarketing/v1/images/SVG/Blob/index.tsx @@ -0,0 +1,18 @@ +import { SVGProps } from "react" + +function Blob(props: SVGProps) { + return ( + + + + + + + + + + + ) +} + +export default Blob \ No newline at end of file diff --git a/src/components/EmailMarketing/v1/images/SVG/Blob2/index.tsx b/src/components/EmailMarketing/v1/images/SVG/Blob2/index.tsx new file mode 100644 index 0000000..6403d80 --- /dev/null +++ b/src/components/EmailMarketing/v1/images/SVG/Blob2/index.tsx @@ -0,0 +1,17 @@ +import { SVGProps } from "react" + +function Blob2(props: SVGProps) { + return ( + + + + + + + + + + ) +} + +export default Blob2 \ No newline at end of file diff --git a/src/components/EmailMarketing/v1/images/SVG/Blob3/index.tsx b/src/components/EmailMarketing/v1/images/SVG/Blob3/index.tsx new file mode 100644 index 0000000..dd7c6ca --- /dev/null +++ b/src/components/EmailMarketing/v1/images/SVG/Blob3/index.tsx @@ -0,0 +1,18 @@ +import { SVGProps } from "react" + +function Blob3(props: SVGProps) { + return ( + + + + + + + + + + + ) +} + +export default Blob3 \ No newline at end of file diff --git a/src/components/EmailMarketing/v1/images/SVG/Blob4/index.tsx b/src/components/EmailMarketing/v1/images/SVG/Blob4/index.tsx new file mode 100644 index 0000000..6001c5c --- /dev/null +++ b/src/components/EmailMarketing/v1/images/SVG/Blob4/index.tsx @@ -0,0 +1,21 @@ +import { SVGProps } from "react" + +function Blob4(props: SVGProps) { + const width = props.width ? Number(props.width) : 419; + const height = props.height ? Number(props.height) : 193; + return ( + + + + + + + + + + + + ) +} + +export default Blob4 \ No newline at end of file diff --git a/src/components/EmailMarketing/v1/pages/MarketingLanding/index.tsx b/src/components/EmailMarketing/v1/pages/MarketingLanding/index.tsx index 0e11329..40f3663 100644 --- a/src/components/EmailMarketing/v1/pages/MarketingLanding/index.tsx +++ b/src/components/EmailMarketing/v1/pages/MarketingLanding/index.tsx @@ -21,23 +21,11 @@ import routes from "@/routes"; import { usePaywall } from "@/hooks/paywall/usePaywall"; import { EPlacementKeys } from "@/api/resources/Paywall"; import BlurComponent from "@/components/BlurComponent"; - -const features = [ - { - text: "Unlimited daily / weekly / monthly / yearly horoscopes" - }, - { - text: "Astrology lessons and articles inside the app" - }, - { - text: "Beauty / health / travel and more calendars" - }, - { - text: "Compatibility check with zodiac signs inside the app" - } -]; +import { useTranslations } from "@/hooks/translations"; +import { ELocalesPlacement } from "@/locales"; function MarketingLanding() { + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1); const navigate = useNavigate(); const { products, getText } = usePaywall({ placementKey: EPlacementKeys["aura.placement.email.marketing"], @@ -47,6 +35,21 @@ function MarketingLanding() { navigate(routes.client.emailMarketingV1SpecialOffer()); } + const features = [ + { + text: translate("marketing-landing.plan-includes-unlimited-horoscopes") + }, + { + text: translate("marketing-landing.plan-includes-astrology-lessons") + }, + { + text: translate("marketing-landing.plan-includes-lifestyle-calendars") + }, + { + text: translate("marketing-landing.plan-includes-compatibility-check") + } + ]; + return (
{/* Background elements */} @@ -58,25 +61,27 @@ function MarketingLanding() { <> <img className={combineStyles(styles.backgroundElement, styles.backgroundElement3)} src={images("gift-small.png")} alt="Gift" /> - Special Offer! + {translate("marketing-landing.title")} </>

- Everything for free. Trial include! + {translate("marketing-landing.description")}

- Hey, Sun <span>👋</span> + {translate("marketing-landing.title-hey")} -

Your wellness and happiness are key for us!

+

+ {translate("marketing-landing.description-hey")} +

<svg className={combineStyles(styles.backgroundElement, styles.backgroundElement5)} width="31" height="31" viewBox="0 0 31 31" fill="none" xmlns="http://www.w3.org/2000/svg"> <circle cx="15.5" cy="15.5" r="15.5" fill="#DEBA00" /> </svg> - Highlights of your plan: + {translate("marketing-landing.title-highlights")}
@@ -125,7 +130,10 @@ function MarketingLanding() {
- + @@ -175,7 +183,7 @@ function MarketingLanding() {
diff --git a/src/components/EmailMarketing/v1/pages/SaveOff/index.tsx b/src/components/EmailMarketing/v1/pages/SaveOff/index.tsx new file mode 100644 index 0000000..950d4a7 --- /dev/null +++ b/src/components/EmailMarketing/v1/pages/SaveOff/index.tsx @@ -0,0 +1,71 @@ +import styles from "./styles.module.scss"; +import Blob from "../../images/SVG/Blob"; +import { images } from "../../data"; +import Title from "@/components/Title"; +import Button from "../../components/Button"; +import Blob2 from "../../images/SVG/Blob2"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import { usePaywall } from "@/hooks/paywall/usePaywall"; +import { EPlacementKeys } from "@/api/resources/Paywall"; +import { addCurrency, ELocalesPlacement } from "@/locales"; +import { useTranslations } from "@/hooks/translations"; +import Header from "@/components/pages/ABDesign/v1/components/Header"; + +const placementKey = EPlacementKeys["aura.placement.email.compatibility.discount"] + +function SaveOff() { + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1); + const { products, currency, getText } = usePaywall({ + placementKey, + localesPlacement: ELocalesPlacement.EmailMarketingCompatibilityV1, + }); + const activeProduct = products[0] + const price = (activeProduct?.price || 0) / 100 + const trialDuration = activeProduct?.trialDuration || 7 + + const navigate = useNavigate(); + + const handleNext = () => { + navigate(routes.client.emailMarketingV1SecretDiscount()); + } + + return ( +
+
+ + + gift + + {translate("save-off.title", { discount: getText("discount") })} + +

+ {translate("save-off.instead", { + price: {addCurrency(price, currency)}, + oldPrice: + {translate("save-off.instead-old-price", { + oldPrice: addCurrency(getText("full.price") as string, currency) + })} + + })} +

+

+ fire + {translate("save-off.trial-duration", { days: trialDuration })} +

+

+ gift + {translate("save-off.discount-offer", { discount: getText("discount") })} +

+ +
+ ) +} + +export default SaveOff \ No newline at end of file diff --git a/src/components/EmailMarketing/v1/pages/SaveOff/styles.module.scss b/src/components/EmailMarketing/v1/pages/SaveOff/styles.module.scss new file mode 100644 index 0000000..8a04a7a --- /dev/null +++ b/src/components/EmailMarketing/v1/pages/SaveOff/styles.module.scss @@ -0,0 +1,85 @@ +.container { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + padding: 20px 26px; + min-height: 100dvh; + max-width: 560px; + margin: 0 auto; +} + +.header { + padding: 8px 0 30px; + + &>button { + margin-left: -12px; + } +} + +.blob { + position: absolute; + top: 0; + right: 0; + z-index: -1; +} + +.blob2 { + position: absolute; + bottom: 0; + right: 0; + z-index: -1; +} + +.gift { + margin-top: 24px; +} + +.title { + margin-top: 32px; + margin-bottom: 14px; + font-size: 32px; + line-height: 26px; + font-weight: 600; + color: #275CA7; +} + +.description { + font-size: 18px; + line-height: 24px; + font-weight: 400; + color: #363636; + + &>.price { + font-weight: 600; + background: linear-gradient(90deg, #FFA1BA 0%, #9A55FF 100%); + background-clip: text; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + } + + &>.discount { + text-decoration: line-through; + } +} + +.point { + width: 100%; + display: flex; + align-items: center; + justify-content: start; + gap: 8px; + font-size: 14px; + line-height: 21px; + font-weight: 600; + color: #2c2c2c; + margin-top: 6px; +} + +.button { + height: 54px; + margin-top: 16px; + font-size: 18px; + line-height: 21px; + font-weight: 600; +} \ No newline at end of file diff --git a/src/components/EmailMarketing/v1/pages/SecretDiscount/index.tsx b/src/components/EmailMarketing/v1/pages/SecretDiscount/index.tsx new file mode 100644 index 0000000..6ac9f81 --- /dev/null +++ b/src/components/EmailMarketing/v1/pages/SecretDiscount/index.tsx @@ -0,0 +1,109 @@ +import styles from "./styles.module.scss"; +import Blob3 from "../../images/SVG/Blob3"; +import Blob4 from "../../images/SVG/Blob4"; +import Title from "@/components/Title"; +import SecretDiscountTable from "../../components/SecretDiscountTable"; +import Button from "../../components/Button"; +import { usePaywall } from "@/hooks/paywall/usePaywall"; +import { EPlacementKeys } from "@/api/resources/Paywall"; +import { addCurrency, ELocalesPlacement } from "@/locales"; +import Modal from "@/components/Modal"; +import { useEffect, useState } from "react"; +import PaymentForm from "@/components/Payment/nmi/PaymentForm"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; +import { useDispatch } from "react-redux"; +import { actions } from "@/store"; +import { useTranslations } from "@/hooks/translations"; +import Header from "@/components/pages/ABDesign/v1/components/Header"; +import { useDynamicSize } from "@/hooks/useDynamicSize"; + +const placementKey = EPlacementKeys["aura.placement.email.compatibility.discount"] + +function SecretDiscount() { + const { width, elementRef } = useDynamicSize({ defaultWidth: 560 }); + const { height, elementRef: policyContainerRef } = useDynamicSize({ defaultWidth: 560, defaultHeight: 193 }); + const dispatch = useDispatch(); + const navigate = useNavigate(); + const { products, currency } = usePaywall({ + placementKey, + localesPlacement: ELocalesPlacement.EmailMarketingCompatibilityV1, + }); + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1); + + const activeProduct = products[0]; + const price = (activeProduct?.price || 0) / 100; + const trialDuration = activeProduct?.trialDuration || 7; + + useEffect(() => { + if (!activeProduct) return; + dispatch(actions.payment.update({ + activeProduct + })) + }, [activeProduct]) + + const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false); + + + const onPaymentSuccess = () => { + return navigate(routes.client.paymentSuccess()) + } + + const onModalClosed = () => { + setIsPaymentModalOpen(false); + } + + const onPaymentError = () => { + return navigate(routes.client.paymentFail()) + } + + const openPaymentModal = () => { + setIsPaymentModalOpen(true); + }; + + return ( +
+
+ {activeProduct && ( + + + + )} + + + {translate("secret-discount.title")} + + + + +
+

+ {translate("secret-discount.policy", { + days: trialDuration, + price: addCurrency(price, currency) + })} +

+ +
+
+ ) +} + +export default SecretDiscount \ No newline at end of file diff --git a/src/components/EmailMarketing/v1/pages/SecretDiscount/styles.module.scss b/src/components/EmailMarketing/v1/pages/SecretDiscount/styles.module.scss new file mode 100644 index 0000000..8454dba --- /dev/null +++ b/src/components/EmailMarketing/v1/pages/SecretDiscount/styles.module.scss @@ -0,0 +1,75 @@ +.container { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + padding: 20px 26px; + min-height: 100dvh; + max-width: 560px; + margin: 0 auto; + position: relative; + overflow: hidden; +} + +.header { + padding: 8px 0 30px; + + &>button { + margin-left: -12px; + } +} + +.blob3 { + position: absolute; + top: 0; + left: 0; + z-index: -1; +} + +.title { + padding: 15px 0; + background-color: #F096C4; + margin: 0; + margin-top: 32px; + line-height: 100%; + width: calc(100% + 52px); + font-size: 20px; + font-weight: 600; + color: #fff; + text-transform: uppercase; + white-space: nowrap; +} + +.button { + font-size: 18px; + font-weight: 600; + padding: 16px 0; + margin-top: 30px; +} + +.policy-container { + position: absolute; + width: calc(100%); + max-width: 560px; + height: fit-content; + bottom: 0; + left: 50%; + transform: translateX(-50%); + + &>.policy { + width: 100%; + margin: 34px 0; + padding: 0 14px; + font-size: 13px; + font-weight: 400; + line-height: 130%; + color: #fff; + } + + .blob4 { + position: absolute; + bottom: 0; + left: 0; + z-index: -1; + } +} \ No newline at end of file diff --git a/src/components/EmailMarketing/v1/pages/SpecialOffer/index.tsx b/src/components/EmailMarketing/v1/pages/SpecialOffer/index.tsx index 7c6115d..22f8cec 100644 --- a/src/components/EmailMarketing/v1/pages/SpecialOffer/index.tsx +++ b/src/components/EmailMarketing/v1/pages/SpecialOffer/index.tsx @@ -12,6 +12,8 @@ import PaymentForm from "@/components/Payment/nmi/PaymentForm"; import routes from "@/routes"; import { useNavigate } from "react-router-dom"; import BlurComponent from "@/components/BlurComponent"; +import { useTranslations } from "@/hooks/translations"; +import { addCurrency, ELocalesPlacement } from "@/locales"; const placementKey = EPlacementKeys["aura.placement.email.marketing"]; @@ -20,8 +22,9 @@ function SpecialOffer() { const navigate = useNavigate(); const [isOpenPaymentModal, setIsOpenPaymentModal] = useState(false); const activeProduct = useSelector(selectors.selectActiveProduct); + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1); - const { products, getText } = usePaywall({ + const { products, currency, getText } = usePaywall({ placementKey, }); @@ -39,6 +42,7 @@ function SpecialOffer() { const handleCloseModal = () => { setIsOpenPaymentModal(false); + return navigate(routes.client.emailMarketingV1SaveOff()) }; const onPaymentError = () => { @@ -67,14 +71,14 @@ function SpecialOffer() { )}
- Special Offer! + {translate("special-offer.title")}
- Start your {trialDuration}-day trial + {translate("special-offer.start-trial", { days: trialDuration })}

- No pressure. Cancel anytime + {translate("special-offer.cancel-anytime")}

- By continuing you agree that if you don't cancel prior to the end of the {trialDuration}-days trial, you will automatically be charged ${price} every 2 weeks until you cancel in settings. Learn more about cancellation and refund policy in Subscription terms + {translate("special-offer.policy", { + days: trialDuration, + price: addCurrency(price, currency) + })}

diff --git a/src/components/PalmistryV1/components/PalmIsReady/index.tsx b/src/components/PalmistryV1/components/PalmIsReady/index.tsx index d744f48..7d65a53 100644 --- a/src/components/PalmistryV1/components/PalmIsReady/index.tsx +++ b/src/components/PalmistryV1/components/PalmIsReady/index.tsx @@ -6,8 +6,11 @@ import { ELocalesPlacement } from "@/locales"; function PalmIsReady() { const { translate } = useTranslations(ELocalesPlacement.PalmistryV1); + return ( -
+
{translate("/trial-payment.palm_is_ready.title", { color: ( @@ -20,9 +23,6 @@ function PalmIsReady() { className={styles["girl-image"]} src={`${palmistryV1Prefix}/trial-payment/girl.png`} alt="Smile girl" - style={{ - shapeOutside: `url(${palmistryV1Prefix}/trial-payment/girl.png)`, - }} /> <p className={styles.description}> {translate("/trial-payment.palm_is_ready.description")} diff --git a/src/components/PalmistryV1/components/PalmIsReady/styles.module.scss b/src/components/PalmistryV1/components/PalmIsReady/styles.module.scss index b258da8..f7387f4 100644 --- a/src/components/PalmistryV1/components/PalmIsReady/styles.module.scss +++ b/src/components/PalmistryV1/components/PalmIsReady/styles.module.scss @@ -62,4 +62,10 @@ margin-top: 33px; margin-right: -10px; width: 191px; + shape-outside: var(--palmistry-prefix-girl-image); + -webkit-shape-outside: var(--palmistry-prefix-girl-image); + shape-image-threshold: 0; + -webkit-shape-image-threshold: 0; + shape-margin: 10px; + -webkit-shape-margin: 10px; } diff --git a/src/components/PalmistryV1/data/index.tsx b/src/components/PalmistryV1/data/index.tsx index c8620cd..d41cd2a 100644 --- a/src/components/PalmistryV1/data/index.tsx +++ b/src/components/PalmistryV1/data/index.tsx @@ -1 +1 @@ -export const answerTimeOut = 1000; +export const answerTimeOut = 600; diff --git a/src/components/PalmistryV1/pages/Birthdate/index.tsx b/src/components/PalmistryV1/pages/Birthdate/index.tsx index 3197bc7..16db291 100644 --- a/src/components/PalmistryV1/pages/Birthdate/index.tsx +++ b/src/components/PalmistryV1/pages/Birthdate/index.tsx @@ -38,12 +38,12 @@ function Birthdate() { return age; }; - const handleNext = async () => { + const handleNext = () => { const age = getAge(); metricService.userParams({ age, }); - await updateSession( + updateSession( { profile: { birthdate: `${birthdate} 00:00`, diff --git a/src/components/PalmistryV1/pages/ElementResonates/index.tsx b/src/components/PalmistryV1/pages/ElementResonates/index.tsx index f8fadb8..3f3ee23 100644 --- a/src/components/PalmistryV1/pages/ElementResonates/index.tsx +++ b/src/components/PalmistryV1/pages/ElementResonates/index.tsx @@ -61,7 +61,7 @@ function ElementResonates() { const handleClick = async (id: IAnswersSessionPalmistry["element_resonates"]) => { dispatch(actions.palmistryV1Answers.update({ elementResonates: id })); - await updateSession({ + updateSession({ answers: { element_resonates: id, }, diff --git a/src/components/PalmistryV1/pages/Email/index.tsx b/src/components/PalmistryV1/pages/Email/index.tsx index 2a4058f..0fd042b 100644 --- a/src/components/PalmistryV1/pages/Email/index.tsx +++ b/src/components/PalmistryV1/pages/Email/index.tsx @@ -74,7 +74,7 @@ function Email() { }; const authorize = async () => { - await updateSession( + updateSession( { profile: { name, diff --git a/src/components/PalmistryV1/pages/FavoriteColor/index.tsx b/src/components/PalmistryV1/pages/FavoriteColor/index.tsx index 79c0f61..07fdbaa 100644 --- a/src/components/PalmistryV1/pages/FavoriteColor/index.tsx +++ b/src/components/PalmistryV1/pages/FavoriteColor/index.tsx @@ -72,7 +72,7 @@ function FavoriteColor() { const handleClick = async (id: IAnswersSessionPalmistry["favorite_color"]) => { dispatch(actions.palmistryV1Answers.update({ favoriteColor: id })); - await updateSession({ + updateSession({ answers: { favorite_color: id, }, diff --git a/src/components/PalmistryV1/pages/GenderPalmistry/index.tsx b/src/components/PalmistryV1/pages/GenderPalmistry/index.tsx index fcf6b1c..38aa46d 100644 --- a/src/components/PalmistryV1/pages/GenderPalmistry/index.tsx +++ b/src/components/PalmistryV1/pages/GenderPalmistry/index.tsx @@ -1,6 +1,5 @@ import styles from "./styles.module.scss"; import Title from "@/components/Title"; -import ChooseGender from "@/components/pages/ABDesign/v1/components/ChooseGender"; import { useDispatch, useSelector } from "react-redux"; import { actions, selectors } from "@/store"; import { Gender } from "@/data"; @@ -19,6 +18,7 @@ import { ELottieKeys, useLottie } from "@/hooks/lottie/useLottie"; import { useSession } from "@/hooks/session/useSession"; import { EGender, ESourceAuthorization } from "@/api/resources/User"; import AlreadyHaveAccount from "@/components/ui/AlreadyHaveAccount"; +import Answer from "../../components/Answer"; function GenderPalmistry() { const { translate } = useTranslations(ELocalesPlacement.PalmistryV1); @@ -28,6 +28,8 @@ function GenderPalmistry() { const { checked: privacyPolicyChecked } = useSelector( selectors.selectPrivacyPolicy ); + console.log(privacyPolicyChecked); + const { gender } = useSelector(selectors.selectQuestionnaire); const [isSelected, setIsSelected] = useState(false); usePreloadImages(["/v1/palmistry/hand-with-eye.svg"]); @@ -35,13 +37,20 @@ function GenderPalmistry() { preloadKey: ELottieKeys.handSymbols, }); - const selectGender = async (_gender: Gender | null) => { + const localGenders = genders.map((gender) => ({ + id: gender.id, + title: translate(gender.id, undefined, ELocalesPlacement.V1), + })); + + const selectGender = (_gender: Gender | null) => { + dispatch(actions.privacyPolicy.updateChecked(true)); setIsSelected(true); dispatch(actions.questionnaire.update({ gender: _gender?.id })); }; const handleNext = useCallback(async () => { if (!gender) return; + dispatch(actions.privacyPolicy.updateChecked(true)); await sleep(1000); metricService.userParams({ gender: genders.find((g) => g.id === gender)?.name, @@ -50,7 +59,7 @@ function GenderPalmistry() { ESourceAuthorization["aura.palmistry.new"] ); if (session?.sessionId?.length) { - await updateSession( + updateSession( { profile: { gender: EGender[gender as keyof typeof EGender], @@ -76,9 +85,19 @@ function GenderPalmistry() { {translate("/gender.title")}

{translate("/gender.description")}

- + {/* */} + +
+ {localGenders.map((_gender, index) => ( + selectGender(genders.find((g) => g.id === _gender.id) ?? null)} + /> + ))} +
- {gender && !privacyPolicyChecked && ( {translate("/gender.toast", undefined, ELocalesPlacement.V1)} diff --git a/src/components/PalmistryV1/pages/GenderPalmistry/styles.module.scss b/src/components/PalmistryV1/pages/GenderPalmistry/styles.module.scss index d7f2660..92280b1 100644 --- a/src/components/PalmistryV1/pages/GenderPalmistry/styles.module.scss +++ b/src/components/PalmistryV1/pages/GenderPalmistry/styles.module.scss @@ -17,6 +17,7 @@ .privacy-policy { max-width: 316px; margin-top: 26px; + text-align: center; } .toast-container { @@ -26,3 +27,9 @@ max-width: 460px; padding: 0 24px; } + +.genders-container { + display: flex; + flex-direction: column-reverse; + width: 100%; +} diff --git a/src/components/PalmistryV1/pages/HeadOrHeart/index.tsx b/src/components/PalmistryV1/pages/HeadOrHeart/index.tsx index a180bad..30026c0 100644 --- a/src/components/PalmistryV1/pages/HeadOrHeart/index.tsx +++ b/src/components/PalmistryV1/pages/HeadOrHeart/index.tsx @@ -55,7 +55,7 @@ function HeadOrHeart() { const handleClick = async (id: IAnswersSessionPalmistry["head_or_heart"]) => { dispatch(actions.palmistryV1Answers.update({ headOrHeart: id })); - await updateSession( + updateSession( { answers: { head_or_heart: id, diff --git a/src/components/PalmistryV1/pages/RelateFollowing/index.tsx b/src/components/PalmistryV1/pages/RelateFollowing/index.tsx index 390e15a..0758c65 100644 --- a/src/components/PalmistryV1/pages/RelateFollowing/index.tsx +++ b/src/components/PalmistryV1/pages/RelateFollowing/index.tsx @@ -58,7 +58,7 @@ function RelateFollowing() { const handleClick = async (answerIndex: number) => { setActiveButton(answerIndex); - await updateSession( + updateSession( { answers: { [questions[parseInt(questionId) - 1].id]: answerIndex + 1, diff --git a/src/components/PalmistryV1/pages/RelationshipStatus/index.tsx b/src/components/PalmistryV1/pages/RelationshipStatus/index.tsx index 5a7a0cc..02bb577 100644 --- a/src/components/PalmistryV1/pages/RelationshipStatus/index.tsx +++ b/src/components/PalmistryV1/pages/RelationshipStatus/index.tsx @@ -46,7 +46,7 @@ function RelationshipStatus() { const handleClick = async (id: IAnswersSessionPalmistry["relationship_status"]) => { dispatch(actions.palmistryV1Answers.update({ relationshipStatus: id })); - await updateSession({ + updateSession({ answers: { relationship_status: id, }, diff --git a/src/components/PalmistryV1/pages/TrialPayment/styles.module.scss b/src/components/PalmistryV1/pages/TrialPayment/styles.module.scss index d801f16..2daa132 100644 --- a/src/components/PalmistryV1/pages/TrialPayment/styles.module.scss +++ b/src/components/PalmistryV1/pages/TrialPayment/styles.module.scss @@ -45,7 +45,7 @@ .paywall__get-prediction { position: fixed; - bottom: 0; + bottom: 0dvh; left: 0; align-items: center; background: #eff2fd; diff --git a/src/components/PalmistryV1/pages/WhatAspects/index.tsx b/src/components/PalmistryV1/pages/WhatAspects/index.tsx index 2161c9d..dfba1a1 100644 --- a/src/components/PalmistryV1/pages/WhatAspects/index.tsx +++ b/src/components/PalmistryV1/pages/WhatAspects/index.tsx @@ -46,7 +46,7 @@ function WhatAspects() { const handleClick = async (id: IAnswersSessionPalmistry["what_aspects"]) => { dispatch(actions.palmistryV1Answers.update({ whatAspects: id })); - await updateSession( + updateSession( { answers: { what_aspects: id, diff --git a/src/components/PalmistryV2/components/Address/index.tsx b/src/components/PalmistryV2/components/Address/index.tsx index 946aa70..dd005da 100644 --- a/src/components/PalmistryV2/components/Address/index.tsx +++ b/src/components/PalmistryV2/components/Address/index.tsx @@ -1,10 +1,16 @@ +import { useTranslations } from "@/hooks/translations"; import styles from "./styles.module.scss"; +import { ELocalesPlacement } from "@/locales"; function Address() { + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingPalmistryV2); + return (

- 2024, Wit Apps LLC,
- 2108 N ST STE 5446 SACRAMENTO, CA 95816, US + {translate("trial-payment.copyright", { + year: new Date().getFullYear(), + br: "\n", + })}

); } diff --git a/src/components/PalmistryV2/components/Address/styles.module.scss b/src/components/PalmistryV2/components/Address/styles.module.scss index af4bf2c..f9a48be 100644 --- a/src/components/PalmistryV2/components/Address/styles.module.scss +++ b/src/components/PalmistryV2/components/Address/styles.module.scss @@ -4,4 +4,5 @@ text-align: center; line-height: 16px; margin-top: 16px; + white-space: pre-line; } \ No newline at end of file diff --git a/src/components/PalmistryV2/components/DiscountExpires/index.tsx b/src/components/PalmistryV2/components/DiscountExpires/index.tsx index 94bebf5..e8f3f01 100644 --- a/src/components/PalmistryV2/components/DiscountExpires/index.tsx +++ b/src/components/PalmistryV2/components/DiscountExpires/index.tsx @@ -7,7 +7,7 @@ import { ELocalesPlacement } from "@/locales"; type TDiscountExpiresProps = HTMLAttributes; function DiscountExpires({ className = "", ...props }: TDiscountExpiresProps) { - const { translate } = useTranslations(ELocalesPlacement.V1); + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingPalmistryV2); const [currentDate, setCurrentDate] = useState(new Date()); const endDate = useMemo( () => new Date().setMinutes(currentDate.getMinutes() + 10), @@ -43,17 +43,17 @@ function DiscountExpires({ className = "", ...props }: TDiscountExpiresProps) { return (
- {translate("/trial-payment.discount_expires")} + {translate("trial-payment.discount_expires")}
{getMinutes()} - {translate("min")} + {translate("trial-payment.min")}

:

{getSeconds()} - {translate("sec")} + {translate("trial-payment.sec")}
diff --git a/src/components/PalmistryV2/components/GuardPayments/index.tsx b/src/components/PalmistryV2/components/GuardPayments/index.tsx index 01f890d..269723f 100644 --- a/src/components/PalmistryV2/components/GuardPayments/index.tsx +++ b/src/components/PalmistryV2/components/GuardPayments/index.tsx @@ -4,11 +4,11 @@ import { ELocalesPlacement } from "@/locales"; import { images } from "../../data"; function GuardPayments() { - const { translate } = useTranslations(ELocalesPlacement.V1); + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingPalmistryV2); return (
Guaranteed security -

{translate("guaranteed_security_payments")}

+

{translate("trial-payment.guaranteed_security_payments")}

); } diff --git a/src/components/PalmistryV2/components/MoneyBackGuarantee/index.tsx b/src/components/PalmistryV2/components/MoneyBackGuarantee/index.tsx index 924fd5d..6ee3c23 100644 --- a/src/components/PalmistryV2/components/MoneyBackGuarantee/index.tsx +++ b/src/components/PalmistryV2/components/MoneyBackGuarantee/index.tsx @@ -5,19 +5,15 @@ import { ELocalesPlacement } from "@/locales"; import { images } from "../../data"; function MoneyBackGuarantee() { - const { translate } = useTranslations(ELocalesPlacement.PalmistryV1); + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingPalmistryV2); return (
Money back - {translate("/trial-payment.money_back_guarantee.title")} + {translate("trial-payment.money_back_guarantee_title")}

- We are convinced that this report will provide you with a deeper - understanding of your partner and suggest ways to enhance your - relationship. With a track record of stellar customer reviews, we are - fully prepared to refund your money if you find that this report does not - deliver any value. + {translate("trial-payment.money_back_guarantee_text")}

); diff --git a/src/components/PalmistryV2/components/PalmsSayAbout/index.tsx b/src/components/PalmistryV2/components/PalmsSayAbout/index.tsx index 36586f9..e6ede1d 100644 --- a/src/components/PalmistryV2/components/PalmsSayAbout/index.tsx +++ b/src/components/PalmistryV2/components/PalmsSayAbout/index.tsx @@ -4,7 +4,7 @@ import { useTranslations } from "@/hooks/translations"; import { images } from "../../data"; function PalmsSayAbout() { - const { translate } = useTranslations(ELocalesPlacement.PalmistryV1); + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingPalmistryV2); return (
@@ -17,16 +17,13 @@ function PalmsSayAbout() {

- {/* {translate("/trial-payment.palms_say_about.point5", { + {translate("trial-payment.palms_say_about_point5", { color: ( - {translate("/trial-payment.palms_say_about.point5_color")} + {translate("trial-payment.palms_say_about_point5_color")} ), - })} */} - - {translate("/trial-payment.palms_say_about.point5_color")} - is a symbol of vitality, holds clues about your health, energy, and passion for life + })}

@@ -39,16 +36,13 @@ function PalmsSayAbout() {

- {/* {translate("/trial-payment.palms_say_about.point3", { + {translate("trial-payment.palms_say_about_point3", { color: ( - {translate("/trial-payment.palms_say_about.point3_color")} + {translate("trial-payment.palms_say_about_point3_color")} ), - })} */} - - {translate("/trial-payment.palms_say_about.point3_color")} - reflects intellectual pursuits and mental strengths + })}

@@ -61,16 +55,13 @@ function PalmsSayAbout() {

- {/* {translate("/trial-payment.palms_say_about.point7", { + {translate("trial-payment.palms_say_about_point7", { color: ( - {translate("/trial-payment.palms_say_about.point7_color")} + {translate("trial-payment.palms_say_about_point7_color")} ), - })} */} - - {translate("/trial-payment.palms_say_about.point7_color")} -  reveals insights into your financial potential and approach towards wealth + })}

@@ -83,17 +74,13 @@ function PalmsSayAbout() {

- {/* {translate("/trial-payment.palms_say_about.point1", { + {translate("trial-payment.palms_say_about_point1", { color: ( - {translate("/trial-payment.palms_say_about.point1_color")} + {translate("trial-payment.palms_say_about_point1_color")} ), - })} */} - - {translate("/trial-payment.palms_say_about.point1_color")} -   can reveal insights - into your romantic journey, mapping your heart's desires + })}

@@ -106,9 +93,7 @@ function PalmsSayAbout() {

- {/* {translate("/trial-payment.palms_say_about.point9")} */} - Each finger is a pillar of your - personality, from leadership and ambition to creativity and self- expression + {translate("trial-payment.palms_say_about_point9")}

diff --git a/src/components/PalmistryV2/components/PaymentTable/index.tsx b/src/components/PalmistryV2/components/PaymentTable/index.tsx index 01986da..dc6bea4 100644 --- a/src/components/PalmistryV2/components/PaymentTable/index.tsx +++ b/src/components/PalmistryV2/components/PaymentTable/index.tsx @@ -22,10 +22,10 @@ function PaymentTable({ placementKey, buttonClick, }: IPaymentTableProps) { - const { translate } = useTranslations(ELocalesPlacement.V1); + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingPalmistryV2); const { getText, currency } = usePaywall({ placementKey, - localesPlacement: ELocalesPlacement.V1, + localesPlacement: ELocalesPlacement.EmailMarketingPalmistryV2, }); const [isOpenPrivacyModal, setIsOpenPrivacyModal] = useState(false); const handleSubscriptionPolicyClick = (event: React.MouseEvent) => { @@ -71,18 +71,17 @@ function PaymentTable({ // backgroundColor: gender === "male" ? "#85B6FF" : "#D1ACF2", }} > - {translate("/trial-payment.payment_table.special_offer")} + {translate("trial-payment.payment_table_special_offer")}
- {/* {translate("/trial-payment.payment_table.title", { - price: <span className={styles.purple}>{getPrice(product)}</span>, - })} */} - Personalized plan for <span className={styles.blue}>{getPrice(product.trialPrice || 0)}</span> + {translate("trial-payment.payment_table_title", { + price: <span className={styles.purple}>{getPrice(product.trialPrice || 0)}</span>, + })}

- {translate("/trial-payment.payment_table.total_today")} + {translate("trial-payment.payment_table_total_today")}

{getPrice(product.trialPrice || 0)}
@@ -90,8 +89,7 @@ function PaymentTable({
{/* {product.trialPrice !== 50 && ( */}

- {/* {translate("/trial-payment.payment_table.cost")} */} - Including 1-week trial personal reading + {translate("trial-payment.payment_table_cost")}

{/* )} */} {/* {product.trialPrice === 50 && ( @@ -117,14 +115,14 @@ function PaymentTable({

- {translate("/trial-payment.subscription_policy", { + {translate("trial-payment.subscription_policy", { policyLink: ( - {translate("/trial-payment.policy_link")} + {translate("trial-payment.policy_link")} ), trialDuration: product.trialDuration, diff --git a/src/components/PalmistryV2/components/PaymentTable/styles.module.css b/src/components/PalmistryV2/components/PaymentTable/styles.module.css index 7e57951..d6970aa 100644 --- a/src/components/PalmistryV2/components/PaymentTable/styles.module.css +++ b/src/components/PalmistryV2/components/PaymentTable/styles.module.css @@ -80,6 +80,7 @@ font-size: 18px; font-weight: 600; line-height: 21px; + text-transform: uppercase; } .policy { diff --git a/src/components/PalmistryV2/components/PersonalInformation/index.tsx b/src/components/PalmistryV2/components/PersonalInformation/index.tsx index 270555a..d8e3737 100644 --- a/src/components/PalmistryV2/components/PersonalInformation/index.tsx +++ b/src/components/PalmistryV2/components/PersonalInformation/index.tsx @@ -15,7 +15,7 @@ function PersonalInformation({ gender, birthPlace, }: IPersonalInformationProps) { - const { translate } = useTranslations(ELocalesPlacement.V1); + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingPalmistryV2); return (

  • -
    {translate("/trial-payment.zodiac_sign")}
    -

    {translate(`zodiac_signs.${zodiacSign?.toLowerCase()}`)}

    +
    {translate("trial-payment.zodiac_sign")}
    +

    {translate(`trial-payment.zodiac_signs_${zodiacSign?.toLowerCase()}`)}

  • -
    {translate("gender")}
    -

    {translate(gender?.toLowerCase())}

    +
    {translate("trial-payment.gender")}
    +

    {translate(`trial-payment.${gender?.toLowerCase()}`)}

  • -
    {translate("/trial-payment.date_of_birth")}
    +
    {translate("trial-payment.date_of_birth")}

    {birthdate}

  • -
    {translate("/trial-payment.place_of_birth")}
    +
    {translate("trial-payment.place_of_birth")}

    {birthPlace}

diff --git a/src/components/PalmistryV2/components/Reviews/index.tsx b/src/components/PalmistryV2/components/Reviews/index.tsx index d74cb79..eca354a 100644 --- a/src/components/PalmistryV2/components/Reviews/index.tsx +++ b/src/components/PalmistryV2/components/Reviews/index.tsx @@ -6,29 +6,29 @@ import { useTranslations } from "@/hooks/translations"; import { ELocalesPlacement } from "@/locales"; function Reviews() { - const { translate } = useTranslations(ELocalesPlacement.PalmistryV1); + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingPalmistryV2); const reviews: IReviewProps[] = useMemo( () => [ { avatar: `${palmistryV1Prefix}/reviews/rebecca.png`, - username: translate("/trial-payment.reviews.username1"), + username: translate("trial-payment.reviews_username1"), date: "01/12/2024", gender: "female", - text: translate("/trial-payment.reviews.text1"), + text: translate("trial-payment.reviews_text1"), }, { avatar: `${palmistryV1Prefix}/reviews/mika.png`, - username: translate("/trial-payment.reviews.username2"), + username: translate("trial-payment.reviews_username2"), date: "07/12/2024", gender: "female", - text: translate("/trial-payment.reviews.text2"), + text: translate("trial-payment.reviews_text2"), }, { avatar: `${palmistryV1Prefix}/reviews/amanda.png`, - username: translate("/trial-payment.reviews.username3"), + username: translate("trial-payment.reviews_username3"), date: "16/11/2024", gender: "female", - text: translate("/trial-payment.reviews.text3"), + text: translate("trial-payment.reviews_text3"), }, ], [translate] diff --git a/src/components/PalmistryV2/components/SecretDiscountTable/index.tsx b/src/components/PalmistryV2/components/SecretDiscountTable/index.tsx index 8487059..e688d63 100644 --- a/src/components/PalmistryV2/components/SecretDiscountTable/index.tsx +++ b/src/components/PalmistryV2/components/SecretDiscountTable/index.tsx @@ -5,6 +5,7 @@ import { usePaywall } from "@/hooks/paywall/usePaywall"; import { addCurrency, ELocalesPlacement } from "@/locales"; import { EPlacementKeys } from "@/api/resources/Paywall"; import { Currency } from "@/components/PaymentTable"; +import { useTranslations } from "@/hooks/translations"; const placementKey = EPlacementKeys["aura.placement.email.palmistry.discount"] @@ -21,8 +22,9 @@ const getPrice = (price: number, currency: Currency) => { function SecretDiscountTable() { const { products, currency, getText } = usePaywall({ placementKey, - localesPlacement: ELocalesPlacement.PalmistryV1, + localesPlacement: ELocalesPlacement.EmailMarketingPalmistryV2, }); + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingPalmistryV2); const activeProduct = products[0]; const price = activeProduct?.price || 0; @@ -32,28 +34,30 @@ function SecretDiscountTable() { return (
- You get a secret discount! + {translate("secret-discount.secret-discount-table_title")} -

No pressure. Cancel anytime.

+

+ {translate("secret-discount.secret-discount-table_subtitle")} +

Gift - Secret discount applied! + {translate("secret-discount.secret-discount-table_discount-applied")} {getText("old.discount")} {getText("new.discount")}
-

Your cost per {trialDuration} days after trial:

+

{translate("secret-discount.secret-discount-table_cost-after-trial", { days: trialDuration })}

{addCurrency(Number(getText("old.price")), currency)} {getPrice(price, currency)}
-

You save {addCurrency(Number(getText("save")), currency)}

+

{translate("secret-discount.secret-discount-table_you-save", { amount: addCurrency(Number(getText("save")), currency) })}


-

Total today

+

{translate("secret-discount.secret-discount-table_total-today")}

{getPrice(trialPrice, currency)}
diff --git a/src/components/PalmistryV2/components/WithPartnerInformation/index.tsx b/src/components/PalmistryV2/components/WithPartnerInformation/index.tsx index 0f09d89..54050e6 100644 --- a/src/components/PalmistryV2/components/WithPartnerInformation/index.tsx +++ b/src/components/PalmistryV2/components/WithPartnerInformation/index.tsx @@ -25,7 +25,7 @@ function WithPartnerInformation(props: IWithPartnerInformationProps) { partnerGender, partnerBirthPlace, } = props; - const { translate } = useTranslations(ELocalesPlacement.V1); + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingPalmistryV2); return (
  • -
    {translate("/trial-payment.zodiac_sign")}
    +
    {translate("trial-payment.zodiac_sign")}

    {zodiacSign?.length - ? translate(`zodiac_signs.${zodiacSign?.toLowerCase()}`) + ? translate(`trial-payment.zodiac_signs_${zodiacSign?.toLowerCase()}`) : "-"}

  • -
    {translate("gender")}
    -

    {gender.length ? translate(gender?.toLowerCase()) : "-"}

    +
    {translate("trial-payment.gender")}
    +

    {gender.length ? translate(`trial-payment.${gender?.toLowerCase()}`) : "-"}

  • -
    {translate("/trial-payment.date_of_birth")}
    +
    {translate("trial-payment.date_of_birth")}

    {birthdate.length ? birthdate : "-"}

  • -
    {translate("/trial-payment.place_of_birth")}
    +
    {translate("trial-payment.place_of_birth")}

    {birthPlace.length ? birthPlace : "-"}

  • -
    {translate("/trial-payment.zodiac_sign")}
    +
    {translate("trial-payment.zodiac_sign")}

    {partnerZodiacSign?.length - ? translate(`zodiac_signs.${partnerZodiacSign?.toLowerCase()}`) + ? translate(`trial-payment.zodiac_signs_${partnerZodiacSign?.toLowerCase()}`) : "-"}

  • -
    {translate("gender")}
    -

    {partnerGender.length ? translate(partnerGender?.toLowerCase()) : "-"}

    +
    {translate("trial-payment.gender")}
    +

    {partnerGender.length ? translate(`trial-payment.${partnerGender?.toLowerCase()}`) : "-"}

  • -
    {translate("/trial-payment.date_of_birth")}
    +
    {translate("trial-payment.date_of_birth")}

    {partnerBirthDate.length ? partnerBirthDate : "-"}

  • -
    {translate("/trial-payment.place_of_birth")}
    +
    {translate("trial-payment.place_of_birth")}

    {partnerBirthPlace.length ? partnerBirthPlace : "-"}

diff --git a/src/components/PalmistryV2/images/SVG/Blob4/index.tsx b/src/components/PalmistryV2/images/SVG/Blob4/index.tsx index 08e3d4e..6001c5c 100644 --- a/src/components/PalmistryV2/images/SVG/Blob4/index.tsx +++ b/src/components/PalmistryV2/images/SVG/Blob4/index.tsx @@ -1,11 +1,13 @@ import { SVGProps } from "react" function Blob4(props: SVGProps) { + const width = props.width ? Number(props.width) : 419; + const height = props.height ? Number(props.height) : 193; return ( - - + + - + diff --git a/src/components/PalmistryV2/pages/SaveOff/index.tsx b/src/components/PalmistryV2/pages/SaveOff/index.tsx index 8fa9fa0..163a138 100644 --- a/src/components/PalmistryV2/pages/SaveOff/index.tsx +++ b/src/components/PalmistryV2/pages/SaveOff/index.tsx @@ -8,14 +8,16 @@ import { useNavigate } from "react-router-dom"; import routes from "@/routes"; import { usePaywall } from "@/hooks/paywall/usePaywall"; import { EPlacementKeys } from "@/api/resources/Paywall"; -import { ELocalesPlacement } from "@/locales"; +import { addCurrency, ELocalesPlacement } from "@/locales"; +import { useTranslations } from "@/hooks/translations"; const placementKey = EPlacementKeys["aura.placement.email.palmistry.discount"] function SaveOff() { - const { products, getText } = usePaywall({ + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingPalmistryV2); + const { products, currency, getText } = usePaywall({ placementKey, - localesPlacement: ELocalesPlacement.PalmistryV1, + localesPlacement: ELocalesPlacement.EmailMarketingPalmistryV2, }); const activeProduct = products[0] const price = (activeProduct?.price || 0) / 100 @@ -33,19 +35,28 @@ function SaveOff() { gift - SAVE {getText("discount")}% OFF! + {translate("save-off.title", { discount: getText("discount") })}

- ${price} instead of ${getText("full.price")} + {translate("save-off.instead", { + price: {addCurrency(price, currency)}, + oldPrice: + {translate("save-off.instead-old-price", { + oldPrice: addCurrency(getText("full.price") as string, currency) + })} + + })}

- fire {trialDuration}-day trial + fire + {translate("save-off.trial-duration", { days: trialDuration })}

- gift {getText("discount")}% off on your personalized plan + gift + {translate("save-off.discount-offer", { discount: getText("discount") })}

) diff --git a/src/components/PalmistryV2/pages/SecretDiscount/index.tsx b/src/components/PalmistryV2/pages/SecretDiscount/index.tsx index 7c0d2c8..01341dc 100644 --- a/src/components/PalmistryV2/pages/SecretDiscount/index.tsx +++ b/src/components/PalmistryV2/pages/SecretDiscount/index.tsx @@ -6,7 +6,7 @@ import SecretDiscountTable from "../../components/SecretDiscountTable"; import Button from "../../components/Button"; import { usePaywall } from "@/hooks/paywall/usePaywall"; import { EPlacementKeys } from "@/api/resources/Paywall"; -import { ELocalesPlacement } from "@/locales"; +import { addCurrency, ELocalesPlacement } from "@/locales"; import Modal from "@/components/Modal"; import { useEffect, useState } from "react"; import PaymentForm from "@/components/Payment/nmi/PaymentForm"; @@ -14,16 +14,22 @@ import { useNavigate } from "react-router-dom"; import routes from "@/routes"; import { useDispatch } from "react-redux"; import { actions } from "@/store"; +import { useTranslations } from "@/hooks/translations"; +import { useDynamicSize } from "@/hooks/useDynamicSize"; +import Header from "@/components/pages/ABDesign/v1/components/Header"; const placementKey = EPlacementKeys["aura.placement.email.palmistry.discount"] function SecretDiscount() { + const { width, elementRef } = useDynamicSize({ defaultWidth: 560 }); + const { height, elementRef: policyContainerRef } = useDynamicSize({ defaultWidth: 560, defaultHeight: 193 }); const dispatch = useDispatch(); const navigate = useNavigate(); - const { products } = usePaywall({ + const { products, currency } = usePaywall({ placementKey, - localesPlacement: ELocalesPlacement.PalmistryV1, + localesPlacement: ELocalesPlacement.EmailMarketingPalmistryV2, }); + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingPalmistryV2); const activeProduct = products[0]; const price = (activeProduct?.price || 0) / 100; @@ -56,7 +62,14 @@ function SecretDiscount() { }; return ( - <> +
+
{activeProduct && ( - You get a secret discount! + {translate("secret-discount.title")} -
+

- By continuing you agree that if you don't cancel prior to the end of the {trialDuration}-days trial, you will automatically be charged ${price} for the introductory period of 14 days thereafter the standard rate of ${price} every 14 days until you cancel in settings. Learn more about cancellation and refund policy in Subscription terms. + {translate("secret-discount.policy", { + days: trialDuration, + price: addCurrency(price, currency) + })}

- +
- +
) } diff --git a/src/components/PalmistryV2/pages/SecretDiscount/styles.module.scss b/src/components/PalmistryV2/pages/SecretDiscount/styles.module.scss index c38b907..8454dba 100644 --- a/src/components/PalmistryV2/pages/SecretDiscount/styles.module.scss +++ b/src/components/PalmistryV2/pages/SecretDiscount/styles.module.scss @@ -1,3 +1,24 @@ +.container { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + padding: 20px 26px; + min-height: 100dvh; + max-width: 560px; + margin: 0 auto; + position: relative; + overflow: hidden; +} + +.header { + padding: 8px 0 30px; + + &>button { + margin-left: -12px; + } +} + .blob3 { position: absolute; top: 0; @@ -27,10 +48,13 @@ } .policy-container { - position: relative; - width: calc(100% + 52px); + position: absolute; + width: calc(100%); + max-width: 560px; height: fit-content; - bottom: -58px; + bottom: 0; + left: 50%; + transform: translateX(-50%); &>.policy { width: 100%; diff --git a/src/components/PalmistryV2/pages/TrialPayment/index.tsx b/src/components/PalmistryV2/pages/TrialPayment/index.tsx index 48a65f5..4defacc 100644 --- a/src/components/PalmistryV2/pages/TrialPayment/index.tsx +++ b/src/components/PalmistryV2/pages/TrialPayment/index.tsx @@ -3,7 +3,7 @@ import Title from "@/components/Title"; import Button from "../../components/Button"; import routes from "@/routes"; import { useNavigate } from "react-router-dom"; -// import { useTranslations } from "@/hooks/translations"; +import { useTranslations } from "@/hooks/translations"; import { ELocalesPlacement } from "@/locales"; import { images } from "../../data"; import DiscountExpires from "../../components/DiscountExpires"; @@ -30,7 +30,7 @@ function TrialPayment() { const api = useApi(); const token = useSelector(selectors.selectToken); const dispatch = useDispatch(); - // const { translate } = useTranslations(ELocalesPlacement.PalmistryV1); + const { translate } = useTranslations(ELocalesPlacement.EmailMarketingPalmistryV2); const { products } = usePaywall({ placementKey, localesPlacement: ELocalesPlacement.PalmistryV1, @@ -107,22 +107,18 @@ function TrialPayment() {
- Transform your <br /> - life with the Power <br /> - of Palmistry — Get your - personalized plan today + {translate("trial-payment.transform_your_life")} Hand
- Personalized Palmistry <br /> - Reading is ready! + {translate("trial-payment.personalized_reading_ready")} - What your hands and fingers can reveal about you + {translate("trial-payment.hands_reveal_title")}

- Your hands and fingers are like a personal storybook, with each line - representing a chapter of your life. + {translate("trial-payment.hands_reveal_description")}

- We will prepare your - personalized plan + {translate("trial-payment.prepare_personalized_plan")} {singleOrWithPartner === "partner" && ( )} - Here are a few stories from - AURA Users + {translate("trial-payment.aura_users_stories")} - As featured in + {translate("trial-payment.as_featured_in")}
Featured diff --git a/src/components/PalmistryV2/pages/TrialPayment/styles.module.scss b/src/components/PalmistryV2/pages/TrialPayment/styles.module.scss index 2be6fd6..30d3f3a 100644 --- a/src/components/PalmistryV2/pages/TrialPayment/styles.module.scss +++ b/src/components/PalmistryV2/pages/TrialPayment/styles.module.scss @@ -24,6 +24,7 @@ text-align: left; color: #2c2c2c; max-width: 215px; + white-space: pre-line } &>img { @@ -60,6 +61,7 @@ color: #2c2c2c; margin-top: 8px; margin-bottom: 8px; + white-space: pre-line; } .title-hands { @@ -87,6 +89,7 @@ text-align: center; color: #224e90; margin-bottom: 0; + white-space: pre-line; } .title-reviews { @@ -97,6 +100,7 @@ text-align: center; color: #224e90; margin-bottom: 0; + white-space: pre-line; } .title-featured { diff --git a/src/components/Payment/nmi/PaymentForm/index.tsx b/src/components/Payment/nmi/PaymentForm/index.tsx index be3f68a..b08a634 100644 --- a/src/components/Payment/nmi/PaymentForm/index.tsx +++ b/src/components/Payment/nmi/PaymentForm/index.tsx @@ -21,6 +21,7 @@ const getPrice = (product: IPaywallProduct | null) => { } interface IPaymentFormProps { + isSinglePayment?: boolean; className?: string; placementKey: EPlacementKeys; onPaymentError?: () => void; @@ -28,7 +29,7 @@ interface IPaymentFormProps { onModalClosed?: () => void; } -function PaymentForm({ className, placementKey, onPaymentError, onPaymentSuccess, onModalClosed }: IPaymentFormProps) { +function PaymentForm({ isSinglePayment = false, className, placementKey, onPaymentError, onPaymentSuccess, onModalClosed }: IPaymentFormProps) { const { translate } = useTranslations(ELocalesPlacement.V1); const currency = useSelector(selectors.selectCurrency); const activeProduct = useSelector(selectors.selectActiveProduct); @@ -48,15 +49,15 @@ function PaymentForm({ className, placementKey, onPaymentError, onPaymentSuccess
- + {!isSinglePayment && <Title variant="h3" className={styles.title}> {translate("payment_modal.title")} - + } { }} /> - {activeProduct && ( + {!isSinglePayment && activeProduct && (

{translate("payment_modal.description", { diff --git a/src/components/pages/ABDesign/v1/components/PrivacyPolicy/index.tsx b/src/components/pages/ABDesign/v1/components/PrivacyPolicy/index.tsx index f9f9288..388458e 100644 --- a/src/components/pages/ABDesign/v1/components/PrivacyPolicy/index.tsx +++ b/src/components/pages/ABDesign/v1/components/PrivacyPolicy/index.tsx @@ -7,9 +7,10 @@ import { ELocalesPlacement } from "@/locales"; interface IPrivacyPolicyProps { containerClassName?: string; + haveCheckbox?: boolean; } -function PrivacyPolicy({ containerClassName = "" }: IPrivacyPolicyProps) { +function PrivacyPolicy({ containerClassName = "", haveCheckbox = true }: IPrivacyPolicyProps) { const dispatch = useDispatch(); const { translate } = useTranslations(ELocalesPlacement.V1); const { checked } = useSelector(selectors.selectPrivacyPolicy); @@ -20,7 +21,7 @@ function PrivacyPolicy({ containerClassName = "" }: IPrivacyPolicyProps) { return (

- + {haveCheckbox && }

{translate("policy", { privacyPolicy: ( diff --git a/src/components/pages/ABDesign/v1/pages/TrialPayment/components/Header/index.tsx b/src/components/pages/ABDesign/v1/pages/TrialPayment/components/Header/index.tsx index 1a75670..601804a 100644 --- a/src/components/pages/ABDesign/v1/pages/TrialPayment/components/Header/index.tsx +++ b/src/components/pages/ABDesign/v1/pages/TrialPayment/components/Header/index.tsx @@ -1,8 +1,6 @@ -import { useSelector } from "react-redux"; import CustomButton from "../CustomButton"; import DiscountExpires from "../DiscountExpires"; import styles from "./styles.module.css"; -import { selectors } from "@/store"; interface IHeaderProps { buttonText?: string; @@ -15,12 +13,12 @@ function Header({ buttonText = "get my reading", buttonClassName = "", }: IHeaderProps) { - const { gender } = useSelector(selectors.selectQuestionnaire); + // const { gender } = useSelector(selectors.selectQuestionnaire); return (

diff --git a/src/components/pages/ABDesign/v1/pages/TrialPayment/components/Header/styles.module.css b/src/components/pages/ABDesign/v1/pages/TrialPayment/components/Header/styles.module.css index bd059bc..adbf58f 100644 --- a/src/components/pages/ABDesign/v1/pages/TrialPayment/components/Header/styles.module.css +++ b/src/components/pages/ABDesign/v1/pages/TrialPayment/components/Header/styles.module.css @@ -3,13 +3,15 @@ top: 0; z-index: 30; height: 62px; - width: 100%; + width: calc(100% + 64px); max-width: 560px; display: flex; -webkit-box-align: center; align-items: center; justify-content: space-between; - padding: 8px 15px; + padding: 8px 47px; + background-color: transparent; + backdrop-filter: blur(5px); } .button { diff --git a/src/components/pages/Auth/index.tsx b/src/components/pages/Auth/index.tsx index 490d411..4849adf 100644 --- a/src/components/pages/Auth/index.tsx +++ b/src/components/pages/Auth/index.tsx @@ -4,7 +4,7 @@ import { useTranslations } from "@/hooks/translations"; import { ELocalesPlacement } from "@/locales"; import { useDispatch, useSelector } from "react-redux"; import { useNavigate, useParams } from "react-router-dom"; -import { useEffect, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import { useDynamicSize } from "@/hooks/useDynamicSize"; import { useAuthentication } from "@/hooks/authentication/use-authentication"; import { actions, selectors } from "@/store"; @@ -32,11 +32,17 @@ interface IAuthPage { } function Auth({ redirectUrl = routes.client.home() }: IAuthPage) { + const [passwordFromQuery, emailFromQuery] = useMemo(() => { + const url = window.location.href; + const [_password, _email] = url.split("?")?.[1]?.split("password=", 2)?.[1]?.split("&email=") || ["", ""] + return [decodeURIComponent(_password), decodeURIComponent(_email)] + }, [window.location.href]); + const { translate } = useTranslations(ELocalesPlacement.V1); const dispatch = useDispatch(); const navigate = useNavigate(); - const [email, setEmail] = useState(""); - const [password, setPassword] = useState(""); + const [email, setEmail] = useState(emailFromQuery || ""); + const [password, setPassword] = useState(passwordFromQuery || ""); const [isDisabled, setIsDisabled] = useState(true); const [isValidEmail, setIsValidEmail] = useState(false); const [isValidPassword, setIsValidPassword] = useState(false); @@ -78,6 +84,16 @@ function Auth({ redirectUrl = routes.client.home() }: IAuthPage) { } }, [subPlan, products]); + useEffect(() => { + if (emailFromQuery?.length) { + setIsValidEmail(true); + } + if (passwordFromQuery?.length) { + setIsValidPassword(true); + } + }, [emailFromQuery, passwordFromQuery]); + + const handleValidEmail = (email: string) => { dispatch(actions.form.addEmail(email)); setEmail(email); diff --git a/src/hooks/authentication/use-authentication.ts b/src/hooks/authentication/use-authentication.ts index 5b5e7a7..72dd281 100644 --- a/src/hooks/authentication/use-authentication.ts +++ b/src/hooks/authentication/use-authentication.ts @@ -42,26 +42,26 @@ export const useAuthentication = () => { const birthtimeFromForm = useSelector(selectors.selectBirthtime); const birthdate = useMemo(() => { - if (birthdateFromQuestionnaire.length) { + if (birthdateFromQuestionnaire?.length) { return birthdateFromQuestionnaire; } - if (birthdateFromForm.length) { + if (birthdateFromForm?.length) { return birthdateFromForm; } }, [birthdateFromForm, birthdateFromQuestionnaire]); const birthtime = useMemo(() => { - if (birthtimeFromQuestionnaire.length) { + if (birthtimeFromQuestionnaire?.length) { return birthtimeFromQuestionnaire; } - if (birthtimeFromForm.length) { + if (birthtimeFromForm?.length) { return birthtimeFromForm; } }, [birthtimeFromForm, birthtimeFromQuestionnaire]); const partnerBirthdate = useMemo(() => { const fromQuestionnaire = `${partnerBirthdateFromQuestionnaire} ${partnerBirthtime}` - if (partnerBirthdateFromQuestionnaire.length) { + if (partnerBirthdateFromQuestionnaire?.length) { return fromQuestionnaire; } return getDateAsString(partnerBirthdateFromForm) @@ -141,14 +141,15 @@ export const useAuthentication = () => { } } const { user } = await api.getUser({ token }); + const { user: userMe } = await api.getMe({ token }); if (userId?.length) { metricService.userParams({ - email: user.email, + email: user?.email, UserID: userId }) metricService.setUserID(userId); } - signUp(token, user); + signUp(token, user, userMe); setToken(token); dispatch(actions.status.update("registred")); } catch (error: unknown) { @@ -167,16 +168,17 @@ export const useAuthentication = () => { const payload = getAuthorizationPayload(email, source); const { token, userId, generatingVideo, videoId, authCode } = await api.authorization(payload); const { user } = await api.getUser({ token }); + const { user: userMe } = await api.getMe({ token }); if (userId?.length) { dispatch(actions.userId.update({ userId })); metricService.userParams({ hasPersonalVideo: generatingVideo || false, - email: user.email, + email: user?.email, UserID: userId }) metricService.setUserID(userId); } - signUp(token, user); + signUp(token, user, userMe); setToken(token); if (authCode?.length) { dispatch(actions.userConfig.setAuthCode(authCode)); diff --git a/src/hooks/chatsSocket/useChatsSocket.ts b/src/hooks/chatsSocket/useChatsSocket.ts index 6c0a605..a4dd699 100644 --- a/src/hooks/chatsSocket/useChatsSocket.ts +++ b/src/hooks/chatsSocket/useChatsSocket.ts @@ -126,15 +126,21 @@ const useChatSocket = (userId: string, chatId: string) => { }, [chatId, fetchBalance]) const receiveMessage = useCallback((message: IMessage[]) => { - if (message[0]?.role === "user") { + if (!message?.[0]) return; + + if (message[0].role === "user") { setIsLoadingSelfMessage(false); } - if (message[0]?.role === "assistant") { + if (message[0].role === "assistant") { setIsLoadingAdvisorMessage(false); } - setMessages((prev) => [...prev, message[0]]); - - }, []) + setMessages((prev) => { + if (prev.some(msg => msg.id === message[0].id)) { + return prev; + } + return [...prev, message[0]]; + }); + }, []); const currentBalance = useCallback((balance: IResponse) => { setBalance(balance?.data); @@ -208,11 +214,11 @@ const useChatSocket = (userId: string, chatId: string) => { init(); }, [init]); - useEffect(() => { - if (!socket) return setIsAvailableChatting(false); - joinChat(chatId); - fetchBalance(chatId); - }, [chatId, fetchBalance, joinChat, socket]); + // useEffect(() => { + // if (!socket) return setIsAvailableChatting(false); + // joinChat(chatId); + // fetchBalance(chatId); + // }, [chatId, fetchBalance, joinChat, socket]); useEffect(() => { const interval = setInterval(() => { @@ -258,6 +264,28 @@ const useChatSocket = (userId: string, chatId: string) => { } }, [dispatch, session]); + useEffect(() => { + if (!socket) return; + + const handleReconnect = () => { + setIsLoadingSelfMessage(false); + setIsLoadingAdvisorMessage(false); + joinChat(chatId); + fetchBalance(chatId); + }; + + socket.on('connect', handleReconnect); + socket.on('disconnect', () => { + setIsLoadingSelfMessage(false); + setIsLoadingAdvisorMessage(false); + }); + + return () => { + socket.off('connect', handleReconnect); + socket.off('disconnect'); + }; + }, [socket, chatId, joinChat, fetchBalance]); + // clean up useEffect(() => { const handleBeforeUnload = () => { diff --git a/src/hooks/paywall/defaultPaywalls.ts b/src/hooks/paywall/defaultPaywalls.ts index 813f398..8f8f0c7 100644 --- a/src/hooks/paywall/defaultPaywalls.ts +++ b/src/hooks/paywall/defaultPaywalls.ts @@ -762,5 +762,63 @@ export const defaultPaywalls: { [key in EPlacementKeys]: IPaywall } = { "currency": "usd" } ] + }, + "aura.placement.email.compatibility.discount": { + "_id": "678ed4d62f5ba6ddbc7dd318", + "key": "aura.paywall.email.compatibility.discount", + "name": "Email Compatibility Discount", + "properties": [ + { + "key": "full.price", + "value": "45", + "_id": "678be264aaa17756a1e517df" + }, + { + "key": "discount", + "value": "70", + "_id": "" + }, + { + "key": "old.discount", + "value": "-30%", + "_id": "678d4093783493141ac1e545" + }, + { + "key": "new.discount", + "value": "-50%", + "_id": "678d4093783493141ac1e546" + }, + { + "key": "old.price", + "value": "19", + "_id": "678d4093783493141ac1e547" + }, + { + "key": "save", + "value": "30", + "_id": "678d4093783493141ac1e548" + } + ], + "products": [ + { + "_id": "66589439ef0d180993cdb72f", + "key": "compatibility.secret.discount.trial.0", + "productId": "prod_PnStTEBzrPLgvL", + "name": "Сompatibility AURA Secret Discount | Trial $0.99", + "priceId": "price_1PpFlMIlX4lgwUxrUTeWDFoI", + "type": "subscription", + "description": "Description", + "discountPrice": null, + "discountPriceId": null, + "isDiscount": false, + "isFreeTrial": false, + "isTrial": true, + "price": 900, + "trialDuration": 3, + "trialPrice": 100, + "trialPriceId": "price_1PpFoNIlX4lgwUxrP4l0lbE5", + "currency": "usd" + } + ] } } \ No newline at end of file diff --git a/src/locales/index.ts b/src/locales/index.ts index 1654092..7d5f4c5 100644 --- a/src/locales/index.ts +++ b/src/locales/index.ts @@ -5,6 +5,8 @@ import locales from './locales.ts' import { Currency } from '@/components/PaymentTable/Price.ts' import { symbolByCurrency } from './currency.ts' +// const environments = import.meta.env; + // export const getClientLocale = () => { // return navigator.language // } @@ -71,7 +73,9 @@ export enum ELocalesPlacement { PalmistryV01 = "palmistry-v0_1", PalmistryV1 = "palmistry-v1", PalmistryV11 = "palmistry-v1_1", - Chats = "chats" + Chats = "chats", + EmailMarketingCompatibilityV1 = "email-marketing-comp-v1", + EmailMarketingPalmistryV2 = "email-marketing-palmistry-v2", } interface ITranslationJSON { @@ -86,6 +90,7 @@ export type TTranslationPlacements = Partial< export const getTranslationsJSON = async (language: string): Promise => { const api = createApi(); + // const isProduction = environments.MODE === "production" && window.location.hostname !== "localhost"; let defaultLanguage = getDefaultLocaleByLanguage(language).toLowerCase(); if (defaultLanguage === "pt") { defaultLanguage = "pt-pt" @@ -94,17 +99,32 @@ export const getTranslationsJSON = async (language: string): Promise placement !== ELocalesPlacement.V0); try { - const responses = await Promise.all( - placements.map(place => - api.getLocaleTranslations({ - funnel: place, - locale: defaultLanguage - }) - ) + const responses = await Promise.allSettled( + placements.map(async place => { + try { + // return isProduction + // ? + return await api.getLocaleTranslations({ + funnel: place, + locale: defaultLanguage + }) + // : await (await fetch(`/locales/${place}/${defaultLanguage}/male_${defaultLanguage}.json`)).json() + } catch (error) { + console.error(`Ошибка загрузки переводов для ${place}:`, error); + return null; // или можно вернуть пустой объект {} + } + }) ); - const result = responses.reduce((merged, current, index) => ({ + // Фильтруем успешные результаты + const successfulResponses = responses + .filter(result => result.status === 'fulfilled') + .map(result => (result as PromiseFulfilledResult).value) + .filter(Boolean); + + const result = successfulResponses.reduce((merged, current, index) => ({ ...merged, + // [placements[index]]: isProduction ? current : { male: current } [placements[index]]: current }), {}); diff --git a/src/routerComponents/ABDesign/v1/LayoutSession/index.tsx b/src/routerComponents/ABDesign/v1/LayoutSession/index.tsx index 85b2cb7..d1a5635 100644 --- a/src/routerComponents/ABDesign/v1/LayoutSession/index.tsx +++ b/src/routerComponents/ABDesign/v1/LayoutSession/index.tsx @@ -16,7 +16,7 @@ function LayoutSession() { ); useEffect(() => { - if (flowChoice.length) { + if (flowChoice?.length) { updateSession( { profile: { @@ -31,7 +31,7 @@ function LayoutSession() { }, [flowChoice]); useEffect(() => { - if (partnerGender.length) { + if (partnerGender?.length) { updateSession( { partner: { diff --git a/src/routerComponents/MarketingLanding/v1/index.tsx b/src/routerComponents/MarketingLanding/v1/index.tsx index 95fb43e..0351eb1 100644 --- a/src/routerComponents/MarketingLanding/v1/index.tsx +++ b/src/routerComponents/MarketingLanding/v1/index.tsx @@ -4,6 +4,8 @@ import NotFoundPage from "@/components/NotFoundPage"; import MarketingLanding from "@/components/EmailMarketing/v1/pages/MarketingLanding"; import styles from "./styles.module.scss"; import SpecialOffer from "@/components/EmailMarketing/v1/pages/SpecialOffer"; +import SecretDiscount from "@/components/EmailMarketing/v1/pages/SecretDiscount"; +import SaveOff from "@/components/EmailMarketing/v1/pages/SaveOff"; const removePrefix = (path: string) => path.replace(emailMarketingV1Prefix, ""); function MarketingLandingV1Routes() { @@ -19,6 +21,14 @@ function MarketingLandingV1Routes() { path={removePrefix(routes.client.emailMarketingV1SpecialOffer())} element={} /> + } + /> + } + /> } /> diff --git a/src/routerComponents/Palmistry/v2/index.tsx b/src/routerComponents/Palmistry/v2/index.tsx index b14c601..9c4705f 100644 --- a/src/routerComponents/Palmistry/v2/index.tsx +++ b/src/routerComponents/Palmistry/v2/index.tsx @@ -13,7 +13,7 @@ const removePrefix = (path: string) => path.replace(palmistryV2Prefix, ""); function PalmistryV2Routes() { const dispatch = useDispatch(); - + useEffect(() => { dispatch(actions.palmistry.update({ fromRedesign: true })); @@ -21,6 +21,10 @@ function PalmistryV2Routes() { return ( + } + /> }> {/* } > */} - } - /> - } - /> - } - /> - {/* } + /> + } + /> + {/* } /> */} - } /> - + } /> + {/* */} ); diff --git a/src/routes.ts b/src/routes.ts index 6314047..948898c 100755 --- a/src/routes.ts +++ b/src/routes.ts @@ -196,6 +196,8 @@ const routes = { // MarketingLandingV1 emailMarketingV1Landing: () => [emailMarketingV1Prefix, "marketing-landing"].join("/"), emailMarketingV1SpecialOffer: () => [emailMarketingV1Prefix, "special-offer"].join("/"), + emailMarketingV1SaveOff: () => [emailMarketingV1Prefix, "save-off"].join("/"), + emailMarketingV1SecretDiscount: () => [emailMarketingV1Prefix, "secret-discount"].join("/"), // ABDesignV1 genderV1: () => [host, "v1", "gender"].join("/"), questionnaireV1: () => [host, "v1", "questionnaire"].join("/"), diff --git a/src/store/paywalls.ts b/src/store/paywalls.ts index 2692ab7..1933c67 100644 --- a/src/store/paywalls.ts +++ b/src/store/paywalls.ts @@ -27,6 +27,7 @@ const initialState: TPaywalls = { "aura.placement.chat": null, "aura.placement.email.palmistry": null, "aura.placement.email.palmistry.discount": null, + "aura.placement.email.compatibility.discount": null, isMustUpdate: { "aura.placement.v1.mike": true, "aura.placement.main": true, @@ -38,6 +39,7 @@ const initialState: TPaywalls = { "aura.placement.chat": true, "aura.placement.email.palmistry": true, "aura.placement.email.palmistry.discount": true, + "aura.placement.email.compatibility.discount": true, }, }