feat: price by category

This commit is contained in:
2024-09-27 04:41:18 +03:00
parent f30c55456c
commit c5f839d9ef
44 changed files with 1316 additions and 681 deletions

View File

@@ -1,22 +1,22 @@
import {Box, Drawer, rem, Tabs, Text} from "@mantine/core";
import {FC, useEffect, useRef} from "react";
import { Box, Drawer, rem, Tabs, Text } from "@mantine/core";
import { FC, useEffect, useRef } from "react";
import DealServicesTable from "../../components/DealServicesTable/DealServicesTable.tsx";
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 { 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 } from "@tabler/icons-react";
import DealStatusChangeTable from "../../components/DealStatusChangeTable/DealStatusChangeTable.tsx";
import DealEditDrawerGeneralTab from "./tabs/DealEditDrawerGeneralTab.tsx";
import {useQueryClient} from "@tanstack/react-query";
import { useQueryClient } from "@tanstack/react-query";
import ProductAndServiceTab from "../../tabs/ProductAndServiceTab/ProductAndServiceTab.tsx";
import {motion} from "framer-motion";
import { motion } from "framer-motion";
// import styles from './DealEditDrawer.module.css';
const useDealServicesTableState = () => {
const {selectedDeal, setSelectedDeal} = useDealPageContext();
const { selectedDeal, setSelectedDeal } = useDealPageContext();
const tableRef = useRef<BaseTableRef<DealServiceSchema>>(null);
const onServiceUpdate = (service: DealServiceSchema) => {
@@ -24,18 +24,18 @@ const useDealServicesTableState = () => {
DealService.updateDealService({
requestBody: {
dealId: selectedDeal.id,
service
}
}).then(async ({ok, message}) => {
service,
},
}).then(async ({ ok, message }) => {
if (!ok) {
notifications.guess(ok, {message});
notifications.guess(ok, { message });
return;
}
await DealService.getDealById({dealId: selectedDeal.id})
.then(setSelectedDeal)
})
}
await DealService.getDealById({ dealId: selectedDeal.id })
.then(setSelectedDeal);
});
};
const onServiceDelete = (service: DealServiceSchema) => {
if (!selectedDeal) return;
modals.openConfirmModal({
@@ -56,23 +56,23 @@ const useDealServicesTableState = () => {
DealService.deleteDealService({
requestBody: {
dealId: selectedDeal.id,
serviceId: service.service.id
}
}).then(async ({ok, message}) => {
serviceId: service.service.id,
},
}).then(async ({ ok, message }) => {
if (!ok) {
notifications.guess(ok, {message});
notifications.guess(ok, { message });
return;
}
await DealService.getDealById({dealId: selectedDeal.id})
.then(setSelectedDeal)
})
await DealService.getDealById({ dealId: selectedDeal.id })
.then(setSelectedDeal);
});
},
labels: {
cancel: "Отмена",
confirm: "Удалить"
}
})
}
confirm: "Удалить",
},
});
};
const onServiceCreate = (service: DealServiceSchema) => {
if (!selectedDeal) return;
DealService.addDealService({
@@ -80,17 +80,17 @@ const useDealServicesTableState = () => {
dealId: selectedDeal.id,
serviceId: service.service.id,
quantity: service.quantity,
price: service.price
}
}).then(async ({ok, message}) => {
price: service.price,
},
}).then(async ({ ok, message }) => {
if (!ok) {
notifications.guess(ok, {message});
notifications.guess(ok, { message });
return;
}
await DealService.getDealById({dealId: selectedDeal.id})
.then(setSelectedDeal)
})
}
await DealService.getDealById({ dealId: selectedDeal.id })
.then(setSelectedDeal);
});
};
const onsServiceMultipleDelete = (items: DealServiceSchema[]) => {
if (!selectedDeal) return;
modals.openConfirmModal({
@@ -106,23 +106,23 @@ const useDealServicesTableState = () => {
DealService.deleteMultipleDealServices({
requestBody: {
dealId: selectedDeal.id,
serviceIds: items.map(item => item.service.id)
}
}).then(async ({ok, message}) => {
serviceIds: items.map(item => item.service.id),
},
}).then(async ({ ok, message }) => {
if (!ok) {
notifications.guess(ok, {message});
notifications.guess(ok, { message });
return;
}
await DealService.getDealById({dealId: selectedDeal.id})
.then(setSelectedDeal)
})
await DealService.getDealById({ dealId: selectedDeal.id })
.then(setSelectedDeal);
});
},
labels: {
cancel: "Отмена",
confirm: "Удалить"
}
})
}
confirm: "Удалить",
},
});
};
return {
onServiceUpdate,
@@ -130,9 +130,9 @@ const useDealServicesTableState = () => {
onServiceCreate,
onsServiceMultipleDelete,
tableRef,
services: selectedDeal?.services || []
}
}
services: selectedDeal?.services || [],
};
};
const DealEditDrawerServicesTable = () => {
const {
services,
@@ -140,7 +140,7 @@ const DealEditDrawerServicesTable = () => {
onServiceCreate,
onServiceUpdate,
onServiceDelete,
onsServiceMultipleDelete
onsServiceMultipleDelete,
} = useDealServicesTableState();
return (<DealServicesTable
@@ -150,26 +150,26 @@ const DealEditDrawerServicesTable = () => {
onDelete={onServiceDelete}
onCreate={onServiceCreate}
onMultipleDelete={onsServiceMultipleDelete}
/>)
}
/>);
};
const useDealProductTableState = () => {
const {selectedDeal, setSelectedDeal} = useDealPageContext();
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});
product: product,
},
}).then(async ({ ok, message }) => {
notifications.guess(ok, { message });
if (!ok) return;
await DealService.getDealById({dealId: selectedDeal.id})
.then(setSelectedDeal)
})
}
await DealService.getDealById({ dealId: selectedDeal.id })
.then(setSelectedDeal);
});
};
const onProductDelete = (product: DealProductSchema) => {
if (!selectedDeal) return;
modals.openConfirmModal({
@@ -190,39 +190,39 @@ const useDealProductTableState = () => {
DealService.deleteDealProduct({
requestBody: {
dealId: selectedDeal.id,
productId: product.product.id
}
}).then(async ({ok, message}) => {
productId: product.product.id,
},
}).then(async ({ ok, message }) => {
if (!ok) {
notifications.guess(ok, {message});
notifications.guess(ok, { message });
return;
}
await DealService.getDealById({dealId: selectedDeal.id})
.then(setSelectedDeal)
})
await DealService.getDealById({ dealId: selectedDeal.id })
.then(setSelectedDeal);
});
},
labels: {
cancel: "Отмена",
confirm: "Удалить"
}
})
}
confirm: "Удалить",
},
});
};
const onProductCreate = (product: DealProductSchema) => {
if (!selectedDeal) return;
DealService.addDealProduct({
requestBody: {
dealId: selectedDeal.id,
product: product
}
}).then(async ({ok, message}) => {
product: product,
},
}).then(async ({ ok, message }) => {
if (!ok) {
notifications.guess(ok, {message});
notifications.guess(ok, { message });
return;
}
await DealService.getDealById({dealId: selectedDeal.id})
.then(setSelectedDeal)
})
}
await DealService.getDealById({ dealId: selectedDeal.id })
.then(setSelectedDeal);
});
};
const onProductMultipleDelete = (items: DealProductSchema[]) => {
if (!selectedDeal) return;
modals.openConfirmModal({
@@ -238,32 +238,32 @@ const useDealProductTableState = () => {
DealService.deleteMultipleDealProducts({
requestBody: {
dealId: selectedDeal.id,
productIds: items.map(item => item.product.id)
}
}).then(async ({ok, message}) => {
productIds: items.map(item => item.product.id),
},
}).then(async ({ ok, message }) => {
if (!ok) {
notifications.guess(ok, {message});
notifications.guess(ok, { message });
return;
}
await DealService.getDealById({dealId: selectedDeal.id})
.then(setSelectedDeal)
})
await DealService.getDealById({ dealId: selectedDeal.id })
.then(setSelectedDeal);
});
},
labels: {
cancel: "Отмена",
confirm: "Удалить"
}
})
}
confirm: "Удалить",
},
});
};
return {
clientId: selectedDeal?.clientId || -1,
products: selectedDeal?.products || [],
onProductUpdate,
onProductDelete,
onProductCreate,
onProductMultipleDelete
}
}
onProductMultipleDelete,
};
};
const DealEditDrawerProductsTable = () => {
const {
products,
@@ -283,79 +283,86 @@ const DealEditDrawerProductsTable = () => {
onCreate={onProductCreate}
/>
)
}
);
};
const useDealStatusChangeState = () => {
const {selectedDeal} = useDealPageContext();
const { selectedDeal } = useDealPageContext();
return {
statusHistory: selectedDeal?.statusHistory || []
}
}
statusHistory: selectedDeal?.statusHistory || [],
};
};
const DealEditDrawerStatusChangeTable = () => {
const {statusHistory} = useDealStatusChangeState();
const { statusHistory } = useDealStatusChangeState();
return (
<DealStatusChangeTable
items={statusHistory}
/>)
}
/>);
};
const useDealEditDrawerState = () => {
const {selectedDeal, setSelectedDeal} = useDealPageContext();
const { selectedDeal, setSelectedDeal } = useDealPageContext();
return {
isVisible: selectedDeal !== undefined,
onClose: () => setSelectedDeal(undefined)
}
}
onClose: () => setSelectedDeal(undefined),
};
};
const DealEditDrawer: FC = () => {
const {isVisible, onClose} = useDealEditDrawerState();
const { isVisible, onClose } = useDealEditDrawerState();
const queryClient = useQueryClient();
useEffect(() => {
if (isVisible) return;
queryClient.invalidateQueries({queryKey: ["getDealSummaries"]})
queryClient.invalidateQueries({ queryKey: ["getDealSummaries"] });
}, [isVisible]);
return (
<Drawer
size={"calc(100vw - 150px)"}
position={"right"}
onClose={onClose}
removeScrollProps={{allowPinchZoom: true}}
removeScrollProps={{ allowPinchZoom: true }}
withCloseButton={false}
opened={isVisible}
styles={{body: {height: '100%'}}}
styles={{
body: {
height: "100%",
display: "flex",
flexDirection: "column", gap: rem(10),
},
}}
>
<Tabs
defaultValue={"general"}
h={'100%'}
flex={1}
variant={"outline"}
orientation={"vertical"}
keepMounted={false}
>
<Tabs.List
>
<Tabs.Tab value={"general"} leftSection={<IconSettings/>}>
<Tabs.Tab value={"general"} leftSection={<IconSettings />}>
Общее
</Tabs.Tab>
<Tabs.Tab value={"history"} leftSection={<IconCalendarUser/>}>
<Tabs.Tab value={"history"} leftSection={<IconCalendarUser />}>
История
</Tabs.Tab>
<Tabs.Tab value={"servicesAndProducts"} leftSection={<IconBox/>}>
<Tabs.Tab value={"servicesAndProducts"} leftSection={<IconBox />}>
Товары и услуги
</Tabs.Tab>
</Tabs.List>
<Tabs.Panel value={"general"}>
<motion.div
initial={{opacity: 0}}
animate={{opacity: 1}}
transition={{duration: 0.2}}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.2 }}
>
<Box h={"100%"} w={"100%"} p={rem(10)}>
<DealEditDrawerGeneralTab/>
<DealEditDrawerGeneralTab />
</Box>
</motion.div>
@@ -364,40 +371,40 @@ const DealEditDrawer: FC = () => {
<Tabs.Panel value={"history"}>
<motion.div
initial={{opacity: 0}}
animate={{opacity: 1}}
transition={{duration: 0.2}}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.2 }}
>
<Box p={rem(10)}>
<DealEditDrawerStatusChangeTable/>
<DealEditDrawerStatusChangeTable />
</Box>
</motion.div>
</Tabs.Panel>
<Tabs.Panel value={"servicesAndProducts"}>
<motion.div
initial={{opacity: 0}}
animate={{opacity: 1}}
transition={{duration: 0.2}}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.2 }}
>
<Box p={rem(10)}>
<ProductAndServiceTab/>
<ProductAndServiceTab />
</Box>
</motion.div>
</Tabs.Panel>
<Tabs.Panel value={"services"}>
<Box p={rem(10)}>
<DealEditDrawerServicesTable/>
<DealEditDrawerServicesTable />
</Box>
</Tabs.Panel>
<Tabs.Panel value={"products"}>
<Box p={rem(10)}>
<DealEditDrawerProductsTable/>
<DealEditDrawerProductsTable />
</Box>
</Tabs.Panel>
</Tabs>
</Drawer>
);
}
};
export default DealEditDrawer;