2023-05-30 18:34:41 +00:00
|
|
|
import { PatchUserRequest, UserSettings, UserSettingsField, UserWithFields } from "@root/model/user";
|
|
|
|
import { produce } from "immer";
|
2023-05-17 11:20:11 +00:00
|
|
|
import { create } from "zustand";
|
|
|
|
import { createJSONStorage, devtools, persist } from "zustand/middleware";
|
2023-05-30 18:34:41 +00:00
|
|
|
import { StringSchema, string } from "yup";
|
|
|
|
import { patchUser } from "@root/api/user";
|
2023-05-17 11:20:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
interface UserStore {
|
|
|
|
userId: string | null;
|
2023-05-30 18:34:41 +00:00
|
|
|
user: UserWithFields | null;
|
|
|
|
settingsFields: UserSettings | null;
|
2023-05-17 11:20:11 +00:00
|
|
|
}
|
|
|
|
|
2023-05-30 18:34:41 +00:00
|
|
|
const defaultFieldValues = {
|
|
|
|
value: "",
|
|
|
|
error: null,
|
|
|
|
touched: false,
|
|
|
|
};
|
|
|
|
|
|
|
|
const defaultFields = {
|
|
|
|
name: { ...defaultFieldValues },
|
|
|
|
surname: { ...defaultFieldValues },
|
|
|
|
middleName: { ...defaultFieldValues },
|
|
|
|
companyName: { ...defaultFieldValues },
|
|
|
|
email: { ...defaultFieldValues },
|
|
|
|
phoneNumber: { ...defaultFieldValues },
|
|
|
|
password: { ...defaultFieldValues },
|
|
|
|
};
|
|
|
|
|
2023-05-17 11:20:11 +00:00
|
|
|
const initialState: UserStore = {
|
|
|
|
userId: null,
|
|
|
|
user: null,
|
2023-05-30 18:34:41 +00:00
|
|
|
settingsFields: { ...defaultFields },
|
2023-05-17 11:20:11 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
export const useUserStore = create<UserStore>()(
|
|
|
|
persist(
|
|
|
|
devtools(
|
|
|
|
(set, get) => initialState,
|
|
|
|
{
|
|
|
|
name: "User store",
|
2023-05-30 18:34:41 +00:00
|
|
|
enabled: process.env.NODE_ENV === "development",
|
2023-05-17 11:20:11 +00:00
|
|
|
}
|
|
|
|
),
|
|
|
|
{
|
|
|
|
name: "user",
|
|
|
|
storage: createJSONStorage(() => localStorage),
|
2023-05-30 18:34:41 +00:00
|
|
|
partialize: state => ({
|
|
|
|
userId: state.userId,
|
|
|
|
user: state.user,
|
|
|
|
})
|
2023-05-17 11:20:11 +00:00
|
|
|
}
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
export const setUserId = (userId: string | null) => useUserStore.setState({ userId });
|
2023-05-30 18:34:41 +00:00
|
|
|
export const setUser = (user: UserWithFields | null) => useUserStore.setState(
|
|
|
|
produce<UserStore>(state => {
|
|
|
|
state.user = user;
|
|
|
|
if (!user) {
|
|
|
|
state.settingsFields = null;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!state.settingsFields) state.settingsFields = { ...defaultFields };
|
|
|
|
|
|
|
|
state.settingsFields.name.value = user.name || "";
|
|
|
|
state.settingsFields.surname.value = user.surname || "";
|
|
|
|
state.settingsFields.middleName.value = user.middleName || "";
|
|
|
|
state.settingsFields.companyName.value = user.companyName || "";
|
|
|
|
state.settingsFields.email.value = user.email;
|
|
|
|
state.settingsFields.phoneNumber.value = user.phoneNumber;
|
|
|
|
state.settingsFields.password.value = "";
|
|
|
|
})
|
|
|
|
);
|
|
|
|
|
|
|
|
export const clearUser = () => useUserStore.setState({ ...initialState });
|
|
|
|
|
|
|
|
export const setSettingsField = async (
|
|
|
|
fieldName: UserSettingsField,
|
|
|
|
value: string,
|
|
|
|
) => {
|
|
|
|
const state = useUserStore.getState();
|
|
|
|
let errorMessage: string | null = null;
|
|
|
|
|
|
|
|
try {
|
|
|
|
validators[fieldName].validateSync(value);
|
|
|
|
} catch (error: any) {
|
|
|
|
errorMessage = error.message;
|
|
|
|
}
|
|
|
|
|
|
|
|
useUserStore.setState(produce<UserStore>(state, state => {
|
|
|
|
if (!state.settingsFields) return;
|
|
|
|
|
|
|
|
state.settingsFields[fieldName].value = value || "";
|
|
|
|
state.settingsFields[fieldName].touched = true;
|
|
|
|
state.settingsFields[fieldName].error = errorMessage;
|
|
|
|
}));
|
|
|
|
};
|
|
|
|
|
|
|
|
export const sendUserData = async () => {
|
|
|
|
const state = useUserStore.getState();
|
|
|
|
if (!state.settingsFields) return;
|
|
|
|
|
|
|
|
const payload: PatchUserRequest = {};
|
|
|
|
|
|
|
|
for (const [fieldName, fieldValue] of Object.entries(state.settingsFields)) {
|
|
|
|
if (
|
|
|
|
fieldValue.value !== (state.user?.[fieldName as UserSettingsField] ?? "")
|
|
|
|
) payload[fieldName as UserSettingsField] = fieldValue.value;
|
|
|
|
}
|
|
|
|
|
|
|
|
const user = await patchUser(payload);
|
|
|
|
setUser(user);
|
|
|
|
};
|
2023-05-17 11:20:11 +00:00
|
|
|
|
2023-05-30 18:34:41 +00:00
|
|
|
const validators: Record<UserSettingsField, StringSchema> = {
|
|
|
|
name: string(),
|
|
|
|
email: string().email("Неверный email"),
|
|
|
|
surname: string(),
|
|
|
|
phoneNumber: string().matches(/^[+\d|\d]*$/, "Неверный номер телефона").min(6, "Номер телефона должен содержать минимум 6 символов"),
|
|
|
|
middleName: string(),
|
|
|
|
password: string().min(8, "Минимум 8 символов").matches(/^[.,:;-_+\d\w]+$/, "Некорректные символы в пароле"),
|
|
|
|
companyName: string(),
|
|
|
|
};
|