import { useCallback, useEffect, useMemo, useState } from "react"; import { Routes, Route, Navigate, Outlet, useLocation, useNavigate, useSearchParams, } from "react-router-dom"; import { useAuth } from "@/auth"; import { useDispatch, useSelector } from "react-redux"; import { actions, selectors } from "@/store"; import routes, { hasNavigation, getRouteBy, hasNoFooter, hasNoHeader, hasNavbarFooter, hasFullDataModal, } from "@/routes"; import BirthdayPage from "../BirthdayPage"; import BirthtimePage from "../BirthtimePage"; import CreateProfilePage from "../CreateProfilePage"; import EmailEnterPage from "../EmailEnterPage"; import SubscriptionPage from "../SubscriptionPage"; import PaymentPage from "../PaymentPage"; import WallpaperPage from "../WallpaperPage"; import StaticPage from "../StaticPage"; import NotFoundPage from "../NotFoundPage"; import Header from "../Header"; import Navbar from "../Navbar"; import Footer from "../Footer"; import "./styles.css"; import DidYouKnowPage from "../DidYouKnowPage"; import FreePeriodInfoPage from "../FreePeriodInfoPage"; import AttentionPage from "../AttentionPage"; import FeedbackPage from "../FeedbackPage"; import CompatibilityPage from "../Compatibility"; import BreathPage from "../BreathPage"; import PriceListPage from "../PriceListPage"; import CompatResultPage from "../CompatResultPage"; import HomePage from "../HomePage"; import UserCallbacksPage from "../UserCallbacksPage"; import NavbarFooter, { INavbarHomeItems } from "../NavbarFooter"; import { EPathsFromHome } from "@/store/siteConfig"; import parseAPNG, { APNG } from "apng-js"; import { useApi, useApiCall } from "@/api"; import { Asset } from "@/api/resources/Assets"; import PaymentResultPage from "../PaymentPage/results"; import PaymentSuccessPage from "../PaymentPage/results/SuccessPage"; import PaymentFailPage from "../PaymentPage/results/ErrorPage"; import { StripePage } from "../StripePage"; import AuthPage from "../AuthPage"; import AuthResultPage from "../AuthResultPage"; import MagicBallPage from "../pages/MagicBall"; import BestiesHoroscopeResult from "../pages/BestiesHoroscopeResult"; import PredictionMoonResult from "../pages/PredictionMoonResult"; import MyHoroscopeResult from "../pages/MyHoroscopeResult"; import ThermalResult from "../pages/ThermalResult"; import MoonPhaseTrackerResult from "../pages/MoonPhaseTrackerResult"; import EnergyVampirismResult from "../pages/EnergyVampirismResult"; import NameHoroscopeResult from "../pages/NameHoroscopeResult"; import GenderPage from "../pages/Gender"; import QuestionnairePage from "../pages/Questionnaire"; import GoalSetupPage from "../pages/GoalSetup"; import HyperPersonalizedAstrologyPage from "../pages/HyperPersonalizedAstrologyPage"; import NoBirthtimePage from "../pages/NoBirthtime"; import LoadingInRelationshipPage from "../pages/LoadingInRelationship"; import QuestionnaireIntermediatePage from "../pages/QuestionnaireIntermediate"; import RelationshipAlmostTherePage from "../pages/RelationshipAlmostThere"; import Modal from "../Modal"; import FullDataModal from "../FullDataModal"; import SingleZodiacInfoPage from "../pages/SingleZodiacInfo"; import ProblemsPage from "../pages/Problems"; import WorksRouterPage from "../pages/WorksRouter"; import NotAlonePage from "../pages/NotAlone"; import AlmostTherePage from "../pages/AlmostThere"; import AllRightPage from "../pages/AllRight"; import PartnerRightPlacePage from "../pages/PartnerRightPlace"; import PartnerThingPage from "../pages/PartnerThing"; import PartnerTotallyNormalPage from "../pages/PartnerTotallyNormal"; import WithHeartPage from "../pages/WithHeart"; import WithHeadPage from "../pages/WithHead"; import BothPage from "../pages/Both"; import RelationshipZodiacInfoPage from "../pages/RelationshipZodiacInfo"; import Satisfied from "../pages/Satisfied"; import AboutUsPage from "../pages/AboutUs"; import LoadingProfilePage from "../pages/LoadingProfile"; import EmailConfirmPage from "../pages/EmailConfirm"; import OnboardingPage from "../pages/Onboarding"; import TrialChoicePage from "../pages/TrialChoice"; import TrialPaymentPage from "../pages/TrialPayment"; import ReactGA from "react-ga4"; import AdditionalDiscount from "../pages/AdditionalDiscount"; import TrialPaymentWithDiscount from "../pages/TrialPaymentWithDiscount"; import MarketingLanding from "../pages/EmailLetters/MarketingLanding"; import MarketingTrialPayment from "../pages/EmailLetters/MarketingTrialPayment"; import { ScrollToTop } from "@/hooks/scrollToTop"; import { EUserDeviceType } from "@/store/userConfig"; import TryAppPage from "../pages/TryApp"; import AdditionalPurchases from "../pages/AdditionalPurchases"; import AddReportPage from "../pages/AdditionalPurchases/pages/AddReport"; import UnlimitedReadingsPage from "../pages/AdditionalPurchases/pages/UnlimitedReadings"; import AddConsultationPage from "../pages/AdditionalPurchases/pages/AddConsultation"; import StepsManager from "@/components/palmistry/steps-manager/steps-manager"; import Advisors from "../pages/Advisors"; import AdvisorChatPage from "../pages/AdvisorChat"; import PaymentWithEmailPage from "../pages/PaymentWithEmailPage"; import SuccessPaymentPage from "../pages/PaymentWithEmailPage/ResultPayment/SuccessPaymentPage"; import FailPaymentPage from "../pages/PaymentWithEmailPage/ResultPayment/FailPaymentPage"; const isProduction = import.meta.env.MODE === "production"; if (isProduction) { ReactGA.initialize("G-00S3ECJGSJ"); } function App(): JSX.Element { const [isSpecialOfferOpen, setIsSpecialOfferOpen] = useState(false); const [leoApng, setLeoApng] = useState(Error); const [padLockApng, setPadLockApng] = useState(Error); const navigate = useNavigate(); const api = useApi(); const dispatch = useDispatch(); const { token, user, signUp } = useAuth(); const [searchParams] = useSearchParams(); const jwtToken = searchParams.get("token"); useEffect(() => { // api.getAppConfig({ bundleId: "auraweb" }), dispatch( actions.siteConfig.update({ openAiToken: "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", }) ); }, [dispatch]); useEffect(() => { if (!isProduction) return; ReactGA.send({ hitType: "pageview", page: document.location.pathname + document.location.search, title: "Custom Title", }); }, []); const closeSpecialOfferAttention = () => { setIsSpecialOfferOpen(false); navigate(routes.client.auth()); }; const assetsData = useCallback(async () => { const { assets } = await api.getAssets({ category: String("au"), }); return assets; }, [api]); const { data } = useApiCall(assetsData); // jwt auth useEffect(() => { (async () => { if (!jwtToken) return; const auth = await api.auth({ jwt: jwtToken }); const { auth: { token, user }, } = auth; signUp(token, user); })(); }, [api, jwtToken, signUp]); useEffect(() => { (async () => { if (!token.length || !user) return; const { user: { has_subscription }, } = await api.getSubscriptionStatus({ token, }); if (has_subscription && user) { return dispatch(actions.status.update("subscribed")); } if (!has_subscription && user) { return dispatch(actions.status.update("unsubscribed")); } if (!user) { return dispatch(actions.status.update("lead")); } })(); }, [dispatch, api, token, user]); useEffect(() => { async function getApng() { if (!data) return; const response = await fetch( data.find((item) => item.key === "au.apng.leo")?.url || "" ); const arrayBuffer = await response.arrayBuffer(); setLeoApng(parseAPNG(arrayBuffer)); } getApng(); }, [data]); useEffect(() => { (async () => { const response = await fetch("/padlock_icon_animation_closing.png"); const arrayBuffer = await response.arrayBuffer(); setPadLockApng(parseAPNG(arrayBuffer)); })(); }, []); useEffect(() => { if (!user) return; dispatch(actions.form.addEmail(user.email)); }, [dispatch, user]); // set user device type useEffect(() => { const isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent); if (isIOS) { dispatch(actions.userConfig.addDeviceType(EUserDeviceType.ios)); } else { dispatch(actions.userConfig.addDeviceType(EUserDeviceType.android)); } }, [dispatch]); return ( }> {/* Email - Pay - Email */} } /> } /> } /> } /> } /> {/* Email - Pay - Email */} {/* Test Routes Start */} } /> }> } /> } /> } > }> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } > } /> {/* Test Routes End */} {/* Email Letters */} } /> } /> {/* Email Letters End */} {/* Additional Purchases */} }> } /> } /> } /> {/* Additional Purchases End */} } > } /> } /> } /> }> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> {/* } /> */} }> } > } /> }> }> {/* } /> */} } /> } /> }> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> ); } interface LayoutProps { setIsSpecialOfferOpen: React.Dispatch>; } function Layout({ setIsSpecialOfferOpen }: LayoutProps): JSX.Element { const location = useLocation(); const navigate = useNavigate(); const dispatch = useDispatch(); const showNavbar = hasNavigation(location.pathname); const showFooter = hasNoFooter(location.pathname); const showHeader = hasNoHeader(location.pathname); const isRouteFullDataModal = hasFullDataModal(location.pathname); const [isMenuOpen, setIsMenuOpen] = useState(false); const changeIsSpecialOfferOpen = () => setIsSpecialOfferOpen(true); const homeConfig = useSelector(selectors.selectHome); const showNavbarFooter = homeConfig.isShowNavbar; const birthdate = useSelector(selectors.selectBirthdate); const dataItems = useMemo(() => [birthdate], [birthdate]); const [isShowFullDataModal, setIsShowFullDataModal] = useState(false); useEffect(() => { setIsShowFullDataModal(getIsShowFullDataModal(dataItems)); }, [dataItems]); const onCloseFullDataModal = (_birthDate: string) => { dispatch(actions.form.addDate(_birthDate)); setIsShowFullDataModal(getIsShowFullDataModal(dataItems)); }; const handleCompatibility = () => { dispatch( actions.siteConfig.update({ home: { pathFromHome: EPathsFromHome.navbar, isShowNavbar: showNavbarFooter, }, }) ); navigate(routes.client.compatibility()); }; const handleBreath = () => { dispatch( actions.siteConfig.update({ home: { pathFromHome: EPathsFromHome.navbar, isShowNavbar: showNavbarFooter, }, }) ); navigate(routes.client.breath()); }; const navbarItems: INavbarHomeItems[] = [ { title: "Breathing", path: routes.client.breath(), paths: [routes.client.breath(), routes.client.breathResult()], image: "Breath.svg", onClick: handleBreath, }, { title: "Aura", path: routes.client.home(), paths: [routes.client.home()], image: "Aura.svg", active: true, onClick: () => null, }, { title: "Compatibility", path: routes.client.compatibility(), paths: [ routes.client.compatibility(), routes.client.compatibilityResult(), ], image: "Compatibility.svg", onClick: handleCompatibility, }, { title: "Advisors", path: routes.client.advisors(), paths: [routes.client.advisors()], image: "moon.svg", onClick: () => null, }, { title: "My Moon", path: routes.client.wallpaper(), paths: [routes.client.wallpaper()], image: "moon.svg", onClick: () => null, }, ]; return (
{showHeader ? (
setIsMenuOpen(true)} clickCross={changeIsSpecialOfferOpen} /> ) : null} {isRouteFullDataModal && ( )}
{showFooter ?
: null} {showNavbar ? ( setIsMenuOpen(false)} /> ) : null} {showNavbarFooter && hasNavbarFooter(location.pathname) ? ( ) : null}
); } function AuthorizedUserOutlet(): JSX.Element { const status = useSelector(selectors.selectStatus); const { user } = useAuth(); return user && status === "subscribed" ? ( ) : ( ); } function PrivateOutlet(): JSX.Element { const { user } = useAuth(); return user ? ( ) : ( ); } function PrivateSubscriptionOutlet(): JSX.Element { const isProduction = import.meta.env.MODE === "production"; const status = useSelector(selectors.selectStatus); return status === "subscribed" || !isProduction ? ( ) : ( ); } function getIsShowFullDataModal(dataItems: Array = []): boolean { let hasNoDataItem = false; for (const item of dataItems) { if (!item) { hasNoDataItem = true; break; } } return hasNoDataItem; } function SkipStep(): JSX.Element { const { user } = useAuth(); return user ? ( ) : ( ); } function MainPage(): JSX.Element { const status = useSelector(selectors.selectStatus); return ; } export default App;