diff --git a/src/client/index.ts b/src/client/index.ts index 6fe2aa5..27d15ba 100644 --- a/src/client/index.ts +++ b/src/client/index.ts @@ -27,8 +27,12 @@ export type { HTTPValidationError } from './models/HTTPValidationError'; export type { PaginationInfoSchema } from './models/PaginationInfoSchema'; export type { ProductCreateRequest } from './models/ProductCreateRequest'; export type { ProductCreateResponse } from './models/ProductCreateResponse'; +export type { ProductDeleteRequest } from './models/ProductDeleteRequest'; +export type { ProductDeleteResponse } from './models/ProductDeleteResponse'; export type { ProductGetResponse } from './models/ProductGetResponse'; export type { ProductSchema } from './models/ProductSchema'; +export type { ProductUpdateRequest } from './models/ProductUpdateRequest'; +export type { ProductUpdateResponse } from './models/ProductUpdateResponse'; export type { ServiceCategorySchema } from './models/ServiceCategorySchema'; export type { ServiceCreateCategoryRequest } from './models/ServiceCreateCategoryRequest'; export type { ServiceCreateCategoryResponse } from './models/ServiceCreateCategoryResponse'; diff --git a/src/client/models/AuthLoginResponse.ts b/src/client/models/AuthLoginResponse.ts index 20f77de..6802330 100644 --- a/src/client/models/AuthLoginResponse.ts +++ b/src/client/models/AuthLoginResponse.ts @@ -3,6 +3,6 @@ /* tslint:disable */ /* eslint-disable */ export type AuthLoginResponse = { - access_token: string; + accessToken: string; }; diff --git a/src/client/models/ClientDetailsSchema.ts b/src/client/models/ClientDetailsSchema.ts index 07637eb..eec1f24 100644 --- a/src/client/models/ClientDetailsSchema.ts +++ b/src/client/models/ClientDetailsSchema.ts @@ -4,7 +4,7 @@ /* eslint-disable */ export type ClientDetailsSchema = { address?: (string | null); - phone_number?: (string | null); + phoneNumber?: (string | null); inn?: (number | null); email?: (string | null); }; diff --git a/src/client/models/ClientUpdateDetailsRequest.ts b/src/client/models/ClientUpdateDetailsRequest.ts index 2451087..f0a7bab 100644 --- a/src/client/models/ClientUpdateDetailsRequest.ts +++ b/src/client/models/ClientUpdateDetailsRequest.ts @@ -4,7 +4,7 @@ /* eslint-disable */ import type { ClientDetailsSchema } from './ClientDetailsSchema'; export type ClientUpdateDetailsRequest = { - client_id: number; + clientId: number; details: ClientDetailsSchema; }; diff --git a/src/client/models/DealAddServicesRequest.ts b/src/client/models/DealAddServicesRequest.ts index 980f7b6..4dede9e 100644 --- a/src/client/models/DealAddServicesRequest.ts +++ b/src/client/models/DealAddServicesRequest.ts @@ -4,7 +4,7 @@ /* eslint-disable */ import type { DealServiceSchema } from './DealServiceSchema'; export type DealAddServicesRequest = { - deal_id: number; + dealId: number; services: Array; }; diff --git a/src/client/models/DealChangeStatusRequest.ts b/src/client/models/DealChangeStatusRequest.ts index 4413149..103878c 100644 --- a/src/client/models/DealChangeStatusRequest.ts +++ b/src/client/models/DealChangeStatusRequest.ts @@ -3,7 +3,7 @@ /* tslint:disable */ /* eslint-disable */ export type DealChangeStatusRequest = { - deal_id: number; - new_status: number; + dealId: number; + newStatus: number; }; diff --git a/src/client/models/DealQuickCreateRequest.ts b/src/client/models/DealQuickCreateRequest.ts index 57f2c3f..16e1dda 100644 --- a/src/client/models/DealQuickCreateRequest.ts +++ b/src/client/models/DealQuickCreateRequest.ts @@ -4,9 +4,9 @@ /* eslint-disable */ export type DealQuickCreateRequest = { name: string; - client_name: string; - client_address: string; + clientName: string; + clientAddress: string; comment: string; - acceptance_date: string; + acceptanceDate: string; }; diff --git a/src/client/models/DealQuickCreateResponse.ts b/src/client/models/DealQuickCreateResponse.ts index bdecb1b..ca0c776 100644 --- a/src/client/models/DealQuickCreateResponse.ts +++ b/src/client/models/DealQuickCreateResponse.ts @@ -3,6 +3,6 @@ /* tslint:disable */ /* eslint-disable */ export type DealQuickCreateResponse = { - deal_id: number; + dealId: number; }; diff --git a/src/client/models/DealSummary.ts b/src/client/models/DealSummary.ts index 6902643..d58178e 100644 --- a/src/client/models/DealSummary.ts +++ b/src/client/models/DealSummary.ts @@ -5,9 +5,9 @@ export type DealSummary = { id: number; name: string; - client_name: string; - changed_at: string; + clientName: string; + changedAt: string; status: number; - total_price: number; + totalPrice: number; }; diff --git a/src/client/models/PaginationInfoSchema.ts b/src/client/models/PaginationInfoSchema.ts index 76b3aba..39f0c6d 100644 --- a/src/client/models/PaginationInfoSchema.ts +++ b/src/client/models/PaginationInfoSchema.ts @@ -3,7 +3,7 @@ /* tslint:disable */ /* eslint-disable */ export type PaginationInfoSchema = { - total_pages: number; - total_items: number; + totalPages: number; + totalItems: number; }; diff --git a/src/client/models/ProductCreateRequest.ts b/src/client/models/ProductCreateRequest.ts index 7e36506..2debc6d 100644 --- a/src/client/models/ProductCreateRequest.ts +++ b/src/client/models/ProductCreateRequest.ts @@ -5,6 +5,7 @@ export type ProductCreateRequest = { name: string; article: string; - client_id: number; + clientId: number; + barcodes: Array; }; diff --git a/src/client/models/ProductCreateResponse.ts b/src/client/models/ProductCreateResponse.ts index 0c2020d..f322cef 100644 --- a/src/client/models/ProductCreateResponse.ts +++ b/src/client/models/ProductCreateResponse.ts @@ -3,6 +3,8 @@ /* tslint:disable */ /* eslint-disable */ export type ProductCreateResponse = { - product_id: number; + ok: boolean; + message: string; + productId?: (number | null); }; diff --git a/src/client/models/ProductDeleteRequest.ts b/src/client/models/ProductDeleteRequest.ts new file mode 100644 index 0000000..7daef09 --- /dev/null +++ b/src/client/models/ProductDeleteRequest.ts @@ -0,0 +1,8 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type ProductDeleteRequest = { + productId: number; +}; + diff --git a/src/client/models/ProductDeleteResponse.ts b/src/client/models/ProductDeleteResponse.ts new file mode 100644 index 0000000..837abf1 --- /dev/null +++ b/src/client/models/ProductDeleteResponse.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type ProductDeleteResponse = { + ok: boolean; + message: string; +}; + diff --git a/src/client/models/ProductGetResponse.ts b/src/client/models/ProductGetResponse.ts index 4af6d3b..492a9d0 100644 --- a/src/client/models/ProductGetResponse.ts +++ b/src/client/models/ProductGetResponse.ts @@ -6,6 +6,6 @@ import type { PaginationInfoSchema } from './PaginationInfoSchema'; import type { ProductSchema } from './ProductSchema'; export type ProductGetResponse = { products: Array; - pagination_info: PaginationInfoSchema; + paginationInfo: PaginationInfoSchema; }; diff --git a/src/client/models/ProductSchema.ts b/src/client/models/ProductSchema.ts index 4ad33c9..aeaec26 100644 --- a/src/client/models/ProductSchema.ts +++ b/src/client/models/ProductSchema.ts @@ -6,6 +6,7 @@ export type ProductSchema = { id: number; name: string; article: string; - client_id: number; + clientId: number; + barcodes: Array; }; diff --git a/src/client/models/ProductUpdateRequest.ts b/src/client/models/ProductUpdateRequest.ts new file mode 100644 index 0000000..d11594e --- /dev/null +++ b/src/client/models/ProductUpdateRequest.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { ProductSchema } from './ProductSchema'; +export type ProductUpdateRequest = { + product: ProductSchema; +}; + diff --git a/src/client/models/ProductUpdateResponse.ts b/src/client/models/ProductUpdateResponse.ts new file mode 100644 index 0000000..6177d28 --- /dev/null +++ b/src/client/models/ProductUpdateResponse.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type ProductUpdateResponse = { + ok: boolean; + message: string; +}; + diff --git a/src/client/services/ProductService.ts b/src/client/services/ProductService.ts index 2e718a5..be807db 100644 --- a/src/client/services/ProductService.ts +++ b/src/client/services/ProductService.ts @@ -4,7 +4,11 @@ /* eslint-disable */ import type { ProductCreateRequest } from '../models/ProductCreateRequest'; import type { ProductCreateResponse } from '../models/ProductCreateResponse'; +import type { ProductDeleteRequest } from '../models/ProductDeleteRequest'; +import type { ProductDeleteResponse } from '../models/ProductDeleteResponse'; import type { ProductGetResponse } from '../models/ProductGetResponse'; +import type { ProductUpdateRequest } from '../models/ProductUpdateRequest'; +import type { ProductUpdateResponse } from '../models/ProductUpdateResponse'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; @@ -14,7 +18,7 @@ export class ProductService { * @returns ProductCreateResponse Successful Response * @throws ApiError */ - public static createProductProductCreatePost({ + public static createProduct({ requestBody, }: { requestBody: ProductCreateRequest, @@ -29,6 +33,46 @@ export class ProductService { }, }); } + /** + * Delete Product + * @returns ProductDeleteResponse Successful Response + * @throws ApiError + */ + public static deleteProduct({ + requestBody, + }: { + requestBody: ProductDeleteRequest, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/product/delete', + body: requestBody, + mediaType: 'application/json', + errors: { + 422: `Validation Error`, + }, + }); + } + /** + * Delete Product + * @returns ProductUpdateResponse Successful Response + * @throws ApiError + */ + public static updateProduct({ + requestBody, + }: { + requestBody: ProductUpdateRequest, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/product/update', + body: requestBody, + mediaType: 'application/json', + errors: { + 422: `Validation Error`, + }, + }); + } /** * Get Product * @returns ProductGetResponse Successful Response diff --git a/src/components/BaseTable/BaseTable.tsx b/src/components/BaseTable/BaseTable.tsx index e7315d3..0baeb13 100644 --- a/src/components/BaseTable/BaseTable.tsx +++ b/src/components/BaseTable/BaseTable.tsx @@ -2,13 +2,12 @@ import { MantineReactTable, MRT_ColumnDef, MRT_RowData, - MRT_Table, MRT_TableInstance, MRT_TableOptions, useMantineReactTable } from "mantine-react-table"; import {MRT_Localization_RU} from "mantine-react-table/locales/ru/index.cjs"; -import {forwardRef, useEffect, useImperativeHandle} from 'react'; +import {forwardRef, useImperativeHandle} from 'react'; type Props, K extends keyof T> = { data: T[], diff --git a/src/components/Dnd/CreateDealButton/CreateDealButton.tsx b/src/components/Dnd/CreateDealButton/CreateDealButton.tsx index 9d06531..c5dcfaa 100644 --- a/src/components/Dnd/CreateDealButton/CreateDealButton.tsx +++ b/src/components/Dnd/CreateDealButton/CreateDealButton.tsx @@ -39,7 +39,7 @@ const CreateDealButton: FC = () => { DealService.quickCreateDealQuickCreatePost({ requestBody: { ...quickDeal, - acceptance_date: dateWithoutTimezone(quickDeal.acceptance_date) + acceptanceDate: dateWithoutTimezone(quickDeal.acceptanceDate) } }) }} diff --git a/src/components/Dnd/CreateDealForm/CreateDealFrom.tsx b/src/components/Dnd/CreateDealForm/CreateDealFrom.tsx index b8b249b..d72d314 100644 --- a/src/components/Dnd/CreateDealForm/CreateDealFrom.tsx +++ b/src/components/Dnd/CreateDealForm/CreateDealFrom.tsx @@ -14,10 +14,10 @@ const CreateDealFrom: FC = ({onSubmit, onCancel}) => { const form = useForm({ initialValues: { name: '', - client_name: '', - client_address: '', + clientName: '', + clientAddress: '', comment: '', - acceptance_date: new Date() + acceptanceDate: new Date() } }); return ( @@ -43,8 +43,8 @@ const CreateDealFrom: FC = ({onSubmit, onCancel}) => {
@@ -60,7 +60,7 @@ const CreateDealFrom: FC = ({onSubmit, onCancel}) => {
diff --git a/src/components/Dnd/DealSummaryCard/DealSummaryCard.tsx b/src/components/Dnd/DealSummaryCard/DealSummaryCard.tsx index e0666d3..8dba636 100644 --- a/src/components/Dnd/DealSummaryCard/DealSummaryCard.tsx +++ b/src/components/Dnd/DealSummaryCard/DealSummaryCard.tsx @@ -15,7 +15,7 @@ const DealSummaryCard: FC = ({dealSummary}) => {
- {dealSummary.client_name} + {dealSummary.clientName}
@@ -23,14 +23,14 @@ const DealSummaryCard: FC = ({dealSummary}) => {
- {dealSummary.total_price.toLocaleString('ru-RU')} руб + {dealSummary.totalPrice.toLocaleString('ru-RU')} руб
- {new Date(dealSummary.changed_at).toLocaleString('ru-RU')} + {new Date(dealSummary.changedAt).toLocaleString('ru-RU')}
diff --git a/src/modals/CreateProductModal/CreateProductModal.tsx b/src/modals/CreateProductModal/CreateProductModal.tsx deleted file mode 100644 index 46ba809..0000000 --- a/src/modals/CreateProductModal/CreateProductModal.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import {ContextModalProps} from "@mantine/modals"; -import {Button, Text} from "@mantine/core"; -import {useForm} from "@mantine/form"; - - -const CreateProductModal = ({ - context, - id, - innerProps, - }: ContextModalProps<{ clientId: number }>) => { - const form = useForm({ - initialValues: { - name: '', - article: '', - barcode: '' - } - }) - return ( - <> - - - ) -}; -export default CreateProductModal; \ No newline at end of file diff --git a/src/modals/modals.ts b/src/modals/modals.ts index 1bbde0b..ce62dc1 100644 --- a/src/modals/modals.ts +++ b/src/modals/modals.ts @@ -1,7 +1,7 @@ import EnterDeadlineModal from "./EnterDeadlineModal/EnterDeadlineModal.tsx"; import CreateServiceCategoryModal from "../pages/ServicesPage/modals/CreateServiceCategoryModal.tsx"; import CreateServiceModal from "../pages/ServicesPage/modals/CreateServiceModal.tsx"; -import createProductModal from "./CreateProductModal/CreateProductModal.tsx"; +import createProductModal from "../pages/ProductsPage/modals/CreateProductModal/CreateProductModal.tsx"; export const modals = { enterDeadline: EnterDeadlineModal, diff --git a/src/pages/LeadsPage/ui/LeadsPage.tsx b/src/pages/LeadsPage/ui/LeadsPage.tsx index e7d1abd..f989195 100644 --- a/src/pages/LeadsPage/ui/LeadsPage.tsx +++ b/src/pages/LeadsPage/ui/LeadsPage.tsx @@ -1,4 +1,4 @@ -import React, {FC, useEffect, useState} from "react"; +import {FC, useEffect, useState} from "react"; import styles from './LeadsPage.module.css'; import Board from "../../../components/Dnd/Board/Board.tsx"; import {DragDropContext} from "@hello-pangea/dnd"; diff --git a/src/pages/LoginPage/LoginPage.tsx b/src/pages/LoginPage/LoginPage.tsx index 69706a1..1fc6dcc 100644 --- a/src/pages/LoginPage/LoginPage.tsx +++ b/src/pages/LoginPage/LoginPage.tsx @@ -39,8 +39,8 @@ const LoginPage = () => { }, (data: TelegramUser) => { AuthService.loginAuthLoginPost({requestBody: data}) - .then(({access_token}) => { - dispatch(login({accessToken: access_token})); + .then(({accessToken}) => { + dispatch(login({accessToken: accessToken})); navigate({to: "/"}).then(() => { notifications.success({message: "Вы успешно вошли!"}) }) diff --git a/src/pages/PageWrapper/PageWrapper.module.css b/src/pages/PageWrapper/PageWrapper.module.css index e1b81e7..43d1bd9 100644 --- a/src/pages/PageWrapper/PageWrapper.module.css +++ b/src/pages/PageWrapper/PageWrapper.module.css @@ -10,5 +10,4 @@ .container { padding: rem(20); display: flex; - //min-height: 100vh; } diff --git a/src/pages/PageWrapper/PageWrapper.tsx b/src/pages/PageWrapper/PageWrapper.tsx index cab4766..bd30426 100644 --- a/src/pages/PageWrapper/PageWrapper.tsx +++ b/src/pages/PageWrapper/PageWrapper.tsx @@ -14,20 +14,17 @@ const PageWrapper: FC = ({children}) => { - {/**/} - {/*
*/} - {/**/} + - + {authState.isAuthorized && + + }
{children}
- -
) diff --git a/src/pages/ProductsPage/components/ProductsTable/ProductsTable.tsx b/src/pages/ProductsPage/components/ProductsTable/ProductsTable.tsx index 2efa2af..a2532f4 100644 --- a/src/pages/ProductsPage/components/ProductsTable/ProductsTable.tsx +++ b/src/pages/ProductsPage/components/ProductsTable/ProductsTable.tsx @@ -1,24 +1,56 @@ import {ProductSchema} from "../../../../client"; -import {FC, RefObject} from "react"; -import {BaseTable, BaseTableRef} from "../../../../components/BaseTable/BaseTable.tsx"; +import {FC} from "react"; +import {BaseTable} from "../../../../components/BaseTable/BaseTable.tsx"; import {MRT_TableOptions} from "mantine-react-table"; import {useProductsTableColumns} from "./columns.tsx"; +import {ActionIcon, Flex, Tooltip} from "@mantine/core"; +import {IconEdit, IconTrash} from "@tabler/icons-react"; +import {CRUDTableProps} from "../../../../types/CRUDTable.tsx"; +import {modals} from "@mantine/modals"; -type Props = { - products: ProductSchema[]; - tableRef?: RefObject> -} -const ProductsTable: FC = ({products, tableRef}) => { + +const ProductsTable: FC> = ({items, onDelete, onChange, tableRef}) => { const columns = useProductsTableColumns(); + const onEditClick = (product: ProductSchema) => { + if (!onChange) return; + modals.openContextModal({ + modal: "createProduct", + title: 'Создание товара', + withCloseButton: false, + innerProps: { + onChange: (newProduct) => onChange(newProduct), + product: product, + } + }) + } return ( - } - /> + ( + + + onEditClick(row.original)} + variant={"default"}> + + + + + { + if (onDelete) onDelete(row.original); + }} variant={"default"}> + + + + + ) + } as MRT_TableOptions} + /> ) } diff --git a/src/pages/ProductsPage/components/ProductsTable/columns.tsx b/src/pages/ProductsPage/components/ProductsTable/columns.tsx index 048a3c9..4785dfb 100644 --- a/src/pages/ProductsPage/components/ProductsTable/columns.tsx +++ b/src/pages/ProductsPage/components/ProductsTable/columns.tsx @@ -1,8 +1,10 @@ import {useMemo} from "react"; import {MRT_ColumnDef} from "mantine-react-table"; import {ProductSchema} from "../../../../client"; +import {List, Spoiler, useMantineTheme} from "@mantine/core"; export const useProductsTableColumns = () => { + const theme = useMantineTheme(); return useMemo[]>(() => [ { accessorKey: "article", @@ -13,8 +15,27 @@ export const useProductsTableColumns = () => { accessorKey: "name", header: "Название", enableSorting: false, - }, + { + accessorKey: "barcodes", + header: "Штрихкоды", + Cell: ({cell}) => { + return ( + + + {cell.getValue().map(barcode => ( + + {barcode} + + ))} + + + + ) + } + } ], []); } \ No newline at end of file diff --git a/src/pages/ProductsPage/hooks/useProductsList.tsx b/src/pages/ProductsPage/hooks/useProductsList.tsx index 1a9bbb4..11613b8 100644 --- a/src/pages/ProductsPage/hooks/useProductsList.tsx +++ b/src/pages/ProductsPage/hooks/useProductsList.tsx @@ -8,12 +8,12 @@ type Props = { } const useServicesList = (props: Props) => { const {clientId, page, itemsPerPage} = props; - const {isPending, error, data, refetch} = useQuery({ + const {data, refetch} = useQuery({ queryKey: ['getAllServices', clientId, page, itemsPerPage], queryFn: () => ProductService.getProductsByClientId({clientId, page, itemsPerPage}) }); - const products = isPending || error || !data ? [] : data.products; - const paginationInfo = data?.pagination_info; + const products = !data ? [] : data.products; + const paginationInfo = data?.paginationInfo; return {products, paginationInfo, refetch} } export default useServicesList; \ No newline at end of file diff --git a/src/pages/ProductsPage/modals/CreateProductModal/CreateProductModal.tsx b/src/pages/ProductsPage/modals/CreateProductModal/CreateProductModal.tsx new file mode 100644 index 0000000..dd02145 --- /dev/null +++ b/src/pages/ProductsPage/modals/CreateProductModal/CreateProductModal.tsx @@ -0,0 +1,97 @@ +import {ContextModalProps} from "@mantine/modals"; +import {Button, Flex, rem, TagsInput, TextInput} from "@mantine/core"; +import {useForm} from "@mantine/form"; +import {BaseProduct, CreateProductRequest} from "../../types.ts"; +import {ProductSchema} from "../../../../client"; + +type CreateProps = { + clientId: number; + onCreate: (values: CreateProductRequest) => void +} + +type EditProps = { + product: ProductSchema, + onChange: (values: ProductSchema) => void +} +type Props = CreateProps | EditProps; + + +const CreateProductModal = ({ + context, + id, + innerProps, + }: ContextModalProps) => { + const isEditProps = 'product' in innerProps; + const isCreatingProps = 'clientId' in innerProps; + const initialValues = isEditProps ? { + name: innerProps.product.name, + article: innerProps.product.article, + barcodes: innerProps.product.barcodes + } : { + name: '', + article: '', + barcodes: [] + }; + const form = useForm({ + initialValues: initialValues, + validate: { + name: (name) => name.trim() !== '' ? null : "Необходимо ввести название товара", + article: (article) => article.trim() !== '' ? null : "Необходимо ввести артикул", + } + }) + const onCancelClick = () => { + context.closeContextModal(id); + } + + const onSubmit = (values: BaseProduct) => { + if (isEditProps) innerProps.onChange({...innerProps.product, ...values}) + if (isCreatingProps) { + innerProps.onCreate({...values, clientId: innerProps.clientId}); + form.reset(); + } + } + return ( + <> +
onSubmit(values))}> + + + + + + + {isEditProps ? + : + <> + + + } + + +
+ + ) +}; +export default CreateProductModal; \ No newline at end of file diff --git a/src/pages/ProductsPage/types.ts b/src/pages/ProductsPage/types.ts new file mode 100644 index 0000000..55d3c36 --- /dev/null +++ b/src/pages/ProductsPage/types.ts @@ -0,0 +1,6 @@ +export type BaseProduct = { + name: string; + article: string; + barcodes: string[]; +} +export type CreateProductRequest = BaseProduct & { clientId: number } \ No newline at end of file diff --git a/src/pages/ProductsPage/ui/ProductsPage.tsx b/src/pages/ProductsPage/ui/ProductsPage.tsx index 8fd6b4a..48b3b9a 100644 --- a/src/pages/ProductsPage/ui/ProductsPage.tsx +++ b/src/pages/ProductsPage/ui/ProductsPage.tsx @@ -1,37 +1,83 @@ import PageBlock from "../../../components/PageBlock/PageBlock.tsx"; import {FC, useEffect, useState} from "react"; import styles from './ProductsPage.module.css'; -import {Button, Drawer, Pagination} from "@mantine/core"; -import {useDisclosure, usePagination} from "@mantine/hooks"; +import {Button, Text, Pagination} from "@mantine/core"; import ClientSelect from "../../../components/Selects/ClientSelect/ClientSelect.tsx"; import ProductsTable from "../components/ProductsTable/ProductsTable.tsx"; import useProductsList from "../hooks/useProductsList.tsx"; -import {notifications} from "../../../shared/lib/notifications.ts"; import {modals} from "@mantine/modals"; +import {notifications} from "../../../shared/lib/notifications.ts"; +import {CreateProductRequest} from "../types.ts"; +import {ProductSchema, ProductService} from "../../../client"; export const ProductsPage: FC = () => { - // const [opened, {open, close}] = useDisclosure(false); const [clientId, setClientId] = useState(-1); const [totalPages, setTotalPages] = useState(1); - const pagination = usePagination({total: totalPages}); - const {products, paginationInfo} = useProductsList({ + const [currentPage, setCurrentPage] = useState(1); + + const {products, paginationInfo, refetch} = useProductsList({ clientId, - page: pagination.active - 1, + page: currentPage - 1, itemsPerPage: 10 }); + const onProductCreate = (request: CreateProductRequest) => { + ProductService.createProduct({requestBody: request}) + .then(async ({ok, message}) => { + notifications.guess(ok, {message: message}); + if (!ok) return; + await refetch(); + }); + } + + const onProductChange = (product: ProductSchema) => { + ProductService.updateProduct({requestBody: {product}}) + .then(async ({ok, message}) => { + notifications.guess(ok, {message}); + if (!ok) return; + await refetch(); + }) + } + const onCreateProductClick = () => { + if (clientId < 0) { + notifications.error({message: "Необходимо выбрать клиента"}); + return + } modals.openContextModal({ modal: "createProduct", - title: 'Создание категории', + title: 'Создание товара', withCloseButton: false, innerProps: { - clientId + clientId, + onCreate: onProductCreate } }) } + + const onDeleteClick = (product: ProductSchema) => { + modals.openConfirmModal({ + title: 'Удаление товара', + centered: true, + children: ( + + Вы уверены что хотите удалить товар {product.name} + + ), + labels: {confirm: 'Да', cancel: "Нет"}, + confirmProps: {color: 'red'}, + onConfirm: () => + ProductService.deleteProduct({requestBody: {productId: product.id}}) + .then(async ({ok, message}) => { + notifications.guess(ok, {message: message}); + if (!ok) return; + await refetch(); + }) + }); + } + useEffect(() => { if (!paginationInfo) return; - setTotalPages(paginationInfo.total_pages); + setTotalPages(paginationInfo.totalPages); }, [paginationInfo]); @@ -50,8 +96,18 @@ export const ProductsPage: FC = () => {
- - + + setCurrentPage(event)} + total={totalPages} + value={currentPage} + />
diff --git a/src/pages/ServicesPage/ui/ServicesPage.tsx b/src/pages/ServicesPage/ui/ServicesPage.tsx index 0a6ab59..6f4083a 100644 --- a/src/pages/ServicesPage/ui/ServicesPage.tsx +++ b/src/pages/ServicesPage/ui/ServicesPage.tsx @@ -26,10 +26,10 @@ export const ServicesPage: FC = () => { } const onCreate = (values: ServiceSchema) => { ServiceService.createService({requestBody: {service: values}}) - .then(({ok, message}) => { + .then(async ({ok, message}) => { notifications.guess(ok, {message: message}); if (!ok) return; - refetch(); + await refetch(); }) } const onCreateCategoryClick = () => { diff --git a/src/types/CRUDTable.tsx b/src/types/CRUDTable.tsx new file mode 100644 index 0000000..9b1cdde --- /dev/null +++ b/src/types/CRUDTable.tsx @@ -0,0 +1,11 @@ +import {RefObject} from "react"; +import {BaseTableRef} from "../components/BaseTable/BaseTable.tsx"; +import {MRT_RowData} from "mantine-react-table"; + +export interface CRUDTableProps { + items: T[]; + onCreate?: (item: T) => void; + onDelete?: (item: T) => void; + onChange?: (item: T) => void; + tableRef?: RefObject> +} \ No newline at end of file diff --git a/src/types/QuickDeal.ts b/src/types/QuickDeal.ts index 560d348..53cb0c6 100644 --- a/src/types/QuickDeal.ts +++ b/src/types/QuickDeal.ts @@ -1,7 +1,7 @@ export type QuickDeal = { name: string - client_name: string - client_address: string + clientName: string + clientAddress: string comment:string - acceptance_date: Date + acceptanceDate: Date } \ No newline at end of file