Merge branch 'users-pagination' into dev
This commit is contained in:
commit
f497252d6b
@ -26,6 +26,7 @@
|
|||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
"craco": "^0.0.3",
|
"craco": "^0.0.3",
|
||||||
"cypress": "^12.17.2",
|
"cypress": "^12.17.2",
|
||||||
|
"date-fns": "^3.3.1",
|
||||||
"dayjs": "^1.11.5",
|
"dayjs": "^1.11.5",
|
||||||
"formik": "^2.2.9",
|
"formik": "^2.2.9",
|
||||||
"immer": "^10.0.2",
|
"immer": "^10.0.2",
|
||||||
|
50
src/api/history/requests.ts
Normal file
50
src/api/history/requests.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import { makeRequest } from "@frontend/kitui";
|
||||||
|
|
||||||
|
import { parseAxiosError } from "@root/utils/parse-error";
|
||||||
|
|
||||||
|
type RawDetail = {
|
||||||
|
Key: string;
|
||||||
|
Value: number | string | RawDetail[];
|
||||||
|
};
|
||||||
|
|
||||||
|
type History = {
|
||||||
|
id: string;
|
||||||
|
userId: string;
|
||||||
|
comment: string;
|
||||||
|
key: string;
|
||||||
|
rawDetails: RawDetail[];
|
||||||
|
isDeleted: boolean;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type HistoryResponse = {
|
||||||
|
records: History[];
|
||||||
|
totalPages: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
const baseUrl = process.env.REACT_APP_DOMAIN + "/customer";
|
||||||
|
|
||||||
|
const getUserHistory = async (
|
||||||
|
accountId: string,
|
||||||
|
page: number
|
||||||
|
): Promise<[HistoryResponse | null, string?]> => {
|
||||||
|
try {
|
||||||
|
const historyResponse = await makeRequest<never, HistoryResponse>({
|
||||||
|
method: "GET",
|
||||||
|
url:
|
||||||
|
baseUrl +
|
||||||
|
`/history?page=${page}&limit=${100}&accountID=${accountId}&type=payCart`,
|
||||||
|
});
|
||||||
|
|
||||||
|
return [historyResponse];
|
||||||
|
} catch (nativeError) {
|
||||||
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
|
||||||
|
return [null, `Ошибка при получении пользователей. ${error}`];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const historyApi = {
|
||||||
|
getUserHistory,
|
||||||
|
};
|
43
src/api/history/swr.ts
Normal file
43
src/api/history/swr.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import useSWRInfinite from "swr/infinite";
|
||||||
|
import { enqueueSnackbar } from "notistack";
|
||||||
|
|
||||||
|
import { historyApi } from "./requests";
|
||||||
|
|
||||||
|
export function useHistory(accountId: string) {
|
||||||
|
const [currentPage, setCurrentPage] = useState<number>(1);
|
||||||
|
|
||||||
|
const swrResponse = useSWRInfinite(
|
||||||
|
() => `history-${currentPage}`,
|
||||||
|
async () => {
|
||||||
|
const [historyResponse, error] = await historyApi.getUserHistory(
|
||||||
|
accountId,
|
||||||
|
currentPage
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw new Error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!historyResponse) {
|
||||||
|
throw new Error("Empty history data");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentPage < historyResponse.totalPages) {
|
||||||
|
setCurrentPage((page) => page + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return historyResponse;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onError(err) {
|
||||||
|
console.log("Error fetching users", err);
|
||||||
|
enqueueSnackbar(err.message, { variant: "error" });
|
||||||
|
},
|
||||||
|
focusThrottleInterval: 60e3,
|
||||||
|
keepPreviousData: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return swrResponse;
|
||||||
|
}
|
@ -1,70 +0,0 @@
|
|||||||
import { makeRequest } from "@frontend/kitui";
|
|
||||||
|
|
||||||
import { parseAxiosError } from "@root/utils/parse-error";
|
|
||||||
|
|
||||||
import type { UserType } from "@root/api/roles";
|
|
||||||
|
|
||||||
type RegisteredUsersResponse = {
|
|
||||||
tatalPages: number;
|
|
||||||
users: UserType[];
|
|
||||||
};
|
|
||||||
|
|
||||||
const baseUrl = process.env.REACT_APP_DOMAIN + "/user";
|
|
||||||
|
|
||||||
export const getUserInfo = async (
|
|
||||||
id: string
|
|
||||||
): Promise<[UserType | null, string?]> => {
|
|
||||||
try {
|
|
||||||
const userInfoResponse = await makeRequest<never, UserType>({
|
|
||||||
url: `${baseUrl}/${id}`,
|
|
||||||
method: "GET",
|
|
||||||
useToken: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
return [userInfoResponse];
|
|
||||||
} catch (nativeError) {
|
|
||||||
const [error] = parseAxiosError(nativeError);
|
|
||||||
|
|
||||||
return [null, `Ошибка получения информации о пользователе. ${error}`];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getRegisteredUsers = async (): Promise<
|
|
||||||
[RegisteredUsersResponse | null, string?]
|
|
||||||
> => {
|
|
||||||
try {
|
|
||||||
const registeredUsersResponse = await makeRequest<
|
|
||||||
never,
|
|
||||||
RegisteredUsersResponse
|
|
||||||
>({
|
|
||||||
method: "get",
|
|
||||||
url: baseUrl + "/",
|
|
||||||
});
|
|
||||||
|
|
||||||
return [registeredUsersResponse];
|
|
||||||
} catch (nativeError) {
|
|
||||||
const [error] = parseAxiosError(nativeError);
|
|
||||||
|
|
||||||
return [null, `Ошибка при получении пользователей. ${error}`];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getManagersList = async (): Promise<
|
|
||||||
[RegisteredUsersResponse | null, string?]
|
|
||||||
> => {
|
|
||||||
try {
|
|
||||||
const managersListResponse = await makeRequest<
|
|
||||||
never,
|
|
||||||
RegisteredUsersResponse
|
|
||||||
>({
|
|
||||||
method: "get",
|
|
||||||
url: baseUrl + "/",
|
|
||||||
});
|
|
||||||
|
|
||||||
return [managersListResponse];
|
|
||||||
} catch (nativeError) {
|
|
||||||
const [error] = parseAxiosError(nativeError);
|
|
||||||
|
|
||||||
return [null, `Ошибка при получении менеджеров. ${error}`];
|
|
||||||
}
|
|
||||||
};
|
|
89
src/api/user/requests.ts
Normal file
89
src/api/user/requests.ts
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import { makeRequest } from "@frontend/kitui";
|
||||||
|
|
||||||
|
import { parseAxiosError } from "@root/utils/parse-error";
|
||||||
|
|
||||||
|
import type { UserType } from "@root/api/roles";
|
||||||
|
|
||||||
|
export type UsersListResponse = {
|
||||||
|
totalPages: number;
|
||||||
|
users: UserType[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const baseUrl = process.env.REACT_APP_DOMAIN + "/user";
|
||||||
|
|
||||||
|
const getUserInfo = async (id: string): Promise<[UserType | null, string?]> => {
|
||||||
|
try {
|
||||||
|
const userInfoResponse = await makeRequest<never, UserType>({
|
||||||
|
url: `${baseUrl}/${id}`,
|
||||||
|
method: "GET",
|
||||||
|
useToken: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
return [userInfoResponse];
|
||||||
|
} catch (nativeError) {
|
||||||
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
|
||||||
|
return [null, `Ошибка получения информации о пользователе. ${error}`];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getUserList = async (
|
||||||
|
page = 1,
|
||||||
|
limit = 10
|
||||||
|
): Promise<[UsersListResponse | null, string?]> => {
|
||||||
|
try {
|
||||||
|
const userResponse = await makeRequest<never, UsersListResponse>({
|
||||||
|
method: "get",
|
||||||
|
url: baseUrl + `/?page=${page}&limit=${limit}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
return [userResponse];
|
||||||
|
} catch (nativeError) {
|
||||||
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
|
||||||
|
return [null, `Ошибка при получении пользователей. ${error}`];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getManagerList = async (
|
||||||
|
page = 1,
|
||||||
|
limit = 10
|
||||||
|
): Promise<[UsersListResponse | null, string?]> => {
|
||||||
|
try {
|
||||||
|
const managerResponse = await makeRequest<never, UsersListResponse>({
|
||||||
|
method: "get",
|
||||||
|
url: baseUrl + `/?page=${page}&limit=${limit}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
return [managerResponse];
|
||||||
|
} catch (nativeError) {
|
||||||
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
|
||||||
|
return [null, `Ошибка при получении менеджеров. ${error}`];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getAdminList = async (
|
||||||
|
page = 1,
|
||||||
|
limit = 10
|
||||||
|
): Promise<[UsersListResponse | null, string?]> => {
|
||||||
|
try {
|
||||||
|
const adminResponse = await makeRequest<never, UsersListResponse>({
|
||||||
|
method: "get",
|
||||||
|
url: baseUrl + `/?page=${page}&limit=${limit}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
return [adminResponse];
|
||||||
|
} catch (nativeError) {
|
||||||
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
|
||||||
|
return [null, `Ошибка при получении админов. ${error}`];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const userApi = {
|
||||||
|
getUserInfo,
|
||||||
|
getUserList,
|
||||||
|
getManagerList,
|
||||||
|
getAdminList,
|
||||||
|
};
|
104
src/api/user/swr.ts
Normal file
104
src/api/user/swr.ts
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import { useRef } from "react";
|
||||||
|
import useSwr from "swr";
|
||||||
|
import { enqueueSnackbar } from "notistack";
|
||||||
|
|
||||||
|
import { userApi } from "./requests";
|
||||||
|
|
||||||
|
export function useAdmins(page: number, pageSize: number) {
|
||||||
|
const adminPagesRef = useRef<number>(0);
|
||||||
|
|
||||||
|
const swrResponse = useSwr(
|
||||||
|
["admin", page, pageSize],
|
||||||
|
async ([_, page, pageSize]) => {
|
||||||
|
const [adminResponse, error] = await userApi.getManagerList(
|
||||||
|
page,
|
||||||
|
pageSize
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw new Error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
adminPagesRef.current = adminResponse?.totalPages || 1;
|
||||||
|
return adminResponse;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onError(err) {
|
||||||
|
console.log("Error fetching users", err);
|
||||||
|
enqueueSnackbar(err.message, { variant: "error" });
|
||||||
|
},
|
||||||
|
focusThrottleInterval: 60e3,
|
||||||
|
keepPreviousData: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...swrResponse,
|
||||||
|
adminPages: adminPagesRef.current,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useManagers(page: number, pageSize: number) {
|
||||||
|
const managerPagesRef = useRef<number>(0);
|
||||||
|
|
||||||
|
const swrResponse = useSwr(
|
||||||
|
["manager", page, pageSize],
|
||||||
|
async ([_, page, pageSize]) => {
|
||||||
|
const [managerResponse, error] = await userApi.getManagerList(
|
||||||
|
page,
|
||||||
|
pageSize
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw new Error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
managerPagesRef.current = managerResponse?.totalPages || 1;
|
||||||
|
return managerResponse;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onError(err) {
|
||||||
|
console.log("Error fetching users", err);
|
||||||
|
enqueueSnackbar(err.message, { variant: "error" });
|
||||||
|
},
|
||||||
|
focusThrottleInterval: 60e3,
|
||||||
|
keepPreviousData: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...swrResponse,
|
||||||
|
managerPages: managerPagesRef.current,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useUsers(page: number, pageSize: number) {
|
||||||
|
const userPagesRef = useRef<number>(0);
|
||||||
|
|
||||||
|
const swrResponse = useSwr(
|
||||||
|
["users", page, pageSize],
|
||||||
|
async ([_, page, pageSize]) => {
|
||||||
|
const [userResponse, error] = await userApi.getUserList(page, pageSize);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw new Error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
userPagesRef.current = userResponse?.totalPages || 1;
|
||||||
|
return userResponse;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onError(err) {
|
||||||
|
console.log("Error fetching users", err);
|
||||||
|
enqueueSnackbar(err.message, { variant: "error" });
|
||||||
|
},
|
||||||
|
focusThrottleInterval: 60e3,
|
||||||
|
keepPreviousData: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...swrResponse,
|
||||||
|
userPagesCount: userPagesRef.current,
|
||||||
|
};
|
||||||
|
}
|
@ -42,11 +42,21 @@ const columns: GridColDef<UserType, string>[] = [
|
|||||||
interface Props {
|
interface Props {
|
||||||
handleSelectionChange: (selectionModel: GridSelectionModel) => void;
|
handleSelectionChange: (selectionModel: GridSelectionModel) => void;
|
||||||
users: UserType[];
|
users: UserType[];
|
||||||
|
page: number;
|
||||||
|
setPage: (page: number) => void;
|
||||||
|
pageSize: number;
|
||||||
|
pagesCount: number;
|
||||||
|
onPageSizeChange?: (count: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ServiceUsersDG({
|
export default function ServiceUsersDG({
|
||||||
handleSelectionChange,
|
handleSelectionChange,
|
||||||
users = [],
|
users = [],
|
||||||
|
page,
|
||||||
|
setPage,
|
||||||
|
pageSize = 10,
|
||||||
|
pagesCount = 1,
|
||||||
|
onPageSizeChange,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
@ -60,6 +70,13 @@ export default function ServiceUsersDG({
|
|||||||
rows={users}
|
rows={users}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
components={{ Toolbar: GridToolbar }}
|
components={{ Toolbar: GridToolbar }}
|
||||||
|
rowCount={pageSize * pagesCount}
|
||||||
|
rowsPerPageOptions={[10, 25, 50, 100]}
|
||||||
|
paginationMode="server"
|
||||||
|
page={page}
|
||||||
|
pageSize={pageSize}
|
||||||
|
onPageChange={setPage}
|
||||||
|
onPageSizeChange={onPageSizeChange}
|
||||||
onSelectionModelChange={handleSelectionChange}
|
onSelectionModelChange={handleSelectionChange}
|
||||||
onCellClick={({ row }, event) => {
|
onCellClick={({ row }, event) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
@ -23,14 +23,24 @@ import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
|||||||
import ConditionalRender from "@root/pages/Setting/ConditionalRender";
|
import ConditionalRender from "@root/pages/Setting/ConditionalRender";
|
||||||
import ModalUser from "@root/pages/dashboard/ModalUser";
|
import ModalUser from "@root/pages/dashboard/ModalUser";
|
||||||
import ServiceUsersDG from "./ServiceUsersDG";
|
import ServiceUsersDG from "./ServiceUsersDG";
|
||||||
import { getRegisteredUsers, getManagersList } from "@root/api/user";
|
import { useUsers, useManagers, useAdmins } from "@root/api/user/swr";
|
||||||
import { getRoles } from "@root/api/privilegies";
|
import { getRoles } from "@root/api/privilegies";
|
||||||
|
|
||||||
import { getRoles_mock, TMockData } from "../../../api/roles";
|
import { getRoles_mock, TMockData } from "../../../api/roles";
|
||||||
|
|
||||||
import theme from "../../../theme";
|
import theme from "../../../theme";
|
||||||
|
|
||||||
import type { UserType } from "../../../api/roles";
|
type Pages = {
|
||||||
|
adminPage: number;
|
||||||
|
managerPage: number;
|
||||||
|
userPage: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type PagesSize = {
|
||||||
|
adminPageSize: number;
|
||||||
|
managerPageSize: number;
|
||||||
|
userPageSize: number;
|
||||||
|
};
|
||||||
|
|
||||||
const Users: React.FC = () => {
|
const Users: React.FC = () => {
|
||||||
const radioboxes = ["admin", "manager", "user"];
|
const radioboxes = ["admin", "manager", "user"];
|
||||||
@ -39,11 +49,11 @@ const Users: React.FC = () => {
|
|||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const [data, setData] = React.useState<TMockData>([]);
|
const [mockData, setMockData] = React.useState<TMockData>([]);
|
||||||
|
|
||||||
const handleChangeData = () => {
|
const handleChangeData = () => {
|
||||||
getRoles_mock().then((mockdata) => {
|
getRoles_mock().then((mockdata) => {
|
||||||
setData(mockdata);
|
setMockData(mockdata);
|
||||||
setAccordionText(mockdata[0].desc || "");
|
setAccordionText(mockdata[0].desc || "");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -53,7 +63,7 @@ const Users: React.FC = () => {
|
|||||||
|
|
||||||
const handleChange = (value: string) => {
|
const handleChange = (value: string) => {
|
||||||
setSelectedValue(value);
|
setSelectedValue(value);
|
||||||
setAccordionText(data.find(({ name }) => name === value)?.desc || "");
|
setAccordionText(mockData.find(({ name }) => name === value)?.desc || "");
|
||||||
|
|
||||||
if (selectedValue === "manager") {
|
if (selectedValue === "manager") {
|
||||||
}
|
}
|
||||||
@ -64,12 +74,33 @@ const Users: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const [roles, setRoles] = React.useState<TMockData>([]);
|
const [roles, setRoles] = React.useState<TMockData>([]);
|
||||||
const [users, setUsers] = React.useState<UserType[]>([]);
|
|
||||||
const [manager, setManager] = React.useState<UserType[]>([]);
|
const [page, setPage] = useState<Pages>({
|
||||||
|
adminPage: 0,
|
||||||
|
managerPage: 0,
|
||||||
|
userPage: 0,
|
||||||
|
});
|
||||||
|
const [pageSize, setPageSize] = useState<PagesSize>({
|
||||||
|
adminPageSize: 10,
|
||||||
|
managerPageSize: 10,
|
||||||
|
userPageSize: 10,
|
||||||
|
});
|
||||||
const [openUserModal, setOpenUserModal] = useState<boolean>(false);
|
const [openUserModal, setOpenUserModal] = useState<boolean>(false);
|
||||||
const [activeUserId, setActiveUserId] = useState<string>("");
|
const [activeUserId, setActiveUserId] = useState<string>("");
|
||||||
|
|
||||||
const { userId } = useParams();
|
const { userId } = useParams();
|
||||||
|
const { data: adminData, adminPages } = useAdmins(
|
||||||
|
page.adminPage + 1,
|
||||||
|
pageSize.adminPageSize
|
||||||
|
);
|
||||||
|
const { data: managerData, managerPages } = useManagers(
|
||||||
|
page.managerPage + 1,
|
||||||
|
pageSize.managerPageSize
|
||||||
|
);
|
||||||
|
const { data: userData, userPagesCount } = useUsers(
|
||||||
|
page.userPage + 1,
|
||||||
|
pageSize.userPageSize
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
handleChangeData();
|
handleChangeData();
|
||||||
@ -88,18 +119,6 @@ const Users: React.FC = () => {
|
|||||||
}, [userId]);
|
}, [userId]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getManagersList().then(([managersListResponse]) => {
|
|
||||||
if (managersListResponse) {
|
|
||||||
setManager(managersListResponse.users);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
getRegisteredUsers().then(([registeredUsersResponse]) => {
|
|
||||||
if (registeredUsersResponse) {
|
|
||||||
setUsers(registeredUsersResponse.users);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
getRoles().then(([rolesResponse]) => {
|
getRoles().then(([rolesResponse]) => {
|
||||||
if (rolesResponse) {
|
if (rolesResponse) {
|
||||||
setRoles(rolesResponse);
|
setRoles(rolesResponse);
|
||||||
@ -210,8 +229,8 @@ const Users: React.FC = () => {
|
|||||||
</TableHead>
|
</TableHead>
|
||||||
|
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{data.length ? (
|
{mockData.length ? (
|
||||||
data.map(function (item, index) {
|
mockData.map(function (item, index) {
|
||||||
return (
|
return (
|
||||||
<TableRow
|
<TableRow
|
||||||
sx={{
|
sx={{
|
||||||
@ -394,16 +413,49 @@ const Users: React.FC = () => {
|
|||||||
<ConditionalRender
|
<ConditionalRender
|
||||||
isLoading={false}
|
isLoading={false}
|
||||||
role={selectedValue}
|
role={selectedValue}
|
||||||
|
childrenAdmin={
|
||||||
|
<ServiceUsersDG
|
||||||
|
users={adminData?.users.length ? adminData.users : []}
|
||||||
|
page={page.adminPage}
|
||||||
|
setPage={(adminPage) =>
|
||||||
|
setPage((pages) => ({ ...pages, adminPage }))
|
||||||
|
}
|
||||||
|
pagesCount={adminPages}
|
||||||
|
pageSize={pageSize.adminPageSize}
|
||||||
|
handleSelectionChange={setSelectedTariffs}
|
||||||
|
onPageSizeChange={(adminPageSize) =>
|
||||||
|
setPageSize((pageSize) => ({ ...pageSize, adminPageSize }))
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
childrenManager={
|
childrenManager={
|
||||||
<ServiceUsersDG
|
<ServiceUsersDG
|
||||||
users={manager}
|
users={managerData?.users.length ? managerData.users : []}
|
||||||
|
page={page.managerPage}
|
||||||
|
setPage={(managerPage) =>
|
||||||
|
setPage((pages) => ({ ...pages, managerPage }))
|
||||||
|
}
|
||||||
|
pagesCount={managerPages}
|
||||||
|
pageSize={pageSize.managerPageSize}
|
||||||
handleSelectionChange={setSelectedTariffs}
|
handleSelectionChange={setSelectedTariffs}
|
||||||
|
onPageSizeChange={(managerPageSize) =>
|
||||||
|
setPageSize((pageSize) => ({ ...pageSize, managerPageSize }))
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
childrenUser={
|
childrenUser={
|
||||||
<ServiceUsersDG
|
<ServiceUsersDG
|
||||||
users={users}
|
users={userData?.users.length ? userData.users : []}
|
||||||
|
page={page.userPage}
|
||||||
|
setPage={(userPage) =>
|
||||||
|
setPage((pages) => ({ ...pages, userPage }))
|
||||||
|
}
|
||||||
|
pagesCount={userPagesCount}
|
||||||
|
pageSize={pageSize.userPageSize}
|
||||||
handleSelectionChange={setSelectedTariffs}
|
handleSelectionChange={setSelectedTariffs}
|
||||||
|
onPageSizeChange={(userPageSize) =>
|
||||||
|
setPageSize((pageSize) => ({ ...pageSize, userPageSize }))
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { Box, useTheme, useMediaQuery } from "@mui/material";
|
import { Box, useTheme, useMediaQuery } from "@mui/material";
|
||||||
import { DataGrid } from "@mui/x-data-grid";
|
import { DataGrid } from "@mui/x-data-grid";
|
||||||
|
import { format } from "date-fns";
|
||||||
|
|
||||||
|
import { useHistory } from "@root/api/history/swr";
|
||||||
import { scrollBlock } from "@root/utils/scrollBlock";
|
import { scrollBlock } from "@root/utils/scrollBlock";
|
||||||
|
|
||||||
import forwardIcon from "@root/assets/icons/forward.svg";
|
import forwardIcon from "@root/assets/icons/forward.svg";
|
||||||
@ -9,6 +11,10 @@ import forwardIcon from "@root/assets/icons/forward.svg";
|
|||||||
import type { ChangeEvent } from "react";
|
import type { ChangeEvent } from "react";
|
||||||
import type { GridColDef } from "@mui/x-data-grid";
|
import type { GridColDef } from "@mui/x-data-grid";
|
||||||
|
|
||||||
|
type PurchaseTabProps = {
|
||||||
|
userId: string;
|
||||||
|
};
|
||||||
|
|
||||||
const COLUMNS: GridColDef[] = [
|
const COLUMNS: GridColDef[] = [
|
||||||
{
|
{
|
||||||
field: "date",
|
field: "date",
|
||||||
@ -68,12 +74,22 @@ const ROWS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const PurchaseTab = () => {
|
export const PurchaseTab = ({ userId }: PurchaseTabProps) => {
|
||||||
const [canScrollToRight, setCanScrollToRight] = useState<boolean>(true);
|
const [canScrollToRight, setCanScrollToRight] = useState<boolean>(true);
|
||||||
const [canScrollToLeft, setCanScrollToLeft] = useState<boolean>(false);
|
const [canScrollToLeft, setCanScrollToLeft] = useState<boolean>(false);
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const smallScreen = useMediaQuery(theme.breakpoints.down(830));
|
const smallScreen = useMediaQuery(theme.breakpoints.down(830));
|
||||||
const gridContainer = useRef<HTMLDivElement>(null);
|
const gridContainer = useRef<HTMLDivElement>(null);
|
||||||
|
const { data: historyData } = useHistory(userId);
|
||||||
|
|
||||||
|
const rows =
|
||||||
|
historyData?.[0].records.map((history) => ({
|
||||||
|
id: history.id,
|
||||||
|
date: format(history.updatedAt, "dd.MM.yyyy"),
|
||||||
|
time: format(history.updatedAt, "HH:mm"),
|
||||||
|
product: "",
|
||||||
|
amount: "",
|
||||||
|
})) ?? [];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleScroll = (nativeEvent: unknown) => {
|
const handleScroll = (nativeEvent: unknown) => {
|
||||||
@ -145,10 +161,8 @@ export const PurchaseTab = () => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DataGrid
|
<DataGrid
|
||||||
rows={ROWS}
|
rows={rows}
|
||||||
columns={COLUMNS}
|
columns={COLUMNS}
|
||||||
pageSize={5}
|
|
||||||
rowsPerPageOptions={[5]}
|
|
||||||
hideFooter
|
hideFooter
|
||||||
disableColumnMenu
|
disableColumnMenu
|
||||||
disableSelectionOnClick
|
disableSelectionOnClick
|
||||||
@ -239,3 +253,62 @@ export const PurchaseTab = () => {
|
|||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const a = {
|
||||||
|
id: "65e4f1b157004756bc5bb15c",
|
||||||
|
userId: "64eb6ce57047f28fdabf69ec",
|
||||||
|
comment: "Успешная оплата корзины",
|
||||||
|
key: "payCart",
|
||||||
|
rawDetails: [
|
||||||
|
[
|
||||||
|
{ Key: "id", Value: "65e4f1881747c1eea8007d3b" },
|
||||||
|
{
|
||||||
|
Key: "name",
|
||||||
|
Value:
|
||||||
|
"Количество Заявок, Скрытие шильдика в опроснике, 2024-03-03T21:54:16.434Z",
|
||||||
|
},
|
||||||
|
{ Key: "price", Value: 0 },
|
||||||
|
{ Key: "iscustom", Value: true },
|
||||||
|
{
|
||||||
|
Key: "privileges",
|
||||||
|
Value: [
|
||||||
|
[
|
||||||
|
{ Key: "id", Value: "" },
|
||||||
|
{ Key: "name", Value: "Количество Заявок" },
|
||||||
|
{ Key: "privilegeid", Value: "quizCnt" },
|
||||||
|
{ Key: "servicekey", Value: "squiz" },
|
||||||
|
{
|
||||||
|
Key: "description",
|
||||||
|
Value: "Количество полных прохождений опросов",
|
||||||
|
},
|
||||||
|
{ Key: "amount", Value: 100 },
|
||||||
|
{ Key: "type", Value: "count" },
|
||||||
|
{ Key: "value", Value: "заявка" },
|
||||||
|
{ Key: "price", Value: 2000 },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ Key: "id", Value: "" },
|
||||||
|
{ Key: "name", Value: "Скрытие шильдика в опроснике" },
|
||||||
|
{ Key: "privilegeid", Value: "squizHideBadge" },
|
||||||
|
{ Key: "servicekey", Value: "squiz" },
|
||||||
|
{
|
||||||
|
Key: "description",
|
||||||
|
Value: "Количество дней скрытия шильдика в опроснике",
|
||||||
|
},
|
||||||
|
{ Key: "amount", Value: 30 },
|
||||||
|
{ Key: "type", Value: "day" },
|
||||||
|
{ Key: "value", Value: "день" },
|
||||||
|
{ Key: "price", Value: 0 },
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{ Key: "deleted", Value: false },
|
||||||
|
{ Key: "createdat", Value: "2024-03-03T21:54:16.825Z" },
|
||||||
|
{ Key: "updatedat", Value: "2024-03-03T21:54:16.825Z" },
|
||||||
|
{ Key: "deletedat", Value: null },
|
||||||
|
],
|
||||||
|
],
|
||||||
|
isDeleted: false,
|
||||||
|
createdAt: "2024-03-03T21:54:57.433Z",
|
||||||
|
updatedAt: "2024-03-03T21:54:57.433Z",
|
||||||
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { Box, Typography, useTheme, useMediaQuery } from "@mui/material";
|
import { Box, Typography, useTheme, useMediaQuery } from "@mui/material";
|
||||||
|
|
||||||
import { getUserInfo } from "@root/api/user";
|
import { userApi } from "@root/api/user/requests";
|
||||||
import { getAccountInfo } from "@root/api/account";
|
import { getAccountInfo } from "@root/api/account";
|
||||||
|
|
||||||
import type { UserType } from "@root/api/roles";
|
import type { UserType } from "@root/api/roles";
|
||||||
@ -19,7 +19,7 @@ export const UserTab = ({ userId }: UserTabProps) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (userId) {
|
if (userId) {
|
||||||
getUserInfo(userId).then(([userInfo]) => setUser(userInfo));
|
userApi.getUserInfo(userId).then(([userInfo]) => setUser(userInfo));
|
||||||
getAccountInfo(userId).then(([accountsInfo]) => setAccount(accountsInfo));
|
getAccountInfo(userId).then(([accountsInfo]) => setAccount(accountsInfo));
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
@ -191,7 +191,7 @@ const ModalUser = ({ open, onClose, userId }: ModalUserProps) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{value === 0 && <UserTab userId={userId} />}
|
{value === 0 && <UserTab userId={userId} />}
|
||||||
{value === 1 && <PurchaseTab />}
|
{value === 1 && <PurchaseTab userId={userId} />}
|
||||||
{value === 2 && <TransactionsTab />}
|
{value === 2 && <TransactionsTab />}
|
||||||
{value === 3 && <VerificationTab userId={userId} />}
|
{value === 3 && <VerificationTab userId={userId} />}
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -5028,6 +5028,11 @@ data-urls@^2.0.0:
|
|||||||
whatwg-mimetype "^2.3.0"
|
whatwg-mimetype "^2.3.0"
|
||||||
whatwg-url "^8.0.0"
|
whatwg-url "^8.0.0"
|
||||||
|
|
||||||
|
date-fns@^3.3.1:
|
||||||
|
version "3.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-3.3.1.tgz#7581daca0892d139736697717a168afbb908cfed"
|
||||||
|
integrity sha512-y8e109LYGgoQDveiEBD3DYXKba1jWf5BA8YU1FL5Tvm0BTdEfy54WLCwnuYWZNnzzvALy/QQ4Hov+Q9RVRv+Zw==
|
||||||
|
|
||||||
dayjs@^1.10.4:
|
dayjs@^1.10.4:
|
||||||
version "1.11.9"
|
version "1.11.9"
|
||||||
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.9.tgz#9ca491933fadd0a60a2c19f6c237c03517d71d1a"
|
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.9.tgz#9ca491933fadd0a60a2c19f6c237c03517d71d1a"
|
||||||
|
Loading…
Reference in New Issue
Block a user