w-aura/src/hooks/authentication/use-authentication.ts
Daniil Chemerkin 0a315b1b13 Develop
2024-10-14 15:12:22 +00:00

214 lines
7.6 KiB
TypeScript

import { ErrorPayload, useApi } from "@/api";
import { EGender, ESourceAuthorization, ICreateAuthorizePayload } from "@/api/resources/User";
import { useAuth } from "@/auth";
import { getClientTimezone } from "@/locales";
import { getDateAsString } from "@/services/date";
import { filterNullKeysOfObject } from "@/services/filter-object";
import metricService, { EGoals } from "@/services/metric/metricService";
import { actions, selectors } from "@/store";
import moment from "moment";
import { useCallback, useMemo, useState } from "react";
import { useTranslations } from "@/hooks/translations";
import { useDispatch, useSelector } from "react-redux";
import { Response } from "@/api/resources/Login";
export const useAuthentication = () => {
const api = useApi();
const feature = useSelector(selectors.selectFeature)
const { i18n } = useTranslations();
const dispatch = useDispatch();
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [token, setToken] = useState<string | null>(null);
const { user, signUp } = useAuth();
const locale = i18n.language;
const { username } = useSelector(selectors.selectUser)
const { name: partnerName, birthDate: partnerBirthdateFromForm } = useSelector(selectors.selectRightUser)
const {
gender,
birthdate: birthdateFromQuestionnaire,
birthtime: birthtimeFromQuestionnaire,
birthPlace,
partnerGender,
partnerBirthdate: partnerBirthdateFromQuestionnaire,
partnerBirthPlace,
partnerBirthtime,
} = useSelector(selectors.selectQuestionnaire)
const { checked, dateOfCheck } = useSelector(selectors.selectPrivacyPolicy)
const birthdateFromForm = useSelector(selectors.selectBirthdate);
const birthtimeFromForm = useSelector(selectors.selectBirthtime);
const birthdate = useMemo(() => {
if (birthdateFromQuestionnaire.length) {
return birthdateFromQuestionnaire;
}
if (birthdateFromForm.length) {
return birthdateFromForm;
}
}, [birthdateFromForm, birthdateFromQuestionnaire]);
const birthtime = useMemo(() => {
if (birthtimeFromQuestionnaire.length) {
return birthtimeFromQuestionnaire;
}
if (birthtimeFromForm.length) {
return birthtimeFromForm;
}
}, [birthtimeFromForm, birthtimeFromQuestionnaire]);
const partnerBirthdate = useMemo(() => {
const fromQuestionnaire = `${partnerBirthdateFromQuestionnaire} ${partnerBirthtime}`
if (partnerBirthdateFromQuestionnaire.length) {
return fromQuestionnaire;
}
return getDateAsString(partnerBirthdateFromForm)
}, [partnerBirthdateFromForm, partnerBirthdateFromQuestionnaire, partnerBirthtime])
const formatDate = useCallback((date: string) => {
const _date = moment(date, "YYYY-MM-DD HH:mm", true).format("YYYY-MM-DD HH:mm");
if (_date === "Invalid date") {
return null;
}
return _date;
}, [])
const getAuthorizationPayload = useCallback((email: string, source: ESourceAuthorization): ICreateAuthorizePayload => {
const timezone = getClientTimezone();
return filterNullKeysOfObject<ICreateAuthorizePayload>({
timezone,
locale,
email,
source,
profile: {
name: username || "",
gender: EGender[gender as keyof typeof EGender] || null,
birthdate: formatDate(`${birthdate} ${birthtime}`),
birthplace: {
address: birthPlace,
},
},
partner: {
name: partnerName,
gender: EGender[partnerGender as keyof typeof EGender] || null,
birthdate: formatDate(partnerBirthdate),
birthplace: {
address: partnerBirthPlace,
},
},
sign: checked,
signDate: dateOfCheck,
feature
})
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
birthPlace,
birthdate,
gender,
locale,
partnerBirthPlace,
partnerBirthdate,
partnerGender,
partnerName,
username,
birthtime,
checked,
dateOfCheck
]);
const authorizationWithPassword = useCallback(async (email: string, password: string) => {
try {
setIsLoading(true);
setError(null)
const payload = {
email,
locale,
timezone: getClientTimezone(),
password
}
const loginResult = await api.login(payload);
const token = "token" in loginResult ? loginResult.token : null;
const userId = "userId" in loginResult ? loginResult.userId : null;
const status = "status" in loginResult ? loginResult.status : null;
const message = "message" in loginResult ? loginResult.message : null;
if (!token) {
return {
status,
message
}
}
const { user } = await api.getUser({ token });
if (userId?.length) {
metricService.userParams({
email: user.email,
UserID: userId
})
metricService.setUserID(userId);
}
signUp(token, user);
setToken(token);
dispatch(actions.status.update("registred"));
} catch (error: unknown) {
const response = (error as ErrorPayload<Response>).responseData
setError((!!response && "message" in response && response.message) || (error as Error).message);
return response
} finally {
setIsLoading(false);
}
}, [api, dispatch, locale, signUp])
const authorization = useCallback(async (email: string, source: ESourceAuthorization) => {
try {
setIsLoading(true);
setError(null)
const payload = getAuthorizationPayload(email, source);
const { token, userId, generatingVideo, videoId, authCode } = await api.authorization(payload);
const { user } = await api.getUser({ token });
if (userId?.length) {
metricService.userParams({
hasPersonalVideo: generatingVideo || false,
email: user.email,
UserID: userId
})
metricService.setUserID(userId);
}
signUp(token, user);
setToken(token);
if (authCode?.length) {
dispatch(actions.userConfig.setAuthCode(authCode));
}
dispatch(actions.personalVideo.updateStatus({ generatingVideo: generatingVideo || false, videoId: videoId || "" }));
if (generatingVideo) {
metricService.reachGoal(EGoals.ROSE_VIDEO_CREATION_START)
}
dispatch(actions.status.update("registred"));
} catch (error) {
setError((error as Error).message);
} finally {
setIsLoading(false);
}
}, [api, dispatch, getAuthorizationPayload, signUp])
return useMemo(
() => ({
isLoading,
error,
token,
user,
authorization,
authorizationWithPassword,
}),
[
isLoading,
error,
token,
user,
authorization,
authorizationWithPassword,
]
);
}