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