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 styles from "./styles.module.css";
|
||||||
import BreathCircle from '../BreathCircle'
|
import BreathCircle from "../BreathCircle";
|
||||||
import { useCallback, useEffect, useState } from 'react'
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { useApi, useApiCall } from '@/api'
|
import { useApi, useApiCall } from "@/api";
|
||||||
import { Asset } from '@/api/resources/Assets'
|
import { Asset } from "@/api/resources/Assets";
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from "react-redux";
|
||||||
import { selectors } from '@/store'
|
import { selectors } from "@/store";
|
||||||
import { getCategoryIdByZodiacSign, getZodiacSignByDate } from '@/services/zodiac-sign'
|
import {
|
||||||
import { useTranslation } from 'react-i18next'
|
getCategoryIdByZodiacSign,
|
||||||
import { getRandomArbitrary } from '@/services/random-value'
|
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 {
|
function BreathPage(): JSX.Element {
|
||||||
const { i18n } = useTranslation()
|
const { i18n } = useTranslation();
|
||||||
const locale = i18n.language
|
const locale = i18n.language;
|
||||||
const birthdate = useSelector(selectors.selectBirthdate)
|
const birthdate = useSelector(selectors.selectBirthdate);
|
||||||
const zodiacSign = getZodiacSignByDate(birthdate)
|
const zodiacSign = getZodiacSignByDate(birthdate);
|
||||||
const [asset, setAsset] = useState<Asset>()
|
const [asset, setAsset] = useState<Asset>();
|
||||||
const api = useApi()
|
const [isOpenModal, setIsOpenModal] = useState<boolean>(true);
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
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({
|
||||||
return assets
|
category: String(categoryId || "1"),
|
||||||
}, [api, locale, zodiacSign])
|
});
|
||||||
|
return assets;
|
||||||
|
}, [api, locale, zodiacSign]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data,
|
data,
|
||||||
// isPending
|
// isPending
|
||||||
} = useApiCall<Asset[]>(assetsData)
|
} = useApiCall<Asset[]>(assetsData);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data) {
|
if (data) {
|
||||||
setAsset(data[getRandomArbitrary(0, data?.length || 0)])
|
setAsset(data[getRandomArbitrary(0, data?.length || 0)]);
|
||||||
}
|
}
|
||||||
}, [data])
|
}, [data]);
|
||||||
|
|
||||||
|
const beginBreath = () => {
|
||||||
|
setIsOpenModal(false);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
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>",
|
you_and: "You and <user>",
|
||||||
sign: "Sign",
|
sign: "Sign",
|
||||||
'aura-10_breath-button': "Increase up to 10%. Practice for the Energy of Money",
|
'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