init: Init React Application

This commit is contained in:
2025-05-29 13:21:33 +03:00
parent 9444939507
commit 17de7e495f
66 changed files with 10425 additions and 0 deletions

View File

@@ -0,0 +1,96 @@
import { API_URL, decodeJWT } from "@shared";
import { makeAutoObservable } from "mobx";
import axios, { AxiosError } from "axios";
type LoginResponse = {
token: string;
user: {
id: number;
name: string;
email: string;
is_admin: boolean;
};
};
class AuthStore {
payload: LoginResponse | null = null;
isLoading = false;
error: string | null = null;
constructor() {
makeAutoObservable(this);
this.initialize();
}
private initialize() {
const storedToken = localStorage.getItem("token") || undefined;
const decoded = decodeJWT(storedToken);
if (decoded) {
this.payload = decoded;
// Set the token in axios defaults for future requests
if (storedToken) {
axios.defaults.headers.common[
"Authorization"
] = `Bearer ${storedToken}`;
}
} else {
// If token is invalid or missing, clear it
this.logout();
}
}
private setAuthToken(token: string) {
localStorage.setItem("token", token);
axios.defaults.headers.common["Authorization"] = `Bearer ${token}`;
}
login = async (email: string, password: string) => {
this.isLoading = true;
this.error = null;
try {
const response = await axios.post<LoginResponse>(
`${API_URL}/auth/login`,
{
email,
password,
}
);
const { token } = response.data;
// Update auth token and store state
this.setAuthToken(token);
this.payload = response.data;
this.error = null;
} catch (error) {
if (error instanceof AxiosError) {
this.error =
error.response?.data?.message || "Ошибка при входе в систему";
} else {
this.error = "Неизвестная ошибка при входе в систему";
}
throw new Error(this.error ?? "Неизвестная ошибка при входе в систему");
} finally {
this.isLoading = false;
}
};
logout = () => {
localStorage.removeItem("token");
this.payload = null;
this.error = null;
};
get isAuthenticated() {
return !!this.payload?.token;
}
get user() {
return this.payload?.user;
}
}
export const authStore = new AuthStore();