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; email: string; is_admin: boolean; name: string; password?: string; icon?: string; roles?: string[]; cities?: UserCity[]; }; class UserStore { users: { data: User[]; loaded: boolean; } = { data: [], loaded: false, }; user: Record = {}; constructor() { makeAutoObservable(this); } getUsers = async () => { const response = await authInstance.get("/user"); runInAction(() => { this.users.data = response.data; this.users.loaded = true; }); }; getUser = async (id: number) => { if (this.user[id]) return this.user[id]; const response = await authInstance.get(`/user/${id}`); runInAction(() => { this.user[id] = response.data as User; }); return response.data; }; deleteUser = async (id: number) => { await authInstance.delete(`/user/${id}`); runInAction(() => { this.users.data = this.users.data.filter((user) => user.id !== id); delete this.user[id]; }); }; createUserData: Partial = { name: "", email: "", password: "", is_admin: false, icon: "", roles: ["articles_ro", "articles_rw", "media_ro", "media_rw"], }; setCreateUserData = ( name: string, email: string, password: string, is_admin: boolean, icon?: string, ) => { this.createUserData = { ...this.createUserData, name, email, password, is_admin, icon: icon ?? "", }; }; createUser = async () => { let id = 1; if (this.users.data.length > 0) { id = this.users.data[this.users.data.length - 1].id + 1; } const payload: Partial = { ...this.createUserData }; const baseRoles = new Set(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); runInAction(() => { this.users.data.push({ id: id, ...response.data, }); }); }; editUserData: Partial = { name: "", email: "", password: "", is_admin: false, icon: "", roles: [], }; setEditUserData = ( name: string, email: string, password: string, is_admin: boolean, icon?: string, ) => { this.editUserData = { ...this.editUserData, name, email, password, is_admin, icon: icon ?? "", }; }; 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, ); 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();