feat: role system

This commit is contained in:
2026-03-18 20:11:07 +03:00
parent 73070fe233
commit c3127b8d47
47 changed files with 2425 additions and 768 deletions

View File

@@ -1,5 +1,11 @@
import { authInstance } from "@shared";
import { authInstance, mobxFetch } from "@shared";
import { makeAutoObservable, runInAction } from "mobx";
import { addUserCityApi } from "./api";
export type UserCity = {
city_id: number;
name: string;
};
export type User = {
id: number;
@@ -8,6 +14,8 @@ export type User = {
name: string;
password?: string;
icon?: string;
roles?: string[];
cities?: UserCity[];
};
class UserStore {
@@ -59,6 +67,7 @@ class UserStore {
password: "",
is_admin: false,
icon: "",
roles: ["articles_ro", "articles_rw", "media_ro", "media_rw"],
};
setCreateUserData = (
@@ -66,9 +75,10 @@ class UserStore {
email: string,
password: string,
is_admin: boolean,
icon?: string
icon?: string,
) => {
this.createUserData = {
...this.createUserData,
name,
email,
password,
@@ -82,7 +92,13 @@ class UserStore {
if (this.users.data.length > 0) {
id = this.users.data[this.users.data.length - 1].id + 1;
}
const payload = { ...this.createUserData };
const payload: Partial<User> = { ...this.createUserData };
const baseRoles = new Set<string>(payload.roles ?? []);
baseRoles.add("articles_ro");
baseRoles.add("articles_rw");
baseRoles.add("media_ro");
baseRoles.add("media_rw");
payload.roles = Array.from(baseRoles);
if (!payload.icon) delete payload.icon;
const response = await authInstance.post("/user", payload);
@@ -100,6 +116,7 @@ class UserStore {
password: "",
is_admin: false,
icon: "",
roles: [],
};
setEditUserData = (
@@ -107,9 +124,10 @@ class UserStore {
email: string,
password: string,
is_admin: boolean,
icon?: string
icon?: string,
) => {
this.editUserData = {
...this.editUserData,
name,
email,
password,
@@ -118,19 +136,50 @@ class UserStore {
};
};
setEditUserRoles = (roles: string[]) => {
this.editUserData = { ...this.editUserData, roles };
};
editUser = async (id: number) => {
const payload = { ...this.editUserData };
if (!payload.icon) delete payload.icon;
if (!payload.password?.trim()) delete payload.password;
const response = await authInstance.patch(`/user/${id}`, payload);
runInAction(() => {
this.users.data = this.users.data.map((user) =>
user.id === id ? { ...user, ...response.data } : user
user.id === id ? { ...user, ...response.data } : user,
);
this.user[id] = { ...this.user[id], ...response.data };
});
};
addUserCityResult: User | null = null;
addUserCityLoading = false;
addUserCityError: string | null = null;
addUserCityAction = mobxFetch<
{ id: number; city_ids: number[] },
User,
UserStore
>({
store: this,
value: "addUserCityResult",
loading: "addUserCityLoading",
error: "addUserCityError",
fn: addUserCityApi,
onSuccess: (result) => {
runInAction(() => {
this.users.data = this.users.data.map((user) =>
user.id === result.id ? { ...user, ...result } : user,
);
if (this.user[result.id]) {
this.user[result.id] = { ...this.user[result.id], ...result };
}
});
},
});
}
export const userStore = new UserStore();