feat: total price and products count display for deals

This commit is contained in:
2025-10-11 16:21:31 +04:00
parent a899177623
commit 2052737561
6 changed files with 55 additions and 14 deletions

View File

@ -12,7 +12,7 @@ type Props = {
const DealCard = ({ deal }: Props) => { const DealCard = ({ deal }: Props) => {
const { selectedProject, modulesSet } = useProjectsContext(); const { selectedProject, modulesSet } = useProjectsContext();
const { dealsCrud } = useDealsContext(); const { dealsCrud, refetchDeals } = useDealsContext();
const { openDrawer } = useDrawersContext(); const { openDrawer } = useDrawersContext();
const onClick = () => { const onClick = () => {
@ -24,6 +24,7 @@ const DealCard = ({ deal }: Props) => {
onDelete: dealsCrud.onDelete, onDelete: dealsCrud.onDelete,
project: selectedProject, project: selectedProject,
}, },
onClose: refetchDeals,
}); });
}; };
@ -51,9 +52,14 @@ const DealCard = ({ deal }: Props) => {
{modulesSet.has(ModuleNames.CLIENTS) && ( {modulesSet.has(ModuleNames.CLIENTS) && (
<Text>{deal.client?.name}</Text> <Text>{deal.client?.name}</Text>
)} )}
<Text>Wb электросталь</Text> {modulesSet.has(ModuleNames.FULFILLMENT_BASE) && (
<Text>19 000 руб.</Text> <>
<Text>130 тов.</Text> <Text key={"price"}>{deal.totalPrice} руб.</Text>
<Text key={"count"}>
{deal.productsQuantity} тов.
</Text>
</>
)}
</Stack> </Stack>
<Group gap={"xs"}> <Group gap={"xs"}>
<Pill className={styles["first-tag"]}>Срочно</Pill> <Pill className={styles["first-tag"]}>Срочно</Pill>

View File

@ -11,9 +11,16 @@ import { DealSchema } from "@/lib/client";
const DealsTable: FC = () => { const DealsTable: FC = () => {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const { selectedProject } = useProjectsContext(); const { selectedProject, modulesSet } = useProjectsContext();
const { deals, paginationInfo, page, setPage, sortingForm, dealsCrud } = const {
useDealsContext(); deals,
paginationInfo,
page,
setPage,
sortingForm,
dealsCrud,
refetchDeals,
} = useDealsContext();
const { openDrawer } = useDrawersContext(); const { openDrawer } = useDrawersContext();
const onEditClick = useCallback( const onEditClick = useCallback(
@ -26,12 +33,13 @@ const DealsTable: FC = () => {
onDelete: dealsCrud.onDelete, onDelete: dealsCrud.onDelete,
project: selectedProject, project: selectedProject,
}, },
onClose: refetchDeals,
}); });
}, },
[openDrawer, dealsCrud] [openDrawer, dealsCrud]
); );
const columns = useDealsTableColumns({ onEditClick }); const columns = useDealsTableColumns({ onEditClick, modulesSet });
return ( return (
<Stack <Stack

View File

@ -4,13 +4,15 @@ import { DataTableColumn } from "mantine-datatable";
import ActionIconWithTip from "@/components/ui/ActionIconWithTip/ActionIconWithTip"; import ActionIconWithTip from "@/components/ui/ActionIconWithTip/ActionIconWithTip";
import useIsMobile from "@/hooks/utils/useIsMobile"; import useIsMobile from "@/hooks/utils/useIsMobile";
import { DealSchema } from "@/lib/client"; import { DealSchema } from "@/lib/client";
import { ModuleNames } from "@/modules/modules";
import { utcDateTimeToLocalString } from "@/utils/datetime"; import { utcDateTimeToLocalString } from "@/utils/datetime";
type Props = { type Props = {
onEditClick: (deal: DealSchema) => void; onEditClick: (deal: DealSchema) => void;
modulesSet: Set<ModuleNames>;
}; };
const useDealsTableColumns = ({ onEditClick }: Props) => { const useDealsTableColumns = ({ onEditClick, modulesSet }: Props) => {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
return useMemo( return useMemo(
@ -35,19 +37,30 @@ const useDealsTableColumns = ({ onEditClick }: Props) => {
accessor: "id", accessor: "id",
title: isMobile ? "№" : "Номер", title: isMobile ? "№" : "Номер",
sortable: true, sortable: true,
width: "20%",
}, },
{ {
accessor: "name", accessor: "name",
title: "Название", title: "Название",
width: "45%",
}, },
{ {
title: "Дата создания", title: "Дата создания",
accessor: "createdAt", accessor: "createdAt",
render: deal => utcDateTimeToLocalString(deal.createdAt), render: deal => utcDateTimeToLocalString(deal.createdAt),
sortable: true, sortable: true,
width: "35%", },
{
title: "Клиент",
accessor: "client.name",
hidden: !modulesSet.has(ModuleNames.CLIENTS),
},
{
title: "Общая стоимость",
accessor: "totalPrice",
render: deal =>
deal.totalPrice
? `${deal.totalPrice.toLocaleString("ru")}`
: "0₽",
hidden: !modulesSet.has(ModuleNames.FULFILLMENT_BASE),
}, },
] as DataTableColumn<DealSchema>[], ] as DataTableColumn<DealSchema>[],
[onEditClick] [onEditClick]

View File

@ -7,6 +7,7 @@ import useProjectsList from "@/hooks/lists/useProjectsList";
import useIsMobile from "@/hooks/utils/useIsMobile"; import useIsMobile from "@/hooks/utils/useIsMobile";
import { ProjectSchema } from "@/lib/client"; import { ProjectSchema } from "@/lib/client";
import makeContext from "@/lib/contextFactory/contextFactory"; import makeContext from "@/lib/contextFactory/contextFactory";
import { ModuleNames } from "@/modules/modules";
type ProjectsContextState = { type ProjectsContextState = {
selectedProject: ProjectSchema | null; selectedProject: ProjectSchema | null;
@ -14,7 +15,7 @@ type ProjectsContextState = {
refetchProjects: () => void; refetchProjects: () => void;
projects: ProjectSchema[]; projects: ProjectSchema[];
projectsCrud: ProjectsCrud; projectsCrud: ProjectsCrud;
modulesSet: Set<string>; modulesSet: Set<ModuleNames>;
}; };
const useProjectsContextState = (): ProjectsContextState => { const useProjectsContextState = (): ProjectsContextState => {
@ -33,7 +34,10 @@ const useProjectsContextState = (): ProjectsContextState => {
); );
const modulesSet = useMemo( const modulesSet = useMemo(
() => new Set(selectedProject?.builtInModules.map(m => m.key)), () =>
new Set(
selectedProject?.builtInModules.map(m => m.key as ModuleNames)
),
[selectedProject] [selectedProject]
); );

View File

@ -855,6 +855,14 @@ export type DealSchema = {
* Createdat * Createdat
*/ */
createdAt: string; createdAt: string;
/**
* Productsquantity
*/
productsQuantity?: number;
/**
* Totalprice
*/
totalPrice?: number;
client?: ClientSchema | null; client?: ClientSchema | null;
}; };

View File

@ -327,6 +327,8 @@ export const zDealSchema = z.object({
createdAt: z.iso.datetime({ createdAt: z.iso.datetime({
offset: true, offset: true,
}), }),
productsQuantity: z.optional(z.int()).default(0),
totalPrice: z.optional(z.number()).default(0),
client: z.optional(z.union([zClientSchema, z.null()])), client: z.optional(z.union([zClientSchema, z.null()])),
}); });