import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, 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"; import { useSchemeColorByElement } from "@/hooks/useSchemeColorByElement"; import GetInformationPartnerPage from "../pages/GetInformationPartner"; import BirthPlacePage from "../pages/BirthPlacePage"; import LoadingPage from "../pages/LoadingPage"; import { EProductKeys, productUrls } from "@/data/products"; 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, logout } = useAuth(); const [searchParams] = useSearchParams(); const jwtToken = searchParams.get("token"); const isForce = searchParams.get("force"); if (isForce === "true") { dispatch(actions.userConfig.addIsForceShortPath(true)); } if (isForce === "false") { dispatch(actions.userConfig.addIsForceShortPath(false)); } const isForceShortPath = useSelector(selectors.selectIsForceShortPath); const { gender: genderFromStore } = useSelector( selectors.selectQuestionnaire ); const birthdateFromStore = useSelector(selectors.selectBirthdate); const { birthPlace: birthPlaceFromStore } = useSelector( selectors.selectQuestionnaire ); const gender = user?.profile?.gender || genderFromStore; const birthdate = user?.profile?.birthday || birthdateFromStore; const birthPlace = user?.profile?.birthplace || birthPlaceFromStore; 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 useLayoutEffect(() => { (async () => { if (!jwtToken) return; logout(); const auth = await api.auth({ jwt: jwtToken }); const { auth: { token, user }, } = auth; signUp(token, user); })(); }, [api, jwtToken, logout, 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 */} {/* Advisor short path */} } > } /> } > } /> } > } /> } > } /> } /> } /> } > } /> {/* Advisor short path */} {/* Single Payment Page Short Path */} } > } > } /> {/* Single Payment Page Short Path */} {/* 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 mainRef = useRef(null); useSchemeColorByElement(mainRef.current, "section.page, .page, section", [ location, ]); 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}
); } // enum EIsAuthPageType { // private, // public, // } // interface ICheckIsAuthOutletProps { // redirectUrl: string; // pageType: EIsAuthPageType; // } // function CheckIsAuthOutlet({ // redirectUrl, // pageType, // }: ICheckIsAuthOutletProps): JSX.Element { // const { user } = useAuth(); // if (user && pageType === EIsAuthPageType.public) { // return ; // } // if (!user && pageType === EIsAuthPageType.private) { // return ; // } // return ; // } interface IShortPathOutletProps { productKey: EProductKeys; requiredParameters: unknown[]; isProductPage?: boolean; redirectUrls: { user?: { yes?: string; no?: string; force?: string; }; data?: { yes?: string; no?: string; force?: string; }; purchasedProduct?: { yes?: string; no?: string; force?: string; }; force?: { yes?: string; no?: string; force?: string; }; }; } function ShortPathOutlet(props: IShortPathOutletProps): JSX.Element { const { productKey, requiredParameters, redirectUrls, isProductPage } = props; const { user, token } = useAuth(); const api = useApi(); const isForce = useSelector(selectors.selectIsForceShortPath); const loadData = useCallback(async () => { if (!token?.length || !user?.email || !productKey?.length) return { status: "error", error: "Missing params", }; try { const purchased = await api.checkProductPurchased({ email: user?.email || "", productKey, token, }); return purchased; } catch (error) { console.error(error); return { status: "error", error: "Something went wrong", }; } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const { data, isPending } = useApiCall(loadData); if (isPending) { return ; } const isPurchasedProduct = !!(data && "active" in data && data.active); const isUser = !!user && !!token.length; const isFullData = requiredParameters.every((item) => !!item); if (!isFullData) { if (isForce && redirectUrls.data?.force) { return ; } if (redirectUrls.data?.no && !isForce) { return ; } return ; } if (!isUser) { if (isForce && redirectUrls.user?.force) { return ; } if (redirectUrls.user?.no && !isForce) { return ; } return ; } if (!isPurchasedProduct) { if (isForce && redirectUrls.purchasedProduct?.force) { return ( ); } if (redirectUrls.purchasedProduct?.no && !isForce) { return ; } return ; } if (isProductPage) { return ; } return ; } 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;