diff --git a/src/api/api.ts b/src/api/api.ts index 547ea56..3143f8b 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -26,7 +26,9 @@ import { AIRequestsV2, Assistants, OpenAI, - SinglePayment + SinglePayment, + Products, + Palmistry, } from './resources' const api = { @@ -69,7 +71,9 @@ const api = { getListRuns: createMethod(OpenAI.createRequest), // Single payment getSinglePaymentProducts: createMethod(SinglePayment.createRequestGet), - createSinglePayment: createMethod(SinglePayment.createRequestPost), + createSinglePayment: createMethod(SinglePayment.createRequestPost), + checkProductPurchased: createMethod(Products.createRequest), + getPalmistryLines: createMethod(Palmistry.createRequest), } export type ApiContextValue = typeof api diff --git a/src/api/resources/Palmistry.ts b/src/api/resources/Palmistry.ts new file mode 100644 index 0000000..1e63920 --- /dev/null +++ b/src/api/resources/Palmistry.ts @@ -0,0 +1,26 @@ +import routes from "@/routes"; + +export interface Payload { + formData: FormData; +} + +export type Response = IPalmistryLine[]; + +export interface IPalmistryLine { + line: string; + points: IPalmistryPoint[]; +} + +export interface IPalmistryPoint { + x: number; + y: number; +} + +export const createRequest = ({ formData }: Payload) => { + const url = new URL(routes.server.getPalmistryLines()); + const body = formData; + return new Request(url, { + method: "POST", + body, + }); +}; diff --git a/src/api/resources/Products.ts b/src/api/resources/Products.ts new file mode 100644 index 0000000..a75100a --- /dev/null +++ b/src/api/resources/Products.ts @@ -0,0 +1,29 @@ +import routes from "@/routes"; +import { getAuthHeaders } from "../utils"; + +interface Payload { + token: string; +} + +export interface PayloadGet extends Payload { + productKey: string; + email: string; +} + +interface ResponseGetSuccess { + status: string; + type: string; + active: boolean; +} + +interface ResponseGetError { + status: string; + message: string; +} + +export type ResponseGet = ResponseGetSuccess | ResponseGetError; + +export const createRequest = ({ token, productKey, email }: PayloadGet): Request => { + const url = new URL(routes.server.dApiCheckProductPurchased(productKey, email)); + return new Request(url, { method: "GET", headers: getAuthHeaders(token) }); +}; diff --git a/src/api/resources/SinglePayment.ts b/src/api/resources/SinglePayment.ts index 84ab8de..f99a6ff 100644 --- a/src/api/resources/SinglePayment.ts +++ b/src/api/resources/SinglePayment.ts @@ -7,6 +7,11 @@ interface Payload { export type PayloadGet = Payload; +export interface IPaymentInfo { + productId: string; + key: string; +} + export interface PayloadPost extends Payload { data: { user: { @@ -21,9 +26,7 @@ export interface PayloadPost extends Payload { sign: string | null; age: number | null; }; - paymentInfo: { - productId: string; - }; + paymentInfo: IPaymentInfo; return_url: string; }; } @@ -35,7 +38,7 @@ export interface ResponseGet { currency: string; } -export interface ResponsePost { +interface ResponsePostNewPaymentData { paymentIntent: { status: string; data: { @@ -57,13 +60,23 @@ export interface ResponsePost { }; } -export interface ResponsePostExistPaymentData { +interface ResponsePostExistPaymentData { payment: { status: string; invoiceId: string; }; } +interface ResponsePostError { + status: string; + message: string; +} + +export type ResponsePost = + | ResponsePostNewPaymentData + | ResponsePostExistPaymentData + | ResponsePostError; + export const createRequestPost = ({ data, token }: PayloadPost): Request => { const url = new URL(routes.server.dApiPaymentCheckout()); const body = JSON.stringify(data); diff --git a/src/api/resources/index.ts b/src/api/resources/index.ts index 6c11bf3..2f721e5 100644 --- a/src/api/resources/index.ts +++ b/src/api/resources/index.ts @@ -25,3 +25,5 @@ export * as AIRequestsV2 from "./AIRequestsV2"; export * as Assistants from "./Assistants"; export * as OpenAI from "./OpenAI"; export * as SinglePayment from "./SinglePayment"; +export * as Products from "./Products"; +export * as Palmistry from "./Palmistry"; diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index 7103ae9..74055fd 100755 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -1,4 +1,11 @@ -import { useCallback, useEffect, useMemo, useState } from "react"; +import { + useCallback, + useEffect, + useLayoutEffect, + useMemo, + useRef, + useState, +} from "react"; import { Routes, Route, @@ -109,7 +116,11 @@ 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"; @@ -124,9 +135,31 @@ function App(): JSX.Element { const navigate = useNavigate(); const api = useApi(); const dispatch = useDispatch(); - const { token, user, signUp } = useAuth(); + const { token, user, signUp, logout } = useAuth(); const [searchParams] = useSearchParams(); const jwtToken = searchParams.get("token"); + const isForce = searchParams.get("force"); + + useEffect(() => { + if (isForce === "true") { + dispatch(actions.userConfig.addIsForceShortPath(true)); + } else { + dispatch(actions.userConfig.addIsForceShortPath(false)); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + 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" }), @@ -161,16 +194,17 @@ function App(): JSX.Element { const { data } = useApiCall(assetsData); // jwt auth - useEffect(() => { + useLayoutEffect(() => { (async () => { if (!jwtToken) return; + logout(); const auth = await api.auth({ jwt: jwtToken }); const { auth: { token, user }, } = auth; signUp(token, user); })(); - }, [api, jwtToken, signUp]); + }, [api, jwtToken, logout, signUp]); useEffect(() => { (async () => { @@ -231,23 +265,238 @@ function App(): JSX.Element { return ( }> + } /> {/* Email - Pay - Email */} - } /> - } /> } - /> + element={ + + } + > + } + /> + } - /> + element={ + + } + > + } + /> + + + } + > + } + /> + } /> {/* Email - Pay - Email */} + {/* Advisor short path */} + + } + > + } + /> + + + } + > + } + /> + + + } + > + } + /> + + + } + > + } + /> + + } + /> + } + /> + + } + > + + } /> + + + {/* Advisor short path */} + + {/* Single Payment Page Short Path */} + + } + > + } + > + } /> + + + {/* Single Payment Page Short Path */} + {/* Test Routes Start */} } /> }> @@ -550,6 +799,10 @@ function Layout({ setIsSpecialOfferOpen }: LayoutProps): JSX.Element { 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]); @@ -644,7 +897,7 @@ function Layout({ setIsSpecialOfferOpen }: LayoutProps): JSX.Element { )} -
+
{showFooter ?