212 lines
5.1 KiB
TypeScript
212 lines
5.1 KiB
TypeScript
import React from 'react';
|
|
|
|
import { useLocation, useNavigate } from 'react-router-dom';
|
|
|
|
import routes from '@/routes';
|
|
|
|
export enum Step {
|
|
Welcome = 'welcome',
|
|
Gender = 'gender',
|
|
Birthdate = 'birthdate',
|
|
PalmsHold = 'palms-hold',
|
|
Wish = 'wish',
|
|
RelationshipStatus = 'relationship-status',
|
|
ResonatedElement = 'resonated-element',
|
|
ColorYouLike = 'color-you-like',
|
|
Decisions = 'decisions',
|
|
GuidancePlan = 'guidance-plan',
|
|
PersonalStatement = 'personal-statement',
|
|
ScanInfo = 'scan-info',
|
|
Upload = 'upload',
|
|
ScanPhoto = 'scan-photo',
|
|
Email = 'email',
|
|
SubscriptionPlan = 'subscription-plan',
|
|
Paywall = 'paywall',
|
|
Payment = 'payment',
|
|
Discount = 'discount',
|
|
PremiumBundle = 'premium-bundle',
|
|
}
|
|
|
|
export const sortedList = [
|
|
Step.Welcome,
|
|
Step.Gender,
|
|
Step.Birthdate,
|
|
Step.PalmsHold,
|
|
Step.Wish,
|
|
Step.RelationshipStatus,
|
|
Step.ResonatedElement,
|
|
Step.ColorYouLike,
|
|
Step.Decisions,
|
|
Step.GuidancePlan,
|
|
Step.PersonalStatement,
|
|
Step.ScanInfo,
|
|
Step.Upload,
|
|
Step.ScanPhoto,
|
|
Step.Email,
|
|
Step.SubscriptionPlan,
|
|
Step.Paywall,
|
|
Step.Payment,
|
|
Step.Discount,
|
|
Step.PremiumBundle,
|
|
];
|
|
|
|
export enum GenderChoice {
|
|
Male = 'male',
|
|
Female = 'female',
|
|
}
|
|
|
|
export enum WishChoice {
|
|
Love = 'Love & Relationship',
|
|
Health = 'Health & Vitality',
|
|
Career = 'Career & Destiny',
|
|
}
|
|
|
|
export enum RelationshipStatusChoice {
|
|
Single = 'single',
|
|
InRelationship = 'relationship',
|
|
}
|
|
|
|
export enum ResonatedElementChoice {
|
|
Earth = 'Earth',
|
|
Water = 'Water',
|
|
Fire = 'Fire',
|
|
Air = 'Air',
|
|
}
|
|
|
|
export enum ColorYouLikeChoice {
|
|
Red = 'Red',
|
|
Yellow = 'Yellow',
|
|
Blue = 'Blue',
|
|
Orange = 'Orange',
|
|
Green = 'Green',
|
|
Violet = 'Violet',
|
|
}
|
|
|
|
export enum DecisionsChoice {
|
|
Heart = 'Heart',
|
|
Head = 'Head',
|
|
Both = 'Both',
|
|
}
|
|
|
|
export type Choice = GenderChoice | WishChoice | RelationshipStatusChoice | ResonatedElementChoice | ColorYouLikeChoice | DecisionsChoice;
|
|
|
|
const buildStoredValues = (value: string | ((s: Step) => string)) => {
|
|
return sortedList.reduce((acc, step) => ({
|
|
...acc,
|
|
[step]: typeof value === 'function' ? value(step) : value,
|
|
}), {} as Record<Step, string>);
|
|
};
|
|
|
|
export default function useSteps() {
|
|
const { pathname } = useLocation();
|
|
const navigate = useNavigate();
|
|
const pathnameTail = pathname.split('/').pop();
|
|
const current = pathnameTail === 'palmistry' ? Step.Welcome : pathnameTail;
|
|
const list = Object.values(Step);
|
|
const count = list.length - 1;
|
|
const progressBarRange = [1, 10];
|
|
const isWelcome = current === Step.Welcome;
|
|
const defaultStep = Step.Welcome;
|
|
const currentNumber = React.useMemo(() => sortedList.findIndex((s) => s === current), [current]);
|
|
const isInvalid = currentNumber === -1;
|
|
|
|
const [isInited, setIsInited] = React.useState(false);
|
|
const [storedValues, setStoredValues] = React.useState(buildStoredValues(''));
|
|
const [firstUnpassedStep, setFirstUnpassedStep] = React.useState<Step | null>(null);
|
|
|
|
const getFromStorage = (key: Step | 'firstUnpassedStep') => {
|
|
return localStorage.getItem(`palmistry.${key}`) || '';
|
|
};
|
|
|
|
React.useEffect(() => {
|
|
if (pathnameTail === 'palmistry') {
|
|
navigate(routes.client.palmistryWelcome());
|
|
}
|
|
|
|
setIsInited(true);
|
|
setStoredValues(buildStoredValues(getFromStorage));
|
|
setFirstUnpassedStep(getFromStorage('firstUnpassedStep') as Step | null);
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, []);
|
|
|
|
const getStoredValue = (key: Step) => {
|
|
return storedValues[key] || '';
|
|
};
|
|
|
|
function saveToStorage(key: Step | 'firstUnpassedStep', value: string) {
|
|
localStorage.setItem(`palmistry.${key}`, value);
|
|
}
|
|
|
|
function getPreviousStep() {
|
|
if (current === Step.ResonatedElement && getStoredValue(Step.Wish) !== WishChoice.Love) {
|
|
return sortedList[currentNumber - 2];
|
|
} else {
|
|
return sortedList[currentNumber - 1];
|
|
}
|
|
}
|
|
|
|
function getNextStep(choice?: Choice) {
|
|
if (current === Step.Wish && choice !== WishChoice.Love) {
|
|
return sortedList[currentNumber + 2];
|
|
} else {
|
|
return sortedList[currentNumber + 1];
|
|
}
|
|
}
|
|
|
|
function goBack() {
|
|
navigate(`/palmistry/${getPreviousStep()}`);
|
|
}
|
|
|
|
function goNext(choice?: Choice) {
|
|
const nextStep = getNextStep();
|
|
|
|
setFirstUnpassedStep(nextStep as Step);
|
|
|
|
if (sortedList.indexOf(nextStep) > sortedList.indexOf(firstUnpassedStep as Step)) {
|
|
saveToStorage('firstUnpassedStep', nextStep as Step);
|
|
}
|
|
|
|
navigate(`/palmistry/${getNextStep(choice)}`);
|
|
}
|
|
|
|
function goFirstUnpassedStep(queryParameters = "") {
|
|
if (!firstUnpassedStep) {
|
|
navigate(`/palmistry/${sortedList[0]}?${queryParameters}`);
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
navigate(`/palmistry/${firstUnpassedStep}?${queryParameters}`, {
|
|
state: {
|
|
from: pathname,
|
|
},
|
|
});
|
|
}
|
|
|
|
function saveCurrent(value: string) {
|
|
saveToStorage(current as Step, value);
|
|
}
|
|
|
|
return {
|
|
isInited,
|
|
current,
|
|
list,
|
|
count,
|
|
progressBarRange,
|
|
isWelcome,
|
|
defaultStep,
|
|
currentNumber,
|
|
isInvalid,
|
|
storedValue: storedValues[current as Step],
|
|
firstUnpassedStep,
|
|
goBack,
|
|
goNext,
|
|
saveToStorage,
|
|
saveCurrent,
|
|
getStoredValue,
|
|
goFirstUnpassedStep,
|
|
setFirstUnpassedStep,
|
|
};
|
|
}
|