214 lines
7.6 KiB
TypeScript
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,
|
|
]
|
|
);
|
|
}
|