refactor: refactored product services table
This commit is contained in:
@ -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<Props> = ({
|
||||
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 (
|
||||
<Stack gap={0}>
|
||||
<BaseTable
|
||||
@ -104,7 +62,7 @@ const ProductServicesTable: FC<Props> = ({
|
||||
{onDuplicateServices && (
|
||||
<ActionIconWithTip
|
||||
tipLabel={"Продублировать услуги"}
|
||||
disabled={dealProductsList.dealProducts.length <= 1}
|
||||
disabled={isDuplicateServicesDisabled}
|
||||
onClick={onDuplicateServices}>
|
||||
<IconCopy />
|
||||
</ActionIconWithTip>
|
||||
@ -117,7 +75,7 @@ const ProductServicesTable: FC<Props> = ({
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
onClick={onCreateClick}
|
||||
onClick={onCreate}
|
||||
variant={"default"}>
|
||||
Добавить услугу
|
||||
</Button>
|
||||
|
||||
@ -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<Props> = ({ 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 (
|
||||
<Flex
|
||||
flex={1}
|
||||
@ -105,7 +56,7 @@ const ProductServicesTable: FC<Props> = ({ dealProduct }) => {
|
||||
<Button
|
||||
flex={1}
|
||||
py={"xs"}
|
||||
onClick={onCreateClick}
|
||||
onClick={onCreate}
|
||||
variant={"default"}>
|
||||
Добавить услугу
|
||||
</Button>
|
||||
|
||||
@ -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 => (
|
||||
<UpdateDeleteTableActions
|
||||
onDelete={() => 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 && (
|
||||
<Text fw={700}>
|
||||
Итог: {totalPrice.toLocaleString("ru")}₽
|
||||
</Text>
|
||||
),
|
||||
},
|
||||
] as DataTableColumn<ProductServiceSchema>[],
|
||||
[totalPrice]
|
||||
);
|
||||
};
|
||||
|
||||
export default useProductServicesTableColumns;
|
||||
@ -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;
|
||||
@ -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 = ({
|
||||
<UpdateDeleteTableActions
|
||||
onDelete={() => 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 && (
|
||||
<Box my={"sm"}>
|
||||
<Box my={isMobile ? 0 : "sm"}>
|
||||
<Text fw={700}>
|
||||
Итог: {totalPrice.toLocaleString("ru")}₽
|
||||
</Text>
|
||||
@ -56,7 +65,7 @@ const useProductServicesTableColumns = ({
|
||||
),
|
||||
},
|
||||
] as DataTableColumn<ProductServiceSchema>[],
|
||||
[totalPrice]
|
||||
[totalPrice, isMobile]
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user