From f650878f3ee6b0f9a5bc9ebebdc26e67e70e449b Mon Sep 17 00:00:00 2001 From: gofnnp Date: Thu, 7 Sep 2023 05:01:19 +0400 Subject: [PATCH] feat: add breath result page and fix numbers problem --- src/api/api.ts | 5 +- src/api/resources/UserCallbacks.ts | 48 +++++++++++ src/api/resources/index.ts | 1 + src/components/App/index.tsx | 2 + src/components/BreathCircle/index.tsx | 2 +- src/components/EnergyValues/index.tsx | 2 +- src/components/EnergyValues/styles.module.css | 6 +- src/components/HomePage/index.tsx | 24 ++---- src/components/PriceListPage/index.tsx | 2 +- src/components/UserCallbacksPage/index.tsx | 79 +++++++++++++++++++ .../UserCallbacksPage/styles.module.css | 37 +++++++++ src/routes.ts | 3 + 12 files changed, 189 insertions(+), 22 deletions(-) create mode 100644 src/api/resources/UserCallbacks.ts create mode 100644 src/components/UserCallbacksPage/index.tsx create mode 100644 src/components/UserCallbacksPage/styles.module.css diff --git a/src/api/api.ts b/src/api/api.ts index a141c63..57b5eb8 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -16,7 +16,8 @@ import { PaymentIntents, AICompatCategories, AICompats, - AIRequests + AIRequests, + UserCallbacks } from './resources' const api = { @@ -39,6 +40,8 @@ const api = { getAiCompatCategories: createMethod(AICompatCategories.createRequest), getAiCompat: createMethod(AICompats.createRequest), getAiRequest: createMethod(AIRequests.createRequest), + createUserCallbacks: createMethod(UserCallbacks.createRequestPost), + getUserCallbacks: createMethod(UserCallbacks.createRequestGet), } export type ApiContextValue = typeof api diff --git a/src/api/resources/UserCallbacks.ts b/src/api/resources/UserCallbacks.ts new file mode 100644 index 0000000..c07b05c --- /dev/null +++ b/src/api/resources/UserCallbacks.ts @@ -0,0 +1,48 @@ +import routes from "@/routes"; +import { getAuthHeaders } from "../utils"; + +export interface PayloadGet { + id: string; + token: string; +} + +export interface PayloadPost { + data: { + user_callback: { + kind: string; + }; + }; + token: string; +} + +export interface Response { + user_callback: IUserCallbacks; +} + +export interface IUserCallbacks { + id: string; + user_id: number; + kind: string; + created_at: string; + updated_at: string; + prev_stat_changes: IPrevStateChanges[]; + description: string; + is_complete: boolean; +} + +export interface IPrevStateChanges { + stat: string; + value: number; + label: string; +} + +export const createRequestPost = ({ data, token }: PayloadPost): Request => { + const url = new URL(routes.server.createUserCallbacks()); + const body = JSON.stringify(data); + return new Request(url, { method: "POST", headers: getAuthHeaders(token), body }); +}; + +export const createRequestGet = ({ id, token }: PayloadGet): Request => { + const url = new URL(routes.server.getUserCallbacks(id)); + return new Request(url, { method: "GET", headers: getAuthHeaders(token) }); +}; diff --git a/src/api/resources/index.ts b/src/api/resources/index.ts index b5f5677..9d8e986 100644 --- a/src/api/resources/index.ts +++ b/src/api/resources/index.ts @@ -15,3 +15,4 @@ export * as PaymentIntents from './UserPaymentIntents' export * as AICompatCategories from './AICompatCategories' export * as AICompats from './AICompats' export * as AIRequests from './AIRequests' +export * as UserCallbacks from './UserCallbacks' diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index 87e01eb..1d35f72 100644 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -28,6 +28,7 @@ import BreathPage from '../BreathPage' import PriceListPage from '../PriceListPage' import CompatResultPage from '../CompatResultPage' import HomePage from '../HomePage' +import UserCallbacksPage from '../UserCallbacksPage' function App(): JSX.Element { const [isSpecialOfferOpen, setIsSpecialOfferOpen] = useState(false) @@ -56,6 +57,7 @@ function App(): JSX.Element { } /> } /> } /> + } /> }> } /> } /> diff --git a/src/components/BreathCircle/index.tsx b/src/components/BreathCircle/index.tsx index 3a1748f..b13fe94 100644 --- a/src/components/BreathCircle/index.tsx +++ b/src/components/BreathCircle/index.tsx @@ -11,7 +11,7 @@ function BreathCircle(): JSX.Element { const navigate = useNavigate() const [text, setText] = useState(t('')) const [counter, setCounter] = useState(0) - const handleNext = () => navigate(routes.client.compatibility()) + const handleNext = () => navigate(routes.client.breathResult()) useEffect(() => { diff --git a/src/components/EnergyValues/index.tsx b/src/components/EnergyValues/index.tsx index 0aed0a7..d3cb4e0 100644 --- a/src/components/EnergyValues/index.tsx +++ b/src/components/EnergyValues/index.tsx @@ -14,7 +14,7 @@ const colors: Record = { } const valueFormatter = (value: number) => { - return `${value * 100}%` + return `${(value * 100).toFixed()}%` } function EnergyValues({ className, values }: IEnergyValues): JSX.Element { diff --git a/src/components/EnergyValues/styles.module.css b/src/components/EnergyValues/styles.module.css index bba3d10..45b5eb3 100644 --- a/src/components/EnergyValues/styles.module.css +++ b/src/components/EnergyValues/styles.module.css @@ -8,7 +8,11 @@ .energy-value { display: flex; flex-direction: row; - gap: 2px; + gap: 4px; font-size: 14px; font-weight: 600; } + +.energy-value__label { + font-weight: 500; +} \ No newline at end of file diff --git a/src/components/HomePage/index.tsx b/src/components/HomePage/index.tsx index 41a51a9..3062b92 100644 --- a/src/components/HomePage/index.tsx +++ b/src/components/HomePage/index.tsx @@ -2,16 +2,9 @@ import { useNavigate } from "react-router-dom"; import { useTranslation } from "react-i18next"; import routes from "@/routes"; import styles from "./styles.module.css"; -import { useSelector } from "react-redux"; -import { selectors } from "@/store"; -import { - getCategoryIdByZodiacSign, - getZodiacSignByDate, -} from "@/services/zodiac-sign"; import { useApi, useApiCall } from "@/api"; import { Asset } from "@/api/resources/Assets"; import { useCallback, useEffect, useState } from "react"; -import { getRandomArbitrary } from "@/services/random-value"; import BlurringSubstrate from "../BlurringSubstrate"; import EnergyValues from "../EnergyValues"; import { UserAura } from "@/api/resources/Auras"; @@ -39,19 +32,19 @@ function HomePage(): JSX.Element { navigate(routes.client.breath()); }; - const { i18n } = useTranslation(); - const locale = i18n.language; - const birthdate = useSelector(selectors.selectBirthdate); - const zodiacSign = getZodiacSignByDate(birthdate); +// const { i18n } = useTranslation(); +// const locale = i18n.language; +// const birthdate = useSelector(selectors.selectBirthdate); +// const zodiacSign = getZodiacSignByDate(birthdate); const [asset, setAsset] = useState(); const api = useApi(); const assetsData = useCallback(async () => { - const { asset_categories } = await api.getAssetCategories({ locale }); - const categoryId = getCategoryIdByZodiacSign(zodiacSign, asset_categories); + // const { asset_categories } = await api.getAssetCategories({ locale }); + // const categoryId = getCategoryIdByZodiacSign(zodiacSign, asset_categories); const { assets } = await api.getAssets({ category: String("10" || "1") }); return assets; - }, [api, locale, zodiacSign]); + }, [api]); const { data: assets, @@ -74,9 +67,6 @@ function HomePage(): JSX.Element { // isPending } = useApiCall(auraData); - console.log(aura); - - return (
{ - navigate(routes.client.breath()) + navigate(routes.client.home()) } return ( diff --git a/src/components/UserCallbacksPage/index.tsx b/src/components/UserCallbacksPage/index.tsx new file mode 100644 index 0000000..e1bff46 --- /dev/null +++ b/src/components/UserCallbacksPage/index.tsx @@ -0,0 +1,79 @@ +import Title from "../Title"; +import styles from "./styles.module.css"; +import { useCallback, useState } from "react"; +import { UserCallbacks, useApi, useApiCall } from "@/api"; +import { IPrevStateChanges } from "@/api/resources/UserCallbacks"; + +function UserCallbacksPage(): JSX.Element { + const token = + "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOjIzNjEyLCJpYXQiOjE2OTM0MTg5MTAsImV4cCI6MTcwMjA1ODkxMCwianRpIjoiNzg5MjkwYWItODg0YS00MGUyLTkyNjEtOWI2OGEyNjkwNmE0IiwiZW1haWwiOiJvdGhlckBleGFtcGxlLmNvbSIsInN0YXRlIjoicHJvdmVuIiwibG9jIjoiZW4iLCJ0eiI6LTI4ODAwLCJ0eXBlIjoiZW1haWwiLCJpc3MiOiJjb20ubGlmZS5hdXJhIn0.J2ocWIv5jKzuKMcwMgWMiNMyGg5qLlMAeln-bQm_9lw"; + const api = useApi(); + const [text, setText] = useState("Loading..."); + const [statChanges, setStatChanges] = useState([] as IPrevStateChanges[]); + + const createCallback = useCallback(async () => { + const data: UserCallbacks.PayloadPost = { + data: { + user_callback: { + kind: "breathing_end", + }, + }, + token, + }; + const createCallbackRequest = await api.createUserCallbacks(data); + setStatChanges(createCallbackRequest.user_callback.prev_stat_changes); + if (!createCallbackRequest.user_callback.is_complete) { + const getUserCallbacksRequest = async () => { + const getCallback = await api.getUserCallbacks({ + id: createCallbackRequest.user_callback.id, + token, + }); + if (!getCallback.user_callback.is_complete) { + setTimeout(getUserCallbacksRequest, 3000); + } + setText(getCallback.user_callback.description || "Loading..."); + return getCallback.user_callback; + }; + return await getUserCallbacksRequest(); + } + + return createCallbackRequest.user_callback; + }, [api]); + + useApiCall(createCallback); + + return ( +
+
+ + <> + <p>Well done!</p> + <p>Your results has changes...</p> + </> + + {/* {t("you_and", { user: rightUser.name })} */} +
+
+
+ {statChanges.map((change, index) => ( +
+ + {change.label} + + 0 ? "#00ea00" : "red" }} + className={styles["result-container__value-value"]} + > + {change.value > 0 ? "+" : ""} + {(change.value * 100).toFixed()}% + +
+ ))} +
+

{text}

+
+
+ ); +} + +export default UserCallbacksPage; diff --git a/src/components/UserCallbacksPage/styles.module.css b/src/components/UserCallbacksPage/styles.module.css new file mode 100644 index 0000000..9fc87c2 --- /dev/null +++ b/src/components/UserCallbacksPage/styles.module.css @@ -0,0 +1,37 @@ +.page { + position: relative; + height: calc(100vh - 50px); + max-height: -webkit-fill-available; + flex: auto; + background-color: #000; + color: #bababb; + overflow-y: scroll; + text-align: center; +} + +.result-container__values { + display: flex; + flex-direction: column; + gap: 8px; + max-width: 250px; + margin: 0 auto; +} + +.result-container__value { + display: flex; + justify-content: space-between; +} + +.result-container__value-label { + color: #fff; + font-weight: 500; +} + +.result-container__value-value { + font-weight: 500; +} + +.result-container__text { + line-height: 1.2; + margin-top: 32px; +} diff --git a/src/routes.ts b/src/routes.ts index 97dddbc..2d1cd26 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -25,6 +25,7 @@ const routes = { breath: () => [host, 'breath'].join('/'), priceList: () => [host, 'price-list'].join('/'), home: () => [host, 'home'].join('/'), + breathResult: () => [host, 'breath', 'result'].join('/'), }, server: { user: () => [apiHost, prefix, 'user.json'].join('/'), @@ -60,6 +61,7 @@ export const entrypoints = [ routes.client.breath(), routes.client.compatibilityResult(), routes.client.home(), + routes.client.breathResult(), ] export const isEntrypoint = (path: string) => entrypoints.includes(path) export const isNotEntrypoint = (path: string) => !isEntrypoint(path) @@ -81,6 +83,7 @@ export const withoutFooterRoutes = [ routes.client.priceList(), routes.client.compatibilityResult(), routes.client.home(), + routes.client.breathResult(), ] export const hasNoFooter = (path: string) => !withoutFooterRoutes.includes(path)