gitscope
← marzneshin / v0.1.1 / app/dashboard/src/stores/users.store.ts
https://dev.kronoz.win/r/marzneshin.git
app/dashboard/src/stores/users.store.ts · TypeScript
Blame Raw
  1import { User, UserCreate } from 'types/user';
  2import { subscribeWithSelector } from 'zustand/middleware';
  3import { create } from 'zustand';
  4import { pageSizeManagers } from 'utils/userPreferenceStorage';
  5import { fetch } from 'service/http';
  6import { useServices, useDashboard } from 'stores';
  7import { StatisticsQueryKey } from 'components/statistics-card';
  8import { queryClient } from 'service/react-query';
  9import { UsersFilterType, FilterUsageType } from 'types/filter';
 10
 11type UsersStateType = {
 12  isCreatingNewUser: boolean;
 13  editingUser: User | null | undefined;
 14  deletingUser: User | null;
 15  users: {
 16    users: User[];
 17    total: number;
 18  };
 19  usersFilters: UsersFilterType;
 20  resetUsageUser: User | null;
 21  revokeSubscriptionUser: User | null;
 22  isResetingAllUsage: boolean;
 23  subscribeUrl: string | null;
 24  QRcodeLinks: string[] | null;
 25  setQRCode: (links: string[] | null) => void;
 26  setSubLink: (subscribeURL: string | null) => void;
 27  onResetAllUsage: (isResetingAllUsage: boolean) => void;
 28  resetAllUsage: () => Promise<void>;
 29  resetDataUsage: (user: User) => Promise<void>;
 30  revokeSubscription: (user: User) => Promise<void>;
 31  onCreateUser: (isOpen: boolean) => void;
 32  onEditingUser: (user: User | null) => void;
 33  onDeletingUser: (user: User | null) => void;
 34  refetchUsers: () => void;
 35  onFilterChange: (filters: Partial<UsersFilterType>) => void;
 36  deleteUser: (user: User) => Promise<void>;
 37  createUser: (user: UserCreate) => Promise<void>;
 38  editUser: (user: UserCreate) => Promise<void>;
 39  fetchUserUsage: (user: User, query: FilterUsageType) => Promise<void>;
 40}
 41
 42export const fetchUsers = async (query: UsersFilterType): Promise<User[]> => {
 43  for (const key in query) {
 44    if (!query[key as keyof UsersFilterType]) delete query[key as keyof UsersFilterType];
 45  }
 46  useDashboard.setState({ loading: true });
 47  return fetch('/users', { query })
 48    .then((users) => {
 49      for (let i = 0; i < users.users.length; i++) {
 50        users.users[i].service = users.users[i].service_ids;
 51      }
 52      useUsers.setState({ users });
 53      return users;
 54    })
 55    .finally(() => {
 56      useDashboard.setState({ loading: false });
 57    });
 58};
 59
 60export const useUsers = create(subscribeWithSelector<UsersStateType>((set, get) => ({
 61  editingUser: null,
 62  deletingUser: null,
 63  isCreatingNewUser: false,
 64  users: {
 65    users: [],
 66    total: 0,
 67  },
 68  resetUsageUser: null,
 69  revokeSubscriptionUser: null,
 70  isResetingAllUsage: false,
 71  usersFilters: {
 72    username: '',
 73    limit: pageSizeManagers.users.getPageSize(),
 74    sort: '-created_at',
 75  },
 76  QRcodeLinks: null,
 77  subscribeUrl: null,
 78  setQRCode: (QRcodeLinks) => {
 79    set({ QRcodeLinks });
 80  },
 81  setSubLink: (subscribeUrl) => {
 82    set({ subscribeUrl });
 83  },
 84  refetchUsers: () => {
 85    fetchUsers(get().usersFilters);
 86  },
 87  resetAllUsage: async () => {
 88    return fetch('/users/reset', { method: 'POST' }).then(() => {
 89      get().onResetAllUsage(false);
 90      get().refetchUsers();
 91    });
 92  },
 93  onResetAllUsage: (isResetingAllUsage) => set({ isResetingAllUsage }),
 94  onCreateUser: (isCreatingNewUser) => set({ isCreatingNewUser }),
 95  onEditingUser: (editingUser) => {
 96    set({ editingUser });
 97  },
 98  onDeletingUser: (deletingUser) => {
 99    set({ deletingUser });
100  },
101  onFilterChange: (filters) => {
102    set({
103      usersFilters: {
104        ...get().usersFilters,
105        ...filters,
106      },
107    });
108    get().refetchUsers();
109  },
110  deleteUser: async (user: User) => {
111    set({ editingUser: null });
112    return fetch(`/users/${user.username}`, { method: 'DELETE' }).then(() => {
113      set({ deletingUser: null });
114      get().refetchUsers();
115      queryClient.invalidateQueries(StatisticsQueryKey);
116    });
117  },
118  createUser: async (body: UserCreate) => {
119    return fetch('/users', { method: 'POST', body }).then(() => {
120      set({ editingUser: null });
121      get().refetchUsers();
122      useServices.getState().refetchServices();
123      queryClient.invalidateQueries(StatisticsQueryKey);
124    });
125  },
126  editUser: async (body: UserCreate) => {
127    return fetch(`/users/${body.username}`, { method: 'PUT', body }).then(
128      () => {
129        get().onEditingUser(null);
130        get().refetchUsers();
131      }
132    );
133  },
134
135  fetchUserUsage: (body: User, query: FilterUsageType) => {
136    for (const key in query) {
137      if (!query[key as keyof FilterUsageType])
138        delete query[key as keyof FilterUsageType];
139    }
140    return fetch(`/users/${body.username}/usage`, { method: 'GET', query });
141  },
142  resetDataUsage: async (user) => {
143    return fetch(`/users/${user.username}/reset`, { method: 'POST' }).then(
144      () => {
145        set({ resetUsageUser: null });
146        get().refetchUsers();
147      }
148    );
149  },
150  revokeSubscription: async (user) => {
151    return fetch(`/users/${user.username}/revoke_sub`, {
152      method: 'POST',
153    }).then((user) => {
154      set({ revokeSubscriptionUser: null, editingUser: user });
155      get().refetchUsers();
156    });
157  },
158})));