feat: add user path from home, add preview before breath, fix home buttons background color

This commit is contained in:
gofnnp 2023-09-16 02:07:33 +04:00
parent ed5cd812ce
commit 30d1ded4f5
16 changed files with 499 additions and 48 deletions

View File

@ -16,6 +16,7 @@ function BreathPage(): JSX.Element {
const { t } = useTranslation(); const { t } = useTranslation();
const [asset, setAsset] = useState<Asset>(); const [asset, setAsset] = useState<Asset>();
const [isOpenModal, setIsOpenModal] = useState<boolean>(true); const [isOpenModal, setIsOpenModal] = useState<boolean>(true);
const [isShowPreview, setIsShowPreview] = useState<boolean>(true);
const api = useApi(); const api = useApi();
const dispatch = useDispatch(); const dispatch = useDispatch();
const navigate = useNavigate(); const navigate = useNavigate();
@ -27,26 +28,33 @@ function BreathPage(): JSX.Element {
return assets; return assets;
}, [api]); }, [api]);
const { const { data } = useApiCall<Asset[]>(assetsData);
data,
} = useApiCall<Asset[]>(assetsData);
useEffect(() => { useEffect(() => {
if (isOpenModal) return; if (isOpenModal) return;
const previewTimeOut = setTimeout(() => {
setIsShowPreview(false);
}, 10_000);
const timeOut = setTimeout(() => { const navigateTimeOut = setTimeout(() => {
navigate(routes.client.breathResult()); navigate(routes.client.breathResult());
}, 50_000); }, 60_000);
return () => { return () => {
clearTimeout(timeOut); clearTimeout(navigateTimeOut);
clearTimeout(previewTimeOut);
}; };
}, [navigate, isOpenModal]); }, [navigate, isOpenModal]);
useEffect(() => { useEffect(() => {
if (data) { if (!data) return;
const leoTimeOut = setTimeout(() => {
setAsset(data[getRandomArbitrary(0, data?.length || 0)]); setAsset(data[getRandomArbitrary(0, data?.length || 0)]);
} }, 10_000);
return () => {
clearTimeout(leoTimeOut);
};
}, [data, isOpenModal]); }, [data, isOpenModal]);
const beginBreath = () => { const beginBreath = () => {
@ -95,13 +103,26 @@ function BreathPage(): JSX.Element {
<section <section
className={`${styles.page} page`} className={`${styles.page} page`}
style={{ style={{
backgroundImage: !isOpenModal ? `url(${asset?.url})` : "none", backgroundImage: `url(${
!isOpenModal && !isShowPreview ? asset?.url : "none"
})`,
}} }}
> >
{!isOpenModal && isShowPreview && (
<div className={styles.preview}>
<img className={styles.leo} src="/leo.png" alt="leo" />
<Title
variant="h2"
className={`${styles.text} ${styles["breath-relax"]}`}
>
{t("aura.breath_relax.text")}
</Title>
</div>
)}
<FullScreenModal isOpen={isOpenModal}> <FullScreenModal isOpen={isOpenModal}>
<StartBreathModalChild handleBegin={beginBreath} /> <StartBreathModalChild handleBegin={beginBreath} />
</FullScreenModal> </FullScreenModal>
{!isOpenModal && ( {!isOpenModal && !isShowPreview && (
<div className={styles["text-container"]}> <div className={styles["text-container"]}>
<Title <Title
variant="h2" variant="h2"

View File

@ -5,8 +5,8 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background-color: #01010b; background-color: #01010b;
background-size: cover;
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: cover;
background-position: center; background-position: center;
flex: auto; flex: auto;
} }
@ -38,6 +38,85 @@
animation-timing-function: linear; animation-timing-function: linear;
} }
.preview {
position: relative;
width: 100%;
display: flex;
justify-content: center;
}
.leo {
width: 90%;
animation-name: leo;
animation-duration: 10s;
animation-iteration-count: 1;
animation-timing-function: linear;
}
.breath-relax {
animation-name: breath-relax;
animation-duration: 10s;
animation-iteration-count: 1;
animation-timing-function: linear;
}
@keyframes leo {
0% {
opacity: 0;
scale: 1;
}
5% {
opacity: 1;
}
10% {
scale: 1;
}
25% {
scale: 1.1;
}
35% {
scale: 1.1;
}
50% {
scale: 1;
}
60% {
scale: 1;
}
75% {
scale: 1.1;
}
85% {
scale: 1.1;
}
95% {
opacity: 1;
}
100% {
scale: 1;
opacity: 0;
}
}
@keyframes breath-relax {
0% {
opacity: 0;
}
5% {
opacity: 0;
}
10% {
opacity: 1;
}
95% {
opacity: 1;
}
100% {
scale: 1;
opacity: 0;
}
}
@keyframes breath-in { @keyframes breath-in {
0% { 0% {
opacity: 0; opacity: 0;

View File

@ -1,21 +1,41 @@
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import Title from "../Title"; import Title from "../Title";
import styles from "./styles.module.css"; import styles from "./styles.module.css";
import { useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { selectors } from "@/store"; import { actions, selectors } from "@/store";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import { AICompats, AIRequests, useApi, useApiCall } from "@/api"; import { AICompats, AIRequests, useApi, useApiCall } from "@/api";
import { useNavigate } from "react-router-dom";
import routes from "@/routes";
import { EPathsFromHome } from "@/store/siteConfig";
function CompatResultPage(): JSX.Element { function CompatResultPage(): JSX.Element {
const token = const token =
"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOjIzNjEyLCJpYXQiOjE2OTM0MTg5MTAsImV4cCI6MTcwMjA1ODkxMCwianRpIjoiNzg5MjkwYWItODg0YS00MGUyLTkyNjEtOWI2OGEyNjkwNmE0IiwiZW1haWwiOiJvdGhlckBleGFtcGxlLmNvbSIsInN0YXRlIjoicHJvdmVuIiwibG9jIjoiZW4iLCJ0eiI6LTI4ODAwLCJ0eXBlIjoiZW1haWwiLCJpc3MiOiJjb20ubGlmZS5hdXJhIn0.J2ocWIv5jKzuKMcwMgWMiNMyGg5qLlMAeln-bQm_9lw"; "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOjIzNjEyLCJpYXQiOjE2OTM0MTg5MTAsImV4cCI6MTcwMjA1ODkxMCwianRpIjoiNzg5MjkwYWItODg0YS00MGUyLTkyNjEtOWI2OGEyNjkwNmE0IiwiZW1haWwiOiJvdGhlckBleGFtcGxlLmNvbSIsInN0YXRlIjoicHJvdmVuIiwibG9jIjoiZW4iLCJ0eiI6LTI4ODAwLCJ0eXBlIjoiZW1haWwiLCJpc3MiOiJjb20ubGlmZS5hdXJhIn0.J2ocWIv5jKzuKMcwMgWMiNMyGg5qLlMAeln-bQm_9lw";
const { t } = useTranslation(); const { t } = useTranslation();
const navigate = useNavigate();
const api = useApi(); const api = useApi();
const dispatch = useDispatch();
const birthdate = useSelector(selectors.selectBirthdate); const birthdate = useSelector(selectors.selectBirthdate);
const rightUser = useSelector(selectors.selectRightUser); const rightUser = useSelector(selectors.selectRightUser);
const categoryId = useSelector(selectors.selectCategoryId); const categoryId = useSelector(selectors.selectCategoryId);
const homeConfig = useSelector(selectors.selectHome);
const [text, setText] = useState("Loading..."); const [text, setText] = useState("Loading...");
const handleNext = () => {
dispatch(
actions.siteConfig.update({
home: { pathFromHome: homeConfig.pathFromHome, isShowNavbar: true },
})
);
if (homeConfig.pathFromHome === EPathsFromHome.breath) {
return navigate(routes.client.home());
}
if (homeConfig.pathFromHome === EPathsFromHome.compatibility) {
return navigate(routes.client.breath());
}
};
const loadData = useCallback(async () => { const loadData = useCallback(async () => {
const right_bday = const right_bday =
typeof rightUser.birthDate === "string" typeof rightUser.birthDate === "string"
@ -55,6 +75,7 @@ function CompatResultPage(): JSX.Element {
return ( return (
<section className={`${styles.page} page`}> <section className={`${styles.page} page`}>
{text !== "Loading..." && <div className={styles.cross} onClick={handleNext}></div>}
<div className={styles["title-container"]}> <div className={styles["title-container"]}>
<Title variant="h2">{t("you_and", { user: rightUser.name })}</Title> <Title variant="h2">{t("you_and", { user: rightUser.name })}</Title>
</div> </div>
@ -64,6 +85,19 @@ function CompatResultPage(): JSX.Element {
</Title> </Title>
<p className={styles["result-container__text"]}>{text}</p> <p className={styles["result-container__text"]}>{text}</p>
</div> </div>
{text !== "Loading..." && (
<div className={styles["button-container"]}>
<p className={styles["button-container__text"]}>
{t("now-you-know")}
</p>
<button
className={styles["button-container__button"]}
onClick={handleNext}
>
{t("go-through")}
</button>
</div>
)}
</section> </section>
); );
} }

View File

@ -2,30 +2,100 @@
position: relative; position: relative;
height: calc(100vh - 50px); height: calc(100vh - 50px);
flex: auto; flex: auto;
max-height: -webkit-fill-available; /* max-height: -webkit-fill-available; */
background-color: #000; background-color: #000;
color: #fff; color: #fff;
overflow-y: scroll; overflow-y: scroll;
padding-bottom: 180px;
} }
.title-container { .title-container {
color: #e9445a; color: #e9445a;
} }
.percent { .percent {
margin-bottom: 0; margin-bottom: 0;
} }
.result-container { .result-container {
width: 100%; width: 100%;
} }
.result-container__title { .result-container__title {
width: 100%; width: 100%;
text-align: left; text-align: left;
} }
.result-container__text { .result-container__text {
white-space:pre-wrap; white-space: pre-wrap;
line-height: 1.2; line-height: 1.2;
} }
.button-container {
position: fixed;
width: 100%;
max-width: 560px;
bottom: 0;
border-radius: 16px 16px 0 0;
background-color: rgba(128, 128, 128, 0.546);
-webkit-backdrop-filter: blur(14px);
backdrop-filter: blur(14px);
display: flex;
align-items: center;
flex-direction: column;
gap: 16px;
padding: 16px 0 24px 0;
}
.button-container__text {
max-width: calc(100% - 64px);
text-align: center;
color: #7ce4fc;
}
.button-container__button {
border: none;
bottom: 24px;
width: calc(100% - 64px);
max-width: 496px;
border-radius: 32px;
padding: 24px 0;
background: -moz-linear-gradient(to bottom, #2dc8e2, #2b7ed6);
background: -webkit-linear-gradient(to bottom, #2dc8e2, #2b7ed6);
background: linear-gradient(to bottom, #2dc8e2, #2b7ed6);
color: #fff;
}
.cross {
position: absolute;
top: 24px;
right: 24px;
width: 24px;
height: 24px;
border: solid 2px #bdbdbd;
border-radius: 100%;
rotate: 45deg;
cursor: pointer;
}
.cross::before {
content: "";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 10px;
height: 2px;
background-color: #bdbdbd;
}
.cross::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 2px;
height: 10px;
background-color: #bdbdbd;
}

View File

@ -22,6 +22,7 @@ function CompatibilityPage(): JSX.Element {
const [name, setName] = useState<string>(''); const [name, setName] = useState<string>('');
const [date, setDate] = useState<string | IDate>(''); const [date, setDate] = useState<string | IDate>('');
const [compatCategory, setCompatCategory] = useState(1); const [compatCategory, setCompatCategory] = useState(1);
const handleNext = () => { const handleNext = () => {
dispatch(actions.compatibility.update({ dispatch(actions.compatibility.update({
rightUser: { rightUser: {

View File

@ -8,13 +8,19 @@ import { useCallback, useEffect, useState } from "react";
import BlurringSubstrate from "../BlurringSubstrate"; import BlurringSubstrate from "../BlurringSubstrate";
import EnergyValues from "../EnergyValues"; import EnergyValues from "../EnergyValues";
import { UserAura } from "@/api/resources/Auras"; import { UserAura } from "@/api/resources/Auras";
import { useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { getCategoryIdByZodiacSign, getZodiacSignByDate } from "@/services/zodiac-sign"; import {
import { selectors } from "@/store"; getCategoryIdByZodiacSign,
getZodiacSignByDate,
} from "@/services/zodiac-sign";
import { actions, selectors } from "@/store";
import { getRandomArbitrary } from "@/services/random-value"; import { getRandomArbitrary } from "@/services/random-value";
import Title from "../Title"; import Title from "../Title";
import { UserDailyForecast } from "@/api/resources/UserDailyForecasts"; import { UserDailyForecast } from "@/api/resources/UserDailyForecasts";
import { download } from "@/services/download"; import { download } from "@/services/download";
import { EPathsFromHome } from "@/store/siteConfig";
import NavbarHome, { INavbarHomeItems } from "../NavbarHome";
const buttonTextFormatter = (text: string): JSX.Element => { const buttonTextFormatter = (text: string): JSX.Element => {
const sentences = text.split("."); const sentences = text.split(".");
@ -32,12 +38,54 @@ function HomePage(): JSX.Element {
"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOjIzNjEyLCJpYXQiOjE2OTM0MTg5MTAsImV4cCI6MTcwMjA1ODkxMCwianRpIjoiNzg5MjkwYWItODg0YS00MGUyLTkyNjEtOWI2OGEyNjkwNmE0IiwiZW1haWwiOiJvdGhlckBleGFtcGxlLmNvbSIsInN0YXRlIjoicHJvdmVuIiwibG9jIjoiZW4iLCJ0eiI6LTI4ODAwLCJ0eXBlIjoiZW1haWwiLCJpc3MiOiJjb20ubGlmZS5hdXJhIn0.J2ocWIv5jKzuKMcwMgWMiNMyGg5qLlMAeln-bQm_9lw"; "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOjIzNjEyLCJpYXQiOjE2OTM0MTg5MTAsImV4cCI6MTcwMjA1ODkxMCwianRpIjoiNzg5MjkwYWItODg0YS00MGUyLTkyNjEtOWI2OGEyNjkwNmE0IiwiZW1haWwiOiJvdGhlckBleGFtcGxlLmNvbSIsInN0YXRlIjoicHJvdmVuIiwibG9jIjoiZW4iLCJ0eiI6LTI4ODAwLCJ0eXBlIjoiZW1haWwiLCJpc3MiOiJjb20ubGlmZS5hdXJhIn0.J2ocWIv5jKzuKMcwMgWMiNMyGg5qLlMAeln-bQm_9lw";
const { t } = useTranslation(); const { t } = useTranslation();
const navigate = useNavigate(); const navigate = useNavigate();
const dispatch = useDispatch();
const homeConfig = useSelector(selectors.selectHome);
const isShowNavbar = homeConfig.isShowNavbar;
const handleCompatibility = () => { const handleCompatibility = () => {
dispatch(
actions.siteConfig.update({
home: { pathFromHome: EPathsFromHome.compatibility, isShowNavbar },
})
);
navigate(routes.client.compatibility()); navigate(routes.client.compatibility());
}; };
const handleBreath = () => { const handleBreath = () => {
dispatch(
actions.siteConfig.update({
home: { pathFromHome: EPathsFromHome.breath, isShowNavbar },
})
);
navigate(routes.client.breath()); navigate(routes.client.breath());
}; };
const navbarHomeItems: INavbarHomeItems[] = [
{
title: 'Breathing',
path: routes.client.breath(),
image: '',
onClick: handleBreath
},
{
title: 'Aura',
path: routes.client.home(),
image: '',
active: true,
onClick: () => null
},
{
title: 'Compatibility',
path: routes.client.compatibility(),
image: '',
onClick: handleCompatibility
},
{
title: 'My Moon',
path: routes.client.home(),
image: '',
onClick: () => null
}
]
const { i18n } = useTranslation(); const { i18n } = useTranslation();
const locale = i18n.language; const locale = i18n.language;
@ -49,9 +97,11 @@ function HomePage(): JSX.Element {
const assetsData = useCallback(async () => { const assetsData = useCallback(async () => {
const { asset_categories } = await api.getAssetCategories({ locale }); const { asset_categories } = await api.getAssetCategories({ locale });
const categoryId = getCategoryIdByZodiacSign(zodiacSign, asset_categories); const categoryId = getCategoryIdByZodiacSign(zodiacSign, asset_categories);
const { assets } = await api.getAssets({ category: String(categoryId || "1") }); const { assets } = await api.getAssets({
category: String(categoryId || "1"),
});
return assets; return assets;
}, [api]); }, [api, locale, zodiacSign]);
const { const {
data: assets, data: assets,
@ -77,7 +127,7 @@ function HomePage(): JSX.Element {
const dailyForecastData = useCallback(async () => { const dailyForecastData = useCallback(async () => {
const { user_daily_forecast } = await api.getDailyForecasts({ token }); const { user_daily_forecast } = await api.getDailyForecasts({ token });
return user_daily_forecast; return user_daily_forecast;
}, [api, token]) }, [api, token]);
const { const {
data: dailyForecast, data: dailyForecast,
@ -85,14 +135,16 @@ function HomePage(): JSX.Element {
} = useApiCall<UserDailyForecast>(dailyForecastData); } = useApiCall<UserDailyForecast>(dailyForecastData);
const downloadImg = () => { const downloadImg = () => {
if( !asset ) return; if (!asset) return;
download(asset.url, 'image.png'); download(asset.url, "image.png");
} };
return ( return (
<section <section
className={`${styles.page} page`} className={`${styles.page} page`}
style={{ backgroundImage: `url(${asset?.url.replace('http://', 'https://')})` }} style={{
backgroundImage: `url(${asset?.url.replace("http://", "https://")})`,
}}
> >
<div className={styles.header}> <div className={styles.header}>
<BlurringSubstrate> <BlurringSubstrate>
@ -128,18 +180,26 @@ function HomePage(): JSX.Element {
</BlurringSubstrate> </BlurringSubstrate>
</div> </div>
<div className={styles["content__daily-forecast"]}> <div className={styles["content__daily-forecast"]}>
{dailyForecast && dailyForecast.forecasts.map((forecast, index) => ( {dailyForecast &&
<div className={styles["content__daily-forecast-item"]} key={index}> dailyForecast.forecasts.map((forecast, index) => (
<Title variant="h3" className={styles["content__daily-forecast-title"]}> <div
{forecast.category} className={styles["content__daily-forecast-item"]}
</Title> key={index}
<p className={styles["content__daily-forecast-body"]}> >
{forecast.body} <Title
</p> variant="h3"
</div> className={styles["content__daily-forecast-title"]}
))} >
{forecast.category}
</Title>
<p className={styles["content__daily-forecast-body"]}>
{forecast.body}
</p>
</div>
))}
</div> </div>
</div> </div>
{isShowNavbar && <NavbarHome items={navbarHomeItems} />}
</section> </section>
); );
} }

View File

@ -97,6 +97,7 @@
border-radius: 25px !important; border-radius: 25px !important;
text-align: center; text-align: center;
color: #fff; color: #fff;
background-color: #00000094;
cursor: pointer; cursor: pointer;
} }

View File

@ -0,0 +1,33 @@
import { Link } from 'react-router-dom'
import styles from './styles.module.css'
export interface INavbarHomeItems {
title: string
path: string
image: string
active?: boolean
onClick?: () => void
}
interface INavbarHomeProps {
items: INavbarHomeItems[]
}
function NavbarHome({items}: INavbarHomeProps): JSX.Element {
return (
<div className={`${styles['container']}`}>
{items.map((item, index) => (
<div className={`${styles['navbar-item']} ${item.active ? styles['navbar-item--active'] : ''}`} key={index}>
<Link to={item.path} onClick={item.onClick}>
{/* <img src={item.image} alt={item.title} /> */}
<p>{item.title}</p>
</Link>
</div>
))}
</div>
)
}
export default NavbarHome

View File

@ -0,0 +1,23 @@
.container {
width: 100vw;
max-width: 560px;
background-color: #232322;
padding: 12px 0;
display: flex;
flex-direction: row;
justify-content: space-evenly;
position: fixed;
bottom: 0;
}
.navbar-item {
font-size: 12px;
display: flex;
flex-direction: column;
justify-content: center;
color: #dedede;
}
.navbar-item--active {
color: #f24058;
}

View File

@ -2,8 +2,8 @@ import { useNavigate } from 'react-router-dom'
import routes from '@/routes' import routes from '@/routes'
import styles from './styles.module.css' import styles from './styles.module.css'
import UserHeader from '../UserHeader' import UserHeader from '../UserHeader'
import { useSelector } from 'react-redux' import { useDispatch, useSelector } from 'react-redux'
import { selectors } from '@/store' import { actions, selectors } from '@/store'
import Title from '../Title' import Title from '../Title'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import EmailsList from '../EmailsList' import EmailsList from '../EmailsList'
@ -12,10 +12,17 @@ import PriceList from '../PriceList'
function PriceListPage(): JSX.Element { function PriceListPage(): JSX.Element {
const { t } = useTranslation() const { t } = useTranslation()
const navigate = useNavigate() const navigate = useNavigate()
const dispatch = useDispatch();
const homeConfig = useSelector(selectors.selectHome);
const selectedPrice = useSelector(selectors.selectSelectedPrice) const selectedPrice = useSelector(selectors.selectSelectedPrice)
const email = useSelector(selectors.selectEmail) const email = useSelector(selectors.selectEmail)
const handleNext = () => { const handleNext = () => {
dispatch(
actions.siteConfig.update({
home: { pathFromHome: homeConfig.pathFromHome, isShowNavbar: false },
})
);
navigate(routes.client.subscription()) navigate(routes.client.subscription())
} }

View File

@ -1,15 +1,33 @@
import Title from "../Title"; import Title from "../Title";
import styles from "./styles.module.css"; import styles from "./styles.module.css";
import { useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { selectors } from "@/store"; import { actions, selectors } from "@/store";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import routes from "@/routes";
import { EPathsFromHome } from "@/store/siteConfig";
function UserCallbacksPage(): JSX.Element { function UserCallbacksPage(): JSX.Element {
const { t } = useTranslation();
const navigate = useNavigate();
const dispatch = useDispatch();
const statChanges = useSelector(selectors.selectUserCallbacksPrevStat); const statChanges = useSelector(selectors.selectUserCallbacksPrevStat);
const text = useSelector(selectors.selectUserCallbacksDescription); const text = useSelector(selectors.selectUserCallbacksDescription);
const homeConfig = useSelector(selectors.selectHome);
const handleNext = () => {
dispatch(actions.siteConfig.update({ home: { pathFromHome: homeConfig.pathFromHome, isShowNavbar: true } }));
if (homeConfig.pathFromHome === EPathsFromHome.compatibility) {
return navigate(routes.client.home());
}
if (homeConfig.pathFromHome === EPathsFromHome.breath) {
return navigate(routes.client.compatibility());
}
};
return ( return (
<section className={`${styles.page} page`}> <section className={`${styles.page} page`}>
<div className={styles.cross} onClick={handleNext}></div>
<div className={styles["title-container"]}> <div className={styles["title-container"]}>
<Title variant="h3" className={styles.percent}> <Title variant="h3" className={styles.percent}>
<> <>
@ -37,6 +55,9 @@ function UserCallbacksPage(): JSX.Element {
</div> </div>
<p className={styles["result-container__text"]}>{text}</p> <p className={styles["result-container__text"]}>{text}</p>
</div> </div>
<button className={styles.button} onClick={handleNext}>
{t("use-all-power")}
</button>
</section> </section>
); );
} }

View File

@ -1,12 +1,13 @@
.page { .page {
position: relative; position: relative;
height: calc(100vh - 50px); height: calc(100vh - 50px);
max-height: -webkit-fill-available; /* max-height: -webkit-fill-available; */
flex: auto; flex: auto;
background-color: #000; background-color: #000;
color: #bababb; color: #bababb;
overflow-y: scroll; overflow-y: scroll;
text-align: center; text-align: center;
padding-bottom: 114px;
} }
.result-container__values { .result-container__values {
@ -35,3 +36,51 @@
line-height: 1.2; line-height: 1.2;
margin-top: 32px; margin-top: 32px;
} }
.button {
position: fixed;
border: none;
bottom: 24px;
width: calc(100% - 64px);
max-width: 496px;
border-radius: 32px;
padding: 24px 0;
background: -moz-linear-gradient(to bottom, #01d400, #196e17);
background: -webkit-linear-gradient(to bottom, #01d400, #196e17);
background: linear-gradient(to bottom, #01d400, #196e17);
color: #fff;
}
.cross {
position: absolute;
top: 24px;
right: 24px;
width: 24px;
height: 24px;
border: solid 2px #bdbdbd;
border-radius: 100%;
rotate: 45deg;
cursor: pointer;
}
.cross::before {
content: "";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 10px;
height: 2px;
background-color: #bdbdbd;
}
.cross::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 2px;
height: 10px;
background-color: #bdbdbd;
}

View File

@ -85,5 +85,9 @@ export default {
"breathe-subtitle": "Breathing practice will help improve your aura. Breath in the positive energy, breathe out the negative...", "breathe-subtitle": "Breathing practice will help improve your aura. Breath in the positive energy, breathe out the negative...",
"breathe-title": "Stop and breathe to help you relax and focus on what really matters.", "breathe-title": "Stop and breathe to help you relax and focus on what really matters.",
"aura-begin_breathe-button": "BEGIN", "aura-begin_breathe-button": "BEGIN",
"aura.breath_relax.text": "Breath & Relax",
"use-all-power": "Use all the power of your Aura",
"go-through": "Go through practicing recovery",
"now-you-know": "Now you know who`s causing your financial energy loss.",
}, },
} }

View File

@ -0,0 +1,5 @@
export const getQueryParam = (paramName: string) => {
const search = window.location.search;
const params = new URLSearchParams(search);
return params.get(paramName);
};

View File

@ -3,6 +3,7 @@ import token, { actions as tokenActions, selectToken } from './token'
import user, { actions as userActions, selectUser } from './user' import user, { actions as userActions, selectUser } from './user'
import form, { actions as formActions, selectors as formSelectors } from './form' import form, { actions as formActions, selectors as formSelectors } from './form'
import aura, { actions as auraActions } from './aura' import aura, { actions as auraActions } from './aura'
import siteConfig, { selectHome, actions as siteConfigActions } from './siteConfig'
import payment, { actions as paymentActions } from './payment' import payment, { actions as paymentActions } from './payment'
import subscriptionPlans, { actions as subscriptionPlasActions, selectPlanById } from './subscriptionPlan' import subscriptionPlans, { actions as subscriptionPlasActions, selectPlanById } from './subscriptionPlan'
import status, { actions as userStatusActions, selectStatus } from './status' import status, { actions as userStatusActions, selectStatus } from './status'
@ -15,8 +16,9 @@ import { selectRightUser, selectCategoryId } from './compatibility'
import { selectUserCallbacksDescription, selectUserCallbacksPrevStat } from './userCallbacks' import { selectUserCallbacksDescription, selectUserCallbacksPrevStat } from './userCallbacks'
const preloadedState = loadStore() const preloadedState = loadStore()
export const reducer = combineReducers({ token, user, form, status, subscriptionPlans, aura, payment, compatibility, userCallbacks }) export const reducer = combineReducers({ token, user, form, status, subscriptionPlans, aura, payment, compatibility, userCallbacks, siteConfig })
export const actions = { export const actions = {
token: tokenActions, token: tokenActions,
user: userActions, user: userActions,
@ -24,6 +26,7 @@ export const actions = {
status: userStatusActions, status: userStatusActions,
subscriptionPlan: subscriptionPlasActions, subscriptionPlan: subscriptionPlasActions,
aura: auraActions, aura: auraActions,
siteConfig: siteConfigActions,
compatibility: compatibilityActions, compatibility: compatibilityActions,
payment: paymentActions, payment: paymentActions,
userCallbacks: userCallbacksActions, userCallbacks: userCallbacksActions,
@ -40,6 +43,7 @@ export const selectors = {
selectSelectedPrice, selectSelectedPrice,
selectUserCallbacksDescription, selectUserCallbacksDescription,
selectUserCallbacksPrevStat, selectUserCallbacksPrevStat,
selectHome,
...formSelectors, ...formSelectors,
} }
export type RootState = ReturnType<typeof reducer> export type RootState = ReturnType<typeof reducer>

39
src/store/siteConfig.ts Normal file
View File

@ -0,0 +1,39 @@
import { createSlice, createSelector } from "@reduxjs/toolkit";
import type { PayloadAction } from "@reduxjs/toolkit";
export enum EPathsFromHome {
compatibility,
breath
}
interface ISiteConfig {
home: {
isShowNavbar: boolean;
pathFromHome: EPathsFromHome;
};
}
const initialState: ISiteConfig = {
home: {
isShowNavbar: false,
pathFromHome: EPathsFromHome.compatibility
},
};
const siteConfigSlice = createSlice({
name: "siteConfig",
initialState,
reducers: {
update(state, action: PayloadAction<Partial<ISiteConfig>>) {
return { ...state, ...action.payload };
},
},
extraReducers: (builder) => builder.addCase("reset", () => initialState),
});
export const { actions } = siteConfigSlice;
export const selectHome = createSelector(
(state: { siteConfig: ISiteConfig }) => state.siteConfig.home,
(siteConfig) => siteConfig
);
export default siteConfigSlice.reducer;