w-aura/src/components/Compatibility/index.tsx

317 lines
10 KiB
TypeScript

import { useTranslation } from "react-i18next";
import MainButton from "../MainButton";
import Title from "../Title";
import styles from "./styles.module.css";
import { useCallback, useEffect, useRef, useState } from "react";
import NameInput from "./nameInput";
import DatePicker from "./DatePicker";
import { IDate, getDateAsString } from "@/services/date";
import { AICompatCategories, useApi, useApiCall } from "@/api";
import { useNavigate } from "react-router-dom";
import routes from "@/routes";
import { useDispatch, useSelector } from "react-redux";
import { actions, selectors } from "@/store";
import { EPathsFromHome } from "@/store/siteConfig";
import {
getCategoryIdByZodiacSign,
getZodiacSignByDate,
} from "@/services/zodiac-sign";
import { Asset } from "@/api/resources/Assets";
import { getRandomArbitrary } from "@/services/random-value";
import Onboarding, { EDirectionOnboarding } from "../Onboarding";
import TextWithFinger from "../TextWithFinger";
function CompatibilityPage(): JSX.Element {
const { t, i18n } = useTranslation();
const navigate = useNavigate();
const dispatch = useDispatch();
const [isDisabled, setIsDisabled] = useState(true);
const [isDisabledName, setIsDisabledName] = useState(true);
const [isDisabledDate, setIsDisabledDate] = useState(true);
const [isChangeDate, setIsChangeDate] = useState(false);
const [currentOnboarding, setCurrentOnboarding] = useState(0);
const [name, setName] = useState<string>("");
const [selectedDate, setSelectedDate] = useState<string | IDate>("");
const [compatCategory, setCompatCategory] = useState(1);
const homeConfig = useSelector(selectors.selectHome);
const showNavbarFooter = homeConfig.isShowNavbar;
const birthdate = useSelector(selectors.selectBirthdate);
const onboardingCompatibility = useSelector(
selectors.selectOnboardingCompatibility
);
const zodiacSign = getZodiacSignByDate(birthdate);
const [asset, setAsset] = useState<Asset>();
const api = useApi();
const inputRef = useRef<HTMLInputElement>(null);
const dateRef = useRef<HTMLInputElement>(null);
const categoriesRef = useRef<HTMLInputElement>(null);
const mainButtonRef = useRef<HTMLInputElement>(null);
const locale = i18n.language;
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 {
data: assets,
// isPending
} = useApiCall<Asset[]>(assetsData);
useEffect(() => {
if (assets) {
setAsset(assets[getRandomArbitrary(0, assets?.length || 0)]);
}
}, [assets]);
const handleNext = () => {
if (isDisabled) return;
dispatch(
actions.onboardingConfig.update({
compatibility: {
isShown: true,
},
})
);
dispatch(
actions.compatibility.update({
rightUser: {
name,
birthDate: selectedDate,
},
categoryId: compatCategory,
})
);
navigate(routes.client.compatibilityResult());
};
const handleCross = () => {
if (homeConfig.pathFromHome === EPathsFromHome.compatibility) {
dispatch(
actions.siteConfig.update({
home: {
pathFromHome: EPathsFromHome.compatibility,
isShowNavbar: false,
},
})
);
return navigate(routes.client.breath());
}
if (homeConfig.pathFromHome === EPathsFromHome.breath) {
dispatch(
actions.siteConfig.update({
home: {
pathFromHome: EPathsFromHome.compatibility,
isShowNavbar: true,
},
})
);
return navigate(routes.client.home());
}
return navigate(routes.client.home());
};
const loadData = useCallback(() => {
return api
.getAiCompatCategories({ locale })
.then((resp: AICompatCategories.Response) => resp.compat_categories);
}, [api, locale]);
const { data } = useApiCall<AICompatCategories.CompatCategory[]>(loadData);
const handleValidName = (name: string) => {
setIsDisabledName(!name.length);
setName(name);
checkAllDisabled();
};
const handleValidDate = (date: string | IDate) => {
setIsDisabledDate(date === "");
setIsChangeDate(date !== getDateAsString(new Date()));
setSelectedDate(date);
checkAllDisabled();
};
const checkAllDisabled = () => {
setIsDisabled(isDisabledName || isDisabledDate);
};
const changeCompatCategory = (event: React.ChangeEvent<HTMLInputElement>) => {
setCompatCategory(parseInt(event.target.value));
};
return (
<section
className={`${styles.page} page`}
style={{
paddingBottom: showNavbarFooter ? "48px" : "16px",
backgroundImage: `url(${asset?.url.replace("http://", "https://")})`,
}}
>
<div className={styles.blurring}></div>
{!showNavbarFooter && (
<div className={styles.cross} onClick={handleCross}></div>
)}
{/* <Title variant="h1" className={styles.title}>
{t("compatibility")}
</Title> */}
<div className={styles.content}>
<Title variant="h2" className={styles.iam}>
{t("iAm")}
</Title>
<Title variant="h3" className={styles.plus}>
+
</Title>
<div className={styles["inputs-container"]}>
{!onboardingCompatibility.isShown && <>
{currentOnboarding === 0 && (
<Onboarding
targetRef={inputRef}
isShow={currentOnboarding === 0}
direction={EDirectionOnboarding.BOTTOM}
showBackground={true}
>
<TextWithFinger
text={t("au.web_onbording.name")}
direction={EDirectionOnboarding.BOTTOM}
crossClickHandler={() => setCurrentOnboarding(1)}
/>
</Onboarding>
)}
{currentOnboarding === 1 && (
<Onboarding
targetRef={dateRef}
isShow={currentOnboarding === 1}
direction={EDirectionOnboarding.BOTTOM}
showBackground={true}
>
<>
<button
className={styles["compatibility-onboarding__button"]}
disabled={!isChangeDate}
onClick={() => setCurrentOnboarding(2)}
>
Done
</button>
<TextWithFinger
text={t("au.web_onbording.date")}
direction={EDirectionOnboarding.BOTTOM}
showCross={false}
/>
</>
</Onboarding>
)}
{currentOnboarding === 3 && (
<Onboarding
targetRef={mainButtonRef}
isShow={currentOnboarding === 3}
direction={EDirectionOnboarding.TOP}
showBackground={true}
>
<TextWithFinger
text={""}
direction={EDirectionOnboarding.TOP}
showCross={false}
/>
</Onboarding>
)}
</>}
<div
className={styles["input-container__name-container"]}
style={{ zIndex: currentOnboarding === 0 ? 99 : 1 }}
ref={inputRef}
>
<NameInput
name="name"
value={name}
placeholder={t("name")}
onKeyDown={(e) => {
if (!name.length) return;
if (e.key === "Enter") {
setCurrentOnboarding(1);
(e.target as HTMLInputElement).blur();
dateRef.current?.scrollIntoView({ behavior: "smooth" });
}
}}
onValid={handleValidName}
onInvalid={() => setIsDisabledName(true)}
/>
</div>
<div
className={styles["input-container__date-container"]}
style={{ zIndex: currentOnboarding === 1 ? 99 : 1 }}
ref={dateRef}
>
<DatePicker onDateChange={handleValidDate} />
</div>
</div>
{currentOnboarding === 2 && !onboardingCompatibility.isShown && (
<Onboarding
targetRef={categoriesRef}
isShow={currentOnboarding === 2}
direction={EDirectionOnboarding.TOP}
showBackground={true}
>
<TextWithFinger
text={t("au.web_onbording.category")}
direction={EDirectionOnboarding.TOP}
showCross={true}
crossClickHandler={() => setCurrentOnboarding(3)}
/>
</Onboarding>
)}
{data && data.length && (
<div
className={styles["compatibility-categories"]}
style={{ zIndex: currentOnboarding === 2 ? 99 : 1 }}
ref={categoriesRef}
>
{data.map((item, index) => (
<div
className="compatibility-categories__item"
key={index}
onClick={() => setCurrentOnboarding(3)}
>
<input
className={`${styles["compatibility-categories__input"]} ${
compatCategory === item.id
? styles["compatibility-categories__input--checked"]
: ""
}`}
type="radio"
name="compatCategory"
id={String(item.id)}
value={item.id}
checked={compatCategory === item.id}
onChange={changeCompatCategory}
/>
<label htmlFor={String(item.id)}>{item.name}</label>
</div>
))}
</div>
)}
<div
style={{
position: "relative",
zIndex: currentOnboarding === 3 ? 99 : 1,
}}
ref={mainButtonRef}
>
<MainButton
className={styles["check-btn"]}
onClick={handleNext}
disabled={isDisabled}
>
{t("check")}
</MainButton>
</div>
</div>
</section>
);
}
export default CompatibilityPage;