feat: add start breath modal

This commit is contained in:
gofnnp 2023-09-08 05:54:49 +04:00
parent f650878f3e
commit 79362a5981
6 changed files with 228 additions and 31 deletions

View File

@ -1,46 +1,65 @@
import styles from './styles.module.css'
import BreathCircle from '../BreathCircle'
import { useCallback, useEffect, useState } from 'react'
import { useApi, useApiCall } from '@/api'
import { Asset } from '@/api/resources/Assets'
import { useSelector } from 'react-redux'
import { selectors } from '@/store'
import { getCategoryIdByZodiacSign, getZodiacSignByDate } from '@/services/zodiac-sign'
import { useTranslation } from 'react-i18next'
import { getRandomArbitrary } from '@/services/random-value'
import styles from "./styles.module.css";
import BreathCircle from "../BreathCircle";
import { useCallback, useEffect, useState } from "react";
import { useApi, useApiCall } from "@/api";
import { Asset } from "@/api/resources/Assets";
import { useSelector } from "react-redux";
import { selectors } from "@/store";
import {
getCategoryIdByZodiacSign,
getZodiacSignByDate,
} from "@/services/zodiac-sign";
import { useTranslation } from "react-i18next";
import { getRandomArbitrary } from "@/services/random-value";
import FullScreenModal from "../FullScreenModal";
import StartBreathModalChild from "../StartBreathModalChild";
function BreathPage(): JSX.Element {
const { i18n } = useTranslation()
const locale = i18n.language
const birthdate = useSelector(selectors.selectBirthdate)
const zodiacSign = getZodiacSignByDate(birthdate)
const [asset, setAsset] = useState<Asset>()
const api = useApi()
const { i18n } = useTranslation();
const locale = i18n.language;
const birthdate = useSelector(selectors.selectBirthdate);
const zodiacSign = getZodiacSignByDate(birthdate);
const [asset, setAsset] = useState<Asset>();
const [isOpenModal, setIsOpenModal] = useState<boolean>(true);
const api = useApi();
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') })
return assets
}, [api, locale, zodiacSign])
const { asset_categories } = await api.getAssetCategories({ locale });
const categoryId = getCategoryIdByZodiacSign(zodiacSign, asset_categories);
const { assets } = await api.getAssets({
category: String(categoryId || "1"),
});
return assets;
}, [api, locale, zodiacSign]);
const {
data,
// isPending
} = useApiCall<Asset[]>(assetsData)
} = useApiCall<Asset[]>(assetsData);
useEffect(() => {
if (data) {
setAsset(data[getRandomArbitrary(0, data?.length || 0)])
setAsset(data[getRandomArbitrary(0, data?.length || 0)]);
}
}, [data])
}, [data]);
const beginBreath = () => {
setIsOpenModal(false);
}
return (
<section className={`${styles.page} page`} style={{ backgroundImage: `url(${asset?.url})` }}>
<BreathCircle />
</section>
)
<>
<section
className={`${styles.page} page`}
style={{ backgroundImage: `url(${asset?.url})` }}
>
<FullScreenModal isOpen={isOpenModal}>
<StartBreathModalChild handleBegin={beginBreath} />
</FullScreenModal>
{!isOpenModal && <BreathCircle />}
</section>
</>
);
}
export default BreathPage
export default BreathPage;

View File

@ -0,0 +1,28 @@
import styles from "./styles.module.css";
interface IFullScreenModalProps {
className?: string;
style?: React.CSSProperties;
children: JSX.Element;
isOpen: boolean;
}
function FullScreenModal({
className,
children,
style,
isOpen,
}: IFullScreenModalProps): JSX.Element {
return (
<div
style={{ ...style }}
className={`${styles["modal"]} ${className || ""} ${
isOpen ? styles.open : ""
}`}
>
<div className={styles["modal__content"]}>{children}</div>
</div>
);
}
export default FullScreenModal;

View File

@ -0,0 +1,66 @@
.modal {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 999;
/* background-color: #000; */
opacity: 0;
-webkit-transition: opacity 3s ease;
-moz-transition: opacity 3s ease;
-ms-transition: opacity 3s ease;
-o-transition: opacity 3s ease;
transition: opacity 3s ease;
will-change: opacity;
animation: disappearance 3s ease;
animation-fill-mode: forwards;
}
.open {
opacity: 1;
animation: appearance 3s ease;
animation-fill-mode: forwards;
}
.modal__content {
width: 100%;
height: 100%;
animation: appearance-content 3s ease;
animation-fill-mode: forwards;
}
@keyframes appearance {
0% {
-webkit-backdrop-filter: blur(0);
backdrop-filter: blur(0);
pointer-events: none;
}
100% {
-webkit-backdrop-filter: blur(50px);
backdrop-filter: blur(50px);
pointer-events: auto;
}
}
@keyframes appearance-content {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes disappearance {
0% {
-webkit-backdrop-filter: blur(50px);
backdrop-filter: blur(50px);
pointer-events: auto;
}
100% {
-webkit-backdrop-filter: blur(0);
backdrop-filter: blur(0);
pointer-events: none;
}
}

View File

@ -0,0 +1,39 @@
import { useTranslation } from "react-i18next";
import Title from "../Title";
import styles from "./styles.module.css";
interface IStartBreathModalChildProps {
handleBegin: () => void;
}
function StartBreathModalChild({
handleBegin,
}: IStartBreathModalChildProps): JSX.Element {
const { t } = useTranslation();
return (
<section className={`${styles["start-breath"]} page`}>
<div className={styles.text}>
<Title variant="h4" className={styles["breathe-title"]}>
{t("breathe-title").split("").map((symbol, index) => (
<span className={styles["symbol"]} style={{ animationDelay: `${index * 0.1}s` }} key={index}>{symbol}</span>
))}
</Title>
<Title variant="h4" className={styles["breathe-subtitle"]}>
{t("breathe-subtitle").split("").map((symbol, index) => (
<span className={styles["symbol"]} style={{ animationDelay: `${(t("breathe-title").split("").length + index) * 0.1}s` }} key={index}>{symbol}</span>
))}
</Title>
</div>
<button
type="button"
className={styles.begin}
onClick={handleBegin}
>
{t("aura-begin_breathe-button")}
</button>
</section>
);
}
export default StartBreathModalChild;

View File

@ -0,0 +1,42 @@
.start-breath {
width: 100%;
height: 100%;
color: #fff;
background-color: #0000009e;
justify-content: space-around;
}
.breathe-title {
font-weight: 500;
}
.breathe-subtitle {
color: #c2c2c3;
}
.begin {
background-color: #00feff;
color: #000;
text-transform: uppercase;
font-weight: 700;
padding: 16px 32px;
border-radius: 24px;
border: none;
}
.symbol {
opacity: 0;
animation-name: appearance;
animation-timing-function: ease;
animation-duration: .3s;
animation-fill-mode: forwards;
}
@keyframes appearance {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}

View File

@ -79,6 +79,9 @@ export default {
you_and: "You and <user>",
sign: "Sign",
'aura-10_breath-button': "Increase up to 10%. Practice for the Energy of Money",
'aura-money_compatibility-button': "low MONEY energy. Determine who drains your energy"
'aura-money_compatibility-button': "low MONEY energy. Determine who drains your energy",
"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.",
"aura-begin_breathe-button": "BEGIN",
},
}