feat: add start breath modal
This commit is contained in:
parent
f650878f3e
commit
79362a5981
@ -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;
|
||||
|
||||
28
src/components/FullScreenModal/index.tsx
Normal file
28
src/components/FullScreenModal/index.tsx
Normal 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;
|
||||
66
src/components/FullScreenModal/styles.module.css
Normal file
66
src/components/FullScreenModal/styles.module.css
Normal 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;
|
||||
}
|
||||
}
|
||||
39
src/components/StartBreathModalChild/index.tsx
Normal file
39
src/components/StartBreathModalChild/index.tsx
Normal 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;
|
||||
42
src/components/StartBreathModalChild/styles.module.css
Normal file
42
src/components/StartBreathModalChild/styles.module.css
Normal 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;
|
||||
}
|
||||
}
|
||||
@ -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",
|
||||
},
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user