From 2bd4fddfa74718c982691453b0403101da4e8bd2 Mon Sep 17 00:00:00 2001 From: AlexSserb Date: Tue, 15 Oct 2024 21:34:39 +0400 Subject: [PATCH] feat: deal prefilling --- src/client/index.ts | 3 + src/client/models/BillStatusUpdateRequest.ts | 3 +- src/client/models/DealPrefillRequest.ts | 9 ++ src/client/services/DealService.ts | 22 +++++ .../Dnd/CreateDealButton/CreateDealButton.tsx | 15 +++- .../CreateDealForm/CreateDealForm.module.css | 5 ++ .../Dnd/CreateDealForm/CreateDealFrom.tsx | 14 +++- .../LeadsPage/contexts/DealPageContext.tsx | 44 +++++++++- .../DealPrefillDrawer.module.css | 33 ++++++++ .../DealPrefillDrawer/DealPrefillDrawer.tsx | 82 +++++++++++++++++++ .../components/Preview/Preview.module.css | 34 ++++++++ .../components/Preview/Preview.tsx | 56 +++++++++++++ .../ProductPreview/ProductPreview.module.css | 33 ++++++++ .../ProductPreview/ProductPreview.tsx | 55 +++++++++++++ .../DealServicesTable/DealServicesTable.tsx | 59 +++++++++++++ .../tables/DealServicesTable/columns.tsx | 30 +++++++ .../tables/DealsTable/DealsTable.tsx | 45 ++++++++++ .../components/tables/DealsTable/columns.tsx | 72 ++++++++++++++++ .../ProductServicesTable.tsx | 31 +++++++ .../tables/ProductServicesTable/columns.tsx | 44 ++++++++++ .../hooks/usePrefillDeal.tsx | 52 ++++++++++++ src/pages/LeadsPage/ui/LeadsPage.tsx | 2 + 22 files changed, 736 insertions(+), 7 deletions(-) create mode 100644 src/client/models/DealPrefillRequest.ts create mode 100644 src/pages/LeadsPage/drawers/DealPrefillDrawer/DealPrefillDrawer.module.css create mode 100644 src/pages/LeadsPage/drawers/DealPrefillDrawer/DealPrefillDrawer.tsx create mode 100644 src/pages/LeadsPage/drawers/DealPrefillDrawer/components/Preview/Preview.module.css create mode 100644 src/pages/LeadsPage/drawers/DealPrefillDrawer/components/Preview/Preview.tsx create mode 100644 src/pages/LeadsPage/drawers/DealPrefillDrawer/components/ProductPreview/ProductPreview.module.css create mode 100644 src/pages/LeadsPage/drawers/DealPrefillDrawer/components/ProductPreview/ProductPreview.tsx create mode 100644 src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/DealServicesTable/DealServicesTable.tsx create mode 100644 src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/DealServicesTable/columns.tsx create mode 100644 src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/DealsTable/DealsTable.tsx create mode 100644 src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/DealsTable/columns.tsx create mode 100644 src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/ProductServicesTable/ProductServicesTable.tsx create mode 100644 src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/ProductServicesTable/columns.tsx create mode 100644 src/pages/LeadsPage/drawers/DealPrefillDrawer/hooks/usePrefillDeal.tsx diff --git a/src/client/index.ts b/src/client/index.ts index c1c6cbc..a5fea07 100644 --- a/src/client/index.ts +++ b/src/client/index.ts @@ -25,6 +25,7 @@ export type { BaseEnumListSchema } from './models/BaseEnumListSchema'; export type { BaseEnumSchema } from './models/BaseEnumSchema'; export type { BaseMarketplaceSchema } from './models/BaseMarketplaceSchema'; export type { BaseShippingWarehouseSchema } from './models/BaseShippingWarehouseSchema'; +export type { BillPaymentInfo } from './models/BillPaymentInfo'; export type { BillPaymentStatus } from './models/BillPaymentStatus'; export type { BillStatusUpdateRequest } from './models/BillStatusUpdateRequest'; export type { Body_upload_product_image } from './models/Body_upload_product_image'; @@ -90,6 +91,8 @@ export type { DealDeleteServicesRequest } from './models/DealDeleteServicesReque export type { DealDeleteServicesResponse } from './models/DealDeleteServicesResponse'; export type { DealGeneralInfoSchema } from './models/DealGeneralInfoSchema'; export type { DealGetAllResponse } from './models/DealGetAllResponse'; +export type { DealPrefillRequest } from './models/DealPrefillRequest'; +export type { DealPrefillResponse } from './models/DealPrefillResponse'; export type { DealProductAddKitRequest } from './models/DealProductAddKitRequest'; export type { DealProductAddKitResponse } from './models/DealProductAddKitResponse'; export type { DealProductSchema } from './models/DealProductSchema'; diff --git a/src/client/models/BillStatusUpdateRequest.ts b/src/client/models/BillStatusUpdateRequest.ts index e1a5848..e1249f4 100644 --- a/src/client/models/BillStatusUpdateRequest.ts +++ b/src/client/models/BillStatusUpdateRequest.ts @@ -2,11 +2,12 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ +import type { BillPaymentInfo } from './BillPaymentInfo'; import type { BillPaymentStatus } from './BillPaymentStatus'; import type { NotificationChannel } from './NotificationChannel'; export type BillStatusUpdateRequest = { listenerTransactionId: number; channel: NotificationChannel; - info: BillPaymentStatus; + info: (BillPaymentInfo | BillPaymentStatus); }; diff --git a/src/client/models/DealPrefillRequest.ts b/src/client/models/DealPrefillRequest.ts new file mode 100644 index 0000000..f5820d2 --- /dev/null +++ b/src/client/models/DealPrefillRequest.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type DealPrefillRequest = { + oldDealId: number; + newDealId: number; +}; + diff --git a/src/client/services/DealService.ts b/src/client/services/DealService.ts index f3dae7f..4198344 100644 --- a/src/client/services/DealService.ts +++ b/src/client/services/DealService.ts @@ -28,6 +28,8 @@ import type { DealDeleteServiceResponse } from '../models/DealDeleteServiceRespo import type { DealDeleteServicesRequest } from '../models/DealDeleteServicesRequest'; import type { DealDeleteServicesResponse } from '../models/DealDeleteServicesResponse'; import type { DealGetAllResponse } from '../models/DealGetAllResponse'; +import type { DealPrefillRequest } from '../models/DealPrefillRequest'; +import type { DealPrefillResponse } from '../models/DealPrefillResponse'; import type { DealProductAddKitRequest } from '../models/DealProductAddKitRequest'; import type { DealProductAddKitResponse } from '../models/DealProductAddKitResponse'; import type { DealQuickCreateRequest } from '../models/DealQuickCreateRequest'; @@ -328,6 +330,26 @@ export class DealService { }, }); } + /** + * Post Prefill Deal + * @returns DealPrefillResponse Successful Response + * @throws ApiError + */ + public static prefillDeal({ + requestBody, + }: { + requestBody: DealPrefillRequest, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/deal/prefill', + body: requestBody, + mediaType: 'application/json', + errors: { + 422: `Validation Error`, + }, + }); + } /** * Services Add * @returns DealAddServicesResponse Successful Response diff --git a/src/components/Dnd/CreateDealButton/CreateDealButton.tsx b/src/components/Dnd/CreateDealButton/CreateDealButton.tsx index e1f9223..c6ba190 100644 --- a/src/components/Dnd/CreateDealButton/CreateDealButton.tsx +++ b/src/components/Dnd/CreateDealButton/CreateDealButton.tsx @@ -6,6 +6,7 @@ import CreateDealFrom from "../CreateDealForm/CreateDealFrom.tsx"; import { DealService } from "../../../client"; import { useQueryClient } from "@tanstack/react-query"; import { dateWithoutTimezone } from "../../../shared/lib/date.ts"; +import { useDealPageContext } from "../../../pages/LeadsPage/contexts/DealPageContext.tsx"; type Props = { onClick: () => void; @@ -14,6 +15,7 @@ const CreateDealButton: FC = () => { const [isCreating, setIsCreating] = useState(false); const [isTransitionEnded, setIsTransitionEnded] = useState(true); const queryClient = useQueryClient(); + const { prefillDeal, setPrefillDeal } = useDealPageContext(); return (
= () => {
{ + setPrefillDeal(undefined); setIsCreating(false); }} onSubmit={quickDeal => { @@ -41,10 +44,18 @@ const CreateDealButton: FC = () => { requestBody: { ...quickDeal, acceptanceDate: dateWithoutTimezone( - quickDeal.acceptanceDate + quickDeal.acceptanceDate, ), }, - }).then(async () => { + }).then(async (result) => { + if (prefillDeal) { + DealService.prefillDeal({ + requestBody: { + oldDealId: prefillDeal.id, + newDealId: result.dealId, + }, + }); + } await queryClient.invalidateQueries({ queryKey: ["getDealSummaries"], }); diff --git a/src/components/Dnd/CreateDealForm/CreateDealForm.module.css b/src/components/Dnd/CreateDealForm/CreateDealForm.module.css index 79921f5..7d973b9 100644 --- a/src/components/Dnd/CreateDealForm/CreateDealForm.module.css +++ b/src/components/Dnd/CreateDealForm/CreateDealForm.module.css @@ -12,3 +12,8 @@ display: flex; gap: rem(10); } + +.button-prefill { + display: grid; + width: 100%; +} \ No newline at end of file diff --git a/src/components/Dnd/CreateDealForm/CreateDealFrom.tsx b/src/components/Dnd/CreateDealForm/CreateDealFrom.tsx index 3c1c58f..a5f5082 100644 --- a/src/components/Dnd/CreateDealForm/CreateDealFrom.tsx +++ b/src/components/Dnd/CreateDealForm/CreateDealFrom.tsx @@ -8,12 +8,14 @@ import { DateTimePicker } from "@mantine/dates"; import ShippingWarehouseAutocomplete from "../../Selects/ShippingWarehouseAutocomplete/ShippingWarehouseAutocomplete.tsx"; import BaseMarketplaceSelect from "../../Selects/BaseMarketplaceSelect/BaseMarketplaceSelect.tsx"; import ServicePriceCategorySelect from "../../Selects/ServicePriceCategorySelect/ServicePriceCategorySelect.tsx"; +import { useDealPageContext } from "../../../pages/LeadsPage/contexts/DealPageContext.tsx"; type Props = { onSubmit: (quickDeal: QuickDeal) => void; onCancel: () => void; }; const CreateDealFrom: FC = ({ onSubmit, onCancel }) => { + const { prefillOnOpen, prefillDeal } = useDealPageContext(); const form = useForm({ initialValues: { name: "", @@ -29,6 +31,9 @@ const CreateDealFrom: FC = ({ onSubmit, onCancel }) => { }, }, }); + + const prefillButtonLabel = prefillDeal ? `Предзаполнено [ID: ${prefillDeal.id}]` : "Предзаполнить"; + return (
= ({ onSubmit, onCancel }) => { {...form.getInputProps("acceptanceDate")} />
- +
+ +
+ { + prefillDeal && + + } + +
+
+ + + ); +}; + +export default DealPrefillDrawer; diff --git a/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/Preview/Preview.module.css b/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/Preview/Preview.module.css new file mode 100644 index 0000000..7d9d02d --- /dev/null +++ b/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/Preview/Preview.module.css @@ -0,0 +1,34 @@ +.container { + display: flex; + gap: rem(10); + max-height: 95vh; + width: 50%; +} + +.products-list { + display: flex; + flex-direction: column; + gap: rem(10); + flex: 2; +} + +.deal-container { + display: flex; + flex-direction: column; + gap: rem(10); + flex: 1; +} + +.deal-container-wrapper { + border: dashed var(--item-border-size) var(--mantine-color-default-border); + border-radius: var(--item-border-radius); + padding: rem(10); +} + +.deal-container-buttons { + gap: rem(10); + display: flex; + flex-direction: column; + margin-top: auto; + width: 100%; +} diff --git a/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/Preview/Preview.tsx b/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/Preview/Preview.tsx new file mode 100644 index 0000000..942a427 --- /dev/null +++ b/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/Preview/Preview.tsx @@ -0,0 +1,56 @@ +import { FC } from "react"; +import styles from "./Preview.module.css"; +import { ScrollArea, Skeleton, Title } from "@mantine/core"; +import { useDealPageContext } from "../../../../contexts/DealPageContext.tsx"; +import DealServicesTable from "../tables/DealServicesTable/DealServicesTable.tsx"; +import ProductPreview from "../ProductPreview/ProductPreview.tsx"; + +const Preview: FC = () => { + const { selectedPrefillDeal } = useDealPageContext(); + + const getTotalPrice = () => { + if (!selectedPrefillDeal) return 0; + const productServicesPrice = selectedPrefillDeal.products.reduce( + (acc, row) => + acc + + row.services.reduce( + (acc2, row2) => acc2 + row2.price * row.quantity, + 0, + ), + 0, + ); + const dealServicesPrice = selectedPrefillDeal.services.reduce( + (acc, row) => acc + row.price * row.quantity, + 0, + ); + return dealServicesPrice + productServicesPrice; + }; + + return ( +
+ + +
+ + Общая стоимость всех услуг:{" "} + {getTotalPrice().toLocaleString("ru")}₽ + + + + +
+ {selectedPrefillDeal?.products.map(product => ( + + ))} +
+
+
+
+
+ ); +}; + +export default Preview; diff --git a/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/ProductPreview/ProductPreview.module.css b/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/ProductPreview/ProductPreview.module.css new file mode 100644 index 0000000..4cca8bd --- /dev/null +++ b/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/ProductPreview/ProductPreview.module.css @@ -0,0 +1,33 @@ +.container { + display: flex; + gap: rem(20); + margin-bottom: rem(10); + flex: 1; +} + +.image-container { + display: flex; + max-height: rem(250); + max-width: rem(250); + height: 100%; +} + +.services-container { + width: 100%; + display: flex; + flex-direction: column; + gap: rem(10); + flex: 1; +} + +.data-container { + max-width: rem(250); + display: flex; + flex-direction: column; + gap: rem(10); + flex: 1; +} + +.attributes-container { + overflow-wrap: break-word; +} diff --git a/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/ProductPreview/ProductPreview.tsx b/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/ProductPreview/ProductPreview.tsx new file mode 100644 index 0000000..a808397 --- /dev/null +++ b/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/ProductPreview/ProductPreview.tsx @@ -0,0 +1,55 @@ +import { FC } from "react"; +import { DealProductSchema, ProductSchema } from "../../../../../../client"; +import { Image, rem, Text, Title } from "@mantine/core"; +import { isNil } from "lodash"; +import { ProductFieldNames } from "../../../../tabs/ProductAndServiceTab/components/ProductView/ProductView.tsx"; +import ProductServicesTable from "../tables/ProductServicesTable/ProductServicesTable.tsx"; +import styles from "./ProductPreview.module.css"; + +type Props = { + product: DealProductSchema; +}; + +const ProductPreview: FC = ({ product }) => { + return ( +
+
+
+ +
+
+ {product.product.name} + + {Object.entries(product.product).map(([key, value]) => { + const fieldName = + ProductFieldNames[key as keyof ProductSchema]; + if (!fieldName || isNil(value) || value === "") return; + return ( + + {fieldName}: {value.toString()}{" "} + + ); + })} + + Штрихкоды: {product.product.barcodes.join(", ")} + + Количество товара: {product.quantity} +
+
+ +
+ +
+
+ ); +}; + +export default ProductPreview; diff --git a/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/DealServicesTable/DealServicesTable.tsx b/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/DealServicesTable/DealServicesTable.tsx new file mode 100644 index 0000000..ba38011 --- /dev/null +++ b/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/DealServicesTable/DealServicesTable.tsx @@ -0,0 +1,59 @@ +import { FC } from "react"; +import { Flex, rem, Title } from "@mantine/core"; +import { DealServiceSchema, DealSummary } from "../../../../../../../client"; +import useDealServicesTableColumns from "./columns.tsx"; +import { BaseTable } from "../../../../../../../components/BaseTable/BaseTable.tsx"; +import { MRT_TableOptions } from "mantine-react-table"; + +type Props = { + items?: DealServiceSchema[]; +}; + +const DealServicesTable: FC = ({ items }) => { + const columns = useDealServicesTableColumns(); + + return ( + + + { + items && items.length > 0 && + <> + + } + /> + + + Итог:{" "} + {items.reduce( + (acc, item) => acc + item.price * item.quantity, + 0, + )} + ₽ + + + } + + + ); +}; +export default DealServicesTable; diff --git a/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/DealServicesTable/columns.tsx b/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/DealServicesTable/columns.tsx new file mode 100644 index 0000000..cc749b3 --- /dev/null +++ b/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/DealServicesTable/columns.tsx @@ -0,0 +1,30 @@ +import { useMemo } from "react"; +import { MRT_ColumnDef } from "mantine-react-table"; +import { DealServiceSchema } from "../../../../../../../client"; + +const useDealServicesTableColumns = () => { + return useMemo[]>( + () => [ + { + header: "Название", + accessorKey: "service.name", + size: 450, + }, + { + header: "Количество", + accessorKey: "quantity", + size: 50, + Cell: ({ cell }) => cell.getValue() + " шт.", + }, + { + accessorKey: "price", + header: "Цена", + size: 50, + Cell: ({ cell }) => cell.getValue() + " ₽", + }, + ], + [] + ); +}; + +export default useDealServicesTableColumns; diff --git a/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/DealsTable/DealsTable.tsx b/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/DealsTable/DealsTable.tsx new file mode 100644 index 0000000..78a0cfd --- /dev/null +++ b/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/DealsTable/DealsTable.tsx @@ -0,0 +1,45 @@ +import { FC, useEffect } from "react"; +import useDealsTableColumns from "./columns.tsx"; +import { DealSummary } from "../../../../../../../client"; +import { useDealPageContext } from "../../../../../contexts/DealPageContext.tsx"; +import { BaseTable } from "../../../../../../../components/BaseTable/BaseTable.tsx"; + +type Props = { + items: DealSummary[]; +}; + +const DealsTable: FC = ({ items }) => { + const { selectPrefillDeal } = useDealPageContext(); + const columns = useDealsTableColumns(); + const defaultSorting = [{ id: "createdAt", desc: false }]; + + useEffect(() => { + if (items.length < 1) return; + selectPrefillDeal(items[0].id); + }, []); + + return ( + + ); +}; + +export default DealsTable; diff --git a/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/DealsTable/columns.tsx b/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/DealsTable/columns.tsx new file mode 100644 index 0000000..2928d12 --- /dev/null +++ b/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/DealsTable/columns.tsx @@ -0,0 +1,72 @@ +import { useMemo } from "react"; +import { MRT_ColumnDef } from "mantine-react-table"; +import { ActionIcon, Image, Radio } from "@mantine/core"; +import { DealSummary } from "../../../../../../../client"; +import { useDealPageContext } from "../../../../../contexts/DealPageContext.tsx"; + +const useDealsTableColumns = () => { + return useMemo[]>( + () => [ + { + accessorKey: "select", + header: "", + size: 5, + enableSorting: false, + Cell: ({ row }) => { + const { selectPrefillDeal, selectedPrefillDeal } = useDealPageContext(); + const checked = row.original.id === selectedPrefillDeal?.id; + return ( + { + selectPrefillDeal(row.original.id); + }} + /> + ); + }, + }, + { + accessorKey: "id", + header: "ID", + size: 20, + }, + { + accessorKey: "clientName", + header: "Клиент", + size: 60, + enableSorting: false, + }, + { + accessorKey: "name", + header: "Название", + enableSorting: false, + size: 60, + }, + { + header: "Дата создания", + accessorKey: "createdAt", + size: 10, + Cell: ({ row }) => + new Date(row.original.createdAt).toLocaleString("ru-RU").substring(0, 17), + enableSorting: true, + sortingFn: (rowA, rowB) => + new Date(rowB.original.createdAt).getTime() - + new Date(rowA.original.createdAt).getTime(), + }, + { + header: "МП", + size: 5, + Cell: ({ row }) => ( + + + + ), + }, + ], + [], + ); +}; + +export default useDealsTableColumns; diff --git a/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/ProductServicesTable/ProductServicesTable.tsx b/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/ProductServicesTable/ProductServicesTable.tsx new file mode 100644 index 0000000..c2807c1 --- /dev/null +++ b/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/ProductServicesTable/ProductServicesTable.tsx @@ -0,0 +1,31 @@ +import { FC } from "react"; +import { MRT_TableOptions } from "mantine-react-table"; +import { DealProductServiceSchema } from "../../../../../../../client"; +import { BaseTable } from "../../../../../../../components/BaseTable/BaseTable.tsx"; +import useProductServicesTableColumns from "./columns.tsx"; + + +type Props = { + items: DealProductServiceSchema[]; + quantity: number; +}; + +const ProductServicesTable: FC = ({ items, quantity }) => { + const columns = useProductServicesTableColumns({ data: items, quantity }); + + return ( + + } + /> + ); +}; +export default ProductServicesTable; diff --git a/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/ProductServicesTable/columns.tsx b/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/ProductServicesTable/columns.tsx new file mode 100644 index 0000000..91503ce --- /dev/null +++ b/src/pages/LeadsPage/drawers/DealPrefillDrawer/components/tables/ProductServicesTable/columns.tsx @@ -0,0 +1,44 @@ +import { useMemo } from "react"; +import { MRT_ColumnDef } from "mantine-react-table"; +import { DealProductServiceSchema } from "../../../../../../../client"; +import { useSelector } from "react-redux"; +import { RootState } from "../../../../../../../redux/store.ts"; + +type Props = { + data: DealProductServiceSchema[]; + quantity: number; +}; + +const useProductServicesTableColumns = (props: Props) => { + const { data, quantity } = props; + const authState = useSelector((state: RootState) => state.auth); + const totalPrice = useMemo( + () => data.reduce((acc, row) => acc + row.price * quantity, 0), + [data, quantity] + ); + const hideGuestColumns = ["service.cost"]; + return useMemo[]>( + () => [ + { + accessorKey: "service.name", + header: "Услуга", + }, + { + accessorKey: "price", + header: "Цена", + size: 5, + Cell: ({ cell }) => cell.getValue() + " ₽", + Footer: () => <>Итог: {totalPrice.toLocaleString("ru")}₽, + }, + ], + [totalPrice] + ).filter( + columnDef => + !( + hideGuestColumns.includes(columnDef.accessorKey || "") && + authState.isGuest + ) + ); +}; + +export default useProductServicesTableColumns; diff --git a/src/pages/LeadsPage/drawers/DealPrefillDrawer/hooks/usePrefillDeal.tsx b/src/pages/LeadsPage/drawers/DealPrefillDrawer/hooks/usePrefillDeal.tsx new file mode 100644 index 0000000..fa32b16 --- /dev/null +++ b/src/pages/LeadsPage/drawers/DealPrefillDrawer/hooks/usePrefillDeal.tsx @@ -0,0 +1,52 @@ +import { useForm } from "@mantine/form"; +import { useEffect, useState } from "react"; +import { BaseMarketplaceSchema } from "../../../../../client"; +import { useDealSummariesFull } from "../../../hooks/useDealSummaries.tsx"; + +type State = { + idOrName: string | null; + marketplace: BaseMarketplaceSchema | null; +}; + +const usePrefillDeal = () => { + const { objects } = useDealSummariesFull(); + const form = useForm({ + initialValues: { + idOrName: null, + marketplace: null, + }, + }); + const [data, setData] = useState(objects); + + const applyFilters = () => { + let result = objects; + if (form.values.idOrName) { + if (isNaN(parseInt(form.values.idOrName))) { + const name: string = form.values.idOrName.toLowerCase(); + result = result.filter( + obj => obj.name.toLowerCase().search(name) !== -1, + ); + } + else { + const id = parseInt(form.values.idOrName); + result = result.filter( + obj => obj.id === id, + ); + } + } + if (form.values.marketplace) { + result = result.filter( + obj => obj.baseMarketplace?.key === form.values.marketplace?.key, + ); + } + setData(result); + }; + + useEffect(() => { + applyFilters(); + }, [form.values, objects]); + + return { data, form }; +}; + +export default usePrefillDeal; diff --git a/src/pages/LeadsPage/ui/LeadsPage.tsx b/src/pages/LeadsPage/ui/LeadsPage.tsx index f9e80ca..34a061c 100644 --- a/src/pages/LeadsPage/ui/LeadsPage.tsx +++ b/src/pages/LeadsPage/ui/LeadsPage.tsx @@ -20,6 +20,7 @@ import ClientSelectNew from "../../../components/Selects/ClientSelectNew/ClientS import DealsTable from "../../DealsPage/components/DealsTable/DealsTable.tsx"; import { motion } from "framer-motion"; import { dateWithoutTimezone } from "../../../shared/lib/date.ts"; +import DealPrefillDrawer from "../drawers/DealPrefillDrawer/DealPrefillDrawer.tsx"; enum DisplayMode { BOARD, @@ -410,6 +411,7 @@ export const LeadsPage: FC = () => { {getBody()} + );