fix: breath page, onboarding compatibility, create profile items size, home page

This commit is contained in:
gofnnp 2023-10-11 01:44:21 +04:00
parent a27b79e0eb
commit 7ce001cc8f
8 changed files with 134 additions and 68 deletions

View File

@ -40,7 +40,7 @@ function BreathPage({ leoApng }: BreathPageProps): JSX.Element {
const navigateTimeOut = setTimeout(() => { const navigateTimeOut = setTimeout(() => {
navigate(routes.client.breathResult()); navigate(routes.client.breathResult());
}, 60_000); }, 50_000);
return () => { return () => {
clearTimeout(navigateTimeOut); clearTimeout(navigateTimeOut);
@ -106,26 +106,7 @@ function BreathPage({ leoApng }: BreathPageProps): JSX.Element {
useApiCall<UserCallbacks.IUserCallbacks>(createCallback); useApiCall<UserCallbacks.IUserCallbacks>(createCallback);
const handleCross = () => { const handleCross = () => {
if (homeConfig.pathFromHome === EPathsFromHome.compatibility) { navigate(routes.client.breathResult());
dispatch(
actions.siteConfig.update({
home: {
pathFromHome: EPathsFromHome.compatibility,
isShowNavbar: true,
},
})
);
return navigate(routes.client.home());
}
if (homeConfig.pathFromHome === EPathsFromHome.breath) {
dispatch(
actions.siteConfig.update({
home: { pathFromHome: EPathsFromHome.breath, isShowNavbar: false },
})
);
return navigate(routes.client.compatibility());
}
return navigate(routes.client.home());
}; };
return ( return (

View File

@ -26,24 +26,29 @@ function CompatibilityPage(): JSX.Element {
const { t, i18n } = useTranslation(); const { t, i18n } = useTranslation();
const navigate = useNavigate(); const navigate = useNavigate();
const dispatch = useDispatch(); 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 homeConfig = useSelector(selectors.selectHome);
const showNavbarFooter = homeConfig.isShowNavbar; const showNavbarFooter = homeConfig.isShowNavbar;
const birthdate = useSelector(selectors.selectBirthdate); const birthdate = useSelector(selectors.selectBirthdate);
const onboardingCompatibility = useSelector( const onboardingCompatibility = useSelector(
selectors.selectOnboardingCompatibility selectors.selectOnboardingCompatibility
); );
const [isDisabled, setIsDisabled] = useState(true);
const [isDisabledName, setIsDisabledName] = useState(true);
const [isDisabledSelfName, setIsDisabledSelfName] = useState(true);
isDisabledSelfName;
const [isDisabledDate, setIsDisabledDate] = useState(true);
const [isChangeDate, setIsChangeDate] = useState(false);
const [currentOnboarding, setCurrentOnboarding] = useState(0);
const [name, setName] = useState<string>("");
const [selfName, setSelfName] = useState<string>("");
const [selectedDate, setSelectedDate] = useState<string | IDate>("");
const [compatCategory, setCompatCategory] = useState(1);
const zodiacSign = getZodiacSignByDate(birthdate); const zodiacSign = getZodiacSignByDate(birthdate);
const [asset, setAsset] = useState<Asset>(); const [asset, setAsset] = useState<Asset>();
const api = useApi(); const api = useApi();
const inputRef = useRef<HTMLInputElement>(null); const inputSelfNameRef = useRef<HTMLInputElement>(null);
const inputNameRef = useRef<HTMLInputElement>(null);
const dateRef = useRef<HTMLInputElement>(null); const dateRef = useRef<HTMLInputElement>(null);
const categoriesRef = useRef<HTMLInputElement>(null); const categoriesRef = useRef<HTMLInputElement>(null);
const mainButtonRef = useRef<HTMLInputElement>(null); const mainButtonRef = useRef<HTMLInputElement>(null);
@ -123,6 +128,14 @@ function CompatibilityPage(): JSX.Element {
}, [api, locale]); }, [api, locale]);
const { data } = useApiCall<AICompatCategories.CompatCategory[]>(loadData); const { data } = useApiCall<AICompatCategories.CompatCategory[]>(loadData);
const handleValidSelfName = (name: string) => {
console.log(name);
setIsDisabledSelfName(!name.length);
setSelfName(name);
checkAllDisabled();
};
const handleValidName = (name: string) => { const handleValidName = (name: string) => {
setIsDisabledName(!name.length); setIsDisabledName(!name.length);
setName(name); setName(name);
@ -137,6 +150,7 @@ function CompatibilityPage(): JSX.Element {
}; };
const checkAllDisabled = () => { const checkAllDisabled = () => {
// isDisabledSelfName
setIsDisabled(isDisabledName || isDisabledDate); setIsDisabled(isDisabledName || isDisabledDate);
}; };
@ -144,10 +158,9 @@ function CompatibilityPage(): JSX.Element {
setCompatCategory(parseInt(event.target.value)); setCompatCategory(parseInt(event.target.value));
}; };
const handleNameOnboarding = () => { const scrollToElementOnboarding = (nextOnboarding: number, ref: HTMLElement | null) => {
if (!name.length) return; setCurrentOnboarding(nextOnboarding);
setCurrentOnboarding(1); ref?.scrollIntoView({ behavior: "smooth" });
dateRef.current?.scrollIntoView({ behavior: "smooth" });
}; };
return ( return (
@ -166,33 +179,81 @@ function CompatibilityPage(): JSX.Element {
{t("compatibility")} {t("compatibility")}
</Title> */} </Title> */}
<div className={styles.content}> <div className={styles.content}>
<Title variant="h2" className={styles.iam}> {onboardingCompatibility && (
{t("iAm")} <Title variant="h2" className={styles.iam}>
</Title> {t("iAm")}
</Title>
)}
{!onboardingCompatibility && (
<div
className={styles["input-container__name-container"]}
style={{ zIndex: currentOnboarding === 0 ? 100 : 1 }}
ref={inputSelfNameRef}
>
<NameInput
name="selfName"
value={selfName}
placeholder={t("au.name.my_name")}
onKeyDown={(e) => {
if (!selfName.length) return;
if (e.key === "Enter") {
(e.target as HTMLInputElement).blur();
}
}}
onValid={handleValidSelfName}
onInvalid={() => setIsDisabledSelfName(true)}
onBlur={() => {
if (!selfName.length) return;
setCurrentOnboarding(1);
inputNameRef.current?.scrollIntoView({ behavior: "smooth" });
}}
/>
</div>
)}
<Title variant="h3" className={styles.plus}> <Title variant="h3" className={styles.plus}>
+ +
</Title> </Title>
<div className={styles["inputs-container"]}> <div className={styles["inputs-container"]}>
{!onboardingCompatibility?.isShown && ( {!onboardingCompatibility && (
<> <>
{currentOnboarding === 0 && ( {currentOnboarding === 0 && (
<Onboarding <Onboarding
targetRef={inputRef.current as HTMLDivElement} targetRef={inputSelfNameRef.current as HTMLDivElement}
isShow={currentOnboarding === 0} isShow={currentOnboarding === 0}
direction={EDirectionOnboarding.BOTTOM} direction={EDirectionOnboarding.BOTTOM}
showBackground={true} showBackground={true}
>
<TextWithFinger
text={t("au.onboarding.my_name")}
direction={EDirectionOnboarding.BOTTOM}
crossClickHandler={() => {
if (!selfName.length) return;
scrollToElementOnboarding(1, inputNameRef.current);
}}
/>
</Onboarding>
)}
{currentOnboarding === 1 && (
<Onboarding
targetRef={inputNameRef.current as HTMLDivElement}
isShow={currentOnboarding === 1}
direction={EDirectionOnboarding.BOTTOM}
showBackground={true}
> >
<TextWithFinger <TextWithFinger
text={t("au.web_onbording.name")} text={t("au.web_onbording.name")}
direction={EDirectionOnboarding.BOTTOM} direction={EDirectionOnboarding.BOTTOM}
crossClickHandler={handleNameOnboarding} crossClickHandler={() => {
if (!name.length) return;
scrollToElementOnboarding(2, dateRef.current);
}}
/> />
</Onboarding> </Onboarding>
)} )}
{currentOnboarding === 1 && ( {currentOnboarding === 2 && (
<Onboarding <Onboarding
targetRef={dateRef.current as HTMLDivElement} targetRef={dateRef.current as HTMLDivElement}
isShow={currentOnboarding === 1} isShow={currentOnboarding === 2}
direction={EDirectionOnboarding.BOTTOM} direction={EDirectionOnboarding.BOTTOM}
showBackground={true} showBackground={true}
> >
@ -200,7 +261,7 @@ function CompatibilityPage(): JSX.Element {
<button <button
className={styles["compatibility-onboarding__button"]} className={styles["compatibility-onboarding__button"]}
disabled={!isChangeDate} disabled={!isChangeDate}
onClick={() => setCurrentOnboarding(2)} onClick={() => setCurrentOnboarding(3)}
> >
Done Done
</button> </button>
@ -212,10 +273,10 @@ function CompatibilityPage(): JSX.Element {
</> </>
</Onboarding> </Onboarding>
)} )}
{currentOnboarding === 3 && ( {currentOnboarding === 4 && (
<Onboarding <Onboarding
targetRef={mainButtonRef.current as HTMLDivElement} targetRef={mainButtonRef.current as HTMLDivElement}
isShow={currentOnboarding === 3} isShow={currentOnboarding === 4}
direction={EDirectionOnboarding.TOP} direction={EDirectionOnboarding.TOP}
showBackground={true} showBackground={true}
> >
@ -230,13 +291,13 @@ function CompatibilityPage(): JSX.Element {
)} )}
<div <div
className={styles["input-container__name-container"]} className={styles["input-container__name-container"]}
style={{ zIndex: currentOnboarding === 0 ? 99 : 1 }} style={{ zIndex: currentOnboarding === 1 ? 99 : 1 }}
ref={inputRef} ref={inputNameRef}
> >
<NameInput <NameInput
name="name" name="name"
value={name} value={name}
placeholder={t("name")} placeholder={t("au.name.person")}
onKeyDown={(e) => { onKeyDown={(e) => {
if (!name.length) return; if (!name.length) return;
if (e.key === "Enter") { if (e.key === "Enter") {
@ -247,23 +308,23 @@ function CompatibilityPage(): JSX.Element {
onInvalid={() => setIsDisabledName(true)} onInvalid={() => setIsDisabledName(true)}
onBlur={() => { onBlur={() => {
if (!name.length) return; if (!name.length) return;
setCurrentOnboarding(1); setCurrentOnboarding(2);
dateRef.current?.scrollIntoView({ behavior: "smooth" }); dateRef.current?.scrollIntoView({ behavior: "smooth" });
}} }}
/> />
</div> </div>
<div <div
className={styles["input-container__date-container"]} className={styles["input-container__date-container"]}
style={{ zIndex: currentOnboarding === 1 ? 99 : 1 }} style={{ zIndex: currentOnboarding === 2 ? 99 : 1 }}
ref={dateRef} ref={dateRef}
> >
<DatePicker onDateChange={handleValidDate} /> <DatePicker onDateChange={handleValidDate} />
</div> </div>
</div> </div>
{currentOnboarding === 2 && !onboardingCompatibility?.isShown && ( {currentOnboarding === 3 && !onboardingCompatibility && (
<Onboarding <Onboarding
targetRef={categoriesRef.current as HTMLDivElement} targetRef={categoriesRef.current as HTMLDivElement}
isShow={currentOnboarding === 2} isShow={currentOnboarding === 3}
direction={EDirectionOnboarding.TOP} direction={EDirectionOnboarding.TOP}
showBackground={true} showBackground={true}
> >
@ -271,21 +332,21 @@ function CompatibilityPage(): JSX.Element {
text={t("au.web_onbording.category")} text={t("au.web_onbording.category")}
direction={EDirectionOnboarding.TOP} direction={EDirectionOnboarding.TOP}
showCross={true} showCross={true}
crossClickHandler={() => setCurrentOnboarding(3)} crossClickHandler={() => setCurrentOnboarding(4)}
/> />
</Onboarding> </Onboarding>
)} )}
{data && data.length && ( {data && data.length && (
<div <div
className={styles["compatibility-categories"]} className={styles["compatibility-categories"]}
style={{ zIndex: currentOnboarding === 2 ? 99 : 1 }} style={{ zIndex: currentOnboarding === 3 ? 99 : 1 }}
ref={categoriesRef} ref={categoriesRef}
> >
{data.map((item, index) => ( {data.map((item, index) => (
<div <div
className="compatibility-categories__item" className="compatibility-categories__item"
key={index} key={index}
onClick={() => setCurrentOnboarding(3)} onClick={() => setCurrentOnboarding(4)}
> >
<input <input
className={`${styles["compatibility-categories__input"]} ${ className={`${styles["compatibility-categories__input"]} ${
@ -308,7 +369,7 @@ function CompatibilityPage(): JSX.Element {
<div <div
style={{ style={{
position: "relative", position: "relative",
zIndex: currentOnboarding === 3 ? 99 : 1, zIndex: currentOnboarding === 4 ? 99 : 1,
}} }}
ref={mainButtonRef} ref={mainButtonRef}
> >

View File

@ -1,4 +1,4 @@
import { useEffect, useState } from 'react' import { useEffect, useRef, useState } from 'react'
import ProcessItem from "./ProcessItem" import ProcessItem from "./ProcessItem"
import styles from './styles.module.css' import styles from './styles.module.css'
@ -32,15 +32,28 @@ const getMultiplier = (currentIdx: number, length: number): number => {
return Math.max(length - (currentIdx + 1) - 1, 0) return Math.max(length - (currentIdx + 1) - 1, 0)
} }
const calculateTop = (currentIdx: number, length: number): number => { const calculateTop = (currentIdx: number, length: number, items: HTMLDivElement[]): number => {
const itemHeight = 63
return getMultiplier(currentIdx, length) * itemHeight return items.slice(currentIdx + 2).reduce((accumulator, item) => {
if (!item) return accumulator;
return accumulator + item.clientHeight
}, 1) + 8 * getMultiplier(currentIdx, length)
// const itemHeight = 63
// return getMultiplier(currentIdx, length) * itemHeight1?.clientHeight
} }
function ProcessFlow({ items, onDone }: ProcessFlowProps): JSX.Element { function ProcessFlow({ items, onDone }: ProcessFlowProps): JSX.Element {
const [status, setStatus] = useState(ProcessStatus.Idle) const [status, setStatus] = useState(ProcessStatus.Idle)
const [doneTaskIdx, setDoneTaskIdx] = useState(-1) const [doneTaskIdx, setDoneTaskIdx] = useState(-1)
const itemsRef = useRef([] as HTMLDivElement[]);
const tasks = items.map(({ task }) => task) const tasks = items.map(({ task }) => task)
const [rerender, setRerender] = useState(false);
rerender
useEffect(() => {
setRerender((prev) => !prev);
}, [itemsRef])
useEffect(() => { useEffect(() => {
if (status !== ProcessStatus.Idle) return if (status !== ProcessStatus.Idle) return
@ -54,8 +67,9 @@ function ProcessFlow({ items, onDone }: ProcessFlowProps): JSX.Element {
return <ProcessItem return <ProcessItem
key={idx} key={idx}
label={label} label={label}
top={calculateTop(doneTaskIdx, items.length)} top={calculateTop(doneTaskIdx, items.length, itemsRef.current)}
isDone={idx <= doneTaskIdx} isDone={idx <= doneTaskIdx}
refItem={(el) => (itemsRef.current[idx] = el as HTMLDivElement)}
/> />
} }
return ( return (

View File

@ -1,3 +1,4 @@
import { LegacyRef } from "react"
import Loader, { LoaderColor } from "../Loader" import Loader, { LoaderColor } from "../Loader"
import styles from "./styles.module.css" import styles from "./styles.module.css"
@ -5,12 +6,13 @@ type ProcessItemProps = {
top: number top: number
label: string label: string
isDone: boolean isDone: boolean
refItem: LegacyRef<HTMLDivElement>
} }
function ProcessItem({ top, label, isDone }: ProcessItemProps): JSX.Element { function ProcessItem({ top, label, isDone, refItem }: ProcessItemProps): JSX.Element {
return ( return (
<div className={styles['process-item']} style={{ top: top }}> <div ref={refItem} className={styles['process-item']} style={{ top: top }}>
<div className={styles['process-item__pick']}> <div className={styles['process-item__pick']}>
{ {
isDone isDone

View File

@ -43,9 +43,9 @@
.process-item { .process-item {
display: flex; display: flex;
font-size: 24px; font-size: 20px;
font-weight: 400; font-weight: 400;
margin-bottom: 24px; margin-bottom: 8px;
line-height: 32px; line-height: 32px;
position: relative; position: relative;
transition: top 0.4s ease-in-out; transition: top 0.4s ease-in-out;

View File

@ -202,7 +202,8 @@ function HomePage(): JSX.Element {
variant="h3" variant="h3"
className={styles["content__daily-forecast-title"]} className={styles["content__daily-forecast-title"]}
> >
{forecast.category} {/* {forecast.category} */}
{t("aura.personal_aura.button")}
</Title> </Title>
<p className={styles["content__daily-forecast-body"]}> <p className={styles["content__daily-forecast-body"]}>
{forecast.body} {forecast.body}

View File

@ -5,6 +5,7 @@ import type { PayloadAction } from "@reduxjs/toolkit";
interface ICompatibility { interface ICompatibility {
rightUser: IUser; rightUser: IUser;
categoryId: number; categoryId: number;
selfName: string;
} }
interface IUser { interface IUser {
@ -18,6 +19,7 @@ const initialState: ICompatibility = {
birthDate: "", birthDate: "",
}, },
categoryId: 1, categoryId: 1,
selfName: "I am",
}; };
const compatibilitySlice = createSlice({ const compatibilitySlice = createSlice({
@ -25,7 +27,7 @@ const compatibilitySlice = createSlice({
initialState, initialState,
reducers: { reducers: {
update(state, action: PayloadAction<Partial<ICompatibility>>) { update(state, action: PayloadAction<Partial<ICompatibility>>) {
return { ...state, ...action.payload }; return { ...initialState, ...state, ...action.payload };
}, },
}, },
extraReducers: (builder) => builder.addCase("reset", () => initialState), extraReducers: (builder) => builder.addCase("reset", () => initialState),
@ -40,4 +42,8 @@ export const selectCategoryId = createSelector(
(state: { compatibility: ICompatibility }) => state.compatibility.categoryId, (state: { compatibility: ICompatibility }) => state.compatibility.categoryId,
(compatibility) => compatibility (compatibility) => compatibility
); );
export const selectSelfName = createSelector(
(state: { compatibility: ICompatibility }) => state.compatibility.selfName,
(compatibility) => compatibility
);
export default compatibilitySlice.reducer; export default compatibilitySlice.reducer;

View File

@ -32,7 +32,7 @@ import subscriptionPlans, {
} from "./subscriptionPlan"; } from "./subscriptionPlan";
import status, { actions as userStatusActions, selectStatus } from "./status"; import status, { actions as userStatusActions, selectStatus } from "./status";
import compatibility, { import compatibility, {
actions as compatibilityActions, actions as compatibilityActions, selectSelfName,
} from "./compatibility"; } from "./compatibility";
import userCallbacks, { import userCallbacks, {
actions as userCallbacksActions, actions as userCallbacksActions,
@ -68,6 +68,7 @@ export const selectors = {
selectPlanById, selectPlanById,
selectAuraCoordinates, selectAuraCoordinates,
selectRightUser, selectRightUser,
selectSelfName,
selectCategoryId, selectCategoryId,
selectSelectedPrice, selectSelectedPrice,
selectUserCallbacksDescription, selectUserCallbacksDescription,