develop
This commit is contained in:
parent
71943b446d
commit
35493be717
498
public/locales/compatibility-v2/en/female_en.json
Normal file
498
public/locales/compatibility-v2/en/female_en.json
Normal file
@ -0,0 +1,498 @@
|
||||
{
|
||||
"next": "Next",
|
||||
"biometric_data": "We don’t collect any biometric data. All recognition processes occur on your device.",
|
||||
"went_wrong": "Something went wrong.",
|
||||
"v": "v1",
|
||||
"config": "en.male",
|
||||
"threadId": "thread_uBoB6htpYLoPp1bHDUXnrVKS",
|
||||
"assistantId": "asst_ZClw0fzJaQlhxUigjxHp87Nc",
|
||||
"privacy_policy": "By continuing, you agree to our <eulaLink> and <privacyLink>. Have a question? Reach out to our support team <clickHere>",
|
||||
"eula_link": "End User License Agreement",
|
||||
"privacy_notice": "Privacy Notice",
|
||||
"policy_here": "here",
|
||||
"thumb": "Thumb",
|
||||
"index_finger": "Index finger",
|
||||
"middle_finger": "Middle finger",
|
||||
"ring_finger": "Ring finger",
|
||||
"pinky": "Little finger",
|
||||
"skip_trial": "Skip trial period",
|
||||
"add_consultant": "Add consultant",
|
||||
"add_guides": "Add guides",
|
||||
"access_product": "Access product",
|
||||
"thank_you": "Thank you!",
|
||||
"order_successful": "Your order was successfully processed!",
|
||||
"male": "Male",
|
||||
"female": "Female",
|
||||
"males": "Males",
|
||||
"females": "Females",
|
||||
"/find-your-happiness": {
|
||||
"title": "Gain Clarity and Confidence in Life",
|
||||
"text": "Use astrology and palmistry to strengthen yourself and your relationships",
|
||||
"advantage1": "In-depth Analysis: We scan the lines on your palm",
|
||||
"advantage2": "Personalized Approach: Compatibility and Future Analysis",
|
||||
"advantage3": "Quick Results: Takes no more than 5 minutes"
|
||||
},
|
||||
"/gender": {
|
||||
"title": "What is Your Gender?",
|
||||
"description": "In palmistry, everyone has both masculine and feminine traits. <br><br> Let's determine yours for a more accurate palm reading.",
|
||||
"already_have_account": "Already have an account? Sign in"
|
||||
},
|
||||
"/birthdate": {
|
||||
"title": "When Were You Born?",
|
||||
"text": "Your birth date can reveal strengths and values that may help you move forward"
|
||||
},
|
||||
"/palms-information": {
|
||||
"aries": {
|
||||
"title": "♈ Aries",
|
||||
"description": "Your palms are a map of destiny, reflecting your strength and character. According to our data, 76 million Aries have a clear and straight head line, indicating decisiveness and independence. In 81% of successful relationships, their partners share their passion for action. Your palms will reveal how well your ambitions and energy align with your partner."
|
||||
},
|
||||
"taurus": {
|
||||
"title": "♉ Taurus",
|
||||
"description": "The patterns on your palms reveal your true self. Our research shows that 83 million Taurus have a long and smooth life line, a sign of resilience and desire for stability. In 86% of harmonious relationships, partners value reliability and comfort. Take a look at your palm—it will indicate how strong your union is."
|
||||
},
|
||||
"gemini": {
|
||||
"title": "♊ Gemini",
|
||||
"description": "Your palms are a mirror of your mind and character. According to our data, 72 million Gemini have a bifurcated or branched head line, suggesting flexibility and multitasking ability. In 78% of successful relationships, partners are ready for change and spontaneity. Check your lines—they will show how well your partner matches your pace."
|
||||
},
|
||||
"cancer": {
|
||||
"title": "♋ Cancer",
|
||||
"description": "Your palm lines hide secrets of emotions and attachments. Our data shows that 78 million Cancers have a clear and expressive heart line, indicating deep sensitivity. In 82% of strong relationships, Cancer partners have well-developed empathy. Your palm will help reveal how well you and your loved one understand each other."
|
||||
},
|
||||
"leo": {
|
||||
"title": "♌ Leo",
|
||||
"description": "Palms store the history of your personality. Our data indicates that 80 million Leos have a noticeable Sun line, which suggests innate charisma and a drive for recognition. In 84% of happy relationships, Leo partners are admired and share their ambitions. Your palm will show how ready your partner is to be part of your shine."
|
||||
},
|
||||
"virgo": {
|
||||
"title": "♍ Virgo",
|
||||
"description": "Every line on your palm is a trace of your character. Our observations show that 75 million Virgos have fine but distinct lines, reflecting attention to detail and rationality. In 79% of successful Virgo relationships, trust and predictability are key. Your palms will reveal how well your values align with your partner."
|
||||
},
|
||||
"libra": {
|
||||
"title": "♎ Libra",
|
||||
"description": "The harmony of your palms reflects the harmony of your soul. Our data shows that 77 million Libras have a curved and smooth heart line, indicating diplomacy and balanced relationships. In 80% of successful partnerships, their partners appreciate honesty and compromise. Look at your palm—it will indicate how much your relationship is based on mutual understanding."
|
||||
},
|
||||
"scorpio": {
|
||||
"title": "♏ Scorpio",
|
||||
"description": "The depth of your palm lines reflects the depth of your feelings. Our research shows that 81 million Scorpios have a deep and straight heart line, indicating passion and devotion. In 83% of successful relationships, their partners share the same emotional intensity. Your palm will show how genuine the connection between you and your partner is."
|
||||
},
|
||||
"sagittarius": {
|
||||
"title": "♐ Sagittarius",
|
||||
"description": "The lines on your palm are a map of your life journey. Our data shows that 74 million Sagittarians have a long and prominent head line, symbolizing curiosity and a quest for freedom. In 77% of long-term relationships, their partners share an adventurous spirit. Your palm will tell you how ready your partner is for your ambitious dreams."
|
||||
},
|
||||
"capricorn": {
|
||||
"title": "♑ Capricorn",
|
||||
"description": "Your palms are a reflection of your strength and determination. Our data shows that 79 million Capricorns have a pronounced fate line, indicating their ambitions and discipline. In 85% of happy marriages, their partners support their pursuit of success. Look at your palm—it will reveal how much your union is based on shared goals."
|
||||
},
|
||||
"aquarius": {
|
||||
"title": "♒ Aquarius",
|
||||
"description": "The lines on your palm are the mark of your uniqueness. Our research shows that 71 million Aquarians have an unconventional head line, indicating originality and non-standard thinking. In 75% of harmonious relationships, their partners respect their freedom and independence. Your palm will reveal how ready your partner is for your innovative ideas."
|
||||
},
|
||||
"pisces": {
|
||||
"title": "♓ Pisces",
|
||||
"description": "Palms conceal the secrets of your soul. Our data shows that 82 million Pisces have a long and smooth heart line, indicating their intuition and deep sense of love. In 84% of strong relationships, their partners share a similar sensitivity. Your palm will tell you how well your partner can feel you on an emotional level."
|
||||
}
|
||||
},
|
||||
"/what-aspects": {
|
||||
"title": "Which Areas of Life Do You Want to Gain a Deeper Understanding Of?",
|
||||
"answer1": "Love and Relationships",
|
||||
"answer2": "Health and Energy",
|
||||
"answer3": "Career and Purpose",
|
||||
"answer4": "Life Transitions"
|
||||
},
|
||||
"/relationship-status": {
|
||||
"title": "To Better Understand You, Indicate Your Current Relationship Status",
|
||||
"answer1": "Single",
|
||||
"answer2": "In a Relationship",
|
||||
"answer3": "Married",
|
||||
"answer4": "Divorced"
|
||||
},
|
||||
"/element-resonates": {
|
||||
"title": "Which Element Empowers You the Most?",
|
||||
"answer1": "Water",
|
||||
"answer2": "Fire",
|
||||
"answer3": "Air",
|
||||
"answer4": "Earth",
|
||||
"answer5": "Light",
|
||||
"answer6": "Darkness"
|
||||
},
|
||||
"/favorite-color": {
|
||||
"title": "Which Color Best Reflects Your Personality?",
|
||||
"answer1": "Blue",
|
||||
"answer2": "Green",
|
||||
"answer3": "Orange",
|
||||
"answer4": "Violet",
|
||||
"answer5": "Red",
|
||||
"answer6": "Yellow",
|
||||
"answer7": "Turquoise"
|
||||
},
|
||||
"/head-or-heart": {
|
||||
"title": "What Guides You in Life: The Call of the Heart or the Voice of Reason?",
|
||||
"answer1": "Follow My Heart",
|
||||
"answer2": "Rely on Reason",
|
||||
"answer3": "Combine Both Approaches",
|
||||
"answer4": "Depends on the Situation"
|
||||
},
|
||||
"/relate-following": {
|
||||
"title": "How Important Is It for You to Meet Your Partner's Expectations?",
|
||||
"question1": "",
|
||||
"question2": "I value and enjoy my own company.",
|
||||
"question3": "I prefer socializing in groups rather than spending time alone.",
|
||||
"question4": "Loneliness is something I actively try to avoid.",
|
||||
"question5": "I enjoy activities that I can do independently.",
|
||||
"strongly_agree": "Very Important",
|
||||
"strongly_disagree": "Not Important at All"
|
||||
},
|
||||
"/gender-partner": {
|
||||
"title": "Your Partner's Gender",
|
||||
"description": "Select your partner's gender for a personalized astrological analysis. The stars consider every detail! ✨",
|
||||
"already_have_account": ""
|
||||
},
|
||||
"/birthdate-partner": {
|
||||
"title": "Your Partner's Birth Date?",
|
||||
"text": "We'll incorporate zodiac influences for a more precise compatibility assessment"
|
||||
},
|
||||
"/date-event": {
|
||||
"single": {
|
||||
"title": "Enter a Significant Date Important to You.",
|
||||
"text": "💫 A significant date can help reveal planetary influences on your life and provide a more personalized analysis."
|
||||
},
|
||||
"relationship": {
|
||||
"title": "Enter a Significant Date Important to You or Your Partner.",
|
||||
"text": "💫 A significant date can help reveal planetary influences on your relationship and provide a more personalized analysis."
|
||||
}
|
||||
},
|
||||
"/palms-information-partner": {
|
||||
"aries": {
|
||||
"title": "♈ Aries",
|
||||
"description": "Passionate, straightforward, and initiative-driven. Falls in love quickly, acts decisively, but can be impatient and jealous. Loves leadership and craves intense emotions, hates routine. If the feelings fade, they leave without regret. You form an intriguing combination, and we have a lot to share with you!"
|
||||
},
|
||||
"taurus": {
|
||||
"title": "♉ Taurus",
|
||||
"description": "Reliable, sensual, and loyal. Moves slowly but thoroughly in love. Values stability, comfort, and physical connection. Can be possessive and reluctant to let go of the past. Doesn't tolerate betrayal or sudden changes. How will your relationship fare? We have the answers!"
|
||||
},
|
||||
"gemini": {
|
||||
"title": "♊ Gemini",
|
||||
"description": "Light-hearted, sociable, and unpredictable. Gets interested quickly but might lose interest just as fast. Enjoys intellectual interaction, flirting, and freedom. Sometimes inconsistent, but with someone who can keep their interest, they're committed. What are your chances for harmony? Let's find out together!"
|
||||
},
|
||||
"cancer": {
|
||||
"title": "♋ Cancer",
|
||||
"description": "Sensitive, caring, and loyal. Emotions are their main element. Falls deeply in love but opens up slowly. Can be vulnerable and needs emotional safety. If disappointed, they leave but linger long over it. What's your emotional compatibility? We have the answer!"
|
||||
},
|
||||
"leo": {
|
||||
"title": "♌ Leo",
|
||||
"description": "Bright, charismatic, and generous. Loves attention, compliments, and drama. Acts like a conqueror in love but desires admiration and loyalty. Can be self-centered but loyal to those who appreciate them. Can you become a true power couple? Let’s check!"
|
||||
},
|
||||
"virgo": {
|
||||
"title": "♍ Virgo",
|
||||
"description": "Rational, reliable, and demanding. Cautious in love, doesn't rush to open up. Values order, honesty, and depth. Can be critical and reserved, but becomes a loyal partner once they trust. Your combination might be incredibly strong—let's discover the details!"
|
||||
},
|
||||
"libra": {
|
||||
"title": "♎ Libra",
|
||||
"description": "Charming, diplomatic, and romantic. Loves harmony, elegant courtship, and intellectual conversation. May hesitate before making decisions but strives for equality and understanding in relationships. What role will you play in this connection? We'll tell you!"
|
||||
},
|
||||
"scorpio": {
|
||||
"title": "♏ Scorpio",
|
||||
"description": "Deep, passionate, and magnetic. Loves seriously and long, but can be jealous and possessive. Trust and emotional connection are vital, and betrayal is unforgivable. Loves deeply. What secrets lie in your union? We know!"
|
||||
},
|
||||
"sagittarius": {
|
||||
"title": "♐ Sagittarius",
|
||||
"description": "Free-spirited, energetic, and optimistic. Loves adventure, novelty, and independence. Falls in love quickly but doesn't tolerate pressure. May avoid commitments but becomes a loyal partner with someone who shares their spirit of freedom. Will your union be full of passion or freedom? Let's find out!"
|
||||
},
|
||||
"capricorn": {
|
||||
"title": "♑ Capricorn",
|
||||
"description": "Reserved, goal-oriented, and reliable. Serious and practical in love, dislikes games and frivolity. Observes for a long time but builds strong, lasting relationships once decided. Faithful, but can be too strict. Compatibility with them can be life-changing—want to know more?"
|
||||
},
|
||||
"aquarius": {
|
||||
"title": "♒ Aquarius",
|
||||
"description": "Original, independent, and intellectual. Loves freedom, experimentation, and friendship in relationships. Can be emotionally detached but with someone who shares their views, becomes a loyal ally. Your bond with them might be unconventional—let’s explore the details!"
|
||||
},
|
||||
"pisces": {
|
||||
"title": "♓ Pisces",
|
||||
"description": "Romantic, intuitive, and dreamy. Falls deeply in love but can be prone to illusions. Seeks spiritual connection, tenderness, and care. May lose themselves in a partner, but if disillusioned, leaves behind a mystery. Will your union be magical or illusory? We know the answer!\n🔮 You form a unique combination, and we can tell you so much more! Let's dive into the details!"
|
||||
}
|
||||
},
|
||||
"/let-scan": {
|
||||
"title": "We Are Scanning Your Palm",
|
||||
"text": "Follow the on-screen instructions so we can analyze the lines of your palm, revealing the future and the secrets of your destiny!"
|
||||
},
|
||||
"/scan-instruction": {
|
||||
"title": "Photograph Your Palm as Shown",
|
||||
"button": "Take Photo Now"
|
||||
},
|
||||
"/email": {
|
||||
"title": "Enter Your Email to Receive a Detailed Palmistry Compatibility Analysis!",
|
||||
"not_share": "We do not share your personal information with third parties.",
|
||||
"placeholder_email": "Your email",
|
||||
"placeholder_name": "Your name"
|
||||
},
|
||||
"app_number_one": {
|
||||
"text": "The <color> app trusted by over 25 million people.",
|
||||
"color": "#1 Astrology"
|
||||
},
|
||||
"/trial-payment": {
|
||||
"information-title": "We're Ready to Give You All the Answers, Don't Spend Years in Doubt!",
|
||||
"information-description-single": "Ever wondered why some relationships flow smoothly while others feel tense like a tightrope? Coincidence or a sign of destiny? Hands tell more than you think. The lines on your palm are a map of your relationships. <color> there are hidden signs in your life that you haven't noticed yet. <eventDescription> <br><br> Receive a detailed palmistry compatibility analysis and discover the answers that are already written in your destiny.",
|
||||
"information-description-single-color": "<zodiacSign> (<birthdate>)",
|
||||
"information-description-single-event-description": "Your date <dateEvent> may have been a turning point or a hidden signal.",
|
||||
"information-description-with-partner": "Hands tell more than you think. The lines on your palm are a map of your relationships. <color> — two signs created for depth, but what secrets does your union hold? <eventDescription> Receive a detailed palmistry compatibility analysis and discover the answers that are already written in your destiny.",
|
||||
"information-description-with-partner-color": "<zodiacSign> (<birthdate>) + <partnerZodiacSign> (<partnerBirthdate>)",
|
||||
"information-description-with-partner-event-description": "Your date <dateEvent> may have been a turning point or a hidden signal.",
|
||||
"palm_is_ready": {
|
||||
"title": "Your Palm Reading <color>",
|
||||
"title_color": "Is Ready",
|
||||
"description": "“I’ve just received your palm scan results. Let’s discuss!”",
|
||||
"text1": "<color> 6 years in palmistry readings and spiritual guidance.",
|
||||
"text1_color": "Akho",
|
||||
"text2": "Choose from 80+ palm readers and astrologers."
|
||||
},
|
||||
"joined_today": {
|
||||
"text1": "Unlimited chats with a palm reader",
|
||||
"text2": "<count> people joined today"
|
||||
},
|
||||
"get_personal_prediction": "Get personal prediction",
|
||||
"how_work": {
|
||||
"title": "How does AURA work?",
|
||||
"point1_title": "Send us your palm scan",
|
||||
"point1_text": "We analyze your palm lines to get hints about your future",
|
||||
"point2_title": "Your palm reading is generated",
|
||||
"point2_text": "One of our professional palm readers puts together a report filled with hints about your future",
|
||||
"point3_title": "Start your trial to receive your prediction",
|
||||
"point3_text": "Once you’re an AURA member, we’ll send over your prediction report so you can begin living a better life.",
|
||||
"point4_title": "Talk with a palm reading specialist anytime",
|
||||
"point4_text": "Get ongoing support by discussing your readings, personal horoscopes, and compatibilities with our expert team."
|
||||
},
|
||||
"money_back_guarantee": {
|
||||
"title": "100% Money-back Guarantee",
|
||||
"text": "If you don’t notice any progress after using the app for at least a week, we are ready to make a complete refund within 14 days."
|
||||
},
|
||||
"begin_trial_now": "Begin Trial Now",
|
||||
"what_included": {
|
||||
"title": "What’s included?",
|
||||
"point1": "<bold> palm readings",
|
||||
"point1_bold": "Unlimited",
|
||||
"point2": "<bold> with professional astrologers",
|
||||
"point2_bold": "1:1 live chats",
|
||||
"point3": "<bold> readings",
|
||||
"point3_bold": "Daily compatibility",
|
||||
"point4": "Cosmic relationship tips",
|
||||
"point5": "Daily horoscopes"
|
||||
},
|
||||
"palms_say_about": {
|
||||
"title": "What do your palms say about you?",
|
||||
"point1": "<color> shows your attitude to love and the quality of love",
|
||||
"point1_color": "Love line",
|
||||
"point2": "A long thumb indicates good fortune",
|
||||
"point3": "<color> reflects your intelligence and mentality",
|
||||
"point3_color": "Head line",
|
||||
"point4": "A long index finger indicates a natural leader",
|
||||
"point5": "<color> defines the quality of your life and what you will achieve",
|
||||
"point5_color": "Life line",
|
||||
"point6": "A short middle finger reveals a free spirit",
|
||||
"point7": "<color> represents your material achievement and career goals",
|
||||
"point7_color": "Fate line",
|
||||
"point8": "A long ring finger reveals that a person tends to take risks",
|
||||
"point9": "A short little finger indicates the person's lack of self-confidence"
|
||||
},
|
||||
"discover_more": "Discover More",
|
||||
"why_love": "Why does everyone <color> ?",
|
||||
"why_love_color": "love AURA",
|
||||
"reviews": {
|
||||
"username1": "Rebecca Bauman",
|
||||
"tagline1": "\"It’s changed my life!\"",
|
||||
"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!",
|
||||
"username2": "Mika Ryan",
|
||||
"tagline2": "\"After years of seeking, I’ve finally found a true love.\"",
|
||||
"text2": "I was hesitant about whether it was really worth trying, but now I have no regrets and I'm enjoying my new relationships!",
|
||||
"username3": "Amanda Holmes",
|
||||
"tagline3": "\"I’ve found a job I really enjoy.\"",
|
||||
"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!"
|
||||
},
|
||||
"success_story": "Become a AURA Success Story!",
|
||||
"as_seen_in": "<color> As Seen in",
|
||||
"footer": {
|
||||
"text1": "Questions? We’re here to help",
|
||||
"text2": "Customer Support",
|
||||
"text3": "Help Center"
|
||||
}
|
||||
},
|
||||
"/payment": {
|
||||
"will_be_charged": "You will be charged only <trialInfo>. Save <save> now. Then <splitPrice> per week. We’ll <emailReminder> before your trial ends.",
|
||||
"will_be_charged_email_reminder": "email you a reminder",
|
||||
"will_be_charged_trial_info": "<trialPrice> for your <trialDuration>-day trial",
|
||||
"payment_information": {
|
||||
"personalized_offer": "Personalized offer reserved",
|
||||
"title": "Start your <trialDuration>-day trial",
|
||||
"total_today": "Total today",
|
||||
"code_applied_bold": "AURA24",
|
||||
"code_applied": "Code <bold> applied!"
|
||||
},
|
||||
"guarantees": {
|
||||
"no_commitment": "No commitment. Cancel anytime.",
|
||||
"30_day_money_back": "30-Day Money-Back Guarantee"
|
||||
},
|
||||
"get_personal_prediction": "Get personal prediction",
|
||||
"total_due": "Total due today: <trialPrice>",
|
||||
"app_number_one_color": "25 million people.",
|
||||
"app_number_one": "The #1 Astrology app trusted by over <color>"
|
||||
},
|
||||
"/scanned-photo": {
|
||||
"title": "Your In-Depth Palmistry Compatibility Analysis Is Almost Ready!",
|
||||
"text": "Judging by your lines, you have an exciting future ahead. Let's dive into all the details!",
|
||||
"without-partner": {
|
||||
"loaders": {
|
||||
"title-1-1": "Analyzing your key traits...",
|
||||
"title-1-2": "Reading astrological parameters...",
|
||||
"title-2-1": "Calculating your unique compatibility chart...",
|
||||
"title-2-2": "Creating a personalized love strategy...",
|
||||
"title-3-1": "Comparing you across 1,120,000 potential astrological combinations...",
|
||||
"title-3-2": "Checking forecast accuracy—almost there..."
|
||||
},
|
||||
"modals": {
|
||||
"title-1": "Clarifying question.",
|
||||
"description-1": "Have you noticed recurring cycles in your life?",
|
||||
"answer-1-left": "NO",
|
||||
"answer-1-right": "YES",
|
||||
"title-2": "Clarifying question.",
|
||||
"description-2": "What's more important to you: fate or choice?",
|
||||
"answer-2-left": "CHOICE",
|
||||
"answer-2-right": "FATE",
|
||||
"title-3": "Clarifying question.",
|
||||
"description-3": "Do you believe there's more to love than chance?",
|
||||
"answer-3-left": "NO",
|
||||
"answer-3-right": "YES"
|
||||
}
|
||||
},
|
||||
"with-partner": {
|
||||
"loaders": {
|
||||
"title-1-1": "Analyzing both your and your partner's key traits...",
|
||||
"title-1-2": "Reading astrological parameters...",
|
||||
"title-2-1": "Calculating your unique compatibility chart...",
|
||||
"title-2-2": "Checking key intersections of your destinies...",
|
||||
"title-3-1": "Comparing your match across 1,120,000 potential astrological combinations...",
|
||||
"title-3-2": "Inputting data: evaluating the depth of your connection—almost there..."
|
||||
},
|
||||
"modals": {
|
||||
"title-1": "Clarifying question.",
|
||||
"description-1": "Have you noticed recurring cycles in your life?",
|
||||
"answer-1-left": "NO",
|
||||
"answer-1-right": "YES",
|
||||
"title-2": "Clarifying question.",
|
||||
"description-2": "What's more important to you: fate or choice?",
|
||||
"answer-2-left": "CHOICE",
|
||||
"answer-2-right": "FATE",
|
||||
"title-3": "Clarifying question.",
|
||||
"description-3": "Do you believe love is more than just luck?",
|
||||
"answer-3-left": "NO",
|
||||
"answer-3-right": "YES"
|
||||
}
|
||||
}
|
||||
},
|
||||
"aura_paywall_palmistry_main": {
|
||||
"text_0": "We have helped millions of people unveil the destiny of their love life and understand what's in store for their future and families.",
|
||||
"text_1": "It costs us $13.21 to compensate our AURA team for the trial period, but please choose an amount that is comfortable for you."
|
||||
},
|
||||
"/skip-trial": {
|
||||
"title": "Not Looking to Look Back?",
|
||||
"price_per_week": "<price> per week",
|
||||
"billing_period": "Billing Period",
|
||||
"billed_amount": "Billed Amount",
|
||||
"billed_in_4_weeks": "Billed in 4 weeks",
|
||||
"start_trial": {
|
||||
"every_week": "Every week",
|
||||
"start_trial": "Start Trial"
|
||||
},
|
||||
"skip_trial": {
|
||||
"save": "save <save>%",
|
||||
"every_4_weeks": "Every 4 weeks",
|
||||
"skip_trial": "Accept Offer and Skip Trial Period"
|
||||
}
|
||||
},
|
||||
"/add-consultant": {
|
||||
"more_for_you": "More for You",
|
||||
"exclusive_offer": "Exclusive offer just for you to help reach your goals faster",
|
||||
"your_unique_consultation": "Your Unique Personal Consultation",
|
||||
"30-minute": "30-minute private consultation with an expert",
|
||||
"description": "You can request insights into your future, analyze life compatibility, check love compatibility, and more",
|
||||
"one_time_price_offer": "Special one-time price:",
|
||||
"original_price": "Original price: <oldPrice> <discount>",
|
||||
"you_will_be_charged": "*You will be charged for any additional services or offers selected at the time of purchase.\n This is a one-time payment.",
|
||||
"get_my_consultation": "Get My Consultation",
|
||||
"discount_save": "Save",
|
||||
"caution": "Caution!",
|
||||
"caution_text": "To avoid double charging, please do not close the page or go back.",
|
||||
"unlock_profound": "Unlock profound insights into your personality, relationships, career path, and key life moments with astrology. This will allow you to make more informed decisions and achieve greater satisfaction.",
|
||||
"choose_from": "Choose from over 80 expert astrologers."
|
||||
},
|
||||
"/camera": {
|
||||
"bad_photo": "Bad Photo!",
|
||||
"try_again": "Try Again",
|
||||
"do_better": "You Can Do Better",
|
||||
"no_access_camera": "No Access to Camera",
|
||||
"give_access": "Give Access",
|
||||
"reload_page": "Please reload the page to continue.",
|
||||
"reload_page_button": "Reload Page",
|
||||
"next": "Next",
|
||||
"modal": {
|
||||
"title": "To scan your hand, access to the Camera is required.",
|
||||
"cancel": "Cancel",
|
||||
"allow": "Allow"
|
||||
}
|
||||
},
|
||||
"/depends": {
|
||||
"with-partner": {
|
||||
"title": "Based on our data, only 9% of <gender> born under the <zodiacSign> have a distinct logical clarity—a rare gift. We'll definitely take this trait into account in your palm lines when preparing your Compatibility analysis with <partnerZodiacSign>."
|
||||
},
|
||||
"single": {
|
||||
"title": "Based on our data, only 9% of <gender> born under the <zodiacSign> sign possess a clear logical clarity—a rare gift. We'll certainly take this trait into account in your lines."
|
||||
}
|
||||
},
|
||||
"/with-heart": {
|
||||
"with-partner": {
|
||||
"title": "Your choice is natural. According to our data, 52% of <gender> <zodiacSign> follow their heart. We will consider this in your palm analysis for Compatibility with <partnerZodiacSign>!"
|
||||
},
|
||||
"single": {
|
||||
"title": "Your choice is natural—based on our data, 51% of <gender> with the <zodiacSign> sign follow their heart. We'll take this into account in your lines!"
|
||||
}
|
||||
},
|
||||
"/with-head": {
|
||||
"with-partner": {
|
||||
"title": "Even among <zodiacSign>, not everything is decided by the heart – Based on our data, 35% of <gender> in your sign make decisions based on reason. We will take this aspect into account in your compatibility analysis with <partnerZodiacSign>."
|
||||
},
|
||||
"single": {
|
||||
"title": "Even among <zodiacSign>, not everything is decided by the heart—based on our data, 35% of <gender> of your sign make decisions guided by reason. We'll factor this into your analysis."
|
||||
}
|
||||
},
|
||||
"/both": {
|
||||
"with-partner": {
|
||||
"title": "The facts speak for themselves! According to our data, only 15% of <gender> born under the <zodiacSign> equally follow both their mind and heart. This is the secret to harmonious relationships with <partnerZodiacSign>, and we'll consider this in your readings."
|
||||
},
|
||||
"single": {
|
||||
"title": "The facts speak for themselves! According to our data, only 15% of <gender> born under the <zodiacSign> sign follow both heart and mind equally. That's the secret to harmonious relationships, and we'll reflect this in your lines."
|
||||
}
|
||||
},
|
||||
"/romantic-gestures": {
|
||||
"title": "How Do You Feel About Romantic Gestures?",
|
||||
"answer1": "Love them",
|
||||
"answer2": "Neutral",
|
||||
"answer3": "Don't see the point"
|
||||
},
|
||||
"/checking-phone": {
|
||||
"title": "What Are Your Thoughts on Checking a Partner's Phone or Messages?",
|
||||
"answer1": "Strongly against",
|
||||
"answer2": "Only in extreme cases",
|
||||
"answer3": "Fine with it"
|
||||
},
|
||||
"zodiac_signs": {
|
||||
"aries": "Aries",
|
||||
"taurus": "Taurus",
|
||||
"gemini": "Gemini",
|
||||
"cancer": "Cancer",
|
||||
"leo": "Leo",
|
||||
"virgo": "Virgo",
|
||||
"libra": "Libra",
|
||||
"scorpio": "Scorpio",
|
||||
"sagittarius": "Sagittarius",
|
||||
"capricorn": "Capricorn",
|
||||
"aquarius": "Aquarius",
|
||||
"pisces": "Pisces"
|
||||
}
|
||||
}
|
||||
489
public/locales/compatibility-v2/en/male_en.json
Normal file
489
public/locales/compatibility-v2/en/male_en.json
Normal file
@ -0,0 +1,489 @@
|
||||
{
|
||||
"next": "Next",
|
||||
"biometric_data": "We don’t collect any biometric data. All recognition processes occur on your device.",
|
||||
"went_wrong": "Something went wrong.",
|
||||
"v": "v1",
|
||||
"config": "en.male",
|
||||
"threadId": "thread_uBoB6htpYLoPp1bHDUXnrVKS",
|
||||
"assistantId": "asst_ZClw0fzJaQlhxUigjxHp87Nc",
|
||||
"privacy_policy": "By continuing, you agree to our <eulaLink> and <privacyLink>. Have a question? Reach out to our support team <clickHere>",
|
||||
"eula_link": "End User License Agreement",
|
||||
"privacy_notice": "Privacy Notice",
|
||||
"policy_here": "here",
|
||||
"thumb": "Thumb",
|
||||
"index_finger": "Index finger",
|
||||
"middle_finger": "Middle finger",
|
||||
"ring_finger": "Ring finger",
|
||||
"pinky": "Little finger",
|
||||
"skip_trial": "Skip trial period",
|
||||
"add_consultant": "Add consultant",
|
||||
"add_guides": "Add guides",
|
||||
"access_product": "Access product",
|
||||
"thank_you": "Thank you!",
|
||||
"order_successful": "Your order was successfully processed!",
|
||||
"male": "Male",
|
||||
"female": "Female",
|
||||
"males": "Males",
|
||||
"females": "Females",
|
||||
"/find-your-happiness": {
|
||||
"title": "Gain Clarity and Confidence in Life",
|
||||
"text": "Use astrology and palmistry to strengthen yourself and your relationships",
|
||||
"advantage1": "In-depth Analysis: We scan the lines on your palm",
|
||||
"advantage2": "Personalized Approach: Compatibility and Future Analysis",
|
||||
"advantage3": "Quick Results: Takes no more than 5 minutes"
|
||||
},
|
||||
"/gender": {
|
||||
"title": "What is Your Gender?",
|
||||
"description": "In palmistry, everyone has both masculine and feminine traits. <br><br> Let's determine yours for a more accurate palm reading.",
|
||||
"already_have_account": "Already have an account? Sign in"
|
||||
},
|
||||
"/birthdate": {
|
||||
"title": "When Were You Born?",
|
||||
"text": "Your birth date can reveal strengths and values that may help you move forward"
|
||||
},
|
||||
"/palms-information": {
|
||||
"aries": {
|
||||
"title": "♈ Aries",
|
||||
"description": "Your palms are a map of destiny, reflecting your strength and character. According to our data, 76 million Aries have a clear and straight head line, indicating decisiveness and independence. In 81% of successful relationships, their partners share their passion for action. Your palms will reveal how well your ambitions and energy align with your partner."
|
||||
},
|
||||
"taurus": {
|
||||
"title": "♉ Taurus",
|
||||
"description": "The patterns on your palms reveal your true self. Our research shows that 83 million Taurus have a long and smooth life line, a sign of resilience and desire for stability. In 86% of harmonious relationships, partners value reliability and comfort. Take a look at your palm—it will indicate how strong your union is."
|
||||
},
|
||||
"gemini": {
|
||||
"title": "♊ Gemini",
|
||||
"description": "Your palms are a mirror of your mind and character. According to our data, 72 million Gemini have a bifurcated or branched head line, suggesting flexibility and multitasking ability. In 78% of successful relationships, partners are ready for change and spontaneity. Check your lines—they will show how well your partner matches your pace."
|
||||
},
|
||||
"cancer": {
|
||||
"title": "♋ Cancer",
|
||||
"description": "Your palm lines hide secrets of emotions and attachments. Our data shows that 78 million Cancers have a clear and expressive heart line, indicating deep sensitivity. In 82% of strong relationships, Cancer partners have well-developed empathy. Your palm will help reveal how well you and your loved one understand each other."
|
||||
},
|
||||
"leo": {
|
||||
"title": "♌ Leo",
|
||||
"description": "Palms store the history of your personality. Our data indicates that 80 million Leos have a noticeable Sun line, which suggests innate charisma and a drive for recognition. In 84% of happy relationships, Leo partners are admired and share their ambitions. Your palm will show how ready your partner is to be part of your shine."
|
||||
},
|
||||
"virgo": {
|
||||
"title": "♍ Virgo",
|
||||
"description": "Every line on your palm is a trace of your character. Our observations show that 75 million Virgos have fine but distinct lines, reflecting attention to detail and rationality. In 79% of successful Virgo relationships, trust and predictability are key. Your palms will reveal how well your values align with your partner."
|
||||
},
|
||||
"libra": {
|
||||
"title": "♎ Libra",
|
||||
"description": "The harmony of your palms reflects the harmony of your soul. Our data shows that 77 million Libras have a curved and smooth heart line, indicating diplomacy and balanced relationships. In 80% of successful partnerships, their partners appreciate honesty and compromise. Look at your palm—it will indicate how much your relationship is based on mutual understanding."
|
||||
},
|
||||
"scorpio": {
|
||||
"title": "♏ Scorpio",
|
||||
"description": "The depth of your palm lines reflects the depth of your feelings. Our research shows that 81 million Scorpios have a deep and straight heart line, indicating passion and devotion. In 83% of successful relationships, their partners share the same emotional intensity. Your palm will show how genuine the connection between you and your partner is."
|
||||
},
|
||||
"sagittarius": {
|
||||
"title": "♐ Sagittarius",
|
||||
"description": "The lines on your palm are a map of your life journey. Our data shows that 74 million Sagittarians have a long and prominent head line, symbolizing curiosity and a quest for freedom. In 77% of long-term relationships, their partners share an adventurous spirit. Your palm will tell you how ready your partner is for your ambitious dreams."
|
||||
},
|
||||
"capricorn": {
|
||||
"title": "♑ Capricorn",
|
||||
"description": "Your palms are a reflection of your strength and determination. Our data shows that 79 million Capricorns have a pronounced fate line, indicating their ambitions and discipline. In 85% of happy marriages, their partners support their pursuit of success. Look at your palm—it will reveal how much your union is based on shared goals."
|
||||
},
|
||||
"aquarius": {
|
||||
"title": "♒ Aquarius",
|
||||
"description": "The lines on your palm are the mark of your uniqueness. Our research shows that 71 million Aquarians have an unconventional head line, indicating originality and non-standard thinking. In 75% of harmonious relationships, their partners respect their freedom and independence. Your palm will reveal how ready your partner is for your innovative ideas."
|
||||
},
|
||||
"pisces": {
|
||||
"title": "♓ Pisces",
|
||||
"description": "Palms conceal the secrets of your soul. Our data shows that 82 million Pisces have a long and smooth heart line, indicating their intuition and deep sense of love. In 84% of strong relationships, their partners share a similar sensitivity. Your palm will tell you how well your partner can feel you on an emotional level."
|
||||
}
|
||||
},
|
||||
"/what-aspects": {
|
||||
"title": "Which Areas of Life Do You Want to Gain a Deeper Understanding Of?",
|
||||
"answer1": "Love and Relationships",
|
||||
"answer2": "Health and Energy",
|
||||
"answer3": "Career and Purpose",
|
||||
"answer4": "Life Transitions"
|
||||
},
|
||||
"/relationship-status": {
|
||||
"title": "To Better Understand You, Indicate Your Current Relationship Status",
|
||||
"answer1": "Single",
|
||||
"answer2": "In a Relationship",
|
||||
"answer3": "Married",
|
||||
"answer4": "Divorced"
|
||||
},
|
||||
"/element-resonates": {
|
||||
"title": "Which Element Empowers You the Most?",
|
||||
"answer1": "Water",
|
||||
"answer2": "Fire",
|
||||
"answer3": "Air",
|
||||
"answer4": "Earth",
|
||||
"answer5": "Light",
|
||||
"answer6": "Darkness"
|
||||
},
|
||||
"/favorite-color": {
|
||||
"title": "Which Color Best Reflects Your Personality?",
|
||||
"answer1": "Blue",
|
||||
"answer2": "Green",
|
||||
"answer3": "Orange",
|
||||
"answer4": "Violet",
|
||||
"answer5": "Red",
|
||||
"answer6": "Yellow",
|
||||
"answer7": "Turquoise"
|
||||
},
|
||||
"/head-or-heart": {
|
||||
"title": "What Guides You in Life: The Call of the Heart or the Voice of Reason?",
|
||||
"answer1": "Follow My Heart",
|
||||
"answer2": "Rely on Reason",
|
||||
"answer3": "Combine Both Approaches",
|
||||
"answer4": "Depends on the Situation"
|
||||
},
|
||||
"/relate-following": {
|
||||
"title": "How Important Is It for You to Meet Your Partner's Expectations?",
|
||||
"question1": "",
|
||||
"question2": "I value and enjoy my own company.",
|
||||
"question3": "I prefer socializing in groups rather than spending time alone.",
|
||||
"question4": "Loneliness is something I actively try to avoid.",
|
||||
"question5": "I enjoy activities that I can do independently.",
|
||||
"strongly_agree": "Very Important",
|
||||
"strongly_disagree": "Not Important at All"
|
||||
},
|
||||
"/gender-partner": {
|
||||
"title": "Your Partner's Gender",
|
||||
"description": "Select your partner's gender for a personalized astrological analysis. The stars consider every detail! ✨",
|
||||
"already_have_account": ""
|
||||
},
|
||||
"/birthdate-partner": {
|
||||
"title": "Your Partner's Birth Date?",
|
||||
"text": "We'll incorporate zodiac influences for a more precise compatibility assessment"
|
||||
},
|
||||
"/date-event": {
|
||||
"single": {
|
||||
"title": "Enter a Significant Date Important to You.",
|
||||
"text": "💫 A significant date can help reveal planetary influences on your life and provide a more personalized analysis."
|
||||
},
|
||||
"relationship": {
|
||||
"title": "Enter a Significant Date Important to You or Your Partner.",
|
||||
"text": "💫 A significant date can help reveal planetary influences on your relationship and provide a more personalized analysis."
|
||||
}
|
||||
},
|
||||
"/palms-information-partner": {
|
||||
"aries": {
|
||||
"title": "♈ Aries",
|
||||
"description": "Passionate, straightforward, and initiative-driven. Falls in love quickly, acts decisively, but can be impatient and jealous. Loves leadership and craves intense emotions, hates routine. If the feelings fade, they leave without regret. You form an intriguing combination, and we have a lot to share with you!"
|
||||
},
|
||||
"taurus": {
|
||||
"title": "♉ Taurus",
|
||||
"description": "Reliable, sensual, and loyal. Moves slowly but thoroughly in love. Values stability, comfort, and physical connection. Can be possessive and reluctant to let go of the past. Doesn't tolerate betrayal or sudden changes. How will your relationship fare? We have the answers!"
|
||||
},
|
||||
"gemini": {
|
||||
"title": "♊ Gemini",
|
||||
"description": "Light-hearted, sociable, and unpredictable. Gets interested quickly but might lose interest just as fast. Enjoys intellectual interaction, flirting, and freedom. Sometimes inconsistent, but with someone who can keep their interest, they're committed. What are your chances for harmony? Let's find out together!"
|
||||
},
|
||||
"cancer": {
|
||||
"title": "♋ Cancer",
|
||||
"description": "Sensitive, caring, and loyal. Emotions are their main element. Falls deeply in love but opens up slowly. Can be vulnerable and needs emotional safety. If disappointed, they leave but linger long over it. What's your emotional compatibility? We have the answer!"
|
||||
},
|
||||
"leo": {
|
||||
"title": "♌ Leo",
|
||||
"description": "Bright, charismatic, and generous. Loves attention, compliments, and drama. Acts like a conqueror in love but desires admiration and loyalty. Can be self-centered but loyal to those who appreciate them. Can you become a true power couple? Let’s check!"
|
||||
},
|
||||
"virgo": {
|
||||
"title": "♍ Virgo",
|
||||
"description": "Rational, reliable, and demanding. Cautious in love, doesn't rush to open up. Values order, honesty, and depth. Can be critical and reserved, but becomes a loyal partner once they trust. Your combination might be incredibly strong—let's discover the details!"
|
||||
},
|
||||
"libra": {
|
||||
"title": "♎ Libra",
|
||||
"description": "Charming, diplomatic, and romantic. Loves harmony, elegant courtship, and intellectual conversation. May hesitate before making decisions but strives for equality and understanding in relationships. What role will you play in this connection? We'll tell you!"
|
||||
},
|
||||
"scorpio": {
|
||||
"title": "♏ Scorpio",
|
||||
"description": "Deep, passionate, and magnetic. Loves seriously and long, but can be jealous and possessive. Trust and emotional connection are vital, and betrayal is unforgivable. Loves deeply. What secrets lie in your union? We know!"
|
||||
},
|
||||
"sagittarius": {
|
||||
"title": "♐ Sagittarius",
|
||||
"description": "Free-spirited, energetic, and optimistic. Loves adventure, novelty, and independence. Falls in love quickly but doesn't tolerate pressure. May avoid commitments but becomes a loyal partner with someone who shares their spirit of freedom. Will your union be full of passion or freedom? Let's find out!"
|
||||
},
|
||||
"capricorn": {
|
||||
"title": "♑ Capricorn",
|
||||
"description": "Reserved, goal-oriented, and reliable. Serious and practical in love, dislikes games and frivolity. Observes for a long time but builds strong, lasting relationships once decided. Faithful, but can be too strict. Compatibility with them can be life-changing—want to know more?"
|
||||
},
|
||||
"aquarius": {
|
||||
"title": "♒ Aquarius",
|
||||
"description": "Original, independent, and intellectual. Loves freedom, experimentation, and friendship in relationships. Can be emotionally detached but with someone who shares their views, becomes a loyal ally. Your bond with them might be unconventional—let’s explore the details!"
|
||||
},
|
||||
"pisces": {
|
||||
"title": "♓ Pisces",
|
||||
"description": "Romantic, intuitive, and dreamy. Falls deeply in love but can be prone to illusions. Seeks spiritual connection, tenderness, and care. May lose themselves in a partner, but if disillusioned, leaves behind a mystery. Will your union be magical or illusory? We know the answer!\n🔮 You form a unique combination, and we can tell you so much more! Let's dive into the details!"
|
||||
}
|
||||
},
|
||||
"/let-scan": {
|
||||
"title": "We Are Scanning Your Palm",
|
||||
"text": "Follow the on-screen instructions so we can analyze the lines of your palm, revealing the future and the secrets of your destiny!"
|
||||
},
|
||||
"/scan-instruction": {
|
||||
"title": "Photograph Your Palm as Shown",
|
||||
"button": "Take Photo Now"
|
||||
},
|
||||
"/email": {
|
||||
"title": "Enter Your Email to Receive a Detailed Palmistry Compatibility Analysis!",
|
||||
"not_share": "We do not share your personal information with third parties.",
|
||||
"placeholder_email": "Your email",
|
||||
"placeholder_name": "Your name"
|
||||
},
|
||||
"app_number_one": {
|
||||
"text": "The <color> app trusted by over 25 million people.",
|
||||
"color": "#1 Astrology"
|
||||
},
|
||||
"/trial-payment": {
|
||||
"information-title": "We're Ready to Give You All the Answers, Don't Spend Years in Doubt!",
|
||||
"information-description-single": "Ever wondered why some relationships flow smoothly while others feel tense like a tightrope? Coincidence or a sign of destiny? Hands tell more than you think. The lines on your palm are a map of your relationships. <color> there are hidden signs in your life that you haven't noticed yet. <eventDescription> <br><br> Receive a detailed palmistry compatibility analysis and discover the answers that are already written in your destiny.",
|
||||
"information-description-single-color": "<zodiacSign> (<birthdate>)",
|
||||
"information-description-single-event-description": "Your date <dateEvent> may have been a turning point or a hidden signal.",
|
||||
"information-description-with-partner": "Hands tell more than you think. The lines on your palm are a map of your relationships. <color> — two signs created for depth, but what secrets does your union hold? <eventDescription> Receive a detailed palmistry compatibility analysis and discover the answers that are already written in your destiny.",
|
||||
"information-description-with-partner-color": "<zodiacSign> (<birthdate>) + <partnerZodiacSign> (<partnerBirthdate>)",
|
||||
"information-description-with-partner-event-description": "Your date <dateEvent> may have been a turning point or a hidden signal.",
|
||||
"palm_is_ready": {
|
||||
"title": "Your Palm Reading <color>",
|
||||
"title_color": "Is Ready",
|
||||
"description": "“I’ve just received your palm scan results. Let’s discuss!”",
|
||||
"text1": "<color> 6 years in palmistry readings and spiritual guidance.",
|
||||
"text1_color": "Akho",
|
||||
"text2": "Choose from 80+ palm readers and astrologers."
|
||||
},
|
||||
"joined_today": {
|
||||
"text1": "Unlimited chats with a palm reader",
|
||||
"text2": "<count> people joined today"
|
||||
},
|
||||
"get_personal_prediction": "Get personal prediction",
|
||||
"how_work": {
|
||||
"title": "How does AURA work?",
|
||||
"point1_title": "Send us your palm scan",
|
||||
"point1_text": "We analyze your palm lines to get hints about your future",
|
||||
"point2_title": "Your palm reading is generated",
|
||||
"point2_text": "One of our professional palm readers puts together a report filled with hints about your future",
|
||||
"point3_title": "Start your trial to receive your prediction",
|
||||
"point3_text": "Once you’re an AURA member, we’ll send over your prediction report so you can begin living a better life.",
|
||||
"point4_title": "Talk with a palm reading specialist anytime",
|
||||
"point4_text": "Get ongoing support by discussing your readings, personal horoscopes, and compatibilities with our expert team."
|
||||
},
|
||||
"money_back_guarantee": {
|
||||
"title": "100% Money-back Guarantee",
|
||||
"text": "If you don’t notice any progress after using the app for at least a week, we are ready to make a complete refund within 14 days."
|
||||
},
|
||||
"begin_trial_now": "Begin Trial Now",
|
||||
"what_included": {
|
||||
"title": "What’s included?",
|
||||
"point1": "<bold> palm readings",
|
||||
"point1_bold": "Unlimited",
|
||||
"point2": "<bold> with professional astrologers",
|
||||
"point2_bold": "1:1 live chats",
|
||||
"point3": "<bold> readings",
|
||||
"point3_bold": "Daily compatibility",
|
||||
"point4": "Cosmic relationship tips",
|
||||
"point5": "Daily horoscopes"
|
||||
},
|
||||
"palms_say_about": {
|
||||
"title": "What do your palms say about you?",
|
||||
"point1": "<color> shows your attitude to love and the quality of love",
|
||||
"point1_color": "Love line",
|
||||
"point2": "A long thumb indicates good fortune",
|
||||
"point3": "<color> reflects your intelligence and mentality",
|
||||
"point3_color": "Head line",
|
||||
"point4": "A long index finger indicates a natural leader",
|
||||
"point5": "<color> defines the quality of your life and what you will achieve",
|
||||
"point5_color": "Life line",
|
||||
"point6": "A short middle finger reveals a free spirit",
|
||||
"point7": "<color> represents your material achievement and career goals",
|
||||
"point7_color": "Fate line",
|
||||
"point8": "A long ring finger reveals that a person tends to take risks",
|
||||
"point9": "A short little finger indicates the person's lack of self-confidence"
|
||||
},
|
||||
"discover_more": "Discover More",
|
||||
"why_love": "Why does everyone <color> ?",
|
||||
"why_love_color": "love AURA",
|
||||
"reviews": {
|
||||
"username1": "Rebecca Bauman",
|
||||
"tagline1": "\"It’s changed my life!\"",
|
||||
"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!",
|
||||
"username2": "Mika Ryan",
|
||||
"tagline2": "\"After years of seeking, I’ve finally found a true love.\"",
|
||||
"text2": "I was hesitant about whether it was really worth trying, but now I have no regrets and I'm enjoying my new relationships!",
|
||||
"username3": "Amanda Holmes",
|
||||
"tagline3": "\"I’ve found a job I really enjoy.\"",
|
||||
"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!"
|
||||
},
|
||||
"success_story": "Become a AURA Success Story!",
|
||||
"as_seen_in": "<color> As Seen in",
|
||||
"footer": {
|
||||
"text1": "Questions? We’re here to help",
|
||||
"text2": "Customer Support",
|
||||
"text3": "Help Center"
|
||||
}
|
||||
},
|
||||
"/payment": {
|
||||
"will_be_charged": "You will be charged only <trialInfo>. Save <save> now. Then <splitPrice> per week. We’ll <emailReminder> before your trial ends.",
|
||||
"will_be_charged_email_reminder": "email you a reminder",
|
||||
"will_be_charged_trial_info": "<trialPrice> for your <trialDuration>-day trial",
|
||||
"payment_information": {
|
||||
"personalized_offer": "Personalized offer reserved",
|
||||
"title": "Start your <trialDuration>-day trial",
|
||||
"total_today": "Total today",
|
||||
"code_applied_bold": "AURA24",
|
||||
"code_applied": "Code <bold> applied!"
|
||||
},
|
||||
"guarantees": {
|
||||
"no_commitment": "No commitment. Cancel anytime.",
|
||||
"30_day_money_back": "30-Day Money-Back Guarantee"
|
||||
},
|
||||
"get_personal_prediction": "Get personal prediction",
|
||||
"total_due": "Total due today: <trialPrice>",
|
||||
"app_number_one_color": "25 million people.",
|
||||
"app_number_one": "The #1 Astrology app trusted by over <color>"
|
||||
},
|
||||
"/scanned-photo": {
|
||||
"title": "Your In-Depth Palmistry Compatibility Analysis Is Almost Ready!",
|
||||
"text": "Judging by your lines, you have an exciting future ahead. Let's dive into all the details!",
|
||||
"without-partner": {
|
||||
"loaders": {
|
||||
"title-1-1": "Analyzing your key traits...",
|
||||
"title-1-2": "Reading astrological parameters...",
|
||||
"title-2-1": "Calculating your unique compatibility chart...",
|
||||
"title-2-2": "Creating a personalized love strategy...",
|
||||
"title-3-1": "Comparing you across 1,120,000 potential astrological combinations...",
|
||||
"title-3-2": "Checking forecast accuracy—almost there..."
|
||||
},
|
||||
"modals": {
|
||||
"title-1": "Clarifying question.",
|
||||
"description-1": "Have you noticed recurring cycles in your life?",
|
||||
"answer-1-left": "NO",
|
||||
"answer-1-right": "YES",
|
||||
"title-2": "Clarifying question.",
|
||||
"description-2": "What's more important to you: fate or choice?",
|
||||
"answer-2-left": "CHOICE",
|
||||
"answer-2-right": "FATE",
|
||||
"title-3": "Clarifying question.",
|
||||
"description-3": "Do you believe there's more to love than chance?",
|
||||
"answer-3-left": "NO",
|
||||
"answer-3-right": "YES"
|
||||
}
|
||||
},
|
||||
"with-partner": {
|
||||
"loaders": {
|
||||
"title-1-1": "Analyzing both your and your partner's key traits...",
|
||||
"title-1-2": "Reading astrological parameters...",
|
||||
"title-2-1": "Calculating your unique compatibility chart...",
|
||||
"title-2-2": "Checking key intersections of your destinies...",
|
||||
"title-3-1": "Comparing your match across 1,120,000 potential astrological combinations...",
|
||||
"title-3-2": "Inputting data: evaluating the depth of your connection—almost there..."
|
||||
},
|
||||
"modals": {
|
||||
"title-1": "Clarifying question.",
|
||||
"description-1": "Have you noticed recurring cycles in your life?",
|
||||
"answer-1-left": "NO",
|
||||
"answer-1-right": "YES",
|
||||
"title-2": "Clarifying question.",
|
||||
"description-2": "What's more important to you: fate or choice?",
|
||||
"answer-2-left": "CHOICE",
|
||||
"answer-2-right": "FATE",
|
||||
"title-3": "Clarifying question.",
|
||||
"description-3": "Do you believe love is more than just luck?",
|
||||
"answer-3-left": "NO",
|
||||
"answer-3-right": "YES"
|
||||
}
|
||||
}
|
||||
},
|
||||
"aura_paywall_palmistry_main": {
|
||||
"text_0": "We have helped millions of people unveil the destiny of their love life and understand what's in store for their future and families.",
|
||||
"text_1": "It costs us $13.21 to compensate our AURA team for the trial period, but please choose an amount that is comfortable for you."
|
||||
},
|
||||
"/skip-trial": {
|
||||
"title": "Not Looking to Look Back?",
|
||||
"price_per_week": "<price> per week",
|
||||
"billing_period": "Billing Period",
|
||||
"billed_amount": "Billed Amount",
|
||||
"billed_in_4_weeks": "Billed in 4 weeks",
|
||||
"start_trial": {
|
||||
"every_week": "Every week",
|
||||
"start_trial": "Start Trial"
|
||||
},
|
||||
"skip_trial": {
|
||||
"save": "save <save>%",
|
||||
"every_4_weeks": "Every 4 weeks",
|
||||
"skip_trial": "Accept Offer and Skip Trial Period"
|
||||
}
|
||||
},
|
||||
"/add-consultant": {
|
||||
"more_for_you": "More for You",
|
||||
"exclusive_offer": "Exclusive offer just for you to help reach your goals faster",
|
||||
"your_unique_consultation": "Your Unique Personal Consultation",
|
||||
"30-minute": "30-minute private consultation with an expert",
|
||||
"description": "You can request insights into your future, analyze life compatibility, check love compatibility, and more",
|
||||
"one_time_price_offer": "Special one-time price:",
|
||||
"original_price": "Original price: <oldPrice> <discount>",
|
||||
"you_will_be_charged": "*You will be charged for any additional services or offers selected at the time of purchase.\n This is a one-time payment.",
|
||||
"get_my_consultation": "Get My Consultation",
|
||||
"discount_save": "Save",
|
||||
"caution": "Caution!",
|
||||
"caution_text": "To avoid double charging, please do not close the page or go back.",
|
||||
"unlock_profound": "Unlock profound insights into your personality, relationships, career path, and key life moments with astrology. This will allow you to make more informed decisions and achieve greater satisfaction.",
|
||||
"choose_from": "Choose from over 80 expert astrologers."
|
||||
},
|
||||
"/camera": {
|
||||
"bad_photo": "Bad Photo!",
|
||||
"try_again": "Try Again",
|
||||
"do_better": "You Can Do Better",
|
||||
"next": "Next"
|
||||
},
|
||||
"/depends": {
|
||||
"with-partner": {
|
||||
"title": "Based on our data, only 9% of <gender> born under the <zodiacSign> have a distinct logical clarity—a rare gift. We'll definitely take this trait into account in your palm lines when preparing your Compatibility analysis with <partnerZodiacSign>."
|
||||
},
|
||||
"single": {
|
||||
"title": "Based on our data, only 9% of <gender> born under the <zodiacSign> sign possess a clear logical clarity—a rare gift. We'll certainly take this trait into account in your lines."
|
||||
}
|
||||
},
|
||||
"/with-heart": {
|
||||
"with-partner": {
|
||||
"title": "Your choice is natural. According to our data, 52% of <gender> <zodiacSign> follow their heart. We will consider this in your palm analysis for Compatibility with <partnerZodiacSign>!"
|
||||
},
|
||||
"single": {
|
||||
"title": "Your choice is natural—based on our data, 51% of <gender> with the <zodiacSign> sign follow their heart. We'll take this into account in your lines!"
|
||||
}
|
||||
},
|
||||
"/with-head": {
|
||||
"with-partner": {
|
||||
"title": "Even among <zodiacSign>, not everything is decided by the heart – Based on our data, 35% of <gender> in your sign make decisions based on reason. We will take this aspect into account in your compatibility analysis with <partnerZodiacSign>."
|
||||
},
|
||||
"single": {
|
||||
"title": "Even among <zodiacSign>, not everything is decided by the heart—based on our data, 35% of <gender> of your sign make decisions guided by reason. We'll factor this into your analysis."
|
||||
}
|
||||
},
|
||||
"/both": {
|
||||
"with-partner": {
|
||||
"title": "The facts speak for themselves! According to our data, only 15% of <gender> born under the <zodiacSign> equally follow both their mind and heart. This is the secret to harmonious relationships with <partnerZodiacSign>, and we'll consider this in your readings."
|
||||
},
|
||||
"single": {
|
||||
"title": "The facts speak for themselves! According to our data, only 15% of <gender> born under the <zodiacSign> sign follow both heart and mind equally. That's the secret to harmonious relationships, and we'll reflect this in your lines."
|
||||
}
|
||||
},
|
||||
"/romantic-gestures": {
|
||||
"title": "How Do You Feel About Romantic Gestures?",
|
||||
"answer1": "Love them",
|
||||
"answer2": "Neutral",
|
||||
"answer3": "Don't see the point"
|
||||
},
|
||||
"/checking-phone": {
|
||||
"title": "What Are Your Thoughts on Checking a Partner's Phone or Messages?",
|
||||
"answer1": "Strongly against",
|
||||
"answer2": "Only in extreme cases",
|
||||
"answer3": "Fine with it"
|
||||
},
|
||||
"zodiac_signs": {
|
||||
"aries": "Aries",
|
||||
"taurus": "Taurus",
|
||||
"gemini": "Gemini",
|
||||
"cancer": "Cancer",
|
||||
"leo": "Leo",
|
||||
"virgo": "Virgo",
|
||||
"libra": "Libra",
|
||||
"scorpio": "Scorpio",
|
||||
"sagittarius": "Sagittarius",
|
||||
"capricorn": "Capricorn",
|
||||
"aquarius": "Aquarius",
|
||||
"pisces": "Pisces"
|
||||
}
|
||||
}
|
||||
@ -2,19 +2,23 @@ import Webcam from "react-webcam";
|
||||
import styles from "./styles.module.scss";
|
||||
import ModalOverlay, { ModalOverlayType } from "@/components/palmistry/modal-overlay/modal-overlay";
|
||||
import Modal from "@/components/palmistry/modal/modal";
|
||||
import { useRef, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
// import { useDynamicSize } from "@/hooks/useDynamicSize";
|
||||
|
||||
interface CameraModalProps {
|
||||
onClose: () => void;
|
||||
onTakePhoto: (photo: string) => void;
|
||||
onError: (error: string | DOMException) => void;
|
||||
reinitializeKey?: number; // for reinitializing the camera (change the key to reinitialize the camera)
|
||||
isCameraVisible?: boolean;
|
||||
}
|
||||
|
||||
function CameraModal({
|
||||
onClose,
|
||||
onTakePhoto,
|
||||
onError,
|
||||
reinitializeKey = 0,
|
||||
isCameraVisible = true
|
||||
}: CameraModalProps) {
|
||||
const [isVideoReady, setIsVideoReady] = useState(false);
|
||||
// const {
|
||||
@ -28,6 +32,9 @@ function CameraModal({
|
||||
// const ratio = isLandscape ? width / height : height / width;
|
||||
const cameraRef = useRef<Webcam>(null);
|
||||
|
||||
useEffect(() => {
|
||||
setIsVideoReady(false);
|
||||
}, [reinitializeKey]);
|
||||
|
||||
const onClickOverlay = (e: React.MouseEvent) => {
|
||||
if (e.target === e.currentTarget) {
|
||||
@ -67,7 +74,8 @@ function CameraModal({
|
||||
<path d="M44.9888 101.991C31.3554 80.777 16.4145 88.555 8.56162 99.382C3.99661 105.676 3.45507 113.764 3.41227 121.539C3.06124 185.302 2.66386 298.933 3.47936 322.748C4.34753 348.102 22.1089 380.082 30.881 392.903C47.521 412.857 95.0172 446.752 151.882 422.699C208.748 398.646 222.91 337.033 223 307.148V181.957V181.957C222.663 170.327 216.966 158.307 205.412 156.937C201.087 156.425 197.042 156.699 193.716 157.409C191.581 157.864 189.641 158.915 187.848 160.159V160.159C181.442 164.605 177.583 171.876 177.493 179.673L176.571 259.523L177.251 200.682L176.705 74.0516C176.618 53.7907 170.942 24.5591 151.038 28.3435C144.116 29.6596 138.353 35.2118 135.333 42.942M44.9888 101.991L46.074 202.212M44.9888 101.991L45.9236 62.9801C46.2026 51.3361 47.4303 38.0466 57.4751 32.1503C67.0778 26.5135 80.2774 27.7506 90.8392 42.942M90.8392 42.942V202.212M90.8392 42.942V38.4912C90.8392 26.0387 91.7293 11.455 102.608 5.39458C108.902 1.88803 116.617 1.86364 124.232 7.80872C130.541 12.7337 133.624 20.5445 134.497 28.5001C134.994 33.0286 135.333 38.1796 135.333 42.942M135.333 42.942V202.212" stroke="white" strokeWidth="6" strokeLinecap="round" />
|
||||
</svg>
|
||||
|
||||
<Webcam
|
||||
{isCameraVisible && <Webcam
|
||||
key={reinitializeKey}
|
||||
ref={cameraRef}
|
||||
className={styles.camera}
|
||||
muted
|
||||
@ -87,7 +95,7 @@ function CameraModal({
|
||||
console.error(error);
|
||||
onError(error);
|
||||
}}
|
||||
/>
|
||||
/>}
|
||||
<div
|
||||
className={styles.shutterButton}
|
||||
onClick={onClickTakePhoto}
|
||||
|
||||
@ -30,7 +30,7 @@ function SecretDiscountTable() {
|
||||
const activeProduct = products[0]
|
||||
// const price = activeProduct?.price || 0;
|
||||
const trialPrice = activeProduct?.trialPrice || 0;
|
||||
// const trialDuration = activeProduct?.trialDuration || 7;
|
||||
const trialDuration = activeProduct?.trialDuration || 7;
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
@ -49,7 +49,7 @@ function SecretDiscountTable() {
|
||||
<span className={styles["new-discount"]}>{getText("new.discount")}</span>
|
||||
</div>
|
||||
<div className={`${styles["grid-line"]} ${styles["days-14"]}`}>
|
||||
<p>{translate("secret-discount.secret-discount-table_cost-after-trial", { days: getText("trial.duration") })}</p>
|
||||
<p>{translate("secret-discount.secret-discount-table_cost-after-trial", { days: trialDuration })}</p>
|
||||
<span className={styles["old-price"]}>{addCurrency(Number(getText("old.price")), currency)}</span>
|
||||
<span className={styles["new-price"]}>{getPrice(trialPrice, currency)}</span>
|
||||
</div>
|
||||
|
||||
@ -7,7 +7,7 @@ import { useDispatch } from "react-redux";
|
||||
import { actions } from "@/store";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import routes from "@/routes";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import Loader, { LoaderColor } from "@/components/Loader";
|
||||
import UploadModal from "@/components/palmistry/upload-modal/upload-modal";
|
||||
import Toast from "@/components/pages/ABDesign/v1/components/Toast";
|
||||
@ -15,15 +15,27 @@ import { useTranslations } from "@/hooks/translations";
|
||||
import { ELocalesPlacement } from "@/locales";
|
||||
import CameraModal from "../../components/CameraModal";
|
||||
import metricService, { EGoals, EMetrics } from "@/services/metric/metricService";
|
||||
import Modal from "@/components/Modal";
|
||||
import Title from "@/components/Title";
|
||||
|
||||
const isProduction = import.meta.env.MODE === "production";
|
||||
|
||||
enum EToastVisible {
|
||||
"try_again" = "try_again",
|
||||
"try_again_or_next" = "try_again_or_next",
|
||||
"no_access_camera" = "no_access_camera",
|
||||
"reload_page" = "reload_page",
|
||||
}
|
||||
|
||||
function Camera() {
|
||||
const isIphoneSafari = useMemo((): boolean => {
|
||||
const userAgent = navigator.userAgent;
|
||||
const isIOS = /iPhone/i.test(userAgent);
|
||||
const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);
|
||||
|
||||
return isIOS && isSafari;
|
||||
}, []);
|
||||
|
||||
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2);
|
||||
const navigate = useNavigate();
|
||||
const api = useApi();
|
||||
@ -31,6 +43,9 @@ function Camera() {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [uploadMenuModalIsOpen, setUploadMenuModalIsOpen] = useState(false);
|
||||
const [toastVisible, setToastVisible] = useState<EToastVisible | null>(null);
|
||||
const [isRequestCameraModalOpen, setIsRequestCameraModalOpen] = useState(isIphoneSafari ? false : true);
|
||||
const [cameraKey, setCameraKey] = useState(0);
|
||||
const [isCameraModalOpen, setIsCameraModalOpen] = useState(false);
|
||||
|
||||
const handleNext = () => {
|
||||
metricService.reachGoal(EGoals.CAMERA_SUCCESS, [EMetrics.YANDEX, EMetrics.KLAVIYO]);
|
||||
@ -164,8 +179,68 @@ function Camera() {
|
||||
}
|
||||
}, [toastVisible]);
|
||||
|
||||
const cameraError = (error: string | DOMException) => {
|
||||
console.error("Camera error", error)
|
||||
if (!isIphoneSafari) return;
|
||||
if (error === "Video is not ready") {
|
||||
return setToastVisible(EToastVisible.no_access_camera)
|
||||
}
|
||||
return setIsRequestCameraModalOpen(true)
|
||||
}
|
||||
|
||||
const requestCameraPermission = async () => {
|
||||
if (cameraKey > 2) {
|
||||
setIsRequestCameraModalOpen(false);
|
||||
setToastVisible(EToastVisible.reload_page);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
|
||||
setToastVisible(null);
|
||||
stream.getTracks().forEach(track => track.stop());
|
||||
setCameraKey(prev => prev + 1);
|
||||
} catch (error) {
|
||||
setCameraKey(prev => prev + 1);
|
||||
console.error("Ошибка при запросе доступа к камере:", error);
|
||||
setIsRequestCameraModalOpen(true);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
isCloseButtonVisible={false}
|
||||
open={isRequestCameraModalOpen}
|
||||
onClose={() => { }}
|
||||
className={styles.modal}
|
||||
containerClassName={styles["modal-container"]}
|
||||
>
|
||||
<Title variant="h4" className={styles["modal-title"]}>
|
||||
{translate("/camera.modal.title")}
|
||||
</Title>
|
||||
<div className={styles["modal-answers"]}>
|
||||
<div className={styles["modal-answer"]} onClick={() => {
|
||||
setIsRequestCameraModalOpen(false);
|
||||
setToastVisible(EToastVisible.no_access_camera);
|
||||
}}>
|
||||
<p className={styles["modal-answer-text"]}>
|
||||
{translate("/camera.modal.cancel")}
|
||||
</p>
|
||||
</div>
|
||||
<div className={styles["modal-answer"]} onClick={() => {
|
||||
setIsRequestCameraModalOpen(false)
|
||||
if (isIphoneSafari) {
|
||||
requestCameraPermission()
|
||||
} else {
|
||||
setIsCameraModalOpen(true)
|
||||
}
|
||||
}}>
|
||||
<p className={styles["modal-answer-text"]}>
|
||||
{translate("/camera.modal.allow")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
{!isProduction && uploadMenuModalIsOpen && (
|
||||
<UploadModal
|
||||
onClose={() => setUploadMenuModalIsOpen(false)}
|
||||
@ -189,10 +264,9 @@ function Camera() {
|
||||
<CameraModal
|
||||
onClose={() => console.log("close")}
|
||||
onTakePhoto={onTakePhoto}
|
||||
onError={(error) => {
|
||||
console.error(error)
|
||||
setToastVisible(EToastVisible.try_again)
|
||||
}}
|
||||
onError={cameraError}
|
||||
isCameraVisible={isIphoneSafari ? true : isCameraModalOpen}
|
||||
reinitializeKey={cameraKey}
|
||||
/>
|
||||
)}
|
||||
{isLoading && (
|
||||
@ -208,6 +282,36 @@ function Camera() {
|
||||
</div>
|
||||
</Toast>
|
||||
)}
|
||||
{toastVisible === EToastVisible.no_access_camera && (
|
||||
<Toast classNameContainer={styles["toast-container"]} variant="error">
|
||||
<div className={styles["toast-content"]}>
|
||||
<span>{translate("/camera.no_access_camera")}</span>
|
||||
<button onClick={() => {
|
||||
setToastVisible(null)
|
||||
if (isIphoneSafari) {
|
||||
requestCameraPermission()
|
||||
} else {
|
||||
setIsCameraModalOpen(true)
|
||||
}
|
||||
}}>
|
||||
{translate("/camera.give_access")}
|
||||
</button>
|
||||
</div>
|
||||
</Toast>
|
||||
)}
|
||||
{toastVisible === EToastVisible.reload_page && (
|
||||
<Toast classNameContainer={styles["toast-container"]} variant="error">
|
||||
<div className={styles["toast-content"]}>
|
||||
<span>{translate("/camera.reload_page")}</span>
|
||||
<button onClick={() => {
|
||||
setToastVisible(null)
|
||||
window.location.reload()
|
||||
}}>
|
||||
{translate("/camera.reload_page_button")}
|
||||
</button>
|
||||
</div>
|
||||
</Toast>
|
||||
)}
|
||||
{toastVisible === EToastVisible.try_again_or_next && (
|
||||
<Toast classNameContainer={styles["toast-container"]} variant="error">
|
||||
<div
|
||||
|
||||
@ -48,3 +48,41 @@
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.modal {
|
||||
z-index: 4000;
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
max-width: 290px;
|
||||
padding: 24px 0px 0px;
|
||||
|
||||
|
||||
&>.modal-title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 16px;
|
||||
padding-inline: 32px;
|
||||
}
|
||||
|
||||
&>.modal-answers {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-top: 24px;
|
||||
border-top: 1px solid #D9D9D9;
|
||||
|
||||
&>.modal-answer {
|
||||
width: 50%;
|
||||
height: 52px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #275DA7;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
|
||||
&:first-child {
|
||||
border-right: 1px solid #D9D9D9;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -67,6 +67,9 @@ function GenderPage() {
|
||||
ESourceAuthorization["aura.compatibility.v2"],
|
||||
session.sessionId
|
||||
);
|
||||
metricService.userParams({
|
||||
sessionId: session.sessionId,
|
||||
});
|
||||
}
|
||||
return navigate(routes.client.compatibilityV2Birthdate());
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
|
||||
@ -16,6 +16,7 @@ import { ELottieKeys, useLottie } from "@/hooks/lottie/useLottie";
|
||||
import { useSession } from "@/hooks/session/useSession";
|
||||
import { EGender, ESourceAuthorization } from "@/api/resources/User";
|
||||
import Answer from "../../components/Answer";
|
||||
import metricService from "@/services/metric/metricService";
|
||||
|
||||
function GenderPartner() {
|
||||
const { translate } = useTranslations(ELocalesPlacement.CompatibilityV2);
|
||||
@ -67,6 +68,9 @@ function GenderPartner() {
|
||||
ESourceAuthorization["aura.compatibility.v2"],
|
||||
session.sessionId
|
||||
);
|
||||
metricService.userParams({
|
||||
sessionId: session.sessionId,
|
||||
});
|
||||
}
|
||||
return navigate(routes.client.compatibilityV2BirthdatePartner());
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
|
||||
@ -25,6 +25,7 @@ function SaveOff() {
|
||||
// const activeProduct = products.find(product => product?.trialPrice === activeProductFromStore?.trialPrice) || products[0]
|
||||
const activeProduct = products[0]
|
||||
const trialPrice = (activeProduct?.trialPrice || 0) / 100;
|
||||
const trialDuration = activeProduct?.trialDuration || 7;
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
@ -58,7 +59,7 @@ function SaveOff() {
|
||||
<img src={images("discount/fire.png")} alt="fire" />
|
||||
{translate("save-off.trial-duration", {
|
||||
// days: trialDuration
|
||||
trialDuration: getText("trial.duration"),
|
||||
trialDuration: trialDuration,
|
||||
oldTrialDuration: <s>{translate("save-off.old-trial-duration", {
|
||||
oldTrialDuration: getText("old.trial.duration")
|
||||
})}</s>,
|
||||
@ -69,7 +70,7 @@ function SaveOff() {
|
||||
{translate("save-off.discount-offer", { discount: getText("discount") })}
|
||||
</p>
|
||||
<Button className={styles.button} onClick={handleNext}>
|
||||
{translate("save-off.button-trial", { days: getText("trial.duration") })}
|
||||
{translate("save-off.button-trial", { days: trialDuration })}
|
||||
</Button>
|
||||
</>
|
||||
)
|
||||
|
||||
@ -35,7 +35,7 @@ function SecretDiscount() {
|
||||
const activeProduct = products[0]
|
||||
// const price = (activeProduct?.price || 0) / 100;
|
||||
const trialPrice = (activeProduct?.trialPrice || 0) / 100;
|
||||
// const trialDuration = activeProduct?.trialDuration || 7;
|
||||
const trialDuration = activeProduct?.trialDuration || 7;
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
@ -131,13 +131,13 @@ function SecretDiscount() {
|
||||
</Title>
|
||||
<SecretDiscountTable />
|
||||
<Button className={styles.button} onClick={openPaymentModal}>
|
||||
{translate("secret-discount.button-trial", { days: getText("trial.duration") })}
|
||||
{translate("secret-discount.button-trial", { days: trialDuration })}
|
||||
</Button>
|
||||
|
||||
<div className={styles["policy-container"]} ref={policyContainerRef}>
|
||||
<p className={styles.policy}>
|
||||
{translate("secret-discount.policy", {
|
||||
days: getText("trial.duration"),
|
||||
days: trialDuration,
|
||||
oldDays: getText("old.trial.duration"),
|
||||
trialPrice: addCurrency(trialPrice, currency),
|
||||
price: addCurrency(
|
||||
|
||||
@ -27,7 +27,7 @@ function SecretDiscountTable() {
|
||||
const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1);
|
||||
|
||||
const activeProduct = products[0];
|
||||
const price = activeProduct?.price || 0;
|
||||
// const price = activeProduct?.price || 0;
|
||||
const trialPrice = activeProduct?.trialPrice || 0;
|
||||
const trialDuration = activeProduct?.trialDuration || 7;
|
||||
|
||||
@ -50,7 +50,7 @@ function SecretDiscountTable() {
|
||||
<div className={`${styles["grid-line"]} ${styles["days-14"]}`}>
|
||||
<p>{translate("secret-discount.secret-discount-table_cost-after-trial", { days: trialDuration })}</p>
|
||||
<span className={styles["old-price"]}>{addCurrency(Number(getText("old.price")), currency)}</span>
|
||||
<span className={styles["new-price"]}>{getPrice(price, currency)}</span>
|
||||
<span className={styles["new-price"]}>{getPrice(trialPrice, currency)}</span>
|
||||
</div>
|
||||
<div className={`${styles["grid-line"]} ${styles["save"]}`}>
|
||||
<p>{translate("secret-discount.secret-discount-table_you-save", { amount: addCurrency(Number(getText("save")), currency) })}</p>
|
||||
|
||||
@ -21,7 +21,8 @@ function SaveOff() {
|
||||
localesPlacement: ELocalesPlacement.EmailMarketingCompatibilityV1,
|
||||
});
|
||||
const activeProduct = products[0]
|
||||
const price = (activeProduct?.price || 0) / 100
|
||||
// const price = (activeProduct?.price || 0) / 100
|
||||
const trialPrice = (activeProduct?.trialPrice || 0) / 100;
|
||||
const trialDuration = activeProduct?.trialDuration || 7
|
||||
|
||||
const navigate = useNavigate();
|
||||
@ -45,17 +46,22 @@ function SaveOff() {
|
||||
</Title>
|
||||
<p className={styles.description}>
|
||||
{translate("save-off.instead", {
|
||||
price: <span className={styles.price}>{addCurrency(price, currency)}</span>,
|
||||
price: <span className={styles.price}>{addCurrency(trialPrice, currency)}</span>,
|
||||
oldPrice: <span className={styles.discount}>
|
||||
{translate("save-off.instead-old-price", {
|
||||
oldPrice: addCurrency(getText("full.price") as string, currency)
|
||||
oldPrice: addCurrency(getText("old.price") as string, currency)
|
||||
})}
|
||||
</span>
|
||||
})}
|
||||
</p>
|
||||
<p className={styles.point} style={{ marginTop: 12 }}>
|
||||
<img src={images("fire.png")} alt="fire" />
|
||||
{translate("save-off.trial-duration", { days: trialDuration })}
|
||||
{translate("save-off.trial-duration", {
|
||||
trialDuration: trialDuration,
|
||||
oldTrialDuration: <s>{translate("save-off.old-trial-duration", {
|
||||
oldTrialDuration: getText("old.trial.duration")
|
||||
})}</s>,
|
||||
})}
|
||||
</p>
|
||||
<p className={styles.point}>
|
||||
<img src={images("gift.png")} alt="gift" />
|
||||
|
||||
@ -15,7 +15,6 @@ import { actions } from "@/store";
|
||||
import { useTranslations } from "@/hooks/translations";
|
||||
import Header from "@/components/pages/ABDesign/v1/components/Header";
|
||||
import { useDynamicSize } from "@/hooks/useDynamicSize";
|
||||
import { usePayment } from "@/hooks/payment/nmi/usePayment";
|
||||
|
||||
const placementKey = EPlacementKeys["aura.placement.email.compatibility.discount"]
|
||||
|
||||
@ -24,14 +23,15 @@ function SecretDiscount() {
|
||||
const { height, elementRef: policyContainerRef } = useDynamicSize<HTMLDivElement>({ defaultWidth: 560, defaultHeight: 193 });
|
||||
const dispatch = useDispatch();
|
||||
const navigate = useNavigate();
|
||||
const { products, currency } = usePaywall({
|
||||
const { products, currency, getText } = usePaywall({
|
||||
placementKey,
|
||||
localesPlacement: ELocalesPlacement.EmailMarketingCompatibilityV1,
|
||||
});
|
||||
const { translate } = useTranslations(ELocalesPlacement.EmailMarketingCompatibilityV1);
|
||||
|
||||
const activeProduct = products[0];
|
||||
const price = (activeProduct?.price || 0) / 100;
|
||||
// const price = (activeProduct?.price || 0) / 100;
|
||||
const trialPrice = (activeProduct?.trialPrice || 0) / 100;
|
||||
const trialDuration = activeProduct?.trialDuration || 7;
|
||||
|
||||
useEffect(() => {
|
||||
@ -44,45 +44,49 @@ function SecretDiscount() {
|
||||
// const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false);
|
||||
|
||||
|
||||
const {
|
||||
error,
|
||||
isPaymentSuccess,
|
||||
showCreditCardForm,
|
||||
} = usePayment({
|
||||
placementKey,
|
||||
activeProduct,
|
||||
paymentFormType: "lightbox"
|
||||
});
|
||||
// const {
|
||||
// error,
|
||||
// isPaymentSuccess,
|
||||
// showCreditCardForm,
|
||||
// } = usePayment({
|
||||
// placementKey,
|
||||
// activeProduct,
|
||||
// paymentFormType: "lightbox"
|
||||
// });
|
||||
|
||||
useEffect(() => {
|
||||
if (error) {
|
||||
onPaymentError();
|
||||
}
|
||||
}, [error])
|
||||
// useEffect(() => {
|
||||
// if (error) {
|
||||
// onPaymentError();
|
||||
// }
|
||||
// }, [error])
|
||||
|
||||
useEffect(() => {
|
||||
if (isPaymentSuccess) {
|
||||
onPaymentSuccess();
|
||||
}
|
||||
}, [isPaymentSuccess])
|
||||
// useEffect(() => {
|
||||
// if (isPaymentSuccess) {
|
||||
// onPaymentSuccess();
|
||||
// }
|
||||
// }, [isPaymentSuccess])
|
||||
|
||||
|
||||
const onPaymentSuccess = () => {
|
||||
return navigate(routes.client.paymentSuccess())
|
||||
}
|
||||
// const onPaymentSuccess = () => {
|
||||
// return navigate(routes.client.paymentSuccess())
|
||||
// }
|
||||
|
||||
// const onModalClosed = () => {
|
||||
// setIsPaymentModalOpen(false);
|
||||
// }
|
||||
|
||||
const onPaymentError = () => {
|
||||
return navigate(routes.client.paymentFail())
|
||||
}
|
||||
// const onPaymentError = () => {
|
||||
// return navigate(routes.client.paymentFail())
|
||||
// }
|
||||
|
||||
// const openPaymentModal = () => {
|
||||
// setIsPaymentModalOpen(true);
|
||||
// };
|
||||
|
||||
const handlePayment = () => {
|
||||
navigate(routes.client.emailMarketingV1SecretDiscountPaymentModal());
|
||||
}
|
||||
|
||||
return (
|
||||
<section className={styles.container} ref={elementRef} style={{
|
||||
paddingBottom: `${height + 42}px`
|
||||
@ -111,7 +115,7 @@ function SecretDiscount() {
|
||||
{translate("secret-discount.title")}
|
||||
</Title>
|
||||
<SecretDiscountTable />
|
||||
<Button className={styles.button} onClick={showCreditCardForm}>
|
||||
<Button className={styles.button} onClick={handlePayment}>
|
||||
{translate("secret-discount.button-trial", { days: trialDuration })}
|
||||
</Button>
|
||||
|
||||
@ -119,7 +123,15 @@ function SecretDiscount() {
|
||||
<p className={styles.policy}>
|
||||
{translate("secret-discount.policy", {
|
||||
days: trialDuration,
|
||||
price: addCurrency(price, currency)
|
||||
oldDays: getText("old.trial.duration"),
|
||||
trialPrice: addCurrency(trialPrice, currency),
|
||||
price: addCurrency(
|
||||
(
|
||||
Number(getText("old.price"))
|
||||
/ (
|
||||
Number(getText("split.price.value")) || 2
|
||||
)
|
||||
), currency),
|
||||
})}
|
||||
</p>
|
||||
<Blob4 className={styles.blob4} width={width} height={height + 34} />
|
||||
|
||||
@ -12,7 +12,6 @@ import { useNavigate } from "react-router-dom";
|
||||
import BlurComponent from "@/components/BlurComponent";
|
||||
import { useTranslations } from "@/hooks/translations";
|
||||
import { addCurrency, ELocalesPlacement } from "@/locales";
|
||||
import { usePayment } from "@/hooks/payment/nmi/usePayment";
|
||||
|
||||
const placementKey = EPlacementKeys["aura.placement.email.marketing"];
|
||||
|
||||
@ -35,52 +34,53 @@ function SpecialOffer() {
|
||||
dispatch(actions.payment.update({ activeProduct: products[0] }));
|
||||
}, [dispatch, products]);
|
||||
|
||||
const {
|
||||
error,
|
||||
isPaymentSuccess,
|
||||
isModalClosed,
|
||||
showCreditCardForm,
|
||||
} = usePayment({
|
||||
placementKey,
|
||||
activeProduct: products[0],
|
||||
paymentFormType: "lightbox"
|
||||
});
|
||||
// const {
|
||||
// error,
|
||||
// isPaymentSuccess,
|
||||
// isModalClosed,
|
||||
// showCreditCardForm,
|
||||
// } = usePayment({
|
||||
// placementKey,
|
||||
// activeProduct: products[0],
|
||||
// paymentFormType: "lightbox"
|
||||
// });
|
||||
|
||||
const openPaymentModal = () => {
|
||||
// setIsOpenPaymentModal(true);
|
||||
showCreditCardForm();
|
||||
// showCreditCardForm();
|
||||
navigate(routes.client.emailMarketingV1PaymentModal());
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (error) {
|
||||
onPaymentError();
|
||||
}
|
||||
}, [error])
|
||||
// useEffect(() => {
|
||||
// if (error) {
|
||||
// onPaymentError();
|
||||
// }
|
||||
// }, [error])
|
||||
|
||||
useEffect(() => {
|
||||
if (isPaymentSuccess) {
|
||||
onPaymentSuccess();
|
||||
}
|
||||
}, [isPaymentSuccess])
|
||||
// useEffect(() => {
|
||||
// if (isPaymentSuccess) {
|
||||
// onPaymentSuccess();
|
||||
// }
|
||||
// }, [isPaymentSuccess])
|
||||
|
||||
useEffect(() => {
|
||||
if (isModalClosed) {
|
||||
handleCloseModal()
|
||||
}
|
||||
}, [isModalClosed])
|
||||
// useEffect(() => {
|
||||
// if (isModalClosed) {
|
||||
// handleCloseModal()
|
||||
// }
|
||||
// }, [isModalClosed])
|
||||
|
||||
const handleCloseModal = () => {
|
||||
// setIsOpenPaymentModal(false);
|
||||
return navigate(routes.client.emailMarketingV1SaveOff())
|
||||
};
|
||||
// const handleCloseModal = () => {
|
||||
// // setIsOpenPaymentModal(false);
|
||||
// return navigate(routes.client.emailMarketingV1SaveOff())
|
||||
// };
|
||||
|
||||
const onPaymentError = () => {
|
||||
return navigate(routes.client.paymentFail())
|
||||
}
|
||||
// const onPaymentError = () => {
|
||||
// return navigate(routes.client.paymentFail())
|
||||
// }
|
||||
|
||||
const onPaymentSuccess = () => {
|
||||
return navigate(routes.client.paymentSuccess())
|
||||
}
|
||||
// const onPaymentSuccess = () => {
|
||||
// return navigate(routes.client.paymentSuccess())
|
||||
// }
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@ -2,19 +2,23 @@ import Webcam from "react-webcam";
|
||||
import styles from "./styles.module.scss";
|
||||
import ModalOverlay, { ModalOverlayType } from "@/components/palmistry/modal-overlay/modal-overlay";
|
||||
import Modal from "@/components/palmistry/modal/modal";
|
||||
import { useRef, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
// import { useDynamicSize } from "@/hooks/useDynamicSize";
|
||||
|
||||
interface CameraModalProps {
|
||||
onClose: () => void;
|
||||
onTakePhoto: (photo: string) => void;
|
||||
onError: (error: string | DOMException) => void;
|
||||
reinitializeKey?: number; // for reinitializing the camera (change the key to reinitialize the camera)
|
||||
isCameraVisible?: boolean;
|
||||
}
|
||||
|
||||
function CameraModal({
|
||||
onClose,
|
||||
onTakePhoto,
|
||||
onError,
|
||||
reinitializeKey = 0,
|
||||
isCameraVisible = true
|
||||
}: CameraModalProps) {
|
||||
const [isVideoReady, setIsVideoReady] = useState(false);
|
||||
// const {
|
||||
@ -28,6 +32,9 @@ function CameraModal({
|
||||
// const ratio = isLandscape ? width / height : height / width;
|
||||
const cameraRef = useRef<Webcam>(null);
|
||||
|
||||
useEffect(() => {
|
||||
setIsVideoReady(false);
|
||||
}, [reinitializeKey]);
|
||||
|
||||
const onClickOverlay = (e: React.MouseEvent) => {
|
||||
if (e.target === e.currentTarget) {
|
||||
@ -67,7 +74,8 @@ function CameraModal({
|
||||
<path d="M44.9888 101.991C31.3554 80.777 16.4145 88.555 8.56162 99.382C3.99661 105.676 3.45507 113.764 3.41227 121.539C3.06124 185.302 2.66386 298.933 3.47936 322.748C4.34753 348.102 22.1089 380.082 30.881 392.903C47.521 412.857 95.0172 446.752 151.882 422.699C208.748 398.646 222.91 337.033 223 307.148V181.957V181.957C222.663 170.327 216.966 158.307 205.412 156.937C201.087 156.425 197.042 156.699 193.716 157.409C191.581 157.864 189.641 158.915 187.848 160.159V160.159C181.442 164.605 177.583 171.876 177.493 179.673L176.571 259.523L177.251 200.682L176.705 74.0516C176.618 53.7907 170.942 24.5591 151.038 28.3435C144.116 29.6596 138.353 35.2118 135.333 42.942M44.9888 101.991L46.074 202.212M44.9888 101.991L45.9236 62.9801C46.2026 51.3361 47.4303 38.0466 57.4751 32.1503C67.0778 26.5135 80.2774 27.7506 90.8392 42.942M90.8392 42.942V202.212M90.8392 42.942V38.4912C90.8392 26.0387 91.7293 11.455 102.608 5.39458C108.902 1.88803 116.617 1.86364 124.232 7.80872C130.541 12.7337 133.624 20.5445 134.497 28.5001C134.994 33.0286 135.333 38.1796 135.333 42.942M135.333 42.942V202.212" stroke="white" strokeWidth="6" strokeLinecap="round" />
|
||||
</svg>
|
||||
|
||||
<Webcam
|
||||
{isCameraVisible && <Webcam
|
||||
key={reinitializeKey}
|
||||
ref={cameraRef}
|
||||
className={styles.camera}
|
||||
muted
|
||||
@ -87,7 +95,7 @@ function CameraModal({
|
||||
console.error(error);
|
||||
onError(error);
|
||||
}}
|
||||
/>
|
||||
/>}
|
||||
<div
|
||||
className={styles.shutterButton}
|
||||
onClick={onClickTakePhoto}
|
||||
|
||||
@ -30,7 +30,7 @@ function SecretDiscountTable() {
|
||||
const activeProduct = products[0]
|
||||
// const price = activeProduct?.price || 0;
|
||||
const trialPrice = activeProduct?.trialPrice || 0;
|
||||
// const trialDuration = activeProduct?.trialDuration || 7;
|
||||
const trialDuration = activeProduct?.trialDuration || 7;
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
@ -49,7 +49,7 @@ function SecretDiscountTable() {
|
||||
<span className={styles["new-discount"]}>{getText("new.discount")}</span>
|
||||
</div>
|
||||
<div className={`${styles["grid-line"]} ${styles["days-14"]}`}>
|
||||
<p>{translate("secret-discount.secret-discount-table_cost-after-trial", { days: getText("trial.duration") })}</p>
|
||||
<p>{translate("secret-discount.secret-discount-table_cost-after-trial", { days: trialDuration })}</p>
|
||||
<span className={styles["old-price"]}>{addCurrency(Number(getText("old.price")), currency)}</span>
|
||||
<span className={styles["new-price"]}>{getPrice(trialPrice, currency)}</span>
|
||||
</div>
|
||||
|
||||
@ -7,7 +7,7 @@ import { useDispatch } from "react-redux";
|
||||
import { actions } from "@/store";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import routes from "@/routes";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import Loader, { LoaderColor } from "@/components/Loader";
|
||||
import UploadModal from "@/components/palmistry/upload-modal/upload-modal";
|
||||
import Toast from "@/components/pages/ABDesign/v1/components/Toast";
|
||||
@ -15,15 +15,27 @@ import { useTranslations } from "@/hooks/translations";
|
||||
import { ELocalesPlacement } from "@/locales";
|
||||
import CameraModal from "../../components/CameraModal";
|
||||
import metricService, { EGoals, EMetrics } from "@/services/metric/metricService";
|
||||
import Modal from "@/components/Modal";
|
||||
import Title from "@/components/Title";
|
||||
|
||||
const isProduction = import.meta.env.MODE === "production";
|
||||
|
||||
enum EToastVisible {
|
||||
"try_again" = "try_again",
|
||||
"try_again_or_next" = "try_again_or_next",
|
||||
"no_access_camera" = "no_access_camera",
|
||||
"reload_page" = "reload_page",
|
||||
}
|
||||
|
||||
function Camera() {
|
||||
const isIphoneSafari = useMemo((): boolean => {
|
||||
const userAgent = navigator.userAgent;
|
||||
const isIOS = /iPhone/i.test(userAgent);
|
||||
const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);
|
||||
|
||||
return isIOS && isSafari;
|
||||
}, []);
|
||||
|
||||
const { translate } = useTranslations(ELocalesPlacement.PalmistryV1);
|
||||
const navigate = useNavigate();
|
||||
const api = useApi();
|
||||
@ -31,6 +43,9 @@ function Camera() {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [uploadMenuModalIsOpen, setUploadMenuModalIsOpen] = useState(false);
|
||||
const [toastVisible, setToastVisible] = useState<EToastVisible | null>(null);
|
||||
const [isRequestCameraModalOpen, setIsRequestCameraModalOpen] = useState(isIphoneSafari ? false : true);
|
||||
const [cameraKey, setCameraKey] = useState(0);
|
||||
const [isCameraModalOpen, setIsCameraModalOpen] = useState(false);
|
||||
|
||||
const handleNext = () => {
|
||||
metricService.reachGoal(EGoals.CAMERA_SUCCESS, [EMetrics.YANDEX, EMetrics.KLAVIYO]);
|
||||
@ -164,8 +179,68 @@ function Camera() {
|
||||
}
|
||||
}, [toastVisible]);
|
||||
|
||||
const cameraError = (error: string | DOMException) => {
|
||||
console.error("Camera error", error)
|
||||
if (!isIphoneSafari) return;
|
||||
if (error === "Video is not ready") {
|
||||
return setToastVisible(EToastVisible.no_access_camera)
|
||||
}
|
||||
return setIsRequestCameraModalOpen(true)
|
||||
}
|
||||
|
||||
const requestCameraPermission = async () => {
|
||||
if (cameraKey > 2) {
|
||||
setIsRequestCameraModalOpen(false);
|
||||
setToastVisible(EToastVisible.reload_page);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
|
||||
setToastVisible(null);
|
||||
stream.getTracks().forEach(track => track.stop());
|
||||
setCameraKey(prev => prev + 1);
|
||||
} catch (error) {
|
||||
setCameraKey(prev => prev + 1);
|
||||
console.error("Ошибка при запросе доступа к камере:", error);
|
||||
setIsRequestCameraModalOpen(true);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
isCloseButtonVisible={false}
|
||||
open={isRequestCameraModalOpen}
|
||||
onClose={() => { }}
|
||||
className={styles.modal}
|
||||
containerClassName={styles["modal-container"]}
|
||||
>
|
||||
<Title variant="h4" className={styles["modal-title"]}>
|
||||
{translate("/camera.modal.title")}
|
||||
</Title>
|
||||
<div className={styles["modal-answers"]}>
|
||||
<div className={styles["modal-answer"]} onClick={() => {
|
||||
setIsRequestCameraModalOpen(false);
|
||||
setToastVisible(EToastVisible.no_access_camera);
|
||||
}}>
|
||||
<p className={styles["modal-answer-text"]}>
|
||||
{translate("/camera.modal.cancel")}
|
||||
</p>
|
||||
</div>
|
||||
<div className={styles["modal-answer"]} onClick={() => {
|
||||
setIsRequestCameraModalOpen(false)
|
||||
if (isIphoneSafari) {
|
||||
requestCameraPermission()
|
||||
} else {
|
||||
setIsCameraModalOpen(true)
|
||||
}
|
||||
}}>
|
||||
<p className={styles["modal-answer-text"]}>
|
||||
{translate("/camera.modal.allow")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
{!isProduction && uploadMenuModalIsOpen && (
|
||||
<UploadModal
|
||||
onClose={() => setUploadMenuModalIsOpen(false)}
|
||||
@ -189,10 +264,9 @@ function Camera() {
|
||||
<CameraModal
|
||||
onClose={() => console.log("close")}
|
||||
onTakePhoto={onTakePhoto}
|
||||
onError={(error) => {
|
||||
console.error(error)
|
||||
setToastVisible(EToastVisible.try_again)
|
||||
}}
|
||||
onError={cameraError}
|
||||
isCameraVisible={isIphoneSafari ? true : isCameraModalOpen}
|
||||
reinitializeKey={cameraKey}
|
||||
/>
|
||||
)}
|
||||
{isLoading && (
|
||||
@ -208,6 +282,36 @@ function Camera() {
|
||||
</div>
|
||||
</Toast>
|
||||
)}
|
||||
{toastVisible === EToastVisible.no_access_camera && (
|
||||
<Toast classNameContainer={styles["toast-container"]} variant="error">
|
||||
<div className={styles["toast-content"]}>
|
||||
<span>{translate("/camera.no_access_camera")}</span>
|
||||
<button onClick={() => {
|
||||
setToastVisible(null)
|
||||
if (isIphoneSafari) {
|
||||
requestCameraPermission()
|
||||
} else {
|
||||
setIsCameraModalOpen(true)
|
||||
}
|
||||
}}>
|
||||
{translate("/camera.give_access")}
|
||||
</button>
|
||||
</div>
|
||||
</Toast>
|
||||
)}
|
||||
{toastVisible === EToastVisible.reload_page && (
|
||||
<Toast classNameContainer={styles["toast-container"]} variant="error">
|
||||
<div className={styles["toast-content"]}>
|
||||
<span>{translate("/camera.reload_page")}</span>
|
||||
<button onClick={() => {
|
||||
setToastVisible(null)
|
||||
window.location.reload()
|
||||
}}>
|
||||
{translate("/camera.reload_page_button")}
|
||||
</button>
|
||||
</div>
|
||||
</Toast>
|
||||
)}
|
||||
{toastVisible === EToastVisible.try_again_or_next && (
|
||||
<Toast classNameContainer={styles["toast-container"]} variant="error">
|
||||
<div
|
||||
|
||||
@ -48,3 +48,41 @@
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.modal {
|
||||
z-index: 4000;
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
max-width: 290px;
|
||||
padding: 24px 0px 0px;
|
||||
|
||||
|
||||
&>.modal-title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 16px;
|
||||
padding-inline: 32px;
|
||||
}
|
||||
|
||||
&>.modal-answers {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-top: 24px;
|
||||
border-top: 1px solid #D9D9D9;
|
||||
|
||||
&>.modal-answer {
|
||||
width: 50%;
|
||||
height: 52px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #275DA7;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
|
||||
&:first-child {
|
||||
border-right: 1px solid #D9D9D9;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -67,6 +67,9 @@ function GenderPalmistry() {
|
||||
ESourceAuthorization["aura.palmistry.new"],
|
||||
session.sessionId
|
||||
);
|
||||
metricService.userParams({
|
||||
sessionId: session.sessionId,
|
||||
});
|
||||
}
|
||||
return navigate(routes.client.palmistryV1Birthdate());
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
|
||||
@ -26,7 +26,7 @@ function SaveOff() {
|
||||
const activeProduct = products[0]
|
||||
const trialPrice = (activeProduct?.trialPrice || 0) / 100;
|
||||
// const price = (activeProduct?.price || 0) / 100
|
||||
// const trialDuration = activeProduct?.trialDuration || 7
|
||||
const trialDuration = activeProduct?.trialDuration || 7
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
@ -60,7 +60,7 @@ function SaveOff() {
|
||||
<img src={images("fire.png")} alt="fire" />
|
||||
{translate("save-off.trial-duration", {
|
||||
// days: trialDuration
|
||||
trialDuration: getText("trial.duration"),
|
||||
trialDuration: trialDuration,
|
||||
oldTrialDuration: <s>{translate("save-off.old-trial-duration", {
|
||||
oldTrialDuration: getText("old.trial.duration")
|
||||
})}</s>,
|
||||
@ -71,7 +71,7 @@ function SaveOff() {
|
||||
{translate("save-off.discount-offer", { discount: getText("discount") })}
|
||||
</p>
|
||||
<Button className={styles.button} onClick={handleNext}>
|
||||
{translate("save-off.button-trial", { days: getText("trial.duration") })}
|
||||
{translate("save-off.button-trial", { days: trialDuration })}
|
||||
</Button>
|
||||
</>
|
||||
)
|
||||
|
||||
@ -34,7 +34,7 @@ function SecretDiscount() {
|
||||
const activeProduct = products[0]
|
||||
// const price = (activeProduct?.price || 0) / 100;
|
||||
const trialPrice = (activeProduct?.trialPrice || 0) / 100;
|
||||
// const trialDuration = activeProduct?.trialDuration || 7;
|
||||
const trialDuration = activeProduct?.trialDuration || 7;
|
||||
// const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
@ -134,13 +134,13 @@ function SecretDiscount() {
|
||||
</Title>
|
||||
<SecretDiscountTable />
|
||||
<Button className={styles.button} onClick={openPaymentModal}>
|
||||
{translate("secret-discount.button-trial", { days: getText("trial.duration") })}
|
||||
{translate("secret-discount.button-trial", { days: trialDuration })}
|
||||
</Button>
|
||||
|
||||
<div className={styles["policy-container"]} ref={policyContainerRef}>
|
||||
<p className={styles.policy}>
|
||||
{translate("secret-discount.policy", {
|
||||
days: getText("trial.duration"),
|
||||
days: trialDuration,
|
||||
oldDays: getText("old.trial.duration"),
|
||||
trialPrice: addCurrency(trialPrice, currency),
|
||||
price: addCurrency(
|
||||
|
||||
@ -27,7 +27,7 @@ function SecretDiscountTable() {
|
||||
const { translate } = useTranslations(ELocalesPlacement.EmailMarketingPalmistryV2);
|
||||
|
||||
const activeProduct = products[0];
|
||||
const price = activeProduct?.price || 0;
|
||||
// const price = activeProduct?.price || 0;
|
||||
const trialPrice = activeProduct?.trialPrice || 0;
|
||||
const trialDuration = activeProduct?.trialDuration || 7;
|
||||
|
||||
@ -50,7 +50,7 @@ function SecretDiscountTable() {
|
||||
<div className={`${styles["grid-line"]} ${styles["days-14"]}`}>
|
||||
<p>{translate("secret-discount.secret-discount-table_cost-after-trial", { days: trialDuration })}</p>
|
||||
<span className={styles["old-price"]}>{addCurrency(Number(getText("old.price")), currency)}</span>
|
||||
<span className={styles["new-price"]}>{getPrice(price, currency)}</span>
|
||||
<span className={styles["new-price"]}>{getPrice(trialPrice, currency)}</span>
|
||||
</div>
|
||||
<div className={`${styles["grid-line"]} ${styles["save"]}`}>
|
||||
<p>{translate("secret-discount.secret-discount-table_you-save", { amount: addCurrency(Number(getText("save")), currency) })}</p>
|
||||
|
||||
@ -20,7 +20,7 @@ function SaveOff() {
|
||||
localesPlacement: ELocalesPlacement.EmailMarketingPalmistryV2,
|
||||
});
|
||||
const activeProduct = products[0]
|
||||
const price = (activeProduct?.price || 0) / 100
|
||||
const trialPrice = (activeProduct?.trialPrice || 0) / 100;
|
||||
const trialDuration = activeProduct?.trialDuration || 7
|
||||
|
||||
const navigate = useNavigate();
|
||||
@ -39,17 +39,22 @@ function SaveOff() {
|
||||
</Title>
|
||||
<p className={styles.description}>
|
||||
{translate("save-off.instead", {
|
||||
price: <span className={styles.price}>{addCurrency(price, currency)}</span>,
|
||||
price: <span className={styles.price}>{addCurrency(trialPrice, currency)}</span>,
|
||||
oldPrice: <span className={styles.discount}>
|
||||
{translate("save-off.instead-old-price", {
|
||||
oldPrice: addCurrency(getText("full.price") as string, currency)
|
||||
oldPrice: addCurrency(getText("old.price") as string, currency)
|
||||
})}
|
||||
</span>
|
||||
})}
|
||||
</p>
|
||||
<p className={styles.point} style={{ marginTop: 12 }}>
|
||||
<img src={images("fire.png")} alt="fire" />
|
||||
{translate("save-off.trial-duration", { days: trialDuration })}
|
||||
{translate("save-off.trial-duration", {
|
||||
trialDuration: trialDuration,
|
||||
oldTrialDuration: <s>{translate("save-off.old-trial-duration", {
|
||||
oldTrialDuration: getText("old.trial.duration")
|
||||
})}</s>,
|
||||
})}
|
||||
</p>
|
||||
<p className={styles.point}>
|
||||
<img src={images("gift.png")} alt="gift" />
|
||||
|
||||
@ -15,7 +15,6 @@ import { actions } from "@/store";
|
||||
import { useTranslations } from "@/hooks/translations";
|
||||
import { useDynamicSize } from "@/hooks/useDynamicSize";
|
||||
import Header from "@/components/pages/ABDesign/v1/components/Header";
|
||||
import { usePayment } from "@/hooks/payment/nmi/usePayment";
|
||||
|
||||
const placementKey = EPlacementKeys["aura.placement.email.palmistry.discount"]
|
||||
|
||||
@ -24,14 +23,15 @@ function SecretDiscount() {
|
||||
const { height, elementRef: policyContainerRef } = useDynamicSize<HTMLDivElement>({ defaultWidth: 560, defaultHeight: 193 });
|
||||
const dispatch = useDispatch();
|
||||
const navigate = useNavigate();
|
||||
const { products, currency } = usePaywall({
|
||||
const { products, currency, getText } = usePaywall({
|
||||
placementKey,
|
||||
localesPlacement: ELocalesPlacement.EmailMarketingPalmistryV2,
|
||||
});
|
||||
const { translate } = useTranslations(ELocalesPlacement.EmailMarketingPalmistryV2);
|
||||
|
||||
const activeProduct = products[0];
|
||||
const price = (activeProduct?.price || 0) / 100;
|
||||
// const price = (activeProduct?.price || 0) / 100;
|
||||
const trialPrice = (activeProduct?.trialPrice || 0) / 100;
|
||||
const trialDuration = activeProduct?.trialDuration || 7;
|
||||
|
||||
useEffect(() => {
|
||||
@ -43,44 +43,45 @@ function SecretDiscount() {
|
||||
|
||||
// const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false);
|
||||
|
||||
const {
|
||||
error,
|
||||
isPaymentSuccess,
|
||||
showCreditCardForm,
|
||||
} = usePayment({
|
||||
placementKey,
|
||||
activeProduct,
|
||||
paymentFormType: "lightbox"
|
||||
});
|
||||
// const {
|
||||
// error,
|
||||
// isPaymentSuccess,
|
||||
// showCreditCardForm,
|
||||
// } = usePayment({
|
||||
// placementKey,
|
||||
// activeProduct,
|
||||
// paymentFormType: "lightbox"
|
||||
// });
|
||||
|
||||
const onPaymentSuccess = () => {
|
||||
return navigate(routes.client.paymentSuccess())
|
||||
}
|
||||
// const onPaymentSuccess = () => {
|
||||
// return navigate(routes.client.paymentSuccess())
|
||||
// }
|
||||
|
||||
// const onModalClosed = () => {
|
||||
// // setIsPaymentModalOpen(false);
|
||||
// }
|
||||
|
||||
const onPaymentError = () => {
|
||||
return navigate(routes.client.paymentFail())
|
||||
}
|
||||
// const onPaymentError = () => {
|
||||
// return navigate(routes.client.paymentFail())
|
||||
// }
|
||||
|
||||
const openPaymentModal = () => {
|
||||
// setIsPaymentModalOpen(true);
|
||||
showCreditCardForm();
|
||||
// showCreditCardForm();
|
||||
navigate(routes.client.palmistryV2SecretDiscountPaymentModal());
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (error) {
|
||||
onPaymentError();
|
||||
}
|
||||
}, [error])
|
||||
// useEffect(() => {
|
||||
// if (error) {
|
||||
// onPaymentError();
|
||||
// }
|
||||
// }, [error])
|
||||
|
||||
useEffect(() => {
|
||||
if (isPaymentSuccess) {
|
||||
onPaymentSuccess();
|
||||
}
|
||||
}, [isPaymentSuccess])
|
||||
// useEffect(() => {
|
||||
// if (isPaymentSuccess) {
|
||||
// onPaymentSuccess();
|
||||
// }
|
||||
// }, [isPaymentSuccess])
|
||||
|
||||
return (
|
||||
<section className={styles.container} ref={elementRef} style={{
|
||||
@ -118,7 +119,15 @@ function SecretDiscount() {
|
||||
<p className={styles.policy}>
|
||||
{translate("secret-discount.policy", {
|
||||
days: trialDuration,
|
||||
price: addCurrency(price, currency)
|
||||
oldDays: getText("old.trial.duration"),
|
||||
trialPrice: addCurrency(trialPrice, currency),
|
||||
price: addCurrency(
|
||||
(
|
||||
Number(getText("old.price"))
|
||||
/ (
|
||||
Number(getText("split.price.value")) || 2
|
||||
)
|
||||
), currency),
|
||||
})}
|
||||
</p>
|
||||
<Blob4 className={styles.blob4} width={width} height={height + 34} />
|
||||
|
||||
@ -21,7 +21,6 @@ import PersonalInformation from "../../components/PersonalInformation";
|
||||
import Reviews from "../../components/Reviews";
|
||||
import Address from "../../components/Address";
|
||||
import { useApi, useApiCall, User } from "@/api";
|
||||
import { usePayment } from "@/hooks/payment/nmi/usePayment";
|
||||
|
||||
const placementKey = EPlacementKeys["aura.placement.email.palmistry"];
|
||||
|
||||
@ -52,57 +51,58 @@ function TrialPayment() {
|
||||
|
||||
// const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false);
|
||||
|
||||
const {
|
||||
error,
|
||||
isPaymentSuccess,
|
||||
isModalClosed,
|
||||
isLoading,
|
||||
showCreditCardForm,
|
||||
} = usePayment({
|
||||
placementKey,
|
||||
activeProduct,
|
||||
paymentFormType: "lightbox"
|
||||
});
|
||||
// const {
|
||||
// error,
|
||||
// isPaymentSuccess,
|
||||
// isModalClosed,
|
||||
// isLoading,
|
||||
// showCreditCardForm,
|
||||
// } = usePayment({
|
||||
// placementKey,
|
||||
// activeProduct,
|
||||
// paymentFormType: "lightbox"
|
||||
// });
|
||||
|
||||
useEffect(() => {
|
||||
if (error) {
|
||||
onPaymentError();
|
||||
}
|
||||
}, [error])
|
||||
// useEffect(() => {
|
||||
// if (error) {
|
||||
// onPaymentError();
|
||||
// }
|
||||
// }, [error])
|
||||
|
||||
useEffect(() => {
|
||||
if (isPaymentSuccess) {
|
||||
onPaymentSuccess();
|
||||
}
|
||||
}, [isPaymentSuccess])
|
||||
// useEffect(() => {
|
||||
// if (isPaymentSuccess) {
|
||||
// onPaymentSuccess();
|
||||
// }
|
||||
// }, [isPaymentSuccess])
|
||||
|
||||
useEffect(() => {
|
||||
if (isModalClosed) {
|
||||
onModalClosed();
|
||||
}
|
||||
}, [isModalClosed])
|
||||
// useEffect(() => {
|
||||
// if (isModalClosed) {
|
||||
// onModalClosed();
|
||||
// }
|
||||
// }, [isModalClosed])
|
||||
|
||||
const onPaymentSuccess = () => {
|
||||
return navigate(routes.client.paymentSuccess())
|
||||
}
|
||||
// const onPaymentSuccess = () => {
|
||||
// return navigate(routes.client.paymentSuccess())
|
||||
// }
|
||||
|
||||
const onModalClosed = () => {
|
||||
// setIsPaymentModalOpen(false);
|
||||
if (isPaymentSuccess || isLoading || error) return;
|
||||
return handleDiscount()
|
||||
}
|
||||
// const onModalClosed = () => {
|
||||
// // setIsPaymentModalOpen(false);
|
||||
// if (isPaymentSuccess || isLoading || error) return;
|
||||
// return handleDiscount()
|
||||
// }
|
||||
|
||||
const handleDiscount = () => {
|
||||
navigate(routes.client.palmistryV2SaveOff());
|
||||
};
|
||||
// const handleDiscount = () => {
|
||||
// navigate(routes.client.palmistryV2SaveOff());
|
||||
// };
|
||||
|
||||
const onPaymentError = () => {
|
||||
return navigate(routes.client.paymentFail())
|
||||
}
|
||||
// const onPaymentError = () => {
|
||||
// return navigate(routes.client.paymentFail())
|
||||
// }
|
||||
|
||||
const openPaymentModal = () => {
|
||||
// setIsPaymentModalOpen(true);
|
||||
showCreditCardForm();
|
||||
// showCreditCardForm();
|
||||
navigate(routes.client.palmistryV2PaymentModal());
|
||||
};
|
||||
|
||||
const userData = useCallback(async () => {
|
||||
|
||||
@ -106,6 +106,9 @@ function GenderPage({ productKey }: IGenderPageProps): JSX.Element {
|
||||
ESourceAuthorization["aura.main.new"],
|
||||
session.sessionId
|
||||
);
|
||||
metricService.userParams({
|
||||
sessionId: session.sessionId,
|
||||
});
|
||||
}
|
||||
if (isNextPageMentioned === "true") {
|
||||
return navigate(routes.client.mentionedInV1());
|
||||
@ -168,8 +171,7 @@ function GenderPage({ productKey }: IGenderPageProps): JSX.Element {
|
||||
<div className={styles["genders-container"]}>
|
||||
{genders.map((gender, index) => (
|
||||
<div
|
||||
className={`${styles["gender"]} ${
|
||||
selectedGender?.id === gender.id && styles["gender--selected"]
|
||||
className={`${styles["gender"]} ${selectedGender?.id === gender.id && styles["gender--selected"]
|
||||
}`}
|
||||
key={index}
|
||||
onClick={() => {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import Title from "@/components/Title";
|
||||
import styles from "./styles.module.scss";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import routes from "@/routes";
|
||||
import routes, { emailMarketingV1Prefix, palmistryV2Prefix } from "@/routes";
|
||||
import { useNavigate, useSearchParams } from "react-router-dom";
|
||||
import { onboardingTitles } from "../../data/onboarding";
|
||||
import ProgressBarLine from "@/components/ui/ProgressBarLine";
|
||||
@ -51,6 +51,12 @@ function OnboardingPage() {
|
||||
if (path === "palmistry") {
|
||||
return navigate(routes.client.home());
|
||||
}
|
||||
if (window.location.pathname.includes(emailMarketingV1Prefix)) {
|
||||
return navigate(routes.client.home());
|
||||
}
|
||||
if (window.location.pathname.includes(palmistryV2Prefix)) {
|
||||
return navigate(routes.client.home());
|
||||
}
|
||||
if (auraVideoTrial === "on") {
|
||||
return navigate(routes.client.trialChoiceVideoV1());
|
||||
}
|
||||
|
||||
@ -20,6 +20,12 @@ function GetInformationPartnerPage() {
|
||||
if (path === "compatibility") {
|
||||
return navigate(routes.client.compatibilityV2SkipTrial());
|
||||
}
|
||||
if (path === "email-compatibility") {
|
||||
return navigate(routes.client.emailMarketingV1SkipTrial());
|
||||
}
|
||||
if (path === "email-palmistry") {
|
||||
return navigate(routes.client.palmistryV2SkipTrial());
|
||||
}
|
||||
navigate(routes.client.addConsultationV1());
|
||||
};
|
||||
|
||||
@ -32,6 +38,12 @@ function GetInformationPartnerPage() {
|
||||
if (path === "compatibility") {
|
||||
return navigate(`${routes.client.palmistryOnboardingV1()}?path=compatibility`);
|
||||
}
|
||||
if (path === "email-compatibility") {
|
||||
return navigate(routes.client.emailMarketingV1Onboarding());
|
||||
}
|
||||
if (path === "email-palmistry") {
|
||||
return navigate(routes.client.palmistryV2Onboarding());
|
||||
}
|
||||
navigate(routes.client.home());
|
||||
};
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ import { useCallback, useEffect, useState } from "react";
|
||||
import { useApi } from "@/api";
|
||||
import { useAuth } from "@/auth";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import routes, { compatibilityV2Prefix } from "@/routes";
|
||||
import routes, { compatibilityV2Prefix, emailMarketingV1Prefix, palmistryV2Prefix } from "@/routes";
|
||||
import { loadStripe, Stripe, StripeElementLocale } from "@stripe/stripe-js";
|
||||
import { ResponseGet } from "@/api/resources/SinglePayment";
|
||||
import { Elements } from "@stripe/react-stripe-js";
|
||||
@ -56,6 +56,12 @@ function SkipTrial() {
|
||||
}, [checkProductPurchased, navigate, token]);
|
||||
|
||||
const handleNext = () => {
|
||||
if (window.location.pathname.includes(emailMarketingV1Prefix)) {
|
||||
return navigate(`${routes.client.getInformationPartner()}?path=email-compatibility`);
|
||||
}
|
||||
if (window.location.pathname.includes(palmistryV2Prefix)) {
|
||||
return navigate(`${routes.client.getInformationPartner()}?path=email-palmistry`);
|
||||
}
|
||||
if (window.location.pathname.includes(compatibilityV2Prefix)) {
|
||||
return navigate(`${routes.client.getInformationPartner()}?path=compatibility`);
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import useSteps from "@/hooks/palmistry/use-steps";
|
||||
import { useSession } from "@/hooks/session/useSession";
|
||||
import { useTranslations } from "@/hooks/translations";
|
||||
import { ELocalesPlacement } from "@/locales";
|
||||
import metricService from "@/services/metric/metricService";
|
||||
|
||||
export default function StepWelcome() {
|
||||
const { translate } = useTranslations(ELocalesPlacement.PalmistryV0);
|
||||
@ -11,7 +12,12 @@ export default function StepWelcome() {
|
||||
const steps = useSteps();
|
||||
|
||||
const onNext = async () => {
|
||||
await createSession(ESourceAuthorization["aura.palmistry"]);
|
||||
const session = await createSession(ESourceAuthorization["aura.palmistry"]);
|
||||
if (session?.sessionId?.length) {
|
||||
metricService.userParams({
|
||||
sessionId: session.sessionId,
|
||||
});
|
||||
}
|
||||
steps.goNext();
|
||||
};
|
||||
|
||||
|
||||
@ -101,7 +101,7 @@ export type TTranslationPlacements = Partial<
|
||||
|
||||
export const getTranslationsJSON = async (language: string): Promise<TTranslationPlacements> => {
|
||||
const api = createApi();
|
||||
// const isProduction = environments.MODE === "production" && window.location.hostname !== "localhost";
|
||||
const isDev = window.location.hostname === "localhost"
|
||||
let defaultLanguage = getDefaultLocaleByLanguage(language).toLowerCase();
|
||||
if (defaultLanguage === "pt") {
|
||||
defaultLanguage = "pt-pt"
|
||||
@ -113,13 +113,14 @@ export const getTranslationsJSON = async (language: string): Promise<TTranslatio
|
||||
const responses = await Promise.allSettled(
|
||||
placements.map(async place => {
|
||||
try {
|
||||
// return isProduction
|
||||
// ?
|
||||
return await api.getLocaleTranslations({
|
||||
return isDev
|
||||
?
|
||||
await (await fetch(`/locales/${place}/${defaultLanguage}/female_${defaultLanguage}.json`)).json()
|
||||
:
|
||||
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; // или можно вернуть пустой объект {}
|
||||
@ -131,12 +132,12 @@ export const getTranslationsJSON = async (language: string): Promise<TTranslatio
|
||||
const successfulResponses = responses
|
||||
.filter(result => result.status === 'fulfilled')
|
||||
.map(result => (result as PromiseFulfilledResult<any>).value)
|
||||
.filter(Boolean);
|
||||
// .filter(Boolean);
|
||||
|
||||
const result = successfulResponses.reduce((merged, current, index) => ({
|
||||
...merged,
|
||||
// [placements[index]]: isProduction ? current : { male: current }
|
||||
[placements[index]]: current
|
||||
[placements[index]]: isDev ? { female: current } : current
|
||||
// [placements[index]]: current
|
||||
}), {});
|
||||
|
||||
return result;
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
import { useAuth } from "@/auth";
|
||||
import routes from "@/routes";
|
||||
import { selectors } from "@/store";
|
||||
import { useSelector } from "react-redux";
|
||||
import { Navigate, Outlet } from "react-router-dom";
|
||||
|
||||
interface ICheckSubscriptionOutletProps {
|
||||
subscribedReturnUrl?: string;
|
||||
unsubscribedReturnUrl?: string;
|
||||
}
|
||||
|
||||
function CheckSubscriptionOutlet({
|
||||
subscribedReturnUrl = routes.client.home(),
|
||||
unsubscribedReturnUrl,
|
||||
}: ICheckSubscriptionOutletProps) {
|
||||
const status = useSelector(selectors.selectStatus);
|
||||
const { user } = useAuth();
|
||||
|
||||
if (user && status === "subscribed") {
|
||||
return <Navigate to={subscribedReturnUrl} replace={true} />;
|
||||
}
|
||||
if (unsubscribedReturnUrl?.length) {
|
||||
return <Navigate to={unsubscribedReturnUrl} replace={true} />;
|
||||
}
|
||||
return <Outlet />;
|
||||
}
|
||||
|
||||
export default CheckSubscriptionOutlet;
|
||||
@ -1,17 +1,108 @@
|
||||
import routes, { emailMarketingV1Prefix } from "@/routes";
|
||||
import { Outlet, Route, Routes } from "react-router-dom";
|
||||
import { Outlet, Route, Routes, useNavigate } from "react-router-dom";
|
||||
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";
|
||||
import CheckSubscriptionOutlet from "./CheckSubscriptionOutlet";
|
||||
import PaymentPage from "@/components/Payment/nmi/PaymentPage";
|
||||
import { EPlacementKeys } from "@/api/resources/Paywall";
|
||||
import { PrivateOutlet } from "@/components/App";
|
||||
import AdditionalPurchasesPalmistry from "@/components/palmistry/AdditionalPurchases";
|
||||
import SkipTrial from "@/components/palmistry/AdditionalPurchases/pages/SkipTrial";
|
||||
import AddConsultant from "@/components/palmistry/AdditionalPurchases/pages/AddConsultant";
|
||||
import AddGuides from "@/components/palmistry/AdditionalPurchases/pages/AddGuides";
|
||||
import OnboardingPage from "@/components/pages/ABDesign/v1/pages/Onboarding";
|
||||
|
||||
const removePrefix = (path: string) => path.replace(emailMarketingV1Prefix, "");
|
||||
|
||||
function MarketingLandingV1Routes() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
function onPaymentError(error?: string | undefined): void {
|
||||
if (error === "Product not found") {
|
||||
return navigate(routes.client.emailMarketingV1SpecialOffer());
|
||||
}
|
||||
}
|
||||
|
||||
function onPaymentSuccess(): void {
|
||||
setTimeout(() => {
|
||||
navigate(routes.client.emailMarketingV1SkipTrial());
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
function onBack(): void {
|
||||
navigate(routes.client.emailMarketingV1SaveOff());
|
||||
}
|
||||
|
||||
function onPopState(): void {
|
||||
if (document.location.toString() === `${window.location.origin}${routes.client.emailMarketingV1SpecialOffer()}`) {
|
||||
navigate(routes.client.emailMarketingV1SaveOff());
|
||||
}
|
||||
}
|
||||
|
||||
function onPaymentErrorDiscount(error?: string | undefined): void {
|
||||
if (error === "Product not found") {
|
||||
return navigate(routes.client.emailMarketingV1SecretDiscount());
|
||||
}
|
||||
}
|
||||
|
||||
function onPaymentSuccessDiscount(): void {
|
||||
setTimeout(() => {
|
||||
navigate(routes.client.emailMarketingV1SkipTrial());
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
<Route
|
||||
path={removePrefix(routes.client.emailMarketingV1Onboarding())}
|
||||
element={<OnboardingPage />}
|
||||
/>
|
||||
<Route element={<PrivateOutlet />}>
|
||||
<Route element={<AdditionalPurchasesPalmistry />}>
|
||||
<Route
|
||||
path={removePrefix(routes.client.emailMarketingV1SkipTrial())}
|
||||
element={<SkipTrial />}
|
||||
/>
|
||||
<Route
|
||||
path={removePrefix(routes.client.emailMarketingV1AddConsultant())}
|
||||
element={<AddConsultant />}
|
||||
/>
|
||||
<Route
|
||||
path={removePrefix(routes.client.emailMarketingV1AddGuides())}
|
||||
element={<AddGuides />}
|
||||
/>
|
||||
</Route>
|
||||
</Route>
|
||||
<Route
|
||||
element={
|
||||
<CheckSubscriptionOutlet
|
||||
subscribedReturnUrl={routes.client.compatibilityV2SkipTrial()}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Route
|
||||
path={removePrefix(routes.client.emailMarketingV1PaymentModal())}
|
||||
element={<PaymentPage
|
||||
placementKey={EPlacementKeys["aura.placement.email.marketing"]}
|
||||
onError={onPaymentError}
|
||||
onSuccess={onPaymentSuccess}
|
||||
onBack={onBack}
|
||||
onPopState={onPopState}
|
||||
/>}
|
||||
/>
|
||||
<Route
|
||||
path={removePrefix(routes.client.emailMarketingV1SecretDiscountPaymentModal())}
|
||||
element={<PaymentPage
|
||||
placementKey={EPlacementKeys["aura.placement.email.compatibility.discount"]}
|
||||
onError={onPaymentErrorDiscount}
|
||||
onSuccess={onPaymentSuccessDiscount}
|
||||
/>}
|
||||
/>
|
||||
</Route>
|
||||
<Route element={<div className={styles.container}><Outlet /></div>}>
|
||||
<Route
|
||||
path={removePrefix(routes.client.emailMarketingV1Landing())}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import routes, { palmistryV2Prefix } from "@/routes";
|
||||
import { Route, Routes } from "react-router-dom";
|
||||
import { Route, Routes, useNavigate } from "react-router-dom";
|
||||
import LayoutPalmistryV2 from "./LayoutPalmistryV2";
|
||||
import NotFoundPage from "@/components/NotFoundPage";
|
||||
import TrialPayment from "@/components/PalmistryV2/pages/TrialPayment";
|
||||
@ -8,19 +8,108 @@ import { useDispatch } from "react-redux";
|
||||
import { actions } from "@/store";
|
||||
import SaveOff from "@/components/PalmistryV2/pages/SaveOff";
|
||||
import SecretDiscount from "@/components/PalmistryV2/pages/SecretDiscount";
|
||||
import OnboardingPage from "@/components/pages/ABDesign/v1/pages/Onboarding";
|
||||
import { PrivateOutlet } from "@/components/App";
|
||||
import AdditionalPurchasesPalmistry from "@/components/palmistry/AdditionalPurchases";
|
||||
import SkipTrial from "@/components/palmistry/AdditionalPurchases/pages/SkipTrial";
|
||||
import AddConsultant from "@/components/palmistry/AdditionalPurchases/pages/AddConsultant";
|
||||
import AddGuides from "@/components/palmistry/AdditionalPurchases/pages/AddGuides";
|
||||
import CheckSubscriptionOutlet from "./CheckSubscriptionOutlet";
|
||||
import PaymentPage from "@/components/Payment/nmi/PaymentPage";
|
||||
import { EPlacementKeys } from "@/api/resources/Paywall";
|
||||
|
||||
const removePrefix = (path: string) => path.replace(palmistryV2Prefix, "");
|
||||
|
||||
function PalmistryV2Routes() {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(actions.palmistry.update({ fromRedesign: true }));
|
||||
}, [dispatch]);
|
||||
|
||||
function onPaymentError(error?: string | undefined): void {
|
||||
if (error === "Product not found") {
|
||||
return navigate(routes.client.palmistryV2TrialPayment());
|
||||
}
|
||||
}
|
||||
|
||||
function onPaymentSuccess(): void {
|
||||
setTimeout(() => {
|
||||
navigate(routes.client.palmistryV2SkipTrial());
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
function onPopState(): void {
|
||||
if (document.location.toString() === `${window.location.origin}${routes.client.palmistryV2TrialPayment()}`) {
|
||||
navigate(routes.client.palmistryV2SaveOff());
|
||||
}
|
||||
}
|
||||
|
||||
function onBack(): void {
|
||||
navigate(routes.client.palmistryV2SaveOff());
|
||||
}
|
||||
|
||||
function onPaymentErrorDiscount(error?: string | undefined): void {
|
||||
if (error === "Product not found") {
|
||||
return navigate(routes.client.palmistryV2SecretDiscount());
|
||||
}
|
||||
}
|
||||
|
||||
function onPaymentSuccessDiscount(): void {
|
||||
setTimeout(() => {
|
||||
navigate(routes.client.palmistryV2SkipTrial());
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
<Route
|
||||
path={removePrefix(routes.client.palmistryV2Onboarding())}
|
||||
element={<OnboardingPage />}
|
||||
/>
|
||||
<Route element={<PrivateOutlet />}>
|
||||
<Route element={<AdditionalPurchasesPalmistry />}>
|
||||
<Route
|
||||
path={removePrefix(routes.client.palmistryV2SkipTrial())}
|
||||
element={<SkipTrial />}
|
||||
/>
|
||||
<Route
|
||||
path={removePrefix(routes.client.palmistryV2AddConsultant())}
|
||||
element={<AddConsultant />}
|
||||
/>
|
||||
<Route
|
||||
path={removePrefix(routes.client.palmistryV2AddGuides())}
|
||||
element={<AddGuides />}
|
||||
/>
|
||||
</Route>
|
||||
</Route>
|
||||
<Route
|
||||
element={
|
||||
<CheckSubscriptionOutlet
|
||||
subscribedReturnUrl={routes.client.palmistryV2SkipTrial()}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Route
|
||||
path={removePrefix(routes.client.palmistryV2PaymentModal())}
|
||||
element={<PaymentPage
|
||||
placementKey={EPlacementKeys["aura.placement.email.palmistry"]}
|
||||
onError={onPaymentError}
|
||||
onSuccess={onPaymentSuccess}
|
||||
onBack={onBack}
|
||||
onPopState={onPopState}
|
||||
/>}
|
||||
/>
|
||||
<Route
|
||||
path={removePrefix(routes.client.palmistryV2SecretDiscountPaymentModal())}
|
||||
element={<PaymentPage
|
||||
placementKey={EPlacementKeys["aura.placement.email.palmistry.discount"]}
|
||||
onError={onPaymentErrorDiscount}
|
||||
onSuccess={onPaymentSuccessDiscount}
|
||||
/>}
|
||||
/>
|
||||
</Route>
|
||||
<Route
|
||||
path={removePrefix(routes.client.palmistryV2SecretDiscount())}
|
||||
element={<SecretDiscount />}
|
||||
|
||||
@ -240,11 +240,23 @@ const routes = {
|
||||
palmistryV2TrialPayment: () => [palmistryEmailMarketingV2Prefix, "trial-payment"].join("/"),
|
||||
palmistryV2SaveOff: () => [palmistryEmailMarketingV2Prefix, "save-off"].join("/"),
|
||||
palmistryV2SecretDiscount: () => [palmistryEmailMarketingV2Prefix, "secret-discount"].join("/"),
|
||||
palmistryV2Onboarding: () => [palmistryEmailMarketingV2Prefix, "onboarding"].join("/"),
|
||||
palmistryV2SkipTrial: () => [palmistryEmailMarketingV2Prefix, "skip-trial"].join("/"),
|
||||
palmistryV2AddConsultant: () => [palmistryEmailMarketingV2Prefix, "add-consultant"].join("/"),
|
||||
palmistryV2AddGuides: () => [palmistryEmailMarketingV2Prefix, "add-guides"].join("/"),
|
||||
palmistryV2PaymentModal: () => [palmistryEmailMarketingV2Prefix, "payment-modal"].join("/"),
|
||||
palmistryV2SecretDiscountPaymentModal: () => [palmistryEmailMarketingV2Prefix, "secret-discount-payment-modal"].join("/"),
|
||||
// MarketingLandingV1
|
||||
emailMarketingV1Landing: () => [emailMarketingV1Prefix, "marketing-landing"].join("/"),
|
||||
emailMarketingV1SpecialOffer: () => [emailMarketingV1Prefix, "special-offer"].join("/"),
|
||||
emailMarketingV1SaveOff: () => [emailMarketingV1Prefix, "save-off"].join("/"),
|
||||
emailMarketingV1SecretDiscount: () => [emailMarketingV1Prefix, "secret-discount"].join("/"),
|
||||
emailMarketingV1PaymentModal: () => [emailMarketingV1Prefix, "payment-modal"].join("/"),
|
||||
emailMarketingV1SecretDiscountPaymentModal: () => [emailMarketingV1Prefix, "secret-discount-payment-modal"].join("/"),
|
||||
emailMarketingV1SkipTrial: () => [emailMarketingV1Prefix, "skip-trial"].join("/"),
|
||||
emailMarketingV1AddConsultant: () => [emailMarketingV1Prefix, "add-consultant"].join("/"),
|
||||
emailMarketingV1AddGuides: () => [emailMarketingV1Prefix, "add-guides"].join("/"),
|
||||
emailMarketingV1Onboarding: () => [emailMarketingV1Prefix, "onboarding"].join("/"),
|
||||
// ABDesignV1
|
||||
genderV1: () => [host, "v1", "gender"].join("/"),
|
||||
questionnaireV1: () => [host, "v1", "questionnaire"].join("/"),
|
||||
|
||||
@ -71,6 +71,7 @@ export enum EMetrics {
|
||||
|
||||
interface IUserParams {
|
||||
UserID: number | string;
|
||||
sessionId: string;
|
||||
genderFrom: string;
|
||||
email: string;
|
||||
hasPersonalVideo: boolean;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user