diff --git a/frontend_reactjs/src/App.tsx b/frontend_reactjs/src/App.tsx index 62cec49..7269b29 100644 --- a/frontend_reactjs/src/App.tsx +++ b/frontend_reactjs/src/App.tsx @@ -11,6 +11,7 @@ import SignUp from "./pages/auth/SignUp" import { initAuth, useAuthStore } from "./store/auth" import { useEffect, useState } from "react" import { Box, CircularProgress, Container } from "@mui/material" +import Documents from "./pages/Documents" function App() { const auth = useAuthStore() @@ -48,6 +49,7 @@ function App() { } /> } /> } /> + } /> } /> } /> diff --git a/frontend_reactjs/src/components/AccountMenu.tsx b/frontend_reactjs/src/components/AccountMenu.tsx index fe7cda8..d558ea0 100644 --- a/frontend_reactjs/src/components/AccountMenu.tsx +++ b/frontend_reactjs/src/components/AccountMenu.tsx @@ -9,10 +9,17 @@ import IconButton from '@mui/material/IconButton'; import Tooltip from '@mui/material/Tooltip'; import Settings from '@mui/icons-material/Settings'; import Logout from '@mui/icons-material/Logout'; +import { useNavigate } from 'react-router-dom'; +import { logout } from '../store/auth'; +import { ListItem } from '@mui/material'; export default function AccountMenu() { + const navigate = useNavigate() + const [anchorEl, setAnchorEl] = React.useState(null); + const open = Boolean(anchorEl); + const handleClick = (event: React.MouseEvent) => { setAnchorEl(event.currentTarget); }; @@ -70,19 +77,18 @@ export default function AccountMenu() { transformOrigin={{ horizontal: 'right', vertical: 'top' }} anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }} > - - Профиль - - - - Настройки - + { + logout() + navigate("/auth/signin") + }} + > diff --git a/frontend_reactjs/src/components/modals/CreateRoleModal.tsx b/frontend_reactjs/src/components/modals/CreateRoleModal.tsx index 732bfa8..4f41265 100644 --- a/frontend_reactjs/src/components/modals/CreateRoleModal.tsx +++ b/frontend_reactjs/src/components/modals/CreateRoleModal.tsx @@ -80,10 +80,11 @@ export default function CreateRoleModal({ - Добавить пользователя + Добавить роль setOpen(false)}> diff --git a/frontend_reactjs/src/components/modals/CreateUserModal.tsx b/frontend_reactjs/src/components/modals/CreateUserModal.tsx index 1b3281a..cdeb670 100644 --- a/frontend_reactjs/src/components/modals/CreateUserModal.tsx +++ b/frontend_reactjs/src/components/modals/CreateUserModal.tsx @@ -124,6 +124,7 @@ export default function CreateUserModal({ diff --git a/frontend_reactjs/src/interfaces/documents.ts b/frontend_reactjs/src/interfaces/documents.ts new file mode 100644 index 0000000..f92d42f --- /dev/null +++ b/frontend_reactjs/src/interfaces/documents.ts @@ -0,0 +1,62 @@ +export interface ICompany { + name: string; + fullname: string; + description: string; + owner_id: number; +} + +export interface IDepartment { + name: string; + fullname: string; + description: string; + company_id: number; + owner_id: number; +} + +export interface IDocumentFolder { + name: string; + description: string; + department_id: number; + create_date: string; +} + +export interface IDocument { + name: string; + description: string; + department_id: number; + create_date: string; +} + +export interface IBank { + name: string; + bik: string; + corschet: string; + activ: boolean; + id_1c: string; +} + +export interface IOrganization { + full_name: string; + name: string; + inn: string; + ogrn: string; + kpp: string; + okopf: string; + legal_address: string; + actual_address: string; + mail_address: string; + id_budget: number; + fio_dir: string; + phone: string; + email: string; + comment: string; + id_bank: string; + id_1c: string; + active: boolean; +} + +export interface IOrganizationBank { + id_organization: string; + id_banks: string; + rasch_schet: string; +} \ No newline at end of file diff --git a/frontend_reactjs/src/layouts/DashboardLayout.tsx b/frontend_reactjs/src/layouts/DashboardLayout.tsx index 6711f84..7bdee70 100644 --- a/frontend_reactjs/src/layouts/DashboardLayout.tsx +++ b/frontend_reactjs/src/layouts/DashboardLayout.tsx @@ -14,7 +14,7 @@ import Container from '@mui/material/Container'; import MenuIcon from '@mui/icons-material/Menu'; import ChevronLeftIcon from '@mui/icons-material/ChevronLeft'; import NotificationsIcon from '@mui/icons-material/Notifications'; -import { AccountCircle, Api, ExitToApp, Home, People, Settings, Shield } from '@mui/icons-material'; +import { AccountCircle, Api, ExitToApp, Home, People, Settings, Shield, Storage } from '@mui/icons-material'; import { ListItem, ListItemButton, ListItemIcon, ListItemText, colors } from '@mui/material'; import { Outlet, useNavigate } from 'react-router-dom'; import { UserData } from '../interfaces/auth'; @@ -88,6 +88,11 @@ const pages = [ path: "/role", icon: }, + { + label: "Документы", + path: "/documents", + icon: + }, { label: "API Test", path: "/api-test", diff --git a/frontend_reactjs/src/pages/Documents.tsx b/frontend_reactjs/src/pages/Documents.tsx new file mode 100644 index 0000000..bb7adaf --- /dev/null +++ b/frontend_reactjs/src/pages/Documents.tsx @@ -0,0 +1,27 @@ +import React, { useEffect, useState } from 'react' +import DocumentService from '../services/DocumentService' +import { Box, Button } from '@mui/material' + +export default function Documents() { + const [data, setData] = useState() + + const fetchData = async () => { + await DocumentService.getDocuments().then(response => { + setData(response.data) + }) + } + + return ( + + { + fetchData() + }}> + Get data + + + + {JSON.stringify(data)} + + + ) +} \ No newline at end of file diff --git a/frontend_reactjs/src/pages/Settings.tsx b/frontend_reactjs/src/pages/Settings.tsx new file mode 100644 index 0000000..bd0629c --- /dev/null +++ b/frontend_reactjs/src/pages/Settings.tsx @@ -0,0 +1,62 @@ +import { Box, Button, CircularProgress } from "@mui/material" +import DataTable from "../components/DataTable" +import { GridColDef } from "@mui/x-data-grid" +import { useRoles, useUsers } from "../hooks/swrHooks" +import { IRole } from "../interfaces/role" +import { useState } from "react" +import CreateUserModal from "../components/modals/CreateUserModal" + +export default function Settings() { + const { users, isError, isLoading } = useUsers() + + const { roles } = useRoles() + + const [open, setOpen] = useState(false) + + const columns: GridColDef[] = [ + { field: 'id', headerName: 'ID', type: "number", width: 70 }, + { field: 'email', headerName: 'Email', width: 130, editable: true }, + { field: 'login', headerName: 'Логин', width: 130, editable: true }, + { field: 'phone', headerName: 'Телефон', width: 90, editable: true }, + { field: 'name', headerName: 'Имя', width: 90, editable: true }, + { field: 'surname', headerName: 'Фамилия', width: 90, editable: true }, + { field: 'is_active', headerName: 'Активен', type: "boolean", width: 90, editable: true }, + { + field: 'role_id', + headerName: 'Роль', + valueGetter: (value, row) => { + if (roles) { + const roleName = roles.find((role: IRole) => role.id === value).name + return roleName + } else { + return value + } + }, + width: 90 + }, + ]; + + if (isError) return Произошла ошибка при получении данных. + if (isLoading) return + + return ( + + setOpen(true)}> + Добавить пользователя + + + + + + + ) +} \ No newline at end of file diff --git a/frontend_reactjs/src/services/DocumentService.ts b/frontend_reactjs/src/services/DocumentService.ts new file mode 100644 index 0000000..20801f0 --- /dev/null +++ b/frontend_reactjs/src/services/DocumentService.ts @@ -0,0 +1,224 @@ +import axiosInstance from "../http/axiosInstance"; +import { IBank, ICompany, IDepartment, IDocument, IDocumentFolder, IOrganization, IOrganizationBank } from "../interfaces/documents"; + +export default class DocumentService { + // Get Main + static async getMain() { + return await axiosInstance.get(`/info/`) + } + + // Get Companies + static async getCompanies(limit?: number, offset?: number) { + return await axiosInstance.get(`/info/companies`, { + params: { + limit: limit || 10, + offset: offset || 0 + } + }) + } + + // Create Company + static async createCompany(data: ICompany) { + return await axiosInstance.post(`/info/companies/`, data) + } + + // Delete Company + static async deleteCompany(company_id: number) { + return await axiosInstance.delete(`/info/companies/${company_id}`) + } + + // Update Company + static async updateCompany(company_id: number) { + return await axiosInstance.patch(`/info/companies/${company_id}`) + } + + // Get Departments + static async getDepartments(limit?: number, offset?: number) { + return await axiosInstance.get(`/info/departments/`, { + params: { + limit: limit || 10, + offset: offset || 0 + } + }) + } + + // Get Department + static async getDepartment(department_id: number) { + return await axiosInstance.get(`/info/departments/${department_id}`) + } + + + // Delete Department + static async deleteDepartment(department_id: number) { + return await axiosInstance.delete(`/info/departments/${department_id}`) + } + + // Update Department + static async updateDepartment(department_id: number, data: IDepartment) { + return await axiosInstance.patch(`/info/departments/${department_id}`, data) + } + + // Create Department + static async createDepartment(data: IDepartment) { + return await axiosInstance.post(`/info/department/`, data) + } + + // Get Documents + static async getDocuments(limit?: number, offset?: number) { + return await axiosInstance.get(`/info/document_folder/`, { + params: { + limit: limit || 10, + offset: offset || 0 + } + }) + } + + // Create Documentfolder + static async createDocumentFolder(data: IDocumentFolder) { + return await axiosInstance.post(`/info/document_folder/`, data) + } + + // Get Document + static async getDocument(folder_id: number) { + return await axiosInstance.get(`/info/document_folder/${folder_id}`) + } + + // Delete Document + static async deleteDocument(folder_id: number) { + return await axiosInstance.delete(`/info/document_folder/${folder_id}`) + } + + // Update Document + static async updateDocument(folder_id: number, data: IDocument) { + return await axiosInstance.patch(`/info/document_folder/${folder_id}`, data) + } + + // Get Docs + static async getDocs(folder_id: number) { + return await axiosInstance.get(`/info/documents/${folder_id}`) + } + + // Upload Files + static async uploadFiles(folder_id: number, files: any) { + return await axiosInstance.post(`/info//documents/upload/${folder_id}`, files) + } + + // Download Doc + static async downloadDoc(folder_id: number, doc_id: number) { + return await axiosInstance.get(`/info/document/`, { + params: { + folder_id: folder_id, + doc_id: doc_id + } + }) + } + + // Delete Doc + static async deleteDoc(folder_id: number, doc_id: number) { + return await axiosInstance.delete(`/info/document/`, { + params: { + folder_id: folder_id, + doc_id: doc_id + } + }) + } + + // Convert Phones + static async convertPhones(data: any) { + return await axiosInstance.post(`/info/other/phones/`, data) + } + + // Get Budget + static async getBudget() { + return await axiosInstance.get(`/info/organization/budget/`) + } + + // Add Bank + static async addBank(data: IBank) { + return await axiosInstance.post(`/info/organization/bank`, data) + } + + // Update Bank + static async updateBank(bank_id: string, bank_1c_id: string, data: IBank) { + return await axiosInstance.patch(`/info/organization/bank`, data, { + params: { + bank_id: bank_id, + bank_1c_id: bank_1c_id + } + }) + } + + // Get Banks + static async getBanks(bank_id: string, search?: string, limit?: number, offset?: number) { + return await axiosInstance.get(`/info/organization/banks`, { + params: { + bank_id: bank_id, + search: search || null, + limit: limit || 10, + offset: offset || 0 + } + }) + } + + // Get Bank + static async getBank(id_1c: string) { + return await axiosInstance.get(`/info/organization/bank/${id_1c}`) + } + + // Delete Bank + static async deleteBank(bank_id: string, bank_1c_id: string) { + return await axiosInstance.get(`/info/organization/bank/`, { + params: { + bank_id: bank_id, + bank_1c_id: bank_1c_id + } + }) + } + + // Add Org + static async addOrganization(data: IOrganization) { + return await axiosInstance.post(`/info/organization/org/`, data) + } + + // Update Org + static async updateOrganization(org_id: string, org_1c_id: string, data: IOrganization) { + return await axiosInstance.patch(`/info/organization/org`, data, { + params: { + org_id: org_id, + org_1c_id: org_1c_id + } + }) + } + + // Delete Org + static async deleteOrganization(org_id: string, org_1c_id: string) { + return await axiosInstance.delete(`/info/organization/org`, { + params: { + org_id: org_id, + org_1c_id: org_1c_id + } + }) + } + + // Get Orgs + static async getOrganizations(org_id?: string, search?: string, limit?: number, offset?: number) { + return await axiosInstance.get(`/info/organization/orgs`, { + params: { + org_id: org_id, + search: search || null, + limit: limit || 10, + offset: offset || 0 + } + }) + } + + // Get Org + static async getOrganization(id_1c: string) { + return await axiosInstance.get(`/info/organization/org/${id_1c}`) + } + + // Add Orgbank + static async addOrganizationBank(data: IOrganizationBank) { + return await axiosInstance.post(`/info/organization/org_bank`, data) + } +} \ No newline at end of file