From da769fa2c0b8e7a32253e98998cd9b371050be7d Mon Sep 17 00:00:00 2001 From: AlexSserb Date: Thu, 30 Oct 2025 13:52:57 +0400 Subject: [PATCH] refactor: refactored product services table --- .../components/ProductServicesTable.tsx | 72 ++++-------------- .../ProductServicesTable.tsx | 63 ++-------------- .../useProductServicesTableColumns.tsx | 62 ---------------- .../hooks/utils/useProductServicesTable.tsx | 74 +++++++++++++++++++ .../utils}/useProductServicesTableColumns.tsx | 15 +++- 5 files changed, 108 insertions(+), 178 deletions(-) delete mode 100644 src/modules/dealModularEditorTabs/FulfillmentBase/mobile/components/ProductServicesTable/useProductServicesTableColumns.tsx create mode 100644 src/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/utils/useProductServicesTable.tsx rename src/modules/dealModularEditorTabs/FulfillmentBase/{desktop/components/ProductView/hooks => shared/hooks/utils}/useProductServicesTableColumns.tsx (81%) diff --git a/src/modules/dealModularEditorTabs/FulfillmentBase/desktop/components/ProductView/components/ProductServicesTable.tsx b/src/modules/dealModularEditorTabs/FulfillmentBase/desktop/components/ProductView/components/ProductServicesTable.tsx index 75b93d3..b3c2bfc 100644 --- a/src/modules/dealModularEditorTabs/FulfillmentBase/desktop/components/ProductView/components/ProductServicesTable.tsx +++ b/src/modules/dealModularEditorTabs/FulfillmentBase/desktop/components/ProductView/components/ProductServicesTable.tsx @@ -1,12 +1,11 @@ import { FC } from "react"; import { IconCopy, IconMoodSad } from "@tabler/icons-react"; import { Button, Flex, Group, Stack, Text } from "@mantine/core"; -import { modals } from "@mantine/modals"; import ActionIconWithTip from "@/components/ui/ActionIconWithTip/ActionIconWithTip"; import BaseTable from "@/components/ui/BaseTable/BaseTable"; -import { DealProductSchema, ProductServiceSchema } from "@/lib/client"; -import useProductServicesTableColumns from "@/modules/dealModularEditorTabs/FulfillmentBase/desktop/components/ProductView/hooks/useProductServicesTableColumns"; -import { useFulfillmentBaseContext } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/contexts/FulfillmentBaseContext"; +import { DealProductSchema } from "@/lib/client"; +import useProductServicesTable from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/utils/useProductServicesTable"; +import useProductServicesTableColumns from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/utils/useProductServicesTableColumns"; type Props = { dealProduct: DealProductSchema; @@ -19,64 +18,23 @@ const ProductServicesTable: FC = ({ onDuplicateServices, onKitAdd, }) => { - const { productServiceCrud, dealProductsList } = - useFulfillmentBaseContext(); - - const onChange = (item: ProductServiceSchema) => { - const excludeServiceIds = dealProduct.productServices.map( - productService => productService.service.id - ); - const totalQuantity = dealProductsList.dealProducts.reduce( - (sum, prod) => prod.quantity + sum, - 0 - ); - - modals.openContextModal({ - modal: "productServiceEditorModal", - innerProps: { - entity: item, - onChange: values => - productServiceCrud.onUpdate( - item.dealId, - item.productId, - item.serviceId, - values - ), - excludeServiceIds, - quantity: totalQuantity, - isEditing: true, - }, - withCloseButton: false, - }); - }; + const { + onChange, + onCreate, + onDelete, + isEmptyTable, + isDuplicateServicesDisabled, + } = useProductServicesTable({ + dealProduct, + }); const columns = useProductServicesTableColumns({ data: dealProduct.productServices, quantity: dealProduct.quantity, - onDelete: productServiceCrud.onDelete, + onDelete, onChange, }); - const onCreateClick = () => { - const excludeServiceIds = dealProduct.productServices.map( - productService => productService.service.id - ); - - modals.openContextModal({ - modal: "productServiceEditorModal", - innerProps: { - onCreate: values => - productServiceCrud.onCreate({ ...dealProduct, ...values }), - excludeServiceIds, - quantity: dealProduct.quantity, - isEditing: false, - }, - withCloseButton: false, - }); - }; - - const isEmptyTable = dealProduct.productServices.length === 0; - return ( = ({ {onDuplicateServices && ( @@ -117,7 +75,7 @@ const ProductServicesTable: FC = ({ )} diff --git a/src/modules/dealModularEditorTabs/FulfillmentBase/mobile/components/ProductServicesTable/ProductServicesTable.tsx b/src/modules/dealModularEditorTabs/FulfillmentBase/mobile/components/ProductServicesTable/ProductServicesTable.tsx index cace90d..1188e4f 100644 --- a/src/modules/dealModularEditorTabs/FulfillmentBase/mobile/components/ProductServicesTable/ProductServicesTable.tsx +++ b/src/modules/dealModularEditorTabs/FulfillmentBase/mobile/components/ProductServicesTable/ProductServicesTable.tsx @@ -1,75 +1,26 @@ import { FC } from "react"; import { IconMoodSad } from "@tabler/icons-react"; import { Button, Flex, Group, ScrollArea, Text } from "@mantine/core"; -import { modals } from "@mantine/modals"; import BaseTable from "@/components/ui/BaseTable/BaseTable"; -import { DealProductSchema, ProductServiceSchema } from "@/lib/client"; -import useProductServicesTableColumns from "@/modules/dealModularEditorTabs/FulfillmentBase/mobile/components/ProductServicesTable/useProductServicesTableColumns"; -import { useFulfillmentBaseContext } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/contexts/FulfillmentBaseContext"; +import { DealProductSchema } from "@/lib/client"; +import useProductServicesTable from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/utils/useProductServicesTable"; +import useProductServicesTableColumns from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/utils/useProductServicesTableColumns"; type Props = { dealProduct: DealProductSchema; }; const ProductServicesTable: FC = ({ dealProduct }) => { - const { productServiceCrud, dealProductsList } = - useFulfillmentBaseContext(); - - const onChange = (item: ProductServiceSchema) => { - const excludeServiceIds = dealProduct.productServices.map( - productService => productService.service.id - ); - const totalQuantity = dealProductsList.dealProducts.reduce( - (sum, prod) => prod.quantity + sum, - 0 - ); - - modals.openContextModal({ - modal: "productServiceEditorModal", - innerProps: { - entity: item, - onChange: values => - productServiceCrud.onUpdate( - item.dealId, - item.productId, - item.serviceId, - values - ), - excludeServiceIds, - quantity: totalQuantity, - isEditing: true, - }, - withCloseButton: false, - }); - }; + const { onChange, onCreate, onDelete, isEmptyTable } = + useProductServicesTable({ dealProduct }); const columns = useProductServicesTableColumns({ data: dealProduct.productServices, quantity: dealProduct.quantity, - onDelete: productServiceCrud.onDelete, + onDelete, onChange, }); - const onCreateClick = () => { - const excludeServiceIds = dealProduct.productServices.map( - productService => productService.service.id - ); - - modals.openContextModal({ - modal: "productServiceEditorModal", - innerProps: { - onCreate: values => - productServiceCrud.onCreate({ ...dealProduct, ...values }), - excludeServiceIds, - quantity: dealProduct.quantity, - isEditing: false, - }, - withCloseButton: false, - }); - }; - - const isEmptyTable = dealProduct.productServices.length === 0; - return ( = ({ dealProduct }) => { diff --git a/src/modules/dealModularEditorTabs/FulfillmentBase/mobile/components/ProductServicesTable/useProductServicesTableColumns.tsx b/src/modules/dealModularEditorTabs/FulfillmentBase/mobile/components/ProductServicesTable/useProductServicesTableColumns.tsx deleted file mode 100644 index fc75368..0000000 --- a/src/modules/dealModularEditorTabs/FulfillmentBase/mobile/components/ProductServicesTable/useProductServicesTableColumns.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { useMemo } from "react"; -import { DataTableColumn } from "mantine-datatable"; -import { Text } from "@mantine/core"; -import UpdateDeleteTableActions from "@/components/ui/BaseTable/components/UpdateDeleteTableActions"; -import { ProductServiceSchema } from "@/lib/client"; - -type Props = { - data: ProductServiceSchema[]; - quantity: number; - onChange: (dealProductService: ProductServiceSchema) => void; - onDelete: (dealProductService: ProductServiceSchema) => void; -}; - -const useProductServicesTableColumns = ({ - data, - quantity, - onChange, - onDelete, -}: Props) => { - const totalPrice = useMemo( - () => data.reduce((acc, row) => acc + row.price * quantity, 0), - [data, quantity] - ); - - return useMemo( - () => - [ - { - accessor: "actions", - title: "Действия", - textAlign: "center", - width: "0%", - render: dealProductService => ( - onDelete(dealProductService)} - onChange={() => onChange(dealProductService)} - /> - ), - }, - { - accessor: "service.name", - title: "Услуга", - width: "70%", - }, - { - accessor: "price", - title: "Цена", - width: "30%", - render: productService => - productService.price.toLocaleString("ru"), - footer: data.length > 0 && ( - - Итог: {totalPrice.toLocaleString("ru")}₽ - - ), - }, - ] as DataTableColumn[], - [totalPrice] - ); -}; - -export default useProductServicesTableColumns; diff --git a/src/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/utils/useProductServicesTable.tsx b/src/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/utils/useProductServicesTable.tsx new file mode 100644 index 0000000..79028ea --- /dev/null +++ b/src/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/utils/useProductServicesTable.tsx @@ -0,0 +1,74 @@ +import { modals } from "@mantine/modals"; +import { DealProductSchema, ProductServiceSchema } from "@/lib/client"; +import { useFulfillmentBaseContext } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/contexts/FulfillmentBaseContext"; + +type Props = { + dealProduct: DealProductSchema; +}; + +const useProductServicesTable = ({ dealProduct }: Props) => { + const { productServiceCrud, dealProductsList } = + useFulfillmentBaseContext(); + + const onChange = (item: ProductServiceSchema) => { + const excludeServiceIds = dealProduct.productServices.map( + productService => productService.service.id + ); + const totalQuantity = dealProductsList.dealProducts.reduce( + (sum, prod) => prod.quantity + sum, + 0 + ); + + modals.openContextModal({ + modal: "productServiceEditorModal", + innerProps: { + entity: item, + onChange: values => + productServiceCrud.onUpdate( + item.dealId, + item.productId, + item.serviceId, + values + ), + excludeServiceIds, + quantity: totalQuantity, + isEditing: true, + }, + withCloseButton: false, + }); + }; + + const onCreate = () => { + const excludeServiceIds = dealProduct.productServices.map( + productService => productService.service.id + ); + + modals.openContextModal({ + modal: "productServiceEditorModal", + innerProps: { + onCreate: values => + productServiceCrud.onCreate({ ...dealProduct, ...values }), + excludeServiceIds, + quantity: dealProduct.quantity, + isEditing: false, + }, + withCloseButton: false, + }); + }; + + const onDelete = productServiceCrud.onDelete; + + const isEmptyTable = dealProduct.productServices.length === 0; + const isDuplicateServicesDisabled = + dealProductsList.dealProducts.length <= 1; + + return { + onChange, + onCreate, + onDelete, + isEmptyTable, + isDuplicateServicesDisabled, + }; +}; + +export default useProductServicesTable; diff --git a/src/modules/dealModularEditorTabs/FulfillmentBase/desktop/components/ProductView/hooks/useProductServicesTableColumns.tsx b/src/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/utils/useProductServicesTableColumns.tsx similarity index 81% rename from src/modules/dealModularEditorTabs/FulfillmentBase/desktop/components/ProductView/hooks/useProductServicesTableColumns.tsx rename to src/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/utils/useProductServicesTableColumns.tsx index 0b08466..1a134f0 100644 --- a/src/modules/dealModularEditorTabs/FulfillmentBase/desktop/components/ProductView/hooks/useProductServicesTableColumns.tsx +++ b/src/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/utils/useProductServicesTableColumns.tsx @@ -2,6 +2,7 @@ import { useMemo } from "react"; import { DataTableColumn } from "mantine-datatable"; import { Box, Text } from "@mantine/core"; import UpdateDeleteTableActions from "@/components/ui/BaseTable/components/UpdateDeleteTableActions"; +import useIsMobile from "@/hooks/utils/useIsMobile"; import { ProductServiceSchema } from "@/lib/client"; type Props = { @@ -17,6 +18,8 @@ const useProductServicesTableColumns = ({ onChange, onDelete, }: Props) => { + const isMobile = useIsMobile(); + const totalPrice = useMemo( () => data.reduce((acc, row) => acc + row.price * quantity, 0), [data, quantity] @@ -34,21 +37,27 @@ const useProductServicesTableColumns = ({ onDelete(dealProductService)} onChange={() => onChange(dealProductService)} - style={{ padding: "var(--mantine-spacing-xs)" }} + style={{ + padding: isMobile + ? 0 + : "var(--mantine-spacing-xs)", + }} /> ), }, { accessor: "service.name", title: "Услуга", + width: "70%", }, { accessor: "price", title: "Цена", + width: "30%", render: productService => productService.price.toLocaleString("ru"), footer: data.length > 0 && ( - + Итог: {totalPrice.toLocaleString("ru")}₽ @@ -56,7 +65,7 @@ const useProductServicesTableColumns = ({ ), }, ] as DataTableColumn[], - [totalPrice] + [totalPrice, isMobile] ); };