From 1f0a6488762b72caad5bc282001d3d71addd4ce7 Mon Sep 17 00:00:00 2001 From: IlyaDoronin Date: Tue, 25 Jul 2023 10:47:20 +0300 Subject: [PATCH] feat: UserTab desktop --- src/api/roles.ts | 10 +- src/assets/icons/check.svg | 4 + src/assets/icons/package.svg | 3 + src/assets/icons/transactions.svg | 3 + src/assets/icons/user.svg | 4 + src/index.tsx | 2 + .../dashboard/Content/ServiceUsersDG.tsx | 43 ++- src/pages/dashboard/Content/Users.tsx | 19 +- src/pages/dashboard/ModalUser/PurchaseTab.tsx | 117 +++++++ src/pages/dashboard/ModalUser/UserTab.tsx | 65 ++++ src/pages/dashboard/ModalUser/index.tsx | 285 +++++++++--------- src/pages/dashboard/index.tsx | 1 - src/theme.ts | 9 +- 13 files changed, 394 insertions(+), 171 deletions(-) create mode 100644 src/assets/icons/check.svg create mode 100644 src/assets/icons/package.svg create mode 100644 src/assets/icons/transactions.svg create mode 100644 src/assets/icons/user.svg create mode 100644 src/pages/dashboard/ModalUser/PurchaseTab.tsx create mode 100644 src/pages/dashboard/ModalUser/UserTab.tsx diff --git a/src/api/roles.ts b/src/api/roles.ts index 78f454e..6310a2a 100644 --- a/src/api/roles.ts +++ b/src/api/roles.ts @@ -21,7 +21,15 @@ export const MOCK_DATA_USERS = [ export type TMockData = typeof MOCK_DATA_USERS; -export type UsersType = { login: string; email: string; phoneNumber: string; isDeleted: boolean; createdAt: string }[]; +export type UserType = { + _id: string; + login: string; + email: string; + phoneNumber: string; + isDeleted: boolean; + createdAt: string; + updatedAt: string; +}; export const getRoles_mock = (): Promise => { return new Promise((resolve) => { diff --git a/src/assets/icons/check.svg b/src/assets/icons/check.svg new file mode 100644 index 0000000..6f0e734 --- /dev/null +++ b/src/assets/icons/check.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/icons/package.svg b/src/assets/icons/package.svg new file mode 100644 index 0000000..50f570a --- /dev/null +++ b/src/assets/icons/package.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/transactions.svg b/src/assets/icons/transactions.svg new file mode 100644 index 0000000..0eb5dc3 --- /dev/null +++ b/src/assets/icons/transactions.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/user.svg b/src/assets/icons/user.svg new file mode 100644 index 0000000..a895504 --- /dev/null +++ b/src/assets/icons/user.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/index.tsx b/src/index.tsx index cb0597d..c7da5db 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -17,6 +17,7 @@ import Sections from "@pages/Sections"; import Dashboard from "@pages/dashboard"; import Error404 from "@pages/Error404"; import Users from "@pages/dashboard/Content/Users"; +import ModalUser from "@root/pages/dashboard/ModalUser"; import Entities from "@pages/dashboard/Content/Entities"; import Tariffs from "@pages/dashboard/Content/Tariffs"; import DiscountManagement from "@root/pages/dashboard/Content/DiscountManagement/DiscountManagement"; @@ -29,6 +30,7 @@ import "./index.css"; const componentsArray = [ ["/users", ], + ["/users/:userId", ], ["/entities", ], ["/tariffs", ], ["/discounts", ], diff --git a/src/pages/dashboard/Content/ServiceUsersDG.tsx b/src/pages/dashboard/Content/ServiceUsersDG.tsx index be71bc2..c851255 100644 --- a/src/pages/dashboard/Content/ServiceUsersDG.tsx +++ b/src/pages/dashboard/Content/ServiceUsersDG.tsx @@ -1,9 +1,10 @@ import { GridColDef, GridSelectionModel, GridToolbar } from "@mui/x-data-grid"; import { Skeleton } from "@mui/material"; +import { useNavigate } from "react-router-dom"; import DataGrid from "@kitUI/datagrid"; -import type { UsersType } from "@root/api/roles"; +import type { UserType } from "@root/api/roles"; const columns: GridColDef[] = [ { field: "login", headerName: "Логин", width: 100 }, @@ -15,14 +16,17 @@ const columns: GridColDef[] = [ interface Props { handleSelectionChange: (selectionModel: GridSelectionModel) => void; - users: any + users: UserType[]; } -export default function ServiceUsersDG({ handleSelectionChange, users }: Props) { - if (!users) { - return Loading...; - } - const gridData = users.users.map((user:any) => ({ +export default function ServiceUsersDG({ + handleSelectionChange, + users = [], +}: Props) { + const navigate = useNavigate(); + + const gridData = users.map((user) => ({ + id: user._id, login: user.login, email: user.email, phoneNumber: user.phoneNumber, @@ -31,14 +35,21 @@ export default function ServiceUsersDG({ handleSelectionChange, users }: Props) })); return ( - users.login} - checkboxSelection={true} - rows={gridData} - columns={columns} - components={{ Toolbar: GridToolbar }} - onSelectionModelChange={handleSelectionChange} - /> + <> + {users.length ? ( + users.login} + checkboxSelection={true} + rows={gridData} + columns={columns} + components={{ Toolbar: GridToolbar }} + onSelectionModelChange={handleSelectionChange} + onRowClick={({ row }) => navigate(row.id)} + /> + ) : ( + Loading... + )} + ); } diff --git a/src/pages/dashboard/Content/Users.tsx b/src/pages/dashboard/Content/Users.tsx index 3aba3a1..bfef0c0 100644 --- a/src/pages/dashboard/Content/Users.tsx +++ b/src/pages/dashboard/Content/Users.tsx @@ -30,7 +30,12 @@ import { getRoles_mock, TMockData } from "../../../api/roles"; import theme from "../../../theme"; -import type { UsersType } from "../../../api/roles"; +import type { UserType } from "../../../api/roles"; + +type RegisteredUsersResponse = { + tatalPages: number; + users: UserType[]; +}; const baseUrl = process.env.NODE_ENV === "production" ? "" : "https://admin.pena.digital"; @@ -85,8 +90,8 @@ const Users: React.FC = () => { handleChangeData(); const [roles, setRoles] = React.useState([]); - const [users, setUsers] = React.useState(); - const [manager, setManager] = React.useState(); + const [users, setUsers] = React.useState([]); + const [manager, setManager] = React.useState([]); useEffect(() => { async function axiosRoles() { @@ -103,12 +108,12 @@ const Users: React.FC = () => { } async function gettingRegisteredUsers() { try { - const usersResponse = await makeRequest({ + const { users } = await makeRequest({ method: "get", url: baseUrl + "/user/", }); - setUsers(usersResponse); + setUsers(users); } catch (error) { console.error("Ошибка при получении пользователей!"); } @@ -116,12 +121,12 @@ const Users: React.FC = () => { async function gettingListManagers() { try { - const managersResponse = await makeRequest({ + const { users } = await makeRequest({ method: "get", url: baseUrl + "/user/", }); - setManager(managersResponse); + setManager(users); } catch (error) { console.error("Ошибка при получении менеджеров!"); } diff --git a/src/pages/dashboard/ModalUser/PurchaseTab.tsx b/src/pages/dashboard/ModalUser/PurchaseTab.tsx new file mode 100644 index 0000000..7d9b06e --- /dev/null +++ b/src/pages/dashboard/ModalUser/PurchaseTab.tsx @@ -0,0 +1,117 @@ +import { DataGrid } from "@mui/x-data-grid"; +import { useTheme } from "@mui/material"; + +import type { GridColDef } from "@mui/x-data-grid"; + +const COLUMNS: GridColDef[] = [ + { + field: "id", + headerName: "ID", + width: 30, + sortable: false, + }, + { + field: "dateTime", + headerName: "Дата / время", + width: 150, + sortable: false, + }, + { + field: "email", + headerName: "Почта", + width: 110, + sortable: false, + }, + { + field: "summa", + headerName: "Сумма", + type: "number", + width: 110, + sortable: false, + }, + { + field: "idLong", + headerName: "ID long", + type: "number", + width: 110, + sortable: false, + }, + { + field: "paymentStatus", + headerName: "Статус платежа", + width: 160, + sortable: false, + }, +]; + +const ROWS = [ + { + id: "row_1", + dateTime: "22.09.22 12:15", + email: "asd@mail.ru", + summa: 100500, + idLong: 123, + paymentStatus: "В обработке", + }, + { + id: "row_2", + dateTime: "22.09.22 12:15", + email: "asd@mail.ru", + summa: 100500, + idLong: 123, + paymentStatus: "В обработке", + }, + { + id: "row_3", + dateTime: "22.09.22 12:15", + email: "asd@mail.ru", + summa: 100500, + idLong: 123, + paymentStatus: "В обработке", + }, + { + id: "row_4", + dateTime: "22.09.22 12:15", + email: "asd@mail.ru", + summa: 100500, + idLong: 123, + paymentStatus: "В обработке", + }, + { + id: "row_5", + dateTime: "22.09.22 12:15", + email: "asd@mail.ru", + summa: 100500, + idLong: 123, + paymentStatus: "В обработке", + }, +]; + +export const PurchaseTab = () => { + const theme = useTheme(); + + return ( + + ); +}; diff --git a/src/pages/dashboard/ModalUser/UserTab.tsx b/src/pages/dashboard/ModalUser/UserTab.tsx new file mode 100644 index 0000000..6b14c74 --- /dev/null +++ b/src/pages/dashboard/ModalUser/UserTab.tsx @@ -0,0 +1,65 @@ +import { Box, Typography } from "@mui/material"; + +type UserTabProps = { + user: { + id: number; + registrationDate: string; + email: string; + phone: string; + type: string; + fullname: string; + walletBalance: string; + }; +}; + +export const UserTab = ({ user }: UserTabProps) => ( + + + + ID + + {" "} + {user.id} + + + + Дата регистрации + + {user.registrationDate} + + + + Email + + {user.email} + + + + Телефон + + {user.phone} + + + + Тип: + + {user.type} + + + + + + ФИО: + + {user.fullname} + + + + Внутренний кошелек + + {user.walletBalance} + + + + +); diff --git a/src/pages/dashboard/ModalUser/index.tsx b/src/pages/dashboard/ModalUser/index.tsx index eba80ff..8a29f7e 100644 --- a/src/pages/dashboard/ModalUser/index.tsx +++ b/src/pages/dashboard/ModalUser/index.tsx @@ -1,183 +1,178 @@ -import * as React from "react"; -import { useLinkClickHandler } from "react-router-dom"; -import { Box, Modal, Fade, Backdrop, Typography } from "@mui/material"; -import Tabs from "@mui/material/Tabs"; -import Tab from "@mui/material/Tab"; -import { DataGrid, GridColDef } from '@mui/x-data-grid'; -import theme from "../../../theme"; +import { useEffect, useState } from "react"; +import { useLinkClickHandler, useParams } from "react-router-dom"; +import { + Box, + Modal, + Fade, + Backdrop, + Typography, + Tabs, + Tab, +} from "@mui/material"; +import { UserTab } from "./UserTab"; +import { PurchaseTab } from "./PurchaseTab"; -export interface MWProps { - open: boolean -} +import { authStore } from "@root/stores/auth"; +import theme from "@root/theme"; -const columns: GridColDef[] = [ - { - field: 'id', - headerName: 'ID', - width: 30, - sortable: false, - }, - { - field: 'dateTime', - headerName: 'Дата / время', - width: 150, - sortable: false, - }, - { - field: 'email', - headerName: 'Почта', - width: 110, - sortable: false, - },{ - field: 'summa', - headerName: 'Сумма', - type: 'number', - width: 110, - sortable: false, - }, - { - field: 'idLong', - headerName: 'ID long', - type: 'number', - width: 110, - sortable: false, - }, - { - field: 'paymentStatus', - headerName: 'Статус платежа', - width: 160, - sortable: false, - }, +import userIcon from "@root/assets/icons/user.svg"; +import packageIcon from "@root/assets/icons/package.svg"; +import transactionsIcon from "@root/assets/icons/transactions.svg"; +import checkIcon from "@root/assets/icons/check.svg"; + +import type { SyntheticEvent } from "react"; + +const TABS = [ + { name: "Пользователь", icon: userIcon }, + { name: "Покупка товаров и услуг", icon: packageIcon }, + { name: "Транзакции", icon: transactionsIcon }, + { name: "Верификация", icon: checkIcon }, ]; -const rows = [ - { id: 1, dateTime: '22.09.22 12:15', email: 'asd@mail.ru', summa: 100500, idLong: 123, paymentStatus: "В обработке" }, - { id: 1, dateTime: '22.09.22 12:15', email: 'asd@mail.ru', summa: 100500, idLong: 123, paymentStatus: "В обработке" }, - { id: 1, dateTime: '22.09.22 12:15', email: 'asd@mail.ru', summa: 100500, idLong: 123, paymentStatus: "В обработке" }, - { id: 1, dateTime: '22.09.22 12:15', email: 'asd@mail.ru', summa: 100500, idLong: 123, paymentStatus: "В обработке" }, - { id: 1, dateTime: '22.09.22 12:15', email: 'asd@mail.ru', summa: 100500, idLong: 123, paymentStatus: "В обработке" }, -]; +const baseUrl = + process.env.NODE_ENV === "production" ? "" : "https://hub.pena.digital"; -const ModalUser = ({open}: MWProps ) => { - const [value, setValue] = React.useState(0); +type File = { + name: "inn" | "rule" | "egrule" | "certificate"; + url: string; +}; + +export type Verification = { + _id: string; + accepted: boolean; + status: "org" | "nko"; + updated_at: string; + comment: string; + files: File[]; +}; + +const ModalUser = () => { + const [user, setUser] = useState(null); + const [value, setValue] = useState(0); + const { userId } = useParams(); + const { makeRequest } = authStore(); + + useEffect(() => { + makeRequest({ + method: "get", + url: baseUrl + `/verification/verification/${userId}`, + }).then(setUser); + }, []); - const handleChange = (event: React.SyntheticEvent, newValue: number) => { - setValue(newValue); - }; - return ( - + <> - - - + + + Пользователь сервиса - - + + setValue(newValue) + } aria-label="Vertical tabs example" - sx={{ - borderRight: 1, - borderColor: theme.palette.secondary.main, - "& .MuiTab-root.Mui-selected": { - color: theme.palette.secondary.main - } - }} - TabIndicatorProps={{style: { - background: theme.palette.secondary.main - }}} + sx={{ padding: "10px", width: "100%", maxWidth: "276px" }} + TabIndicatorProps={{ style: { background: "transparent" } }} > - - - - - { value == 0 && ( - - Id: 1 - Email: 2 - Номер телефона: 3 - - ) } - - { value == 1 && ( - - ( + } + iconPosition="start" + key={name} + label={name} sx={{ - color: theme.palette.secondary.main, - width: "720px", - height: "350px", - overflowY: "auto", - "& .MuiDataGrid-iconSeparator": { - display: "none" + justifyContent: "flex-start", + textTransform: "inherit", + minHeight: "auto", + fontSize: "15px", + padding: "15px", + marginBottom: "5px", + color: theme.palette.common.black, + "&.MuiButtonBase-root.Mui-selected": { + borderRadius: "12px", + color: "#7E2AEA", + background: "rgba(126, 42, 234, 0.07)", }, - "& .css-levciy-MuiTablePagination-displayedRows": { - color: theme.palette.secondary.main - }, - "& .MuiSvgIcon-root": { - color: theme.palette.secondary.main - } }} /> - - ) } + ))} + + + {value === 0 && ( + + )} + {value === 1 && } + - + ); -} - +}; export default ModalUser; diff --git a/src/pages/dashboard/index.tsx b/src/pages/dashboard/index.tsx index bcfc4a3..ad783a2 100644 --- a/src/pages/dashboard/index.tsx +++ b/src/pages/dashboard/index.tsx @@ -59,7 +59,6 @@ export default () => { - ); diff --git a/src/theme.ts b/src/theme.ts index 10c4292..f4f56ca 100644 --- a/src/theme.ts +++ b/src/theme.ts @@ -1,4 +1,3 @@ -import { Theme } from "@mui/material/styles"; import { createTheme, PaletteColorOptions, ThemeOptions } from "@mui/material"; import { deepmerge } from "@mui/utils"; //import { createTheme } from "./types"; @@ -19,6 +18,14 @@ declare module "@mui/material/styles" { primary: { main: string; }; + common: { + black: string; + white: string; + }; + background: { + default: string; + paper: string; + }; secondary: { main: string; };