feat: services table, base segmented control
This commit is contained in:
@ -1,11 +1,15 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { Box, Group } from "@mantine/core";
|
import { IconPlus } from "@tabler/icons-react";
|
||||||
|
import { Box, Group, Text } from "@mantine/core";
|
||||||
import CreateServiceKitButton from "@/app/services/components/desktop/CreateServiceKitButton/CreateServiceKitButton";
|
import CreateServiceKitButton from "@/app/services/components/desktop/CreateServiceKitButton/CreateServiceKitButton";
|
||||||
import ServiceTabSegmentedControl, {
|
import ServiceTabSegmentedControl, {
|
||||||
ServicesTab,
|
ServicesTab,
|
||||||
} from "@/app/services/components/shared/ServiceTabSegmentedControl/ServiceTabSegmentedControl";
|
} from "@/app/services/components/shared/ServiceTabSegmentedControl/ServiceTabSegmentedControl";
|
||||||
|
import useCategoriesActions from "@/app/services/hooks/useCategoriesActions";
|
||||||
|
import useServicesActions from "@/app/services/hooks/useServicesActions";
|
||||||
|
import InlineButton from "@/components/ui/InlineButton/InlineButton";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
serviceTab: ServicesTab;
|
serviceTab: ServicesTab;
|
||||||
@ -16,12 +20,25 @@ const ServicesDesktopHeader: FC<Props> = ({
|
|||||||
serviceTab,
|
serviceTab,
|
||||||
onServiceTabChange,
|
onServiceTabChange,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { onCreateService } = useServicesActions();
|
||||||
|
const { onCreateCategory } = useCategoriesActions();
|
||||||
|
|
||||||
const getTabActions = () => {
|
const getTabActions = () => {
|
||||||
switch (serviceTab) {
|
switch (serviceTab) {
|
||||||
case ServicesTab.DEAL_SERVICE:
|
case ServicesTab.DEAL_SERVICE:
|
||||||
return <Box />;
|
|
||||||
case ServicesTab.PRODUCT_SERVICE:
|
case ServicesTab.PRODUCT_SERVICE:
|
||||||
return <Box />;
|
return (
|
||||||
|
<Group>
|
||||||
|
<InlineButton onClick={onCreateService}>
|
||||||
|
<IconPlus />
|
||||||
|
<Text>Услуга</Text>
|
||||||
|
</InlineButton>
|
||||||
|
<InlineButton onClick={onCreateCategory}>
|
||||||
|
<IconPlus />
|
||||||
|
<Text>Категория</Text>
|
||||||
|
</InlineButton>
|
||||||
|
</Group>
|
||||||
|
);
|
||||||
case ServicesTab.SERVICES_KITS:
|
case ServicesTab.SERVICES_KITS:
|
||||||
return <CreateServiceKitButton />;
|
return <CreateServiceKitButton />;
|
||||||
default:
|
default:
|
||||||
@ -35,8 +52,8 @@ const ServicesDesktopHeader: FC<Props> = ({
|
|||||||
justify={"space-between"}>
|
justify={"space-between"}>
|
||||||
{getTabActions()}
|
{getTabActions()}
|
||||||
<ServiceTabSegmentedControl
|
<ServiceTabSegmentedControl
|
||||||
value={serviceTab.toString()}
|
value={serviceTab}
|
||||||
onChange={tab => onServiceTabChange(Number(tab))}
|
onChange={onServiceTabChange}
|
||||||
/>
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -16,8 +16,8 @@ const ServicesMobileHeader: FC<Props> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<ServiceTabSegmentedControl
|
<ServiceTabSegmentedControl
|
||||||
value={serviceTab.toString()}
|
value={serviceTab}
|
||||||
onChange={tab => onServiceTabChange(Number(tab))}
|
onChange={onServiceTabChange}
|
||||||
w={"100%"}
|
w={"100%"}
|
||||||
py={"md"}
|
py={"md"}
|
||||||
px={"sm"}
|
px={"sm"}
|
||||||
|
|||||||
@ -1,12 +1,15 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import { Stack } from "@mantine/core";
|
||||||
import ServicesDesktopHeader from "@/app/services/components/desktop/ServicesDesktopHeader/ServicesDesktopHeader";
|
import ServicesDesktopHeader from "@/app/services/components/desktop/ServicesDesktopHeader/ServicesDesktopHeader";
|
||||||
import ServicesMobileHeader from "@/app/services/components/mobile/ServicesMobileHeader/ServicesMobileHeader";
|
import ServicesMobileHeader from "@/app/services/components/mobile/ServicesMobileHeader/ServicesMobileHeader";
|
||||||
import ServicesKitsTable from "@/app/services/components/shared/ServicesKitTable/ServicesKitTable";
|
import ServicesKitsTable from "@/app/services/components/shared/ServicesKitTable/ServicesKitTable";
|
||||||
|
import ServicesTable from "@/app/services/components/shared/ServicesTable/ServicesTable";
|
||||||
import { ServicesTab } from "@/app/services/components/shared/ServiceTabSegmentedControl/ServiceTabSegmentedControl";
|
import { ServicesTab } from "@/app/services/components/shared/ServiceTabSegmentedControl/ServiceTabSegmentedControl";
|
||||||
import PageBlock from "@/components/layout/PageBlock/PageBlock";
|
import PageBlock from "@/components/layout/PageBlock/PageBlock";
|
||||||
import useIsMobile from "@/hooks/utils/useIsMobile";
|
import useIsMobile from "@/hooks/utils/useIsMobile";
|
||||||
|
import { ServiceType } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/types/service";
|
||||||
|
|
||||||
const PageBody = () => {
|
const PageBody = () => {
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
@ -18,9 +21,11 @@ const PageBody = () => {
|
|||||||
const getPageBody = () => {
|
const getPageBody = () => {
|
||||||
switch (servicesTab) {
|
switch (servicesTab) {
|
||||||
case ServicesTab.PRODUCT_SERVICE:
|
case ServicesTab.PRODUCT_SERVICE:
|
||||||
return <></>;
|
return (
|
||||||
|
<ServicesTable serviceType={ServiceType.PRODUCT_SERVICE} />
|
||||||
|
);
|
||||||
case ServicesTab.DEAL_SERVICE:
|
case ServicesTab.DEAL_SERVICE:
|
||||||
return <></>;
|
return <ServicesTable serviceType={ServiceType.DEAL_SERVICE} />;
|
||||||
case ServicesTab.SERVICES_KITS:
|
case ServicesTab.SERVICES_KITS:
|
||||||
return <ServicesKitsTable />;
|
return <ServicesKitsTable />;
|
||||||
default:
|
default:
|
||||||
@ -29,7 +34,7 @@ const PageBody = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Stack h={"100%"}>
|
||||||
{!isMobile && (
|
{!isMobile && (
|
||||||
<PageBlock>
|
<PageBlock>
|
||||||
<ServicesDesktopHeader
|
<ServicesDesktopHeader
|
||||||
@ -38,7 +43,7 @@ const PageBody = () => {
|
|||||||
/>
|
/>
|
||||||
</PageBlock>
|
</PageBlock>
|
||||||
)}
|
)}
|
||||||
<PageBlock fullHeight>
|
<PageBlock style={{ flex: 1, minHeight: 0 }}>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
height: "100%",
|
height: "100%",
|
||||||
@ -56,7 +61,7 @@ const PageBody = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</PageBlock>
|
</PageBlock>
|
||||||
</>
|
</Stack>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,24 @@
|
|||||||
|
import { FC } from "react";
|
||||||
|
import ObjectSelect, {
|
||||||
|
ObjectSelectProps,
|
||||||
|
} from "@/components/selects/ObjectSelect/ObjectSelect";
|
||||||
|
import { ServiceCategorySchema } from "@/lib/client";
|
||||||
|
import useServiceCategoriesList from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/lists/useServiceCategoriesList";
|
||||||
|
|
||||||
|
type Props = Omit<
|
||||||
|
ObjectSelectProps<ServiceCategorySchema | null>,
|
||||||
|
"data" | "getLabelFn" | "getValueFn"
|
||||||
|
>;
|
||||||
|
|
||||||
|
const ServiceCategorySelect: FC<Props> = props => {
|
||||||
|
const { categories } = useServiceCategoriesList();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ObjectSelect
|
||||||
|
data={categories}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ServiceCategorySelect;
|
||||||
@ -1,5 +1,7 @@
|
|||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { SegmentedControl, SegmentedControlProps } from "@mantine/core";
|
import BaseSegmentedControl, {
|
||||||
|
BaseSegmentedControlProps,
|
||||||
|
} from "@/components/ui/BaseSegmentedControl/BaseSegmentedControl";
|
||||||
|
|
||||||
export enum ServicesTab {
|
export enum ServicesTab {
|
||||||
DEAL_SERVICE,
|
DEAL_SERVICE,
|
||||||
@ -7,25 +9,25 @@ export enum ServicesTab {
|
|||||||
SERVICES_KITS,
|
SERVICES_KITS,
|
||||||
}
|
}
|
||||||
|
|
||||||
type Props = Omit<SegmentedControlProps, "data">;
|
type Props = Omit<BaseSegmentedControlProps<ServicesTab>, "data">;
|
||||||
|
|
||||||
const data = [
|
const data = [
|
||||||
{
|
{
|
||||||
label: "Для товара",
|
label: "Для товара",
|
||||||
value: ServicesTab.PRODUCT_SERVICE.toString(),
|
value: ServicesTab.PRODUCT_SERVICE,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Для сделки",
|
label: "Для сделки",
|
||||||
value: ServicesTab.DEAL_SERVICE.toString(),
|
value: ServicesTab.DEAL_SERVICE,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Наборы услуг",
|
label: "Наборы услуг",
|
||||||
value: ServicesTab.SERVICES_KITS.toString(),
|
value: ServicesTab.SERVICES_KITS,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const ServiceTabSegmentedControl: FC<Props> = props => (
|
const ServiceTabSegmentedControl: FC<Props> = props => (
|
||||||
<SegmentedControl
|
<BaseSegmentedControl
|
||||||
data={data}
|
data={data}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,22 +1,24 @@
|
|||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { SegmentedControl, SegmentedControlProps } from "@mantine/core";
|
import BaseSegmentedControl, {
|
||||||
|
BaseSegmentedControlProps,
|
||||||
|
} from "@/components/ui/BaseSegmentedControl/BaseSegmentedControl";
|
||||||
import { ServiceType } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/types/service";
|
import { ServiceType } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/types/service";
|
||||||
|
|
||||||
type Props = Omit<SegmentedControlProps, "data">;
|
type Props = Omit<BaseSegmentedControlProps<ServiceType>, "data">;
|
||||||
|
|
||||||
const data = [
|
const data = [
|
||||||
{
|
{
|
||||||
label: "Для сделки",
|
label: "Для сделки",
|
||||||
value: ServiceType.DEAL_SERVICE.toString(),
|
value: ServiceType.DEAL_SERVICE,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Для товара",
|
label: "Для товара",
|
||||||
value: ServiceType.PRODUCT_SERVICE.toString(),
|
value: ServiceType.PRODUCT_SERVICE,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const ServiceTypeSegmentedControl: FC<Props> = props => (
|
const ServiceTypeSegmentedControl: FC<Props> = props => (
|
||||||
<SegmentedControl
|
<BaseSegmentedControl
|
||||||
data={data}
|
data={data}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -0,0 +1,76 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { FC, useMemo, useState } from "react";
|
||||||
|
import useServicesInnerTableColumns from "@/app/services/components/shared/ServicesTable/hooks/servicesInnerTableColumns";
|
||||||
|
import useServicesOuterTableColumns from "@/app/services/components/shared/ServicesTable/hooks/servicesOuterTableColumns";
|
||||||
|
import { GroupedServices } from "@/app/services/components/shared/ServicesTable/types/GroupedServices";
|
||||||
|
import { useServicesContext } from "@/app/services/contexts/ServicesContext";
|
||||||
|
import BaseTable from "@/components/ui/BaseTable/BaseTable";
|
||||||
|
import { ServiceType } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/types/service";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
serviceType: ServiceType;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ServicesTable: FC<Props> = ({ serviceType }) => {
|
||||||
|
const { servicesList } = useServicesContext();
|
||||||
|
|
||||||
|
const [expandedCategoryIds, setExpandedCategoryIds] = useState<number[]>(
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
const innerColumns = useServicesInnerTableColumns();
|
||||||
|
const outerColumns = useServicesOuterTableColumns({
|
||||||
|
expandedCategoryIds,
|
||||||
|
setExpandedCategoryIds,
|
||||||
|
});
|
||||||
|
|
||||||
|
const groupedServices: GroupedServices[] = useMemo(() => {
|
||||||
|
const grouped: GroupedServices[] = [];
|
||||||
|
servicesList.services.forEach(service => {
|
||||||
|
if (service.serviceType !== serviceType) return;
|
||||||
|
|
||||||
|
const existingGroup = grouped.find(
|
||||||
|
group => group.category.id === service.category.id
|
||||||
|
);
|
||||||
|
if (existingGroup) {
|
||||||
|
existingGroup.services.push(service);
|
||||||
|
} else {
|
||||||
|
grouped.push({
|
||||||
|
category: service.category,
|
||||||
|
services: [service],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return grouped;
|
||||||
|
}, [servicesList.services, serviceType]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BaseTable
|
||||||
|
withTableBorder
|
||||||
|
columns={outerColumns}
|
||||||
|
records={groupedServices}
|
||||||
|
verticalSpacing={"md"}
|
||||||
|
groups={undefined}
|
||||||
|
idAccessor={"category.id"}
|
||||||
|
rowExpansion={{
|
||||||
|
allowMultiple: true,
|
||||||
|
expanded: {
|
||||||
|
recordIds: expandedCategoryIds,
|
||||||
|
onRecordIdsChange: setExpandedCategoryIds,
|
||||||
|
},
|
||||||
|
content: ({ record }) => (
|
||||||
|
<BaseTable
|
||||||
|
withTableBorder
|
||||||
|
columns={innerColumns}
|
||||||
|
records={record.services}
|
||||||
|
verticalSpacing={"md"}
|
||||||
|
groups={undefined}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ServicesTable;
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
import { useMemo } from "react";
|
||||||
|
import { DataTableColumn } from "mantine-datatable";
|
||||||
|
import { List, Text } from "@mantine/core";
|
||||||
|
import { ServiceSchema } from "@/lib/client";
|
||||||
|
|
||||||
|
const useServicesInnerTableColumns = () => {
|
||||||
|
const getPriceRow = (service: ServiceSchema) => {
|
||||||
|
if (service.priceRanges.length === 0) {
|
||||||
|
return <>{service.price.toLocaleString("ru")}₽</>;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<List>
|
||||||
|
{service.priceRanges.map(range => (
|
||||||
|
<List.Item key={range.id}>
|
||||||
|
<Text>
|
||||||
|
{`${range.fromQuantity} - ${range.toQuantity}: ${range.price.toLocaleString("ru")}₽`}
|
||||||
|
</Text>
|
||||||
|
</List.Item>
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return useMemo(
|
||||||
|
() =>
|
||||||
|
[
|
||||||
|
{
|
||||||
|
accessor: "name",
|
||||||
|
title: "Название",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessor: "price",
|
||||||
|
title: "Цена",
|
||||||
|
render: service => getPriceRow(service),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessor: "cost",
|
||||||
|
title: "Себестоимость",
|
||||||
|
render: service => `${service.cost?.toLocaleString("ru")}₽`,
|
||||||
|
},
|
||||||
|
] as DataTableColumn<ServiceSchema>[],
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useServicesInnerTableColumns;
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
import { useMemo } from "react";
|
||||||
|
import {
|
||||||
|
IconChevronDown,
|
||||||
|
IconChevronsDown,
|
||||||
|
IconChevronsRight,
|
||||||
|
IconChevronsUp,
|
||||||
|
IconChevronUp,
|
||||||
|
} from "@tabler/icons-react";
|
||||||
|
import { DataTableColumn } from "mantine-datatable";
|
||||||
|
import { Box, Group, Text } from "@mantine/core";
|
||||||
|
import { GroupedServices } from "@/app/services/components/shared/ServicesTable/types/GroupedServices";
|
||||||
|
import { useServicesContext } from "@/app/services/contexts/ServicesContext";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
expandedCategoryIds: number[];
|
||||||
|
setExpandedCategoryIds: (ids: number[]) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const useServicesOuterTableColumns = ({
|
||||||
|
expandedCategoryIds,
|
||||||
|
setExpandedCategoryIds,
|
||||||
|
}: Props) => {
|
||||||
|
const { categoriesList } = useServicesContext();
|
||||||
|
|
||||||
|
const onExpandAllClick = () => {
|
||||||
|
if (expandedCategoryIds.length !== categoriesList.categories.length) {
|
||||||
|
setExpandedCategoryIds(categoriesList.categories.map(c => c.id));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setExpandedCategoryIds([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getExpandAllIcon = () => {
|
||||||
|
if (expandedCategoryIds.length === categoriesList.categories.length)
|
||||||
|
return <IconChevronsUp />;
|
||||||
|
if (expandedCategoryIds.length === 0) return <IconChevronsDown />;
|
||||||
|
return <IconChevronsRight />;
|
||||||
|
};
|
||||||
|
|
||||||
|
return useMemo(
|
||||||
|
() =>
|
||||||
|
[
|
||||||
|
{
|
||||||
|
accessor: "name",
|
||||||
|
title: (
|
||||||
|
<Group>
|
||||||
|
<Box
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
onClick={onExpandAllClick}>
|
||||||
|
{getExpandAllIcon()}
|
||||||
|
</Box>
|
||||||
|
Категория
|
||||||
|
</Group>
|
||||||
|
),
|
||||||
|
noWrap: true,
|
||||||
|
render: ({ category: { id, name } }) => (
|
||||||
|
<Group key={id}>
|
||||||
|
{expandedCategoryIds.includes(id) ? (
|
||||||
|
<IconChevronUp />
|
||||||
|
) : (
|
||||||
|
<IconChevronDown />
|
||||||
|
)}
|
||||||
|
<Text>{name}</Text>
|
||||||
|
</Group>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
] as DataTableColumn<GroupedServices>[],
|
||||||
|
[expandedCategoryIds, categoriesList.categories]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useServicesOuterTableColumns;
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
import { ServiceCategorySchema, ServiceSchema } from "@/lib/client";
|
||||||
|
|
||||||
|
export type GroupedServices = {
|
||||||
|
category: ServiceCategorySchema;
|
||||||
|
services: ServiceSchema[];
|
||||||
|
};
|
||||||
@ -1,6 +1,10 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import makeContext from "@/lib/contextFactory/contextFactory";
|
import makeContext from "@/lib/contextFactory/contextFactory";
|
||||||
|
import {
|
||||||
|
ServiceCategoriesCrud,
|
||||||
|
useServiceCategoriesCrud,
|
||||||
|
} from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/cruds/useServiceCategoriesCrud";
|
||||||
import {
|
import {
|
||||||
ServicesCrud,
|
ServicesCrud,
|
||||||
useServicesCrud,
|
useServicesCrud,
|
||||||
@ -9,6 +13,9 @@ import {
|
|||||||
ServicesKitsCrud,
|
ServicesKitsCrud,
|
||||||
useServicesKitsCrud,
|
useServicesKitsCrud,
|
||||||
} from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/cruds/useServicesKitsCrud";
|
} from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/cruds/useServicesKitsCrud";
|
||||||
|
import useServiceCategoriesList, {
|
||||||
|
ServiceCategoriesList,
|
||||||
|
} from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/lists/useServiceCategoriesList";
|
||||||
import useServicesKitsList, {
|
import useServicesKitsList, {
|
||||||
ServicesKitsList,
|
ServicesKitsList,
|
||||||
} from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/lists/useServicesKitsList";
|
} from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/lists/useServicesKitsList";
|
||||||
@ -21,6 +28,8 @@ type ServicesContextState = {
|
|||||||
servicesCrud: ServicesCrud;
|
servicesCrud: ServicesCrud;
|
||||||
servicesKitList: ServicesKitsList;
|
servicesKitList: ServicesKitsList;
|
||||||
servicesKitCrud: ServicesKitsCrud;
|
servicesKitCrud: ServicesKitsCrud;
|
||||||
|
categoriesList: ServiceCategoriesList;
|
||||||
|
categoriesCrud: ServiceCategoriesCrud;
|
||||||
};
|
};
|
||||||
|
|
||||||
const useFulfillmentBaseContextState = (): ServicesContextState => {
|
const useFulfillmentBaseContextState = (): ServicesContextState => {
|
||||||
@ -30,11 +39,16 @@ const useFulfillmentBaseContextState = (): ServicesContextState => {
|
|||||||
const servicesKitList = useServicesKitsList();
|
const servicesKitList = useServicesKitsList();
|
||||||
const servicesKitCrud = useServicesKitsCrud(servicesKitList);
|
const servicesKitCrud = useServicesKitsCrud(servicesKitList);
|
||||||
|
|
||||||
|
const categoriesList = useServiceCategoriesList();
|
||||||
|
const categoriesCrud = useServiceCategoriesCrud(categoriesList);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
servicesList,
|
servicesList,
|
||||||
servicesCrud,
|
servicesCrud,
|
||||||
servicesKitList,
|
servicesKitList,
|
||||||
servicesKitCrud,
|
servicesKitCrud,
|
||||||
|
categoriesList,
|
||||||
|
categoriesCrud,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
39
src/app/services/hooks/useCategoriesActions.ts
Normal file
39
src/app/services/hooks/useCategoriesActions.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { modals } from "@mantine/modals";
|
||||||
|
import { useServicesContext } from "@/app/services/contexts/ServicesContext";
|
||||||
|
import { ServiceCategorySchema } from "@/lib/client";
|
||||||
|
|
||||||
|
const useCategoriesActions = () => {
|
||||||
|
const { categoriesCrud } = useServicesContext();
|
||||||
|
|
||||||
|
const onChangeCategory = (category: ServiceCategorySchema) => {
|
||||||
|
modals.openContextModal({
|
||||||
|
modal: "serviceCategoryEditorModal",
|
||||||
|
title: "Создание категории",
|
||||||
|
withCloseButton: false,
|
||||||
|
innerProps: {
|
||||||
|
onChange: value => categoriesCrud.onUpdate(category.id, value),
|
||||||
|
entity: category,
|
||||||
|
isEditing: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onCreateCategory = () => {
|
||||||
|
modals.openContextModal({
|
||||||
|
modal: "serviceCategoryEditorModal",
|
||||||
|
title: "Создание категории",
|
||||||
|
withCloseButton: false,
|
||||||
|
innerProps: {
|
||||||
|
onCreate: categoriesCrud.onCreate,
|
||||||
|
isEditing: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
onCreateCategory,
|
||||||
|
onChangeCategory,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useCategoriesActions;
|
||||||
39
src/app/services/hooks/useServicesActions.ts
Normal file
39
src/app/services/hooks/useServicesActions.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { modals } from "@mantine/modals";
|
||||||
|
import { useServicesContext } from "@/app/services/contexts/ServicesContext";
|
||||||
|
import { ServiceSchema } from "@/lib/client";
|
||||||
|
|
||||||
|
const useServicesActions = () => {
|
||||||
|
const { servicesCrud } = useServicesContext();
|
||||||
|
|
||||||
|
const onChangeService = (service: ServiceSchema) => {
|
||||||
|
modals.openContextModal({
|
||||||
|
modal: "serviceEditorModal",
|
||||||
|
title: "Редактирование услуги",
|
||||||
|
withCloseButton: false,
|
||||||
|
innerProps: {
|
||||||
|
onChange: value => servicesCrud.onUpdate(service.id, value),
|
||||||
|
entity: service,
|
||||||
|
isEditing: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onCreateService = () => {
|
||||||
|
modals.openContextModal({
|
||||||
|
modal: "serviceEditorModal",
|
||||||
|
title: "Создание услуги",
|
||||||
|
withCloseButton: false,
|
||||||
|
innerProps: {
|
||||||
|
onCreate: servicesCrud.onCreate,
|
||||||
|
isEditing: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
onCreateService,
|
||||||
|
onChangeService,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useServicesActions;
|
||||||
64
src/app/services/modals/ServiceCategoryEditorModal.tsx
Normal file
64
src/app/services/modals/ServiceCategoryEditorModal.tsx
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { Flex, TextInput } from "@mantine/core";
|
||||||
|
import { useForm } from "@mantine/form";
|
||||||
|
import { ContextModalProps } from "@mantine/modals";
|
||||||
|
import {
|
||||||
|
CreateServiceCategorySchema,
|
||||||
|
ServiceCategorySchema,
|
||||||
|
UpdateServiceCategorySchema,
|
||||||
|
} from "@/lib/client";
|
||||||
|
import BaseFormModal, {
|
||||||
|
CreateEditFormProps,
|
||||||
|
} from "@/modals/base/BaseFormModal/BaseFormModal";
|
||||||
|
|
||||||
|
type Props = CreateEditFormProps<
|
||||||
|
CreateServiceCategorySchema,
|
||||||
|
UpdateServiceCategorySchema,
|
||||||
|
ServiceCategorySchema
|
||||||
|
>;
|
||||||
|
|
||||||
|
const ServiceCategoryEditorModal = ({
|
||||||
|
context,
|
||||||
|
id,
|
||||||
|
innerProps,
|
||||||
|
}: ContextModalProps<Props>) => {
|
||||||
|
const initialValues = innerProps.isEditing
|
||||||
|
? innerProps.entity
|
||||||
|
: {
|
||||||
|
name: "",
|
||||||
|
dealServiceRank: "",
|
||||||
|
productServiceRank: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
const form = useForm<Partial<ServiceCategorySchema>>({
|
||||||
|
initialValues,
|
||||||
|
validate: {
|
||||||
|
name: name =>
|
||||||
|
(!name || name.trim() === "") &&
|
||||||
|
"Необходимо ввести название категории",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const onClose = () => context.closeContextModal(id);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BaseFormModal
|
||||||
|
{...innerProps}
|
||||||
|
form={form}
|
||||||
|
closeOnSubmit
|
||||||
|
onClose={onClose}>
|
||||||
|
<Flex
|
||||||
|
gap={"xs"}
|
||||||
|
direction={"column"}>
|
||||||
|
<TextInput
|
||||||
|
placeholder={"Введите название категори"}
|
||||||
|
label={"Название категории"}
|
||||||
|
{...form.getInputProps("name")}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</BaseFormModal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ServiceCategoryEditorModal;
|
||||||
@ -0,0 +1,141 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState } from "react";
|
||||||
|
import { Fieldset, Flex, NumberInput, Stack, TextInput } from "@mantine/core";
|
||||||
|
import { useForm } from "@mantine/form";
|
||||||
|
import { ContextModalProps } from "@mantine/modals";
|
||||||
|
import ServiceCategorySelect from "@/app/services/components/shared/ServiceCategorySelect/ServiceCategorySelect";
|
||||||
|
import ServiceTypeSegmentedControl from "@/app/services/components/shared/ServiceTypeSegmentedControl/ServiceTypeSegmentedControl";
|
||||||
|
import RangePriceInput, {
|
||||||
|
PriceRangeInputType,
|
||||||
|
} from "@/app/services/modals/ServiceEditorModal/components/RangePriceInput";
|
||||||
|
import ServicePriceTypeSegmentedControl from "@/app/services/modals/ServiceEditorModal/components/ServicePriceTypeSegmentedControl";
|
||||||
|
import {
|
||||||
|
CreateServiceSchema,
|
||||||
|
ServiceSchema,
|
||||||
|
UpdateServiceSchema,
|
||||||
|
} from "@/lib/client";
|
||||||
|
import BaseFormModal, {
|
||||||
|
CreateEditFormProps,
|
||||||
|
} from "@/modals/base/BaseFormModal/BaseFormModal";
|
||||||
|
import {
|
||||||
|
ServicePriceType,
|
||||||
|
ServiceType,
|
||||||
|
} from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/types/service";
|
||||||
|
|
||||||
|
type Props = CreateEditFormProps<
|
||||||
|
CreateServiceSchema,
|
||||||
|
UpdateServiceSchema,
|
||||||
|
ServiceSchema
|
||||||
|
>;
|
||||||
|
|
||||||
|
const ServiceEditorModal = ({
|
||||||
|
context,
|
||||||
|
id,
|
||||||
|
innerProps,
|
||||||
|
}: ContextModalProps<Props>) => {
|
||||||
|
const [priceType, setPriceType] = useState<ServicePriceType>(
|
||||||
|
ServicePriceType.DEFAULT
|
||||||
|
);
|
||||||
|
|
||||||
|
const initialValues = innerProps.isEditing
|
||||||
|
? innerProps.entity
|
||||||
|
: {
|
||||||
|
name: "",
|
||||||
|
price: 0,
|
||||||
|
cost: 0,
|
||||||
|
serviceType: ServiceType.DEAL_SERVICE,
|
||||||
|
priceRanges: [],
|
||||||
|
lexorank: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
const form = useForm<Partial<ServiceSchema>>({
|
||||||
|
initialValues,
|
||||||
|
validate: {
|
||||||
|
name: name =>
|
||||||
|
(!name || name.trim() === "") &&
|
||||||
|
"Необходимо ввести название услуги",
|
||||||
|
category: category => !category && "Необходимо выбрать категорию",
|
||||||
|
priceRanges: (value, values) =>
|
||||||
|
(!value || value.length === 0) &&
|
||||||
|
(!values.price || values.price <= 0) &&
|
||||||
|
"Необходимо добавить хотя бы один диапазон цен или указать цену за единицу услуги",
|
||||||
|
price: (value, values) =>
|
||||||
|
(!value || value === 0) &&
|
||||||
|
(!values.priceRanges || values.priceRanges.length === 0) &&
|
||||||
|
"Необходимо добавить хотя бы один диапазон цен или указать цену за единицу услуги",
|
||||||
|
cost: cost => (!cost || cost < 0) && "Введите себестоимость",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const getPriceBody = () => {
|
||||||
|
if (priceType === ServicePriceType.DEFAULT)
|
||||||
|
return (
|
||||||
|
<NumberInput
|
||||||
|
placeholder={"Введите стоимость услуги"}
|
||||||
|
label={"Cтоимость услуги"}
|
||||||
|
hideControls
|
||||||
|
{...form.getInputProps("price")}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<RangePriceInput
|
||||||
|
{...(form.getInputProps("priceRanges") as PriceRangeInputType)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onCancel = () => context.closeContextModal(id);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BaseFormModal
|
||||||
|
{...innerProps}
|
||||||
|
closeOnSubmit
|
||||||
|
form={form}
|
||||||
|
onClose={onCancel}>
|
||||||
|
<Fieldset
|
||||||
|
legend={"Общие параметры"}
|
||||||
|
bdrs={"lg"}>
|
||||||
|
<Stack>
|
||||||
|
<ServiceCategorySelect
|
||||||
|
placeholder={"Выберите категорию"}
|
||||||
|
label={"Категория услуги"}
|
||||||
|
{...form.getInputProps("category")}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
placeholder={"Введите название услуги"}
|
||||||
|
label={"Название услуги"}
|
||||||
|
{...form.getInputProps("name")}
|
||||||
|
/>
|
||||||
|
<NumberInput
|
||||||
|
placeholder={"Введите себестоимость услуги"}
|
||||||
|
label={"Себестоимость услуги"}
|
||||||
|
hideControls
|
||||||
|
{...form.getInputProps("cost")}
|
||||||
|
allowNegative={false}
|
||||||
|
/>
|
||||||
|
<ServiceTypeSegmentedControl
|
||||||
|
{...form.getInputProps("serviceType")}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
</Fieldset>
|
||||||
|
<Fieldset
|
||||||
|
legend={"Стоимость"}
|
||||||
|
bdrs={"lg"}>
|
||||||
|
<Flex
|
||||||
|
direction={"column"}
|
||||||
|
gap={"xs"}
|
||||||
|
justify={"center"}>
|
||||||
|
<ServicePriceTypeSegmentedControl
|
||||||
|
value={priceType}
|
||||||
|
onChange={setPriceType}
|
||||||
|
/>
|
||||||
|
{getPriceBody()}
|
||||||
|
</Flex>
|
||||||
|
</Fieldset>
|
||||||
|
</BaseFormModal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ServiceEditorModal;
|
||||||
@ -0,0 +1,105 @@
|
|||||||
|
import { FC } from "react";
|
||||||
|
import { IconTrash } from "@tabler/icons-react";
|
||||||
|
import { isNumber } from "lodash";
|
||||||
|
import { ActionIcon, Flex, Input, NumberInput, rem } from "@mantine/core";
|
||||||
|
import InlineButton from "@/components/ui/InlineButton/InlineButton";
|
||||||
|
import { ServicePriceRangeSchema } from "@/lib/client";
|
||||||
|
import BaseFormInputProps from "@/utils/baseFormInputProps";
|
||||||
|
|
||||||
|
export type PriceRangeInputType = BaseFormInputProps<ServicePriceRangeSchema[]>;
|
||||||
|
|
||||||
|
const RangePriceInput: FC<PriceRangeInputType> = props => {
|
||||||
|
const onAddRange = () => {
|
||||||
|
const newRange = {
|
||||||
|
fromQuantity: 0,
|
||||||
|
toQuantity: 0,
|
||||||
|
price: 0,
|
||||||
|
id: null,
|
||||||
|
};
|
||||||
|
props.onChange([...props.value, newRange]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDeleteRange = (idx: number) => {
|
||||||
|
const newRanges = props.value.filter((_, i) => i !== idx);
|
||||||
|
props.onChange(newRanges);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onChangeRange = (
|
||||||
|
idx: number,
|
||||||
|
values: Partial<ServicePriceRangeSchema>
|
||||||
|
) => {
|
||||||
|
const newRanges = props.value.map((item, i) =>
|
||||||
|
i === idx
|
||||||
|
? {
|
||||||
|
...item,
|
||||||
|
...values,
|
||||||
|
}
|
||||||
|
: item
|
||||||
|
);
|
||||||
|
props.onChange(newRanges);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Input.Wrapper
|
||||||
|
error={props.error}
|
||||||
|
label={"Диапазон цен"}>
|
||||||
|
<Flex
|
||||||
|
direction={"column"}
|
||||||
|
gap={"xs"}>
|
||||||
|
{props.value.map((range, idx) => (
|
||||||
|
<Flex
|
||||||
|
key={idx}
|
||||||
|
gap={rem(10)}
|
||||||
|
align={"flex-end"}>
|
||||||
|
<ActionIcon
|
||||||
|
onClick={() => onDeleteRange(idx)}
|
||||||
|
variant={"default"}>
|
||||||
|
<IconTrash />
|
||||||
|
</ActionIcon>
|
||||||
|
<NumberInput
|
||||||
|
label={"От количества"}
|
||||||
|
placeholder={"От"}
|
||||||
|
hideControls
|
||||||
|
value={range.fromQuantity}
|
||||||
|
onChange={val =>
|
||||||
|
val &&
|
||||||
|
isNumber(val) &&
|
||||||
|
onChangeRange(idx, { fromQuantity: val })
|
||||||
|
}
|
||||||
|
allowNegative={false}
|
||||||
|
/>
|
||||||
|
<NumberInput
|
||||||
|
label={"До количества"}
|
||||||
|
placeholder={"До"}
|
||||||
|
hideControls
|
||||||
|
value={range.toQuantity}
|
||||||
|
onChange={val =>
|
||||||
|
val &&
|
||||||
|
isNumber(val) &&
|
||||||
|
onChangeRange(idx, { toQuantity: val })
|
||||||
|
}
|
||||||
|
allowNegative={false}
|
||||||
|
/>
|
||||||
|
<NumberInput
|
||||||
|
label={"Цена"}
|
||||||
|
placeholder={"Цена"}
|
||||||
|
hideControls
|
||||||
|
value={range.price}
|
||||||
|
onChange={val =>
|
||||||
|
val &&
|
||||||
|
isNumber(val) &&
|
||||||
|
onChangeRange(idx, { price: val })
|
||||||
|
}
|
||||||
|
allowNegative={false}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<InlineButton onClick={onAddRange}>
|
||||||
|
Добавить диапазон
|
||||||
|
</InlineButton>
|
||||||
|
</Flex>
|
||||||
|
</Input.Wrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default RangePriceInput;
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
import { FC } from "react";
|
||||||
|
import BaseSegmentedControl, {
|
||||||
|
BaseSegmentedControlProps,
|
||||||
|
} from "@/components/ui/BaseSegmentedControl/BaseSegmentedControl";
|
||||||
|
|
||||||
|
export enum ServicePriceType {
|
||||||
|
DEFAULT,
|
||||||
|
BY_RANGE,
|
||||||
|
}
|
||||||
|
|
||||||
|
type Props = Omit<BaseSegmentedControlProps<ServicePriceType>, "data">;
|
||||||
|
|
||||||
|
const ServicePriceTypeSegmentedControl: FC<Props> = props => {
|
||||||
|
const data = [
|
||||||
|
{
|
||||||
|
label: "По умолчанию",
|
||||||
|
value: ServicePriceType.DEFAULT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "По диапазону",
|
||||||
|
value: ServicePriceType.BY_RANGE,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BaseSegmentedControl
|
||||||
|
data={data}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ServicePriceTypeSegmentedControl;
|
||||||
@ -1 +1,3 @@
|
|||||||
export { default as ServicesKitEditorModal } from "@/app/services/modals/ServicesKitEditorModal";
|
export { default as ServicesKitEditorModal } from "@/app/services/modals/ServicesKitEditorModal";
|
||||||
|
export { default as ServiceCategoryEditorModal } from "@/app/services/modals/ServiceCategoryEditorModal";
|
||||||
|
export { default as ServiceEditorModal } from "@/app/services/modals/ServiceEditorModal/ServiceEditorModal";
|
||||||
|
|||||||
@ -0,0 +1,34 @@
|
|||||||
|
import { SegmentedControl, SegmentedControlProps } from "@mantine/core";
|
||||||
|
|
||||||
|
export type BaseSegmentedControlProps<T> = Omit<
|
||||||
|
SegmentedControlProps,
|
||||||
|
"onChange" | "value" | "data"
|
||||||
|
> & {
|
||||||
|
onChange?: (value: T) => void;
|
||||||
|
value?: T;
|
||||||
|
data: { label: string; value: T }[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const BaseSegmentedControl = <T extends string | number>(
|
||||||
|
props: BaseSegmentedControlProps<T>
|
||||||
|
) => {
|
||||||
|
const handleChange = (value: string) => {
|
||||||
|
const numValue = Number(value);
|
||||||
|
const convertedValue = isNaN(numValue) ? (value as T) : (numValue as T);
|
||||||
|
props.onChange?.(convertedValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SegmentedControl
|
||||||
|
{...props}
|
||||||
|
onChange={handleChange}
|
||||||
|
value={String(props.value)}
|
||||||
|
data={props.data.map(item => ({
|
||||||
|
...item,
|
||||||
|
value: item.value.toString(),
|
||||||
|
}))}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BaseSegmentedControl;
|
||||||
@ -19,6 +19,7 @@ import {
|
|||||||
createProduct,
|
createProduct,
|
||||||
createProject,
|
createProject,
|
||||||
createService,
|
createService,
|
||||||
|
createServiceCategory,
|
||||||
createServicesKit,
|
createServicesKit,
|
||||||
createStatus,
|
createStatus,
|
||||||
deleteBoard,
|
deleteBoard,
|
||||||
@ -29,6 +30,7 @@ import {
|
|||||||
deleteProduct,
|
deleteProduct,
|
||||||
deleteProject,
|
deleteProject,
|
||||||
deleteService,
|
deleteService,
|
||||||
|
deleteServiceCategory,
|
||||||
deleteServicesKit,
|
deleteServicesKit,
|
||||||
deleteStatus,
|
deleteStatus,
|
||||||
duplicateProductServices,
|
duplicateProductServices,
|
||||||
@ -39,6 +41,7 @@ import {
|
|||||||
getDealServices,
|
getDealServices,
|
||||||
getProducts,
|
getProducts,
|
||||||
getProjects,
|
getProjects,
|
||||||
|
getServiceCategories,
|
||||||
getServices,
|
getServices,
|
||||||
getServicesKits,
|
getServicesKits,
|
||||||
getStatuses,
|
getStatuses,
|
||||||
@ -51,6 +54,7 @@ import {
|
|||||||
updateProduct,
|
updateProduct,
|
||||||
updateProject,
|
updateProject,
|
||||||
updateService,
|
updateService,
|
||||||
|
updateServiceCategory,
|
||||||
updateServicesKit,
|
updateServicesKit,
|
||||||
updateStatus,
|
updateStatus,
|
||||||
type Options,
|
type Options,
|
||||||
@ -83,6 +87,9 @@ import type {
|
|||||||
CreateProjectData,
|
CreateProjectData,
|
||||||
CreateProjectError,
|
CreateProjectError,
|
||||||
CreateProjectResponse2,
|
CreateProjectResponse2,
|
||||||
|
CreateServiceCategoryData,
|
||||||
|
CreateServiceCategoryError,
|
||||||
|
CreateServiceCategoryResponse2,
|
||||||
CreateServiceData,
|
CreateServiceData,
|
||||||
CreateServiceError,
|
CreateServiceError,
|
||||||
CreateServiceResponse2,
|
CreateServiceResponse2,
|
||||||
@ -113,6 +120,9 @@ import type {
|
|||||||
DeleteProjectData,
|
DeleteProjectData,
|
||||||
DeleteProjectError,
|
DeleteProjectError,
|
||||||
DeleteProjectResponse2,
|
DeleteProjectResponse2,
|
||||||
|
DeleteServiceCategoryData,
|
||||||
|
DeleteServiceCategoryError,
|
||||||
|
DeleteServiceCategoryResponse2,
|
||||||
DeleteServiceData,
|
DeleteServiceData,
|
||||||
DeleteServiceError,
|
DeleteServiceError,
|
||||||
DeleteServiceResponse2,
|
DeleteServiceResponse2,
|
||||||
@ -136,6 +146,7 @@ import type {
|
|||||||
GetProductsError,
|
GetProductsError,
|
||||||
GetProductsResponse2,
|
GetProductsResponse2,
|
||||||
GetProjectsData,
|
GetProjectsData,
|
||||||
|
GetServiceCategoriesData,
|
||||||
GetServicesData,
|
GetServicesData,
|
||||||
GetServicesKitsData,
|
GetServicesKitsData,
|
||||||
GetStatusesData,
|
GetStatusesData,
|
||||||
@ -161,6 +172,9 @@ import type {
|
|||||||
UpdateProjectData,
|
UpdateProjectData,
|
||||||
UpdateProjectError,
|
UpdateProjectError,
|
||||||
UpdateProjectResponse2,
|
UpdateProjectResponse2,
|
||||||
|
UpdateServiceCategoryData,
|
||||||
|
UpdateServiceCategoryError,
|
||||||
|
UpdateServiceCategoryResponse2,
|
||||||
UpdateServiceData,
|
UpdateServiceData,
|
||||||
UpdateServiceError,
|
UpdateServiceError,
|
||||||
UpdateServiceResponse2,
|
UpdateServiceResponse2,
|
||||||
@ -1644,6 +1658,135 @@ export const updateServiceMutation = (
|
|||||||
return mutationOptions;
|
return mutationOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getServiceCategoriesQueryKey = (
|
||||||
|
options?: Options<GetServiceCategoriesData>
|
||||||
|
) => createQueryKey("getServiceCategories", options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Services Categories
|
||||||
|
*/
|
||||||
|
export const getServiceCategoriesOptions = (
|
||||||
|
options?: Options<GetServiceCategoriesData>
|
||||||
|
) => {
|
||||||
|
return queryOptions({
|
||||||
|
queryFn: async ({ queryKey, signal }) => {
|
||||||
|
const { data } = await getServiceCategories({
|
||||||
|
...options,
|
||||||
|
...queryKey[0],
|
||||||
|
signal,
|
||||||
|
throwOnError: true,
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
queryKey: getServiceCategoriesQueryKey(options),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createServiceCategoryQueryKey = (
|
||||||
|
options: Options<CreateServiceCategoryData>
|
||||||
|
) => createQueryKey("createServiceCategory", options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Service Category
|
||||||
|
*/
|
||||||
|
export const createServiceCategoryOptions = (
|
||||||
|
options: Options<CreateServiceCategoryData>
|
||||||
|
) => {
|
||||||
|
return queryOptions({
|
||||||
|
queryFn: async ({ queryKey, signal }) => {
|
||||||
|
const { data } = await createServiceCategory({
|
||||||
|
...options,
|
||||||
|
...queryKey[0],
|
||||||
|
signal,
|
||||||
|
throwOnError: true,
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
queryKey: createServiceCategoryQueryKey(options),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Service Category
|
||||||
|
*/
|
||||||
|
export const createServiceCategoryMutation = (
|
||||||
|
options?: Partial<Options<CreateServiceCategoryData>>
|
||||||
|
): UseMutationOptions<
|
||||||
|
CreateServiceCategoryResponse2,
|
||||||
|
AxiosError<CreateServiceCategoryError>,
|
||||||
|
Options<CreateServiceCategoryData>
|
||||||
|
> => {
|
||||||
|
const mutationOptions: UseMutationOptions<
|
||||||
|
CreateServiceCategoryResponse2,
|
||||||
|
AxiosError<CreateServiceCategoryError>,
|
||||||
|
Options<CreateServiceCategoryData>
|
||||||
|
> = {
|
||||||
|
mutationFn: async localOptions => {
|
||||||
|
const { data } = await createServiceCategory({
|
||||||
|
...options,
|
||||||
|
...localOptions,
|
||||||
|
throwOnError: true,
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return mutationOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete Service Category
|
||||||
|
*/
|
||||||
|
export const deleteServiceCategoryMutation = (
|
||||||
|
options?: Partial<Options<DeleteServiceCategoryData>>
|
||||||
|
): UseMutationOptions<
|
||||||
|
DeleteServiceCategoryResponse2,
|
||||||
|
AxiosError<DeleteServiceCategoryError>,
|
||||||
|
Options<DeleteServiceCategoryData>
|
||||||
|
> => {
|
||||||
|
const mutationOptions: UseMutationOptions<
|
||||||
|
DeleteServiceCategoryResponse2,
|
||||||
|
AxiosError<DeleteServiceCategoryError>,
|
||||||
|
Options<DeleteServiceCategoryData>
|
||||||
|
> = {
|
||||||
|
mutationFn: async localOptions => {
|
||||||
|
const { data } = await deleteServiceCategory({
|
||||||
|
...options,
|
||||||
|
...localOptions,
|
||||||
|
throwOnError: true,
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return mutationOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Service Category
|
||||||
|
*/
|
||||||
|
export const updateServiceCategoryMutation = (
|
||||||
|
options?: Partial<Options<UpdateServiceCategoryData>>
|
||||||
|
): UseMutationOptions<
|
||||||
|
UpdateServiceCategoryResponse2,
|
||||||
|
AxiosError<UpdateServiceCategoryError>,
|
||||||
|
Options<UpdateServiceCategoryData>
|
||||||
|
> => {
|
||||||
|
const mutationOptions: UseMutationOptions<
|
||||||
|
UpdateServiceCategoryResponse2,
|
||||||
|
AxiosError<UpdateServiceCategoryError>,
|
||||||
|
Options<UpdateServiceCategoryData>
|
||||||
|
> = {
|
||||||
|
mutationFn: async localOptions => {
|
||||||
|
const { data } = await updateServiceCategory({
|
||||||
|
...options,
|
||||||
|
...localOptions,
|
||||||
|
throwOnError: true,
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return mutationOptions;
|
||||||
|
};
|
||||||
|
|
||||||
export const getServicesKitsQueryKey = (
|
export const getServicesKitsQueryKey = (
|
||||||
options?: Options<GetServicesKitsData>
|
options?: Options<GetServicesKitsData>
|
||||||
) => createQueryKey("getServicesKits", options);
|
) => createQueryKey("getServicesKits", options);
|
||||||
|
|||||||
@ -30,6 +30,9 @@ import type {
|
|||||||
CreateProjectData,
|
CreateProjectData,
|
||||||
CreateProjectErrors,
|
CreateProjectErrors,
|
||||||
CreateProjectResponses,
|
CreateProjectResponses,
|
||||||
|
CreateServiceCategoryData,
|
||||||
|
CreateServiceCategoryErrors,
|
||||||
|
CreateServiceCategoryResponses,
|
||||||
CreateServiceData,
|
CreateServiceData,
|
||||||
CreateServiceErrors,
|
CreateServiceErrors,
|
||||||
CreateServiceResponses,
|
CreateServiceResponses,
|
||||||
@ -60,6 +63,9 @@ import type {
|
|||||||
DeleteProjectData,
|
DeleteProjectData,
|
||||||
DeleteProjectErrors,
|
DeleteProjectErrors,
|
||||||
DeleteProjectResponses,
|
DeleteProjectResponses,
|
||||||
|
DeleteServiceCategoryData,
|
||||||
|
DeleteServiceCategoryErrors,
|
||||||
|
DeleteServiceCategoryResponses,
|
||||||
DeleteServiceData,
|
DeleteServiceData,
|
||||||
DeleteServiceErrors,
|
DeleteServiceErrors,
|
||||||
DeleteServiceResponses,
|
DeleteServiceResponses,
|
||||||
@ -91,6 +97,8 @@ import type {
|
|||||||
GetProductsResponses,
|
GetProductsResponses,
|
||||||
GetProjectsData,
|
GetProjectsData,
|
||||||
GetProjectsResponses,
|
GetProjectsResponses,
|
||||||
|
GetServiceCategoriesData,
|
||||||
|
GetServiceCategoriesResponses,
|
||||||
GetServicesData,
|
GetServicesData,
|
||||||
GetServicesKitsData,
|
GetServicesKitsData,
|
||||||
GetServicesKitsResponses,
|
GetServicesKitsResponses,
|
||||||
@ -122,6 +130,9 @@ import type {
|
|||||||
UpdateProjectData,
|
UpdateProjectData,
|
||||||
UpdateProjectErrors,
|
UpdateProjectErrors,
|
||||||
UpdateProjectResponses,
|
UpdateProjectResponses,
|
||||||
|
UpdateServiceCategoryData,
|
||||||
|
UpdateServiceCategoryErrors,
|
||||||
|
UpdateServiceCategoryResponses,
|
||||||
UpdateServiceData,
|
UpdateServiceData,
|
||||||
UpdateServiceErrors,
|
UpdateServiceErrors,
|
||||||
UpdateServiceResponses,
|
UpdateServiceResponses,
|
||||||
@ -151,6 +162,8 @@ import {
|
|||||||
zCreateProductResponse2,
|
zCreateProductResponse2,
|
||||||
zCreateProjectData,
|
zCreateProjectData,
|
||||||
zCreateProjectResponse2,
|
zCreateProjectResponse2,
|
||||||
|
zCreateServiceCategoryData,
|
||||||
|
zCreateServiceCategoryResponse2,
|
||||||
zCreateServiceData,
|
zCreateServiceData,
|
||||||
zCreateServiceResponse2,
|
zCreateServiceResponse2,
|
||||||
zCreateServicesKitData,
|
zCreateServicesKitData,
|
||||||
@ -171,6 +184,8 @@ import {
|
|||||||
zDeleteProductResponse2,
|
zDeleteProductResponse2,
|
||||||
zDeleteProjectData,
|
zDeleteProjectData,
|
||||||
zDeleteProjectResponse2,
|
zDeleteProjectResponse2,
|
||||||
|
zDeleteServiceCategoryData,
|
||||||
|
zDeleteServiceCategoryResponse2,
|
||||||
zDeleteServiceData,
|
zDeleteServiceData,
|
||||||
zDeleteServiceResponse2,
|
zDeleteServiceResponse2,
|
||||||
zDeleteServicesKitData,
|
zDeleteServicesKitData,
|
||||||
@ -193,6 +208,8 @@ import {
|
|||||||
zGetProductsResponse2,
|
zGetProductsResponse2,
|
||||||
zGetProjectsData,
|
zGetProjectsData,
|
||||||
zGetProjectsResponse2,
|
zGetProjectsResponse2,
|
||||||
|
zGetServiceCategoriesData,
|
||||||
|
zGetServiceCategoriesResponse2,
|
||||||
zGetServicesData,
|
zGetServicesData,
|
||||||
zGetServicesKitsData,
|
zGetServicesKitsData,
|
||||||
zGetServicesKitsResponse,
|
zGetServicesKitsResponse,
|
||||||
@ -215,6 +232,8 @@ import {
|
|||||||
zUpdateProductResponse2,
|
zUpdateProductResponse2,
|
||||||
zUpdateProjectData,
|
zUpdateProjectData,
|
||||||
zUpdateProjectResponse2,
|
zUpdateProjectResponse2,
|
||||||
|
zUpdateServiceCategoryData,
|
||||||
|
zUpdateServiceCategoryResponse2,
|
||||||
zUpdateServiceData,
|
zUpdateServiceData,
|
||||||
zUpdateServiceResponse2,
|
zUpdateServiceResponse2,
|
||||||
zUpdateServicesKitData,
|
zUpdateServicesKitData,
|
||||||
@ -1244,6 +1263,106 @@ export const updateService = <ThrowOnError extends boolean = false>(
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Services Categories
|
||||||
|
*/
|
||||||
|
export const getServiceCategories = <ThrowOnError extends boolean = false>(
|
||||||
|
options?: Options<GetServiceCategoriesData, ThrowOnError>
|
||||||
|
) => {
|
||||||
|
return (options?.client ?? _heyApiClient).get<
|
||||||
|
GetServiceCategoriesResponses,
|
||||||
|
unknown,
|
||||||
|
ThrowOnError
|
||||||
|
>({
|
||||||
|
requestValidator: async data => {
|
||||||
|
return await zGetServiceCategoriesData.parseAsync(data);
|
||||||
|
},
|
||||||
|
responseType: "json",
|
||||||
|
responseValidator: async data => {
|
||||||
|
return await zGetServiceCategoriesResponse2.parseAsync(data);
|
||||||
|
},
|
||||||
|
url: "/modules/fulfillment-base/service-category/",
|
||||||
|
...options,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Service Category
|
||||||
|
*/
|
||||||
|
export const createServiceCategory = <ThrowOnError extends boolean = false>(
|
||||||
|
options: Options<CreateServiceCategoryData, ThrowOnError>
|
||||||
|
) => {
|
||||||
|
return (options.client ?? _heyApiClient).post<
|
||||||
|
CreateServiceCategoryResponses,
|
||||||
|
CreateServiceCategoryErrors,
|
||||||
|
ThrowOnError
|
||||||
|
>({
|
||||||
|
requestValidator: async data => {
|
||||||
|
return await zCreateServiceCategoryData.parseAsync(data);
|
||||||
|
},
|
||||||
|
responseType: "json",
|
||||||
|
responseValidator: async data => {
|
||||||
|
return await zCreateServiceCategoryResponse2.parseAsync(data);
|
||||||
|
},
|
||||||
|
url: "/modules/fulfillment-base/service-category/",
|
||||||
|
...options,
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
...options.headers,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete Service Category
|
||||||
|
*/
|
||||||
|
export const deleteServiceCategory = <ThrowOnError extends boolean = false>(
|
||||||
|
options: Options<DeleteServiceCategoryData, ThrowOnError>
|
||||||
|
) => {
|
||||||
|
return (options.client ?? _heyApiClient).delete<
|
||||||
|
DeleteServiceCategoryResponses,
|
||||||
|
DeleteServiceCategoryErrors,
|
||||||
|
ThrowOnError
|
||||||
|
>({
|
||||||
|
requestValidator: async data => {
|
||||||
|
return await zDeleteServiceCategoryData.parseAsync(data);
|
||||||
|
},
|
||||||
|
responseType: "json",
|
||||||
|
responseValidator: async data => {
|
||||||
|
return await zDeleteServiceCategoryResponse2.parseAsync(data);
|
||||||
|
},
|
||||||
|
url: "/modules/fulfillment-base/service-category/{pk}",
|
||||||
|
...options,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Service Category
|
||||||
|
*/
|
||||||
|
export const updateServiceCategory = <ThrowOnError extends boolean = false>(
|
||||||
|
options: Options<UpdateServiceCategoryData, ThrowOnError>
|
||||||
|
) => {
|
||||||
|
return (options.client ?? _heyApiClient).patch<
|
||||||
|
UpdateServiceCategoryResponses,
|
||||||
|
UpdateServiceCategoryErrors,
|
||||||
|
ThrowOnError
|
||||||
|
>({
|
||||||
|
requestValidator: async data => {
|
||||||
|
return await zUpdateServiceCategoryData.parseAsync(data);
|
||||||
|
},
|
||||||
|
responseType: "json",
|
||||||
|
responseValidator: async data => {
|
||||||
|
return await zUpdateServiceCategoryResponse2.parseAsync(data);
|
||||||
|
},
|
||||||
|
url: "/modules/fulfillment-base/service-category/{pk}",
|
||||||
|
...options,
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
...options.headers,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Services Kits
|
* Get Services Kits
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -388,6 +388,42 @@ export type CreateProjectSchema = {
|
|||||||
name: string;
|
name: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CreateServiceCategoryRequest
|
||||||
|
*/
|
||||||
|
export type CreateServiceCategoryRequest = {
|
||||||
|
entity: CreateServiceCategorySchema;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CreateServiceCategoryResponse
|
||||||
|
*/
|
||||||
|
export type CreateServiceCategoryResponse = {
|
||||||
|
/**
|
||||||
|
* Message
|
||||||
|
*/
|
||||||
|
message: string;
|
||||||
|
entity: ServiceCategorySchema;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CreateServiceCategorySchema
|
||||||
|
*/
|
||||||
|
export type CreateServiceCategorySchema = {
|
||||||
|
/**
|
||||||
|
* Name
|
||||||
|
*/
|
||||||
|
name: string;
|
||||||
|
/**
|
||||||
|
* Dealservicerank
|
||||||
|
*/
|
||||||
|
dealServiceRank: string;
|
||||||
|
/**
|
||||||
|
* Productservicerank
|
||||||
|
*/
|
||||||
|
productServiceRank: string;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CreateServiceRequest
|
* CreateServiceRequest
|
||||||
*/
|
*/
|
||||||
@ -410,10 +446,6 @@ export type CreateServiceResponse = {
|
|||||||
* CreateServiceSchema
|
* CreateServiceSchema
|
||||||
*/
|
*/
|
||||||
export type CreateServiceSchema = {
|
export type CreateServiceSchema = {
|
||||||
/**
|
|
||||||
* Id
|
|
||||||
*/
|
|
||||||
id: number;
|
|
||||||
/**
|
/**
|
||||||
* Name
|
* Name
|
||||||
*/
|
*/
|
||||||
@ -713,6 +745,16 @@ export type DeleteProjectResponse = {
|
|||||||
message: string;
|
message: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DeleteServiceCategoryResponse
|
||||||
|
*/
|
||||||
|
export type DeleteServiceCategoryResponse = {
|
||||||
|
/**
|
||||||
|
* Message
|
||||||
|
*/
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DeleteServiceResponse
|
* DeleteServiceResponse
|
||||||
*/
|
*/
|
||||||
@ -814,6 +856,16 @@ export type GetProjectsResponse = {
|
|||||||
items: Array<ProjectSchema>;
|
items: Array<ProjectSchema>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetServiceCategoriesResponse
|
||||||
|
*/
|
||||||
|
export type GetServiceCategoriesResponse = {
|
||||||
|
/**
|
||||||
|
* Items
|
||||||
|
*/
|
||||||
|
items: Array<ServiceCategorySchema>;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GetServicesKitResponse
|
* GetServicesKitResponse
|
||||||
*/
|
*/
|
||||||
@ -1015,10 +1067,6 @@ export type ProjectSchema = {
|
|||||||
* ServiceCategorySchema
|
* ServiceCategorySchema
|
||||||
*/
|
*/
|
||||||
export type ServiceCategorySchema = {
|
export type ServiceCategorySchema = {
|
||||||
/**
|
|
||||||
* Id
|
|
||||||
*/
|
|
||||||
id: number;
|
|
||||||
/**
|
/**
|
||||||
* Name
|
* Name
|
||||||
*/
|
*/
|
||||||
@ -1031,6 +1079,10 @@ export type ServiceCategorySchema = {
|
|||||||
* Productservicerank
|
* Productservicerank
|
||||||
*/
|
*/
|
||||||
productServiceRank: string;
|
productServiceRank: string;
|
||||||
|
/**
|
||||||
|
* Id
|
||||||
|
*/
|
||||||
|
id: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1059,10 +1111,6 @@ export type ServicePriceRangeSchema = {
|
|||||||
* ServiceSchema
|
* ServiceSchema
|
||||||
*/
|
*/
|
||||||
export type ServiceSchema = {
|
export type ServiceSchema = {
|
||||||
/**
|
|
||||||
* Id
|
|
||||||
*/
|
|
||||||
id: number;
|
|
||||||
/**
|
/**
|
||||||
* Name
|
* Name
|
||||||
*/
|
*/
|
||||||
@ -1088,6 +1136,10 @@ export type ServiceSchema = {
|
|||||||
* Lexorank
|
* Lexorank
|
||||||
*/
|
*/
|
||||||
lexorank: string;
|
lexorank: string;
|
||||||
|
/**
|
||||||
|
* Id
|
||||||
|
*/
|
||||||
|
id: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1409,6 +1461,45 @@ export type UpdateProjectSchema = {
|
|||||||
builtInModules?: Array<BuiltInModuleSchemaInput>;
|
builtInModules?: Array<BuiltInModuleSchemaInput>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UpdateServiceCategoryRequest
|
||||||
|
*/
|
||||||
|
export type UpdateServiceCategoryRequest = {
|
||||||
|
entity: UpdateServiceCategorySchema;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UpdateServiceCategoryResponse
|
||||||
|
*/
|
||||||
|
export type UpdateServiceCategoryResponse = {
|
||||||
|
/**
|
||||||
|
* Message
|
||||||
|
*/
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UpdateServiceCategorySchema
|
||||||
|
*/
|
||||||
|
export type UpdateServiceCategorySchema = {
|
||||||
|
/**
|
||||||
|
* Name
|
||||||
|
*/
|
||||||
|
name: string;
|
||||||
|
/**
|
||||||
|
* Dealservicerank
|
||||||
|
*/
|
||||||
|
dealServiceRank: string;
|
||||||
|
/**
|
||||||
|
* Productservicerank
|
||||||
|
*/
|
||||||
|
productServiceRank: string;
|
||||||
|
/**
|
||||||
|
* Id
|
||||||
|
*/
|
||||||
|
id: number;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UpdateServiceRequest
|
* UpdateServiceRequest
|
||||||
*/
|
*/
|
||||||
@ -1430,10 +1521,6 @@ export type UpdateServiceResponse = {
|
|||||||
* UpdateServiceSchema
|
* UpdateServiceSchema
|
||||||
*/
|
*/
|
||||||
export type UpdateServiceSchema = {
|
export type UpdateServiceSchema = {
|
||||||
/**
|
|
||||||
* Id
|
|
||||||
*/
|
|
||||||
id: number;
|
|
||||||
/**
|
/**
|
||||||
* Name
|
* Name
|
||||||
*/
|
*/
|
||||||
@ -1459,6 +1546,10 @@ export type UpdateServiceSchema = {
|
|||||||
* Lexorank
|
* Lexorank
|
||||||
*/
|
*/
|
||||||
lexorank: string;
|
lexorank: string;
|
||||||
|
/**
|
||||||
|
* Id
|
||||||
|
*/
|
||||||
|
id: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2767,6 +2858,114 @@ export type UpdateServiceResponses = {
|
|||||||
export type UpdateServiceResponse2 =
|
export type UpdateServiceResponse2 =
|
||||||
UpdateServiceResponses[keyof UpdateServiceResponses];
|
UpdateServiceResponses[keyof UpdateServiceResponses];
|
||||||
|
|
||||||
|
export type GetServiceCategoriesData = {
|
||||||
|
body?: never;
|
||||||
|
path?: never;
|
||||||
|
query?: never;
|
||||||
|
url: "/modules/fulfillment-base/service-category/";
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GetServiceCategoriesResponses = {
|
||||||
|
/**
|
||||||
|
* Successful Response
|
||||||
|
*/
|
||||||
|
200: GetServiceCategoriesResponse;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GetServiceCategoriesResponse2 =
|
||||||
|
GetServiceCategoriesResponses[keyof GetServiceCategoriesResponses];
|
||||||
|
|
||||||
|
export type CreateServiceCategoryData = {
|
||||||
|
body: CreateServiceCategoryRequest;
|
||||||
|
path?: never;
|
||||||
|
query?: never;
|
||||||
|
url: "/modules/fulfillment-base/service-category/";
|
||||||
|
};
|
||||||
|
|
||||||
|
export type CreateServiceCategoryErrors = {
|
||||||
|
/**
|
||||||
|
* Validation Error
|
||||||
|
*/
|
||||||
|
422: HttpValidationError;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type CreateServiceCategoryError =
|
||||||
|
CreateServiceCategoryErrors[keyof CreateServiceCategoryErrors];
|
||||||
|
|
||||||
|
export type CreateServiceCategoryResponses = {
|
||||||
|
/**
|
||||||
|
* Successful Response
|
||||||
|
*/
|
||||||
|
200: CreateServiceCategoryResponse;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type CreateServiceCategoryResponse2 =
|
||||||
|
CreateServiceCategoryResponses[keyof CreateServiceCategoryResponses];
|
||||||
|
|
||||||
|
export type DeleteServiceCategoryData = {
|
||||||
|
body?: never;
|
||||||
|
path: {
|
||||||
|
/**
|
||||||
|
* Pk
|
||||||
|
*/
|
||||||
|
pk: number;
|
||||||
|
};
|
||||||
|
query?: never;
|
||||||
|
url: "/modules/fulfillment-base/service-category/{pk}";
|
||||||
|
};
|
||||||
|
|
||||||
|
export type DeleteServiceCategoryErrors = {
|
||||||
|
/**
|
||||||
|
* Validation Error
|
||||||
|
*/
|
||||||
|
422: HttpValidationError;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type DeleteServiceCategoryError =
|
||||||
|
DeleteServiceCategoryErrors[keyof DeleteServiceCategoryErrors];
|
||||||
|
|
||||||
|
export type DeleteServiceCategoryResponses = {
|
||||||
|
/**
|
||||||
|
* Successful Response
|
||||||
|
*/
|
||||||
|
200: DeleteServiceCategoryResponse;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type DeleteServiceCategoryResponse2 =
|
||||||
|
DeleteServiceCategoryResponses[keyof DeleteServiceCategoryResponses];
|
||||||
|
|
||||||
|
export type UpdateServiceCategoryData = {
|
||||||
|
body: UpdateServiceCategoryRequest;
|
||||||
|
path: {
|
||||||
|
/**
|
||||||
|
* Pk
|
||||||
|
*/
|
||||||
|
pk: number;
|
||||||
|
};
|
||||||
|
query?: never;
|
||||||
|
url: "/modules/fulfillment-base/service-category/{pk}";
|
||||||
|
};
|
||||||
|
|
||||||
|
export type UpdateServiceCategoryErrors = {
|
||||||
|
/**
|
||||||
|
* Validation Error
|
||||||
|
*/
|
||||||
|
422: HttpValidationError;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type UpdateServiceCategoryError =
|
||||||
|
UpdateServiceCategoryErrors[keyof UpdateServiceCategoryErrors];
|
||||||
|
|
||||||
|
export type UpdateServiceCategoryResponses = {
|
||||||
|
/**
|
||||||
|
* Successful Response
|
||||||
|
*/
|
||||||
|
200: UpdateServiceCategoryResponse;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type UpdateServiceCategoryResponse2 =
|
||||||
|
UpdateServiceCategoryResponses[keyof UpdateServiceCategoryResponses];
|
||||||
|
|
||||||
export type GetServicesKitsData = {
|
export type GetServicesKitsData = {
|
||||||
body?: never;
|
body?: never;
|
||||||
path?: never;
|
path?: never;
|
||||||
|
|||||||
@ -119,10 +119,10 @@ export const zProductSchema = z.object({
|
|||||||
* ServiceCategorySchema
|
* ServiceCategorySchema
|
||||||
*/
|
*/
|
||||||
export const zServiceCategorySchema = z.object({
|
export const zServiceCategorySchema = z.object({
|
||||||
id: z.int(),
|
|
||||||
name: z.string(),
|
name: z.string(),
|
||||||
dealServiceRank: z.string(),
|
dealServiceRank: z.string(),
|
||||||
productServiceRank: z.string(),
|
productServiceRank: z.string(),
|
||||||
|
id: z.int(),
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -139,7 +139,6 @@ export const zServicePriceRangeSchema = z.object({
|
|||||||
* ServiceSchema
|
* ServiceSchema
|
||||||
*/
|
*/
|
||||||
export const zServiceSchema = z.object({
|
export const zServiceSchema = z.object({
|
||||||
id: z.int(),
|
|
||||||
name: z.string(),
|
name: z.string(),
|
||||||
category: zServiceCategorySchema,
|
category: zServiceCategorySchema,
|
||||||
price: z.number(),
|
price: z.number(),
|
||||||
@ -147,6 +146,7 @@ export const zServiceSchema = z.object({
|
|||||||
priceRanges: z.array(zServicePriceRangeSchema),
|
priceRanges: z.array(zServicePriceRangeSchema),
|
||||||
cost: z.union([z.number(), z.null()]),
|
cost: z.union([z.number(), z.null()]),
|
||||||
lexorank: z.string(),
|
lexorank: z.string(),
|
||||||
|
id: z.int(),
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -351,11 +351,34 @@ export const zCreateProjectResponse = z.object({
|
|||||||
entity: zProjectSchema,
|
entity: zProjectSchema,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CreateServiceCategorySchema
|
||||||
|
*/
|
||||||
|
export const zCreateServiceCategorySchema = z.object({
|
||||||
|
name: z.string(),
|
||||||
|
dealServiceRank: z.string(),
|
||||||
|
productServiceRank: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CreateServiceCategoryRequest
|
||||||
|
*/
|
||||||
|
export const zCreateServiceCategoryRequest = z.object({
|
||||||
|
entity: zCreateServiceCategorySchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CreateServiceCategoryResponse
|
||||||
|
*/
|
||||||
|
export const zCreateServiceCategoryResponse = z.object({
|
||||||
|
message: z.string(),
|
||||||
|
entity: zServiceCategorySchema,
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CreateServiceSchema
|
* CreateServiceSchema
|
||||||
*/
|
*/
|
||||||
export const zCreateServiceSchema = z.object({
|
export const zCreateServiceSchema = z.object({
|
||||||
id: z.int(),
|
|
||||||
name: z.string(),
|
name: z.string(),
|
||||||
category: zServiceCategorySchema,
|
category: zServiceCategorySchema,
|
||||||
price: z.number(),
|
price: z.number(),
|
||||||
@ -518,6 +541,13 @@ export const zDeleteProjectResponse = z.object({
|
|||||||
message: z.string(),
|
message: z.string(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DeleteServiceCategoryResponse
|
||||||
|
*/
|
||||||
|
export const zDeleteServiceCategoryResponse = z.object({
|
||||||
|
message: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DeleteServiceResponse
|
* DeleteServiceResponse
|
||||||
*/
|
*/
|
||||||
@ -597,6 +627,13 @@ export const zGetProjectsResponse = z.object({
|
|||||||
items: z.array(zProjectSchema),
|
items: z.array(zProjectSchema),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetServiceCategoriesResponse
|
||||||
|
*/
|
||||||
|
export const zGetServiceCategoriesResponse = z.object({
|
||||||
|
items: z.array(zServiceCategorySchema),
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GetServicesKitResponse
|
* GetServicesKitResponse
|
||||||
*/
|
*/
|
||||||
@ -845,11 +882,34 @@ export const zUpdateProjectResponse = z.object({
|
|||||||
message: z.string(),
|
message: z.string(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UpdateServiceCategorySchema
|
||||||
|
*/
|
||||||
|
export const zUpdateServiceCategorySchema = z.object({
|
||||||
|
name: z.string(),
|
||||||
|
dealServiceRank: z.string(),
|
||||||
|
productServiceRank: z.string(),
|
||||||
|
id: z.int(),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UpdateServiceCategoryRequest
|
||||||
|
*/
|
||||||
|
export const zUpdateServiceCategoryRequest = z.object({
|
||||||
|
entity: zUpdateServiceCategorySchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UpdateServiceCategoryResponse
|
||||||
|
*/
|
||||||
|
export const zUpdateServiceCategoryResponse = z.object({
|
||||||
|
message: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UpdateServiceSchema
|
* UpdateServiceSchema
|
||||||
*/
|
*/
|
||||||
export const zUpdateServiceSchema = z.object({
|
export const zUpdateServiceSchema = z.object({
|
||||||
id: z.int(),
|
|
||||||
name: z.string(),
|
name: z.string(),
|
||||||
category: zServiceCategorySchema,
|
category: zServiceCategorySchema,
|
||||||
price: z.number(),
|
price: z.number(),
|
||||||
@ -857,6 +917,7 @@ export const zUpdateServiceSchema = z.object({
|
|||||||
priceRanges: z.array(zServicePriceRangeSchema),
|
priceRanges: z.array(zServicePriceRangeSchema),
|
||||||
cost: z.union([z.number(), z.null()]),
|
cost: z.union([z.number(), z.null()]),
|
||||||
lexorank: z.string(),
|
lexorank: z.string(),
|
||||||
|
id: z.int(),
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1431,6 +1492,54 @@ export const zUpdateServiceData = z.object({
|
|||||||
*/
|
*/
|
||||||
export const zUpdateServiceResponse2 = zUpdateServiceResponse;
|
export const zUpdateServiceResponse2 = zUpdateServiceResponse;
|
||||||
|
|
||||||
|
export const zGetServiceCategoriesData = z.object({
|
||||||
|
body: z.optional(z.never()),
|
||||||
|
path: z.optional(z.never()),
|
||||||
|
query: z.optional(z.never()),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Successful Response
|
||||||
|
*/
|
||||||
|
export const zGetServiceCategoriesResponse2 = zGetServiceCategoriesResponse;
|
||||||
|
|
||||||
|
export const zCreateServiceCategoryData = z.object({
|
||||||
|
body: zCreateServiceCategoryRequest,
|
||||||
|
path: z.optional(z.never()),
|
||||||
|
query: z.optional(z.never()),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Successful Response
|
||||||
|
*/
|
||||||
|
export const zCreateServiceCategoryResponse2 = zCreateServiceCategoryResponse;
|
||||||
|
|
||||||
|
export const zDeleteServiceCategoryData = z.object({
|
||||||
|
body: z.optional(z.never()),
|
||||||
|
path: z.object({
|
||||||
|
pk: z.int(),
|
||||||
|
}),
|
||||||
|
query: z.optional(z.never()),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Successful Response
|
||||||
|
*/
|
||||||
|
export const zDeleteServiceCategoryResponse2 = zDeleteServiceCategoryResponse;
|
||||||
|
|
||||||
|
export const zUpdateServiceCategoryData = z.object({
|
||||||
|
body: zUpdateServiceCategoryRequest,
|
||||||
|
path: z.object({
|
||||||
|
pk: z.int(),
|
||||||
|
}),
|
||||||
|
query: z.optional(z.never()),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Successful Response
|
||||||
|
*/
|
||||||
|
export const zUpdateServiceCategoryResponse2 = zUpdateServiceCategoryResponse;
|
||||||
|
|
||||||
export const zGetServicesKitsData = z.object({
|
export const zGetServicesKitsData = z.object({
|
||||||
body: z.optional(z.never()),
|
body: z.optional(z.never()),
|
||||||
path: z.optional(z.never()),
|
path: z.optional(z.never()),
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import DealsBoardFiltersModal from "@/app/deals/modals/DealsBoardFiltersModal/DealsBoardFiltersModal";
|
import DealsBoardFiltersModal from "@/app/deals/modals/DealsBoardFiltersModal/DealsBoardFiltersModal";
|
||||||
import DealsScheduleFiltersModal from "@/app/deals/modals/DealsScheduleFiltersModal/DealsScheduleFiltersModal";
|
import DealsScheduleFiltersModal from "@/app/deals/modals/DealsScheduleFiltersModal/DealsScheduleFiltersModal";
|
||||||
import DealsTableFiltersModal from "@/app/deals/modals/DealsTableFiltersModal/DealsTableFiltersModal";
|
import DealsTableFiltersModal from "@/app/deals/modals/DealsTableFiltersModal/DealsTableFiltersModal";
|
||||||
import { ServicesKitEditorModal } from "@/app/services/modals";
|
import { ServiceCategoryEditorModal, ServiceEditorModal, ServicesKitEditorModal } from "@/app/services/modals";
|
||||||
import EnterNameModal from "@/modals/EnterNameModal/EnterNameModal";
|
import EnterNameModal from "@/modals/EnterNameModal/EnterNameModal";
|
||||||
import {
|
import {
|
||||||
DealProductEditorModal,
|
DealProductEditorModal,
|
||||||
@ -24,4 +24,6 @@ export const modals = {
|
|||||||
duplicateServicesModal: DuplicateServicesModal,
|
duplicateServicesModal: DuplicateServicesModal,
|
||||||
servicesKitSelectModal: ServicesKitSelectModal,
|
servicesKitSelectModal: ServicesKitSelectModal,
|
||||||
servicesKitEditorModal: ServicesKitEditorModal,
|
servicesKitEditorModal: ServicesKitEditorModal,
|
||||||
|
serviceCategoryEditorModal: ServiceCategoryEditorModal,
|
||||||
|
serviceEditorModal: ServiceEditorModal,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -0,0 +1,84 @@
|
|||||||
|
import { LexoRank } from "lexorank";
|
||||||
|
import { useCrudOperations } from "@/hooks/cruds/baseCrud";
|
||||||
|
import {
|
||||||
|
CreateServiceCategorySchema,
|
||||||
|
ServiceCategorySchema,
|
||||||
|
UpdateServiceCategorySchema,
|
||||||
|
} from "@/lib/client";
|
||||||
|
import {
|
||||||
|
createServiceCategoryMutation,
|
||||||
|
deleteServiceCategoryMutation,
|
||||||
|
updateServiceCategoryMutation,
|
||||||
|
} from "@/lib/client/@tanstack/react-query.gen";
|
||||||
|
import { ServiceType } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/types/service";
|
||||||
|
import { getMaxLexorankByKey, getNewLexorank } from "@/utils/lexorank";
|
||||||
|
|
||||||
|
type UseServiceCategoryProps = {
|
||||||
|
queryKey: any[];
|
||||||
|
categories: ServiceCategorySchema[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ServiceCategoriesCrud = {
|
||||||
|
onCreate: (category: CreateServiceCategorySchema) => void;
|
||||||
|
onUpdate: (
|
||||||
|
categoryId: number,
|
||||||
|
category: UpdateServiceCategorySchema,
|
||||||
|
onSuccess?: () => void
|
||||||
|
) => void;
|
||||||
|
onDelete: (service: ServiceCategorySchema) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useServiceCategoriesCrud = ({
|
||||||
|
queryKey,
|
||||||
|
categories,
|
||||||
|
}: UseServiceCategoryProps): ServiceCategoriesCrud => {
|
||||||
|
const getCategoryRank = (serviceType: ServiceType): string => {
|
||||||
|
const lastCategory = getMaxLexorankByKey(
|
||||||
|
categories,
|
||||||
|
serviceType === ServiceType.DEAL_SERVICE
|
||||||
|
? "dealServiceRank"
|
||||||
|
: "productServiceRank"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!lastCategory) return LexoRank.middle().toString();
|
||||||
|
|
||||||
|
const rank =
|
||||||
|
serviceType === ServiceType.DEAL_SERVICE
|
||||||
|
? lastCategory.dealServiceRank
|
||||||
|
: lastCategory?.productServiceRank;
|
||||||
|
|
||||||
|
return getNewLexorank(LexoRank.parse(rank)).toString();
|
||||||
|
};
|
||||||
|
|
||||||
|
return useCrudOperations<
|
||||||
|
ServiceCategorySchema,
|
||||||
|
UpdateServiceCategorySchema,
|
||||||
|
CreateServiceCategorySchema
|
||||||
|
>({
|
||||||
|
key: "getServiceCategories",
|
||||||
|
queryKey,
|
||||||
|
mutations: {
|
||||||
|
create: createServiceCategoryMutation(),
|
||||||
|
update: updateServiceCategoryMutation(),
|
||||||
|
delete: deleteServiceCategoryMutation(),
|
||||||
|
},
|
||||||
|
getCreateEntity: category => {
|
||||||
|
const dealServiceRank = getCategoryRank(ServiceType.DEAL_SERVICE);
|
||||||
|
const productServiceRank = getCategoryRank(
|
||||||
|
ServiceType.PRODUCT_SERVICE
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
dealServiceRank,
|
||||||
|
productServiceRank,
|
||||||
|
name: category.name!,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
getUpdateEntity: (old, update) =>
|
||||||
|
({
|
||||||
|
...old,
|
||||||
|
...update,
|
||||||
|
}) as ServiceCategorySchema,
|
||||||
|
getDeleteConfirmTitle: () => "Удаление категории услуг",
|
||||||
|
});
|
||||||
|
};
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { LexoRank } from "lexorank";
|
||||||
import { useCrudOperations } from "@/hooks/cruds/baseCrud";
|
import { useCrudOperations } from "@/hooks/cruds/baseCrud";
|
||||||
import {
|
import {
|
||||||
CreateServiceSchema,
|
CreateServiceSchema,
|
||||||
@ -9,9 +10,11 @@ import {
|
|||||||
deleteServiceMutation,
|
deleteServiceMutation,
|
||||||
updateServiceMutation,
|
updateServiceMutation,
|
||||||
} from "@/lib/client/@tanstack/react-query.gen";
|
} from "@/lib/client/@tanstack/react-query.gen";
|
||||||
|
import { getMaxByLexorank, getNewLexorank } from "@/utils/lexorank";
|
||||||
|
|
||||||
type UseServicesProps = {
|
type UseServicesProps = {
|
||||||
queryKey: any[];
|
queryKey: any[];
|
||||||
|
services: ServiceSchema[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ServicesCrud = {
|
export type ServicesCrud = {
|
||||||
@ -26,6 +29,7 @@ export type ServicesCrud = {
|
|||||||
|
|
||||||
export const useServicesCrud = ({
|
export const useServicesCrud = ({
|
||||||
queryKey,
|
queryKey,
|
||||||
|
services,
|
||||||
}: UseServicesProps): ServicesCrud => {
|
}: UseServicesProps): ServicesCrud => {
|
||||||
return useCrudOperations<
|
return useCrudOperations<
|
||||||
ServiceSchema,
|
ServiceSchema,
|
||||||
@ -39,6 +43,15 @@ export const useServicesCrud = ({
|
|||||||
update: updateServiceMutation(),
|
update: updateServiceMutation(),
|
||||||
delete: deleteServiceMutation(),
|
delete: deleteServiceMutation(),
|
||||||
},
|
},
|
||||||
|
getCreateEntity: service => {
|
||||||
|
const maxRankStr = getMaxByLexorank(services)?.lexorank;
|
||||||
|
const maxRank = maxRankStr ? LexoRank.parse(maxRankStr) : null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...(service as CreateServiceSchema),
|
||||||
|
lexorank: getNewLexorank(maxRank).toString(),
|
||||||
|
};
|
||||||
|
},
|
||||||
getUpdateEntity: (old, update) =>
|
getUpdateEntity: (old, update) =>
|
||||||
({
|
({
|
||||||
...old,
|
...old,
|
||||||
|
|||||||
@ -0,0 +1,43 @@
|
|||||||
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
|
import { ServiceCategorySchema } from "@/lib/client";
|
||||||
|
import {
|
||||||
|
getServiceCategoriesOptions,
|
||||||
|
getServiceCategoriesQueryKey,
|
||||||
|
} from "@/lib/client/@tanstack/react-query.gen";
|
||||||
|
|
||||||
|
export type ServiceCategoriesList = {
|
||||||
|
categories: ServiceCategorySchema[];
|
||||||
|
setCategories: (categories: ServiceCategorySchema[]) => void;
|
||||||
|
refetch: () => void;
|
||||||
|
queryKey: any[];
|
||||||
|
isLoading: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const useServiceCategoriesList = (): ServiceCategoriesList => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const { data, refetch, isLoading } = useQuery(
|
||||||
|
getServiceCategoriesOptions()
|
||||||
|
);
|
||||||
|
|
||||||
|
const queryKey = getServiceCategoriesQueryKey();
|
||||||
|
|
||||||
|
const setCategories = (categories: ServiceCategorySchema[]) => {
|
||||||
|
queryClient.setQueryData(
|
||||||
|
queryKey,
|
||||||
|
(old: { items: ServiceCategorySchema[] }) => ({
|
||||||
|
...old,
|
||||||
|
items: categories,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
categories: data?.items ?? [],
|
||||||
|
setCategories,
|
||||||
|
refetch,
|
||||||
|
queryKey,
|
||||||
|
isLoading,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useServiceCategoriesList;
|
||||||
@ -2,3 +2,8 @@ export enum ServiceType {
|
|||||||
DEAL_SERVICE,
|
DEAL_SERVICE,
|
||||||
PRODUCT_SERVICE,
|
PRODUCT_SERVICE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum ServicePriceType {
|
||||||
|
DEFAULT,
|
||||||
|
BY_RANGE,
|
||||||
|
}
|
||||||
|
|||||||
@ -30,6 +30,13 @@ export function getMaxByLexorank<T extends LexorankSortable>(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getMaxLexorankByKey<T>(items: T[], key: keyof T): T | null {
|
||||||
|
return items.reduce(
|
||||||
|
(max, item) => (!max || item[key] > max[key] ? item : max),
|
||||||
|
null as T | null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function getNewLexorank(
|
export function getNewLexorank(
|
||||||
left?: LexoRank | null,
|
left?: LexoRank | null,
|
||||||
right?: LexoRank | null
|
right?: LexoRank | null
|
||||||
|
|||||||
Reference in New Issue
Block a user