mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 16:28:12 +00:00
196 lines
5.4 KiB
TypeScript
196 lines
5.4 KiB
TypeScript
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
import { api } from "@/services/api";
|
|
import type {
|
|
LoginPayload,
|
|
LoginResponse,
|
|
SignupPayload,
|
|
SignupResponse,
|
|
OtpResponse,
|
|
} from "@/types/auth";
|
|
import type { Result } from "@/utils/result";
|
|
import { extractApiError } from "@/utils/result";
|
|
import { useEffect } from "react";
|
|
|
|
function setCookie(name: string, value: string, days: number) {
|
|
const expires = new Date();
|
|
expires.setDate(expires.getDate() + days);
|
|
document.cookie = `${name}=${value}; path=/; expires=${expires.toUTCString()}; SameSite=Lax`;
|
|
}
|
|
|
|
function getCookie(name: string): string | undefined {
|
|
return document.cookie
|
|
.split("; ")
|
|
.find((row) => row.startsWith(`${name}=`))
|
|
?.split("=")[1];
|
|
}
|
|
|
|
const useAuth = () => {
|
|
const queryClient = useQueryClient();
|
|
|
|
const authQuery = useQuery(
|
|
api.auth.getMyInfo.queryOptions({
|
|
retry: false,
|
|
staleTime: 10 * 60 * 1000,
|
|
}),
|
|
);
|
|
|
|
const companyQuery = useQuery(
|
|
api.companies.getInfo.queryOptions({
|
|
enabled: !!authQuery.data?.id,
|
|
retry: false,
|
|
staleTime: 10 * 60 * 1000,
|
|
refetchOnWindowFocus: false,
|
|
}),
|
|
);
|
|
|
|
useEffect(() => {
|
|
console.log({
|
|
user: authQuery.data,
|
|
company: companyQuery.data,
|
|
isCompany: !!companyQuery.data,
|
|
isUserPending: authQuery.isPending,
|
|
isCompanyPending: companyQuery.isPending,
|
|
});
|
|
}, [authQuery, companyQuery]);
|
|
|
|
const hasToken = !!getCookie("auth-token");
|
|
const isPending = authQuery.isPending && hasToken;
|
|
|
|
const login = async (
|
|
payload: LoginPayload,
|
|
): Promise<Result<LoginResponse>> => {
|
|
try {
|
|
const res = await api.auth.login.call(payload);
|
|
setCookie("auth-token", res.token, 7);
|
|
setCookie("refresh-token", res.refreshToken, 7);
|
|
await authQuery.refetch();
|
|
return { success: true, data: res };
|
|
} catch (err) {
|
|
return { success: false, error: extractApiError(err) };
|
|
}
|
|
};
|
|
|
|
const signup = async (
|
|
payload: SignupPayload,
|
|
): Promise<Result<SignupResponse>> => {
|
|
try {
|
|
const res = await api.auth.createUser.call(payload);
|
|
setCookie("auth-token", res.token, 7);
|
|
setCookie("refresh-token", res.refreshToken, 7);
|
|
await authQuery.refetch();
|
|
const otpCode = res.otp?.split(" ")?.[6] ?? "";
|
|
localStorage.setItem("otp", otpCode);
|
|
localStorage.setItem("otp-phone", payload.phoneNumber);
|
|
localStorage.setItem("otp-email", payload.email);
|
|
api.auth.sendOTP
|
|
.call({ phone: payload.phoneNumber, otp: otpCode })
|
|
.catch(() => { });
|
|
return { success: true, data: res };
|
|
} catch (err) {
|
|
return { success: false, error: extractApiError(err) };
|
|
}
|
|
};
|
|
|
|
const setPassword = async (data: {
|
|
newPassword: string;
|
|
confirmPassword: string;
|
|
}): Promise<Result<void>> => {
|
|
try {
|
|
const userId = authQuery.data?.id ?? "";
|
|
const email = localStorage.getItem("otp-email") ?? "";
|
|
const verificationCode = localStorage.getItem("otp") ?? "";
|
|
await api.auth.setPassword.call({
|
|
newPassword: data.newPassword,
|
|
confirmPassword: data.confirmPassword,
|
|
userId,
|
|
email,
|
|
verificationCode,
|
|
});
|
|
["userId", "otp", "otp-phone", "otp-email"].forEach((k) =>
|
|
localStorage.removeItem(k),
|
|
);
|
|
await queryClient.invalidateQueries({
|
|
queryKey: api.auth.getMyInfo.queryKey(),
|
|
});
|
|
return { success: true, data: undefined };
|
|
} catch (err) {
|
|
return { success: false, error: extractApiError(err) };
|
|
}
|
|
};
|
|
|
|
const verifyOTP = async (otp: string): Promise<Result<OtpResponse>> => {
|
|
try {
|
|
const phone = localStorage.getItem("otp-phone") ?? "";
|
|
const res = await api.auth.verifyOTP.call({ phone, otp });
|
|
return { success: true, data: res };
|
|
} catch (err) {
|
|
return { success: false, error: extractApiError(err) };
|
|
}
|
|
};
|
|
|
|
const sendOTP = async (otp: string): Promise<Result<OtpResponse>> => {
|
|
try {
|
|
const phone = localStorage.getItem("otp-phone") ?? "";
|
|
const res = await api.auth.sendOTP.call({ phone, otp });
|
|
return { success: true, data: res };
|
|
} catch (err) {
|
|
return { success: false, error: extractApiError(err) };
|
|
}
|
|
};
|
|
|
|
const generateVerificationCode = async (
|
|
type: string,
|
|
): Promise<Result<string>> => {
|
|
try {
|
|
const email = localStorage.getItem("otp-email") ?? "";
|
|
const phoneNumber = localStorage.getItem("otp-phone") ?? "";
|
|
const res = await api.auth.generateVerificationCode.call({
|
|
email,
|
|
phoneNumber,
|
|
type,
|
|
});
|
|
return { success: true, data: res };
|
|
} catch (err) {
|
|
return { success: false, error: extractApiError(err) };
|
|
}
|
|
};
|
|
|
|
const logout = async () => {
|
|
try {
|
|
await api.auth.logout.call();
|
|
} catch {
|
|
// proceed with client-side cleanup even if server call fails
|
|
}
|
|
[
|
|
"auth-token",
|
|
"refresh-token",
|
|
"auth-user",
|
|
"current-position-id",
|
|
"selected-position-id",
|
|
].forEach((name) => {
|
|
document.cookie = `${name}=; Max-Age=0; path=/`;
|
|
});
|
|
localStorage.clear();
|
|
queryClient.clear();
|
|
};
|
|
|
|
return {
|
|
isPending,
|
|
user: authQuery.data ?? null,
|
|
company: companyQuery.data ?? null,
|
|
customer: companyQuery.data ?? null,
|
|
login,
|
|
signup,
|
|
setPassword,
|
|
verifyOTP,
|
|
sendOTP,
|
|
generateVerificationCode,
|
|
logout,
|
|
authQuery,
|
|
companyQuery,
|
|
customerQuery: companyQuery,
|
|
};
|
|
};
|
|
|
|
export default useAuth;
|