diff --git a/src/components/Dnd/DealSummaryCard/DealSummaryCard.tsx b/src/components/Dnd/DealSummaryCard/DealSummaryCard.tsx index 86724b9..a31fe3a 100644 --- a/src/components/Dnd/DealSummaryCard/DealSummaryCard.tsx +++ b/src/components/Dnd/DealSummaryCard/DealSummaryCard.tsx @@ -118,7 +118,7 @@ const DealSummaryCard: FC = ({ dealSummary }) => { - Приемка: {(new Date(dealSummary.receivingSlotDate)).toLocaleDateString("ru-RU")} + Слот: {(new Date(dealSummary.receivingSlotDate)).toLocaleDateString("ru-RU")} )} diff --git a/src/pages/LeadsPage/drawers/DealEditDrawer/DealEditDrawer.tsx b/src/pages/LeadsPage/drawers/DealEditDrawer/DealEditDrawer.tsx index 63cf2d7..46ce31d 100644 --- a/src/pages/LeadsPage/drawers/DealEditDrawer/DealEditDrawer.tsx +++ b/src/pages/LeadsPage/drawers/DealEditDrawer/DealEditDrawer.tsx @@ -1,290 +1,281 @@ -import { Box, Drawer, rem, Tabs, Text } from "@mantine/core"; -import { FC, useEffect, useRef } from "react"; -import DealServicesTable from "../../components/DealServicesTable/DealServicesTable.tsx"; +import { Box, Drawer, rem, Tabs } from "@mantine/core"; +import { FC, useEffect } from "react"; import { useDealPageContext } from "../../contexts/DealPageContext.tsx"; -import { - DealProductSchema, - DealService, - DealServiceSchema, -} from "../../../../client"; -import { notifications } from "../../../../shared/lib/notifications.ts"; -import { modals } from "@mantine/modals"; -import { BaseTableRef } from "../../../../components/BaseTable/BaseTable.tsx"; -import DealProductsTable from "../../components/DealProductsTable/DealProductsTable.tsx"; -import { IconBox, IconCalendarUser, IconSettings } from "@tabler/icons-react"; +import { IconBox, IconCalendarUser, IconSettings, IconUser } from "@tabler/icons-react"; import DealStatusChangeTable from "../../components/DealStatusChangeTable/DealStatusChangeTable.tsx"; import DealEditDrawerGeneralTab from "./tabs/DealEditDrawerGeneralTab.tsx"; import { useQueryClient } from "@tanstack/react-query"; import ProductAndServiceTab from "../../tabs/ProductAndServiceTab/ProductAndServiceTab.tsx"; import { motion } from "framer-motion"; +import ClientTab from "./tabs/ClientTab.tsx"; // import styles from './DealEditDrawer.module.css'; -const useDealServicesTableState = () => { - const { selectedDeal, setSelectedDeal } = useDealPageContext(); - const tableRef = useRef>(null); +// const useDealServicesTableState = () => { +// const { selectedDeal, setSelectedDeal } = useDealPageContext(); +// const tableRef = useRef>(null); +// +// const onServiceUpdate = (service: DealServiceSchema) => { +// if (!selectedDeal) return; +// DealService.updateDealService({ +// requestBody: { +// dealId: selectedDeal.id, +// service, +// }, +// }).then(async ({ ok, message }) => { +// if (!ok) { +// notifications.guess(ok, { message }); +// return; +// } +// await DealService.getDealById({ dealId: selectedDeal.id }).then( +// setSelectedDeal, +// ); +// }); +// }; +// const onServiceDelete = (service: DealServiceSchema) => { +// if (!selectedDeal) return; +// modals.openConfirmModal({ +// title: "Удаление услуги", +// children: ( +// <> +// Вы уверены, что хотите удалить услугу: +// {service.service.name}? +// +// ), +// onConfirm: () => { +// DealService.deleteDealService({ +// requestBody: { +// dealId: selectedDeal.id, +// serviceId: service.service.id, +// }, +// }).then(async ({ ok, message }) => { +// if (!ok) { +// notifications.guess(ok, { message }); +// return; +// } +// await DealService.getDealById({ +// dealId: selectedDeal.id, +// }).then(setSelectedDeal); +// }); +// }, +// labels: { +// cancel: "Отмена", +// confirm: "Удалить", +// }, +// }); +// }; +// const onServiceCreate = (service: DealServiceSchema) => { +// if (!selectedDeal) return; +// DealService.addDealService({ +// requestBody: { +// dealId: selectedDeal.id, +// serviceId: service.service.id, +// quantity: service.quantity, +// price: service.price, +// }, +// }).then(async ({ ok, message }) => { +// if (!ok) { +// notifications.guess(ok, { message }); +// return; +// } +// await DealService.getDealById({ dealId: selectedDeal.id }).then( +// setSelectedDeal, +// ); +// }); +// }; +// const onsServiceMultipleDelete = (items: DealServiceSchema[]) => { +// if (!selectedDeal) return; +// modals.openConfirmModal({ +// title: "Удаление услуг", +// children: ( +// <> +// +// Вы уверены, что хотите удалить выбранные услуги? +// +// +// ), +// onConfirm: () => { +// DealService.deleteMultipleDealServices({ +// requestBody: { +// dealId: selectedDeal.id, +// serviceIds: items.map(item => item.service.id), +// }, +// }).then(async ({ ok, message }) => { +// if (!ok) { +// notifications.guess(ok, { message }); +// return; +// } +// await DealService.getDealById({ +// dealId: selectedDeal.id, +// }).then(setSelectedDeal); +// }); +// }, +// labels: { +// cancel: "Отмена", +// confirm: "Удалить", +// }, +// }); +// }; +// +// return { +// onServiceUpdate, +// onServiceDelete, +// onServiceCreate, +// onsServiceMultipleDelete, +// tableRef, +// services: selectedDeal?.services || [], +// }; +// }; +// const DealEditDrawerServicesTable = () => { +// const { +// services, +// tableRef, +// onServiceCreate, +// onServiceUpdate, +// onServiceDelete, +// onsServiceMultipleDelete, +// } = useDealServicesTableState(); +// +// return ( +// +// ); +// }; - const onServiceUpdate = (service: DealServiceSchema) => { - if (!selectedDeal) return; - DealService.updateDealService({ - requestBody: { - dealId: selectedDeal.id, - service, - }, - }).then(async ({ ok, message }) => { - if (!ok) { - notifications.guess(ok, { message }); - return; - } - await DealService.getDealById({ dealId: selectedDeal.id }).then( - setSelectedDeal - ); - }); - }; - const onServiceDelete = (service: DealServiceSchema) => { - if (!selectedDeal) return; - modals.openConfirmModal({ - title: "Удаление услуги", - children: ( - <> - Вы уверены, что хотите удалить услугу: - {service.service.name}? - - ), - onConfirm: () => { - DealService.deleteDealService({ - requestBody: { - dealId: selectedDeal.id, - serviceId: service.service.id, - }, - }).then(async ({ ok, message }) => { - if (!ok) { - notifications.guess(ok, { message }); - return; - } - await DealService.getDealById({ - dealId: selectedDeal.id, - }).then(setSelectedDeal); - }); - }, - labels: { - cancel: "Отмена", - confirm: "Удалить", - }, - }); - }; - const onServiceCreate = (service: DealServiceSchema) => { - if (!selectedDeal) return; - DealService.addDealService({ - requestBody: { - dealId: selectedDeal.id, - serviceId: service.service.id, - quantity: service.quantity, - price: service.price, - }, - }).then(async ({ ok, message }) => { - if (!ok) { - notifications.guess(ok, { message }); - return; - } - await DealService.getDealById({ dealId: selectedDeal.id }).then( - setSelectedDeal - ); - }); - }; - const onsServiceMultipleDelete = (items: DealServiceSchema[]) => { - if (!selectedDeal) return; - modals.openConfirmModal({ - title: "Удаление услуг", - children: ( - <> - - Вы уверены, что хотите удалить выбранные услуги? - - - ), - onConfirm: () => { - DealService.deleteMultipleDealServices({ - requestBody: { - dealId: selectedDeal.id, - serviceIds: items.map(item => item.service.id), - }, - }).then(async ({ ok, message }) => { - if (!ok) { - notifications.guess(ok, { message }); - return; - } - await DealService.getDealById({ - dealId: selectedDeal.id, - }).then(setSelectedDeal); - }); - }, - labels: { - cancel: "Отмена", - confirm: "Удалить", - }, - }); - }; - - return { - onServiceUpdate, - onServiceDelete, - onServiceCreate, - onsServiceMultipleDelete, - tableRef, - services: selectedDeal?.services || [], - }; -}; -const DealEditDrawerServicesTable = () => { - const { - services, - tableRef, - onServiceCreate, - onServiceUpdate, - onServiceDelete, - onsServiceMultipleDelete, - } = useDealServicesTableState(); - - return ( - - ); -}; - -const useDealProductTableState = () => { - const { selectedDeal, setSelectedDeal } = useDealPageContext(); - - const onProductUpdate = (product: DealProductSchema) => { - if (!selectedDeal) return; - DealService.updateDealProduct({ - requestBody: { - dealId: selectedDeal.id, - product: product, - }, - }).then(async ({ ok, message }) => { - notifications.guess(ok, { message }); - if (!ok) return; - await DealService.getDealById({ dealId: selectedDeal.id }).then( - setSelectedDeal - ); - }); - }; - const onProductDelete = (product: DealProductSchema) => { - if (!selectedDeal) return; - modals.openConfirmModal({ - title: "Удаление товара", - children: ( - <> - Вы уверены, что хотите удалить товар: - {product.product.name}? - - ), - onConfirm: () => { - DealService.deleteDealProduct({ - requestBody: { - dealId: selectedDeal.id, - productId: product.product.id, - }, - }).then(async ({ ok, message }) => { - if (!ok) { - notifications.guess(ok, { message }); - return; - } - await DealService.getDealById({ - dealId: selectedDeal.id, - }).then(setSelectedDeal); - }); - }, - labels: { - cancel: "Отмена", - confirm: "Удалить", - }, - }); - }; - const onProductCreate = (product: DealProductSchema) => { - if (!selectedDeal) return; - DealService.addDealProduct({ - requestBody: { - dealId: selectedDeal.id, - product: product, - }, - }).then(async ({ ok, message }) => { - if (!ok) { - notifications.guess(ok, { message }); - return; - } - await DealService.getDealById({ dealId: selectedDeal.id }).then( - setSelectedDeal - ); - }); - }; - const onProductMultipleDelete = (items: DealProductSchema[]) => { - if (!selectedDeal) return; - modals.openConfirmModal({ - title: "Удаление товаров", - children: ( - <> - - Вы уверены, что хотите удалить выбранные товары? - - - ), - onConfirm: () => { - DealService.deleteMultipleDealProducts({ - requestBody: { - dealId: selectedDeal.id, - productIds: items.map(item => item.product.id), - }, - }).then(async ({ ok, message }) => { - if (!ok) { - notifications.guess(ok, { message }); - return; - } - await DealService.getDealById({ - dealId: selectedDeal.id, - }).then(setSelectedDeal); - }); - }, - labels: { - cancel: "Отмена", - confirm: "Удалить", - }, - }); - }; - return { - clientId: selectedDeal?.clientId || -1, - products: selectedDeal?.products || [], - onProductUpdate, - onProductDelete, - onProductCreate, - onProductMultipleDelete, - }; -}; -const DealEditDrawerProductsTable = () => { - const { - products, - clientId, - onProductUpdate, - onProductDelete, - onProductCreate, - onProductMultipleDelete, - } = useDealProductTableState(); - return ( - - ); -}; +// const useDealProductTableState = () => { +// const { selectedDeal, setSelectedDeal } = useDealPageContext(); +// +// const onProductUpdate = (product: DealProductSchema) => { +// if (!selectedDeal) return; +// DealService.updateDealProduct({ +// requestBody: { +// dealId: selectedDeal.id, +// product: product, +// }, +// }).then(async ({ ok, message }) => { +// notifications.guess(ok, { message }); +// if (!ok) return; +// await DealService.getDealById({ dealId: selectedDeal.id }).then( +// setSelectedDeal, +// ); +// }); +// }; +// const onProductDelete = (product: DealProductSchema) => { +// if (!selectedDeal) return; +// modals.openConfirmModal({ +// title: "Удаление товара", +// children: ( +// <> +// Вы уверены, что хотите удалить товар: +// {product.product.name}? +// +// ), +// onConfirm: () => { +// DealService.deleteDealProduct({ +// requestBody: { +// dealId: selectedDeal.id, +// productId: product.product.id, +// }, +// }).then(async ({ ok, message }) => { +// if (!ok) { +// notifications.guess(ok, { message }); +// return; +// } +// await DealService.getDealById({ +// dealId: selectedDeal.id, +// }).then(setSelectedDeal); +// }); +// }, +// labels: { +// cancel: "Отмена", +// confirm: "Удалить", +// }, +// }); +// }; +// const onProductCreate = (product: DealProductSchema) => { +// if (!selectedDeal) return; +// DealService.addDealProduct({ +// requestBody: { +// dealId: selectedDeal.id, +// product: product, +// }, +// }).then(async ({ ok, message }) => { +// if (!ok) { +// notifications.guess(ok, { message }); +// return; +// } +// await DealService.getDealById({ dealId: selectedDeal.id }).then( +// setSelectedDeal, +// ); +// }); +// }; +// const onProductMultipleDelete = (items: DealProductSchema[]) => { +// if (!selectedDeal) return; +// modals.openConfirmModal({ +// title: "Удаление товаров", +// children: ( +// <> +// +// Вы уверены, что хотите удалить выбранные товары? +// +// +// ), +// onConfirm: () => { +// DealService.deleteMultipleDealProducts({ +// requestBody: { +// dealId: selectedDeal.id, +// productIds: items.map(item => item.product.id), +// }, +// }).then(async ({ ok, message }) => { +// if (!ok) { +// notifications.guess(ok, { message }); +// return; +// } +// await DealService.getDealById({ +// dealId: selectedDeal.id, +// }).then(setSelectedDeal); +// }); +// }, +// labels: { +// cancel: "Отмена", +// confirm: "Удалить", +// }, +// }); +// }; +// return { +// clientId: selectedDeal?.clientId || -1, +// products: selectedDeal?.products || [], +// onProductUpdate, +// onProductDelete, +// onProductCreate, +// onProductMultipleDelete, +// }; +// }; +// const DealEditDrawerProductsTable = () => { +// const { +// products, +// clientId, +// onProductUpdate, +// onProductDelete, +// onProductCreate, +// onProductMultipleDelete, +// } = useDealProductTableState(); +// return ( +// +// ); +// }; const useDealStatusChangeState = () => { const { selectedDeal } = useDealPageContext(); @@ -292,6 +283,7 @@ const useDealStatusChangeState = () => { statusHistory: selectedDeal?.statusHistory || [], }; }; + const DealEditDrawerStatusChangeTable = () => { const { statusHistory } = useDealStatusChangeState(); @@ -341,6 +333,11 @@ const DealEditDrawer: FC = () => { leftSection={}> Общее + }> + Клиент + }> @@ -365,6 +362,16 @@ const DealEditDrawer: FC = () => { + + + + + + + { - - - - - - - - - - ); diff --git a/src/pages/LeadsPage/drawers/DealEditDrawer/tabs/ClientTab.tsx b/src/pages/LeadsPage/drawers/DealEditDrawer/tabs/ClientTab.tsx new file mode 100644 index 0000000..4ab7bcb --- /dev/null +++ b/src/pages/LeadsPage/drawers/DealEditDrawer/tabs/ClientTab.tsx @@ -0,0 +1,92 @@ +import { Button, Fieldset, Flex, rem, TextInput } from "@mantine/core"; +import { useDealPageContext } from "../../../contexts/DealPageContext.tsx"; +import { useForm } from "@mantine/form"; +import { DealGeneralFormType } from "./DealEditDrawerGeneralTab.tsx"; +import { ClientService, DealSchema, DealService } from "../../../../../client"; +import { isEqual } from "lodash"; +import { notifications } from "../../../../../shared/lib/notifications.ts"; +import { useQueryClient } from "@tanstack/react-query"; + +const ClientTab = () => { + const { selectedDeal: deal, setSelectedDeal } = useDealPageContext(); + const initialValues: DealGeneralFormType = deal as DealSchema; + const queryClient = useQueryClient(); + + const form = useForm( + { + initialValues: initialValues, + validate: { + name: (value: string) => value.length > 0 ? null : "Название сделки не может быть пустым", + }, + }, + ); + const hasChanges = !isEqual(form.values, initialValues); + const updateClientInfo = async (values: DealGeneralFormType) => { + return ClientService.updateClient({ + requestBody: { + data: values.client, + }, + }).then(({ ok, message }) => notifications.guess(ok, { message })); + }; + const update = async () => { + return DealService.getDealById({ dealId: form.values.id }).then(data => { + setSelectedDeal(data); + form.setInitialValues(data); + queryClient.invalidateQueries({ + queryKey: ["getDealSummaries"], + }); + }); + }; + const handleSave = () => { + updateClientInfo(form.values).then(async () => { + await update(); + }); + }; + const handleCancel = () => { + form.setInitialValues(initialValues); + }; + return ( + + +
+ + + + + +
+
+ + + + +
+ + ); +}; +export default ClientTab; \ No newline at end of file diff --git a/src/pages/LeadsPage/drawers/DealEditDrawer/tabs/DealEditDrawerGeneralTab.tsx b/src/pages/LeadsPage/drawers/DealEditDrawer/tabs/DealEditDrawerGeneralTab.tsx index 0598782..b3f4fb4 100644 --- a/src/pages/LeadsPage/drawers/DealEditDrawer/tabs/DealEditDrawerGeneralTab.tsx +++ b/src/pages/LeadsPage/drawers/DealEditDrawer/tabs/DealEditDrawerGeneralTab.tsx @@ -35,7 +35,7 @@ type Props = { deal: DealSchema; }; -type FormType = Omit; +export type DealGeneralFormType = Omit; const Content: FC = ({ deal }) => { const { setSelectedDeal } = useDealPageContext(); @@ -44,7 +44,7 @@ const Content: FC = ({ deal }) => { // ignore typescript - const initialValues: FormType = { + const initialValues: DealGeneralFormType = { ...deal, // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error @@ -53,7 +53,7 @@ const Content: FC = ({ deal }) => { // @ts-expect-error receivingSlotDate: deal.receivingSlotDate ? new Date(deal.receivingSlotDate) : null, }; - const form = useForm({ + const form = useForm({ initialValues: initialValues, validate: { name: (value: string) => @@ -62,7 +62,7 @@ const Content: FC = ({ deal }) => { : "Название сделки не может быть пустым", }, }); - const updateDealInfo = async (values: FormType) => { + const updateDealInfo = async (values: DealGeneralFormType) => { return DealService.updateDealGeneralInfo({ requestBody: { dealId: deal.id, @@ -83,14 +83,14 @@ const Content: FC = ({ deal }) => { }); }); }; - const updateClientInfo = async (values: FormType) => { + const updateClientInfo = async (values: DealGeneralFormType) => { return ClientService.updateClient({ requestBody: { data: values.client, }, }).then(({ ok, message }) => notifications.guess(ok, { message })); }; - const handleSubmit = async (values: FormType) => { + const handleSubmit = async (values: DealGeneralFormType) => { // Updating client info if there changes if (!isEqual(values.client, deal.client)) { await updateClientInfo(values);