diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index 1d35f72..aadad84 100644 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -58,9 +58,9 @@ function App(): JSX.Element { } /> } /> } /> + } /> + } /> }> - } /> - } /> } /> } /> diff --git a/src/components/BreathPage/index.tsx b/src/components/BreathPage/index.tsx index 0e19267..6e28ca9 100644 --- a/src/components/BreathPage/index.tsx +++ b/src/components/BreathPage/index.tsx @@ -1,48 +1,53 @@ import styles from "./styles.module.css"; -import BreathCircle from "../BreathCircle"; import { useCallback, useEffect, useState } from "react"; import { UserCallbacks, useApi, useApiCall } from "@/api"; import { Asset } from "@/api/resources/Assets"; -import { useDispatch, useSelector } from "react-redux"; -import { actions, selectors } from "@/store"; -import { - getCategoryIdByZodiacSign, - getZodiacSignByDate, -} from "@/services/zodiac-sign"; +import { useDispatch } from "react-redux"; +import { actions } from "@/store"; import { useTranslation } from "react-i18next"; import { getRandomArbitrary } from "@/services/random-value"; import FullScreenModal from "../FullScreenModal"; import StartBreathModalChild from "../StartBreathModalChild"; +import Title from "../Title"; +import { useNavigate } from "react-router-dom"; +import routes from "@/routes"; function BreathPage(): JSX.Element { - const { i18n } = useTranslation(); - const locale = i18n.language; - const birthdate = useSelector(selectors.selectBirthdate); - const zodiacSign = getZodiacSignByDate(birthdate); + const { t } = useTranslation(); const [asset, setAsset] = useState(); const [isOpenModal, setIsOpenModal] = useState(true); const api = useApi(); const dispatch = useDispatch(); + const navigate = useNavigate(); const assetsData = useCallback(async () => { - const { asset_categories } = await api.getAssetCategories({ locale }); - const categoryId = getCategoryIdByZodiacSign(zodiacSign, asset_categories); const { assets } = await api.getAssets({ - category: String(categoryId || "1"), + category: String("au"), }); return assets; - }, [api, locale, zodiacSign]); + }, [api]); const { data, - // isPending } = useApiCall(assetsData); + useEffect(() => { + if (isOpenModal) return; + + const timeOut = setTimeout(() => { + navigate(routes.client.breathResult()); + }, 50_000); + + return () => { + clearTimeout(timeOut); + }; + }, [navigate, isOpenModal]); + useEffect(() => { if (data) { setAsset(data[getRandomArbitrary(0, data?.length || 0)]); } - }, [data]); + }, [data, isOpenModal]); const beginBreath = () => { setIsOpenModal(false); @@ -89,12 +94,29 @@ function BreathPage(): JSX.Element { <>
- {!isOpenModal && } + {!isOpenModal && ( +
+ + {t("breathIn")} + + + {t("breathOut")} + +
+ )}
); diff --git a/src/components/BreathPage/styles.module.css b/src/components/BreathPage/styles.module.css index 2ec5d58..2de0e1e 100644 --- a/src/components/BreathPage/styles.module.css +++ b/src/components/BreathPage/styles.module.css @@ -1,12 +1,80 @@ .page { - position: relative; - height: calc(100vh - 50px); - flex: auto; - justify-content: center; - display: grid; - grid-template-rows: 1fr 96px; - justify-items: center; - background-color: #01010b; - background-size: cover; - background-repeat: no-repeat; -} \ No newline at end of file + position: relative; + height: calc(100vh - 50px); + display: flex; + justify-content: center; + align-items: center; + background-color: #01010b; + background-size: cover; + background-repeat: no-repeat; + background-position: center; + flex: auto; +} + +.text-container { + position: relative; + width: 138px; + height: 200px; +} + +.text { + position: absolute; + bottom: 0; + color: #fff; + will-change: scale, opacity; +} + +.breath-in { + animation-name: breath-in; + animation-duration: 10s; + animation-iteration-count: infinite; + animation-timing-function: linear; +} + +.breath-out { + animation-name: breath-out; + animation-duration: 10s; + animation-iteration-count: infinite; + animation-timing-function: linear; +} + +@keyframes breath-in { + 0% { + opacity: 0; + scale: 1; + } + 10% { + opacity: 1; + } + 40% { + opacity: 1; + } + 50% { + opacity: 0; + scale: 2; + } + 100% { + opacity: 0; + } +} + +@keyframes breath-out { + 0% { + opacity: 0; + scale: 1; + } + 50% { + opacity: 0; + scale: 2; + } + 60% { + opacity: 1; + } + 90% { + opacity: 1; + } + 100% { + opacity: 0; + scale: 1; + } +} diff --git a/src/components/Compatibility/index.tsx b/src/components/Compatibility/index.tsx index 3cd8eaa..81534db 100644 --- a/src/components/Compatibility/index.tsx +++ b/src/components/Compatibility/index.tsx @@ -21,7 +21,7 @@ function CompatibilityPage(): JSX.Element { const [isDisabledDate, setIsDisabledDate] = useState(true); const [name, setName] = useState(''); const [date, setDate] = useState(''); - const [compatCategory, setCompatCategory] = useState(2); + const [compatCategory, setCompatCategory] = useState(1); const handleNext = () => { dispatch(actions.compatibility.update({ rightUser: { diff --git a/src/components/Header/index.tsx b/src/components/Header/index.tsx index 5665ec9..bbdba66 100644 --- a/src/components/Header/index.tsx +++ b/src/components/Header/index.tsx @@ -11,10 +11,11 @@ type HeaderProps = { openMenu?: () => void showBack?: boolean showCross?: boolean + classCross?: CSSModuleClasses | string clickCross?: () => void } -function Header({ openMenu, showBack, showCross, clickCross = () => {undefined}, ...props }: HeaderProps & React.HTMLAttributes): JSX.Element { +function Header({ openMenu, showBack, showCross, classCross, clickCross = () => {undefined}, ...props }: HeaderProps & React.HTMLAttributes): JSX.Element { const { t } = useTranslation() const navigate = useNavigate() const location = useLocation() @@ -44,9 +45,11 @@ function Header({ openMenu, showBack, showCross, clickCross = () => {undefined}, return (
{ (showBackButton || showBack) ? : null } - logo - {t('app_name')} - {(showCrossButton || showCross) ? Cross : null} +
+ logo + {t('app_name')} +
+ {(showCrossButton || showCross) ? Cross : null} {showMenuButton ?
menu
: null} diff --git a/src/components/Header/styles.module.css b/src/components/Header/styles.module.css index e41c6b5..09ab45f 100644 --- a/src/components/Header/styles.module.css +++ b/src/components/Header/styles.module.css @@ -36,3 +36,9 @@ height: 33%; width: auto; } + +.header__logo-container { + display: flex; + flex-direction: row; + align-items: center; +} diff --git a/src/components/HomePage/styles.module.css b/src/components/HomePage/styles.module.css index 15368a2..e900ad7 100644 --- a/src/components/HomePage/styles.module.css +++ b/src/components/HomePage/styles.module.css @@ -10,7 +10,7 @@ background-size: calc(100% + 186px); background-position: center; background-repeat: no-repeat; - padding: 16px 12px; + padding: 16px 12px 0; overflow-y: scroll; } @@ -62,11 +62,11 @@ background-repeat: no-repeat; background-position: center center; -webkit-backdrop-filter: blur(14px); - background-color: #ffffff69; + background-color: #696969; backdrop-filter: blur(14px); border-radius: 100%; cursor: pointer; - background-blend-mode: exclusion; + /* background-blend-mode: exclusion; */ } .header__save > a { @@ -108,11 +108,28 @@ } .content__daily-forecast-body { - color: #a4a4a4; + color: #cbcbcb; line-height: 130%; font-weight: 500; } +.content__daily-forecast { + display: flex; + flex-direction: column; + gap: 12px; +} + +.content__daily-forecast-item { + -webkit-backdrop-filter: blur(14px); + backdrop-filter: blur(14px); + padding: 12px; + box-shadow: inset 0px 0px 25px rgba(0,0,0,0.5); + background-color: #00000094; + border-radius: 18px; + width: 100vw; + /* margin-left: 13px; */ +} + @keyframes pulse { 0% { transform: scale(0.9); diff --git a/src/components/PriceListPage/index.tsx b/src/components/PriceListPage/index.tsx index d54adfc..992998e 100644 --- a/src/components/PriceListPage/index.tsx +++ b/src/components/PriceListPage/index.tsx @@ -16,7 +16,7 @@ function PriceListPage(): JSX.Element { const email = useSelector(selectors.selectEmail) const handleNext = () => { - navigate(routes.client.home()) + navigate(routes.client.subscription()) } return ( diff --git a/src/components/SubscriptionPage/index.tsx b/src/components/SubscriptionPage/index.tsx index 5ca0d63..b70d8c6 100644 --- a/src/components/SubscriptionPage/index.tsx +++ b/src/components/SubscriptionPage/index.tsx @@ -1,49 +1,60 @@ -import { useSelector } from 'react-redux' -import { useTranslation } from 'react-i18next' -import { useNavigate } from 'react-router-dom' -import { selectors } from '@/store' -import MainButton from '../MainButton' -import Policy from '../Policy' -import Countdown from '../Countdown' -import PaymentTable, { Currency, Locale } from '../PaymentTable' -import UserHeader from '../UserHeader' -import CallToAction from '../CallToAction' -import routes from '@/routes' -import './styles.css' +import { useSelector } from "react-redux"; +import { useTranslation } from "react-i18next"; +import { useNavigate } from "react-router-dom"; +import { selectors } from "@/store"; +import MainButton from "../MainButton"; +import Policy from "../Policy"; +import Countdown from "../Countdown"; +import PaymentTable, { Currency, Locale } from "../PaymentTable"; +import UserHeader from "../UserHeader"; +import CallToAction from "../CallToAction"; +import routes from "@/routes"; +import styles from "./styles.module.css"; +import Header from "../Header"; -const currency = Currency.USD -const locale = Locale.EN -const itemPriceId = 'aura-membership-2-week-USD' +const currency = Currency.USD; +const locale = Locale.EN; +const itemPriceId = "aura-membership-2-week-USD"; const paymentItems = [ { - title: 'Per 7-Day Trial For', - price: 1.00, - description: '2-Week Plan', + title: "Per 7-Day Trial For", + price: 1.0, + description: "2-Week Plan", }, -] +]; function SubscriptionPage(): JSX.Element { - const { t } = useTranslation() - const navigate = useNavigate() - const email = useSelector(selectors.selectEmail) - const itemPrice = useSelector(selectors.selectPlanById(itemPriceId)) - const handleClick = () => navigate(routes.client.paymentMethod()) - const policyLink = {t('subscription_policy')} - console.log({ itemPrice }) + const { t } = useTranslation(); + const navigate = useNavigate(); + const email = useSelector(selectors.selectEmail); + const itemPrice = useSelector(selectors.selectPlanById(itemPriceId)); + const handleClick = () => navigate(routes.client.paymentMethod()); + const handleCross = () => navigate(routes.client.home()); + const policyLink = ( + + {t("subscription_policy")} + + ); + console.log({ itemPrice }); return ( <> +
-
+
- - -
- {t('get_access')} + + +
+ {t("get_access")}
- {t('subscription_text', { policyLink })} + {t("subscription_text", { policyLink })}
- ) + ); } -export default SubscriptionPage +export default SubscriptionPage; diff --git a/src/components/SubscriptionPage/styles.css b/src/components/SubscriptionPage/styles.module.css similarity index 86% rename from src/components/SubscriptionPage/styles.css rename to src/components/SubscriptionPage/styles.module.css index cb36945..97d1d54 100644 --- a/src/components/SubscriptionPage/styles.css +++ b/src/components/SubscriptionPage/styles.module.css @@ -7,4 +7,8 @@ justify-content: center; background-color: #fff; padding: 15px; +} + +.cross { + left: 28px; } \ No newline at end of file diff --git a/src/index.css b/src/index.css index b1667eb..2b45277 100644 --- a/src/index.css +++ b/src/index.css @@ -75,7 +75,7 @@ div[class^=divider] { } ::-webkit-scrollbar { - width: 13px; + /* width: 13px; */ } ::-webkit-scrollbar-track { diff --git a/src/routes.ts b/src/routes.ts index 2d1cd26..a7cc266 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -1,54 +1,74 @@ -import type { UserStatus } from "./types" +import type { UserStatus } from "./types"; -const host = '' -const apiHost = 'https://aura.wit.life' -const prefix = 'api/v1' +const host = ""; +const apiHost = "https://aura.wit.life"; +const prefix = "api/v1"; const routes = { client: { - root: () => [host, ''].join('/'), - birthday: () => [host, 'birthday'].join('/'), - didYouKnow: () => [host, 'did-you-know'].join('/'), - freePeriodInfo: () => [host, 'free-period'].join('/'), - birthtime: () => [host, 'birthtime'].join('/'), - emailEnter: () => [host, 'email'].join('/'), - subscription: () => [host, 'subscription'].join('/'), - createProfile: () => [host, 'profile', 'create'].join('/'), - attention: () => [host, 'attention'].join('/'), - feedback: () => [host, 'feedback'].join('/'), - paymentMethod: () => [host, 'payment', 'method'].join('/'), - wallpaper: () => [host, 'wallpaper'].join('/'), - static: () => [host, 'static', ':typeId'].join('/'), - legal: (type: string) => [host, 'static', type].join('/'), - compatibility: () => [host, 'compatibility'].join('/'), - compatibilityResult: () => [host, 'compatibility', 'result'].join('/'), - breath: () => [host, 'breath'].join('/'), - priceList: () => [host, 'price-list'].join('/'), - home: () => [host, 'home'].join('/'), - breathResult: () => [host, 'breath', 'result'].join('/'), + root: () => [host, ""].join("/"), + birthday: () => [host, "birthday"].join("/"), + didYouKnow: () => [host, "did-you-know"].join("/"), + freePeriodInfo: () => [host, "free-period"].join("/"), + birthtime: () => [host, "birthtime"].join("/"), + emailEnter: () => [host, "email"].join("/"), + subscription: () => [host, "subscription"].join("/"), + createProfile: () => [host, "profile", "create"].join("/"), + attention: () => [host, "attention"].join("/"), + feedback: () => [host, "feedback"].join("/"), + paymentMethod: () => [host, "payment", "method"].join("/"), + wallpaper: () => [host, "wallpaper"].join("/"), + static: () => [host, "static", ":typeId"].join("/"), + legal: (type: string) => [host, "static", type].join("/"), + compatibility: () => [host, "compatibility"].join("/"), + compatibilityResult: () => [host, "compatibility", "result"].join("/"), + 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('/'), - token: () => [apiHost, prefix, 'auth', 'token.json'].join('/'), - elements: () => [apiHost, prefix, 'elements.json'].join('/'), - element: (type: string) => [apiHost, prefix, 'elements', `${type}.json`].join('/'), - apps: (bundleId: string) => [apiHost, prefix, 'apps', `${bundleId}.json`].join('/'), - assets: (category: string) => [apiHost, prefix, 'assets', 'categories', `${category}.json`].join('/'), - assetCategories: () => [apiHost, prefix, 'assets', 'categories.json'].join('/'), - dailyForecasts: () => [apiHost, prefix, 'user', 'daily_forecast.json'].join('/'), - auras: () => [apiHost, prefix, 'user', 'aura.json'].join('/'), - paymentIntents: () => [apiHost, prefix, 'user', 'payment_intents.json'].join('/'), - subscriptionItems: () => [apiHost, prefix, 'user', 'subscription', 'item_prices.json'].join('/'), - subscriptionCheckout: () => [apiHost, prefix, 'user', 'subscription', 'checkout', 'new.json'].join('/'), - subscriptionStatus: () => [apiHost, prefix, 'user', 'subscription_receipts', 'status.json'].join('/'), - subscriptionReceipts: () => [apiHost, prefix, 'user', 'subscription_receipts.json'].join('/'), - subscriptionReceipt: (id: string) => [apiHost, prefix, 'user', 'subscription_receipts', `${id}.json`].join('/'), - compatCategories: () => [apiHost, prefix, 'ai', 'compat_categories.json'].join('/'), - compat: () => [apiHost, prefix, 'ai', 'compats.json'].join('/'), - createUserCallbacks: () => [apiHost, prefix, 'user', 'callbacks.json'].join('/'), - getUserCallbacks: (id: string) => [apiHost, prefix, 'user', 'callbacks', `${id}.json`].join('/'), + user: () => [apiHost, prefix, "user.json"].join("/"), + token: () => [apiHost, prefix, "auth", "token.json"].join("/"), + elements: () => [apiHost, prefix, "elements.json"].join("/"), + element: (type: string) => + [apiHost, prefix, "elements", `${type}.json`].join("/"), + apps: (bundleId: string) => + [apiHost, prefix, "apps", `${bundleId}.json`].join("/"), + assets: (category: string) => + [apiHost, prefix, "assets", "categories", `${category}.json`].join("/"), + assetCategories: () => + [apiHost, prefix, "assets", "categories.json"].join("/"), + dailyForecasts: () => + [apiHost, prefix, "user", "daily_forecast.json"].join("/"), + auras: () => [apiHost, prefix, "user", "aura.json"].join("/"), + paymentIntents: () => + [apiHost, prefix, "user", "payment_intents.json"].join("/"), + subscriptionItems: () => + [apiHost, prefix, "user", "subscription", "item_prices.json"].join("/"), + subscriptionCheckout: () => + [apiHost, prefix, "user", "subscription", "checkout", "new.json"].join( + "/" + ), + subscriptionStatus: () => + [apiHost, prefix, "user", "subscription_receipts", "status.json"].join( + "/" + ), + subscriptionReceipts: () => + [apiHost, prefix, "user", "subscription_receipts.json"].join("/"), + subscriptionReceipt: (id: string) => + [apiHost, prefix, "user", "subscription_receipts", `${id}.json`].join( + "/" + ), + compatCategories: () => + [apiHost, prefix, "ai", "compat_categories.json"].join("/"), + compat: () => [apiHost, prefix, "ai", "compats.json"].join("/"), + createUserCallbacks: () => + [apiHost, prefix, "user", "callbacks.json"].join("/"), + getUserCallbacks: (id: string) => + [apiHost, prefix, "user", "callbacks", `${id}.json`].join("/"), }, -} +}; export const entrypoints = [ routes.client.root(), @@ -62,15 +82,20 @@ export const entrypoints = [ routes.client.compatibilityResult(), routes.client.home(), routes.client.breathResult(), -] -export const isEntrypoint = (path: string) => entrypoints.includes(path) -export const isNotEntrypoint = (path: string) => !isEntrypoint(path) -export const withNavigationRoutes = [routes.client.wallpaper()] -export const hasNavigation = (path: string) => withNavigationRoutes.includes(path) -export const hasNoNavigation = (path: string) => !hasNavigation(path) +]; +export const isEntrypoint = (path: string) => entrypoints.includes(path); +export const isNotEntrypoint = (path: string) => !isEntrypoint(path); +export const withNavigationRoutes = [routes.client.wallpaper()]; +export const hasNavigation = (path: string) => + withNavigationRoutes.includes(path); +export const hasNoNavigation = (path: string) => !hasNavigation(path); -export const withCrossButtonRoutes = [routes.client.attention()] -export const hasCrossButton = (path: string) => withCrossButtonRoutes.includes(path) +export const withCrossButtonRoutes = [ + routes.client.attention(), + routes.client.subscription(), +]; +export const hasCrossButton = (path: string) => + withCrossButtonRoutes.includes(path); export const withoutFooterRoutes = [ routes.client.didYouKnow(), @@ -84,26 +109,29 @@ export const withoutFooterRoutes = [ routes.client.compatibilityResult(), routes.client.home(), routes.client.breathResult(), -] -export const hasNoFooter = (path: string) => !withoutFooterRoutes.includes(path) +]; +export const hasNoFooter = (path: string) => + !withoutFooterRoutes.includes(path); export const withoutHeaderRoutes = [ routes.client.compatibility(), -] -export const hasNoHeader = (path: string) => !withoutHeaderRoutes.includes(path) + routes.client.subscription(), +]; +export const hasNoHeader = (path: string) => + !withoutHeaderRoutes.includes(path); export const getRouteBy = (status: UserStatus): string => { switch (status) { - case 'lead': - return routes.client.birthday() - case 'registred': - case 'unsubscribed': - return routes.client.subscription() - case 'subscribed': - return routes.client.wallpaper() + case "lead": + return routes.client.birthday(); + case "registred": + case "unsubscribed": + return routes.client.subscription(); + case "subscribed": + return routes.client.wallpaper(); default: - throw new Error(`Unknown user status, received status is "${status}"`) + throw new Error(`Unknown user status, received status is "${status}"`); } -} +}; -export default routes +export default routes;