feat: removed price categories
This commit is contained in:
@@ -174,14 +174,6 @@ const Content: FC<Props> = ({ deal }) => {
|
||||
{...form.getInputProps("status")}
|
||||
label={"Статус"}
|
||||
/>
|
||||
{deal.category && (
|
||||
<TextInput
|
||||
disabled
|
||||
placeholder={"Категория"}
|
||||
label={"Категория"}
|
||||
value={deal.category.name}
|
||||
/>
|
||||
)}
|
||||
<Textarea
|
||||
h={rem(150)}
|
||||
styles={{
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
import { ContextModalProps } from "@mantine/modals";
|
||||
import BaseFormModal, {
|
||||
CreateEditFormProps,
|
||||
} from "../../ClientsPage/modals/BaseFormModal/BaseFormModal.tsx";
|
||||
import { DealServiceSchema, ServicePriceCategorySchema } from "../../../client";
|
||||
import BaseFormModal, { CreateEditFormProps } from "../../ClientsPage/modals/BaseFormModal/BaseFormModal.tsx";
|
||||
import { DealServiceSchema } from "../../../client";
|
||||
import { useForm } from "@mantine/form";
|
||||
import {
|
||||
ComboboxItem,
|
||||
ComboboxItemGroup,
|
||||
NumberInput,
|
||||
OptionsFilter,
|
||||
} from "@mantine/core";
|
||||
import { ComboboxItem, ComboboxItemGroup, NumberInput, OptionsFilter } from "@mantine/core";
|
||||
import ServiceWithPriceInput from "../../../components/ServiceWithPriceInput/ServiceWithPriceInput.tsx";
|
||||
import { ServiceType } from "../../../shared/enums/ServiceType.ts";
|
||||
import { useSelector } from "react-redux";
|
||||
@@ -17,7 +10,6 @@ import { RootState } from "../../../redux/store.ts";
|
||||
|
||||
type RestProps = {
|
||||
serviceIds?: number[];
|
||||
category?: ServicePriceCategorySchema;
|
||||
};
|
||||
type Props = CreateEditFormProps<Partial<DealServiceSchema>> & RestProps;
|
||||
const AddDealServiceModal = ({
|
||||
@@ -26,7 +18,6 @@ const AddDealServiceModal = ({
|
||||
innerProps,
|
||||
}: ContextModalProps<Props>) => {
|
||||
const authState = useSelector((state: RootState) => state.auth);
|
||||
console.log(innerProps.category);
|
||||
const isEditing = "element" in innerProps;
|
||||
const form = useForm<Partial<DealServiceSchema>>({
|
||||
initialValues: isEditing
|
||||
@@ -77,7 +68,6 @@ const AddDealServiceModal = ({
|
||||
<BaseFormModal.Body>
|
||||
<>
|
||||
<ServiceWithPriceInput
|
||||
category={innerProps.category}
|
||||
serviceProps={{
|
||||
...form.getInputProps("service"),
|
||||
label: "Услуга",
|
||||
|
||||
@@ -3,7 +3,6 @@ import BaseFormModal, {
|
||||
} from "../../ClientsPage/modals/BaseFormModal/BaseFormModal.tsx";
|
||||
import {
|
||||
DealProductServiceSchema,
|
||||
ServicePriceCategorySchema,
|
||||
ServiceSchema,
|
||||
} from "../../../client";
|
||||
import { ContextModalProps } from "@mantine/modals";
|
||||
@@ -18,7 +17,6 @@ import { RootState } from "../../../redux/store.ts";
|
||||
type RestProps = {
|
||||
quantity: number;
|
||||
serviceIds: number[];
|
||||
category?: ServicePriceCategorySchema;
|
||||
};
|
||||
type Props = CreateEditFormProps<DealProductServiceSchema> & RestProps;
|
||||
|
||||
@@ -60,7 +58,6 @@ const ProductServiceFormModal = ({
|
||||
<>
|
||||
<Flex w={"100%"} direction={"column"} gap={rem(10)}>
|
||||
<ServiceWithPriceInput
|
||||
category={innerProps.category}
|
||||
serviceProps={{
|
||||
...form.getInputProps("service"),
|
||||
label: "Услуга",
|
||||
|
||||
@@ -50,7 +50,6 @@ const DealServicesTable: FC<Props> = ({
|
||||
innerProps: {
|
||||
onCreate: onCreate,
|
||||
serviceIds,
|
||||
category: dealState.deal?.category || undefined,
|
||||
},
|
||||
withCloseButton: false,
|
||||
});
|
||||
|
||||
@@ -48,7 +48,6 @@ const ProductServicesTable: FC<Props> = ({
|
||||
onCreate: onCreate,
|
||||
serviceIds,
|
||||
quantity,
|
||||
category: dealState.deal?.category || undefined,
|
||||
},
|
||||
withCloseButton: false,
|
||||
});
|
||||
@@ -63,7 +62,6 @@ const ProductServicesTable: FC<Props> = ({
|
||||
onChange,
|
||||
serviceIds,
|
||||
quantity,
|
||||
category: dealState.deal?.category || undefined,
|
||||
},
|
||||
withCloseButton: false,
|
||||
});
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
import { CRUDTableProps } from "../../../../types/CRUDTable.tsx";
|
||||
import { ServicePriceCategorySchema } from "../../../../client";
|
||||
import { FC } from "react";
|
||||
import { BaseTable } from "../../../../components/BaseTable/BaseTable.tsx";
|
||||
import useServicePriceCategoryTableColumns from "./columns.tsx";
|
||||
import { MRT_TableOptions } from "mantine-react-table";
|
||||
import { ActionIcon, Flex, Tooltip } from "@mantine/core";
|
||||
import { IconEdit, IconTrash } from "@tabler/icons-react";
|
||||
|
||||
type Props = CRUDTableProps<ServicePriceCategorySchema>;
|
||||
|
||||
const ServicePriceCategoryTable: FC<Props> = ({
|
||||
items,
|
||||
onChange,
|
||||
onDelete,
|
||||
}) => {
|
||||
const columns = useServicePriceCategoryTableColumns();
|
||||
return (
|
||||
<BaseTable
|
||||
data={items}
|
||||
columns={columns}
|
||||
restProps={
|
||||
{
|
||||
enableRowActions: true,
|
||||
renderRowActions: ({ row }) => (
|
||||
<Flex gap="md">
|
||||
<Tooltip label="Редактировать">
|
||||
<ActionIcon
|
||||
onClick={() =>
|
||||
onChange && onChange(row.original)
|
||||
}
|
||||
variant={"default"}>
|
||||
<IconEdit />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
<Tooltip label="Удалить">
|
||||
<ActionIcon
|
||||
onClick={() =>
|
||||
onDelete && onDelete(row.original)
|
||||
}
|
||||
variant={"default"}>
|
||||
<IconTrash />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
</Flex>
|
||||
),
|
||||
} as MRT_TableOptions<ServicePriceCategorySchema>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ServicePriceCategoryTable;
|
||||
@@ -1,19 +0,0 @@
|
||||
import { useMemo } from "react";
|
||||
import { MRT_ColumnDef } from "mantine-react-table";
|
||||
import { ServicePriceCategorySchema } from "../../../../client";
|
||||
|
||||
const useServicePriceCategoryTableColumns = () => {
|
||||
return useMemo<MRT_ColumnDef<ServicePriceCategorySchema>[]>(
|
||||
() => [
|
||||
{
|
||||
accessorKey: "name",
|
||||
header: "Название",
|
||||
enableColumnActions: false,
|
||||
enableSorting: false,
|
||||
},
|
||||
],
|
||||
[]
|
||||
);
|
||||
};
|
||||
|
||||
export default useServicePriceCategoryTableColumns;
|
||||
@@ -1,70 +0,0 @@
|
||||
import { BaseFormInputProps } from "../../../../types/utils.ts";
|
||||
import type {
|
||||
ServiceCategoryPriceSchema,
|
||||
ServicePriceCategorySchema,
|
||||
} from "../../../../client";
|
||||
import { FC, useEffect, useState } from "react";
|
||||
import { Flex, NumberInput, rem } from "@mantine/core";
|
||||
import ServicePriceCategorySelect from "../../../../components/Selects/ServicePriceCategorySelect/ServicePriceCategorySelect.tsx";
|
||||
|
||||
export type PriceCategoryInputProps = BaseFormInputProps<
|
||||
ServiceCategoryPriceSchema[]
|
||||
>;
|
||||
|
||||
const PriceCategoryInput: FC<PriceCategoryInputProps> = (
|
||||
props: PriceCategoryInputProps
|
||||
) => {
|
||||
const [innerState, setInnerState] = useState<ServiceCategoryPriceSchema[]>(
|
||||
props.value || []
|
||||
);
|
||||
const [category, setCategory] = useState<
|
||||
ServicePriceCategorySchema | undefined
|
||||
>(undefined);
|
||||
|
||||
const getValue = (): number | undefined | string => {
|
||||
if (category === undefined) return undefined;
|
||||
const value = innerState.find(item => item.category.id === category.id);
|
||||
|
||||
return value?.price || "";
|
||||
};
|
||||
const handleChange = (value: number | string) => {
|
||||
// remove value if is string
|
||||
if (typeof value === "string") {
|
||||
setInnerState(
|
||||
innerState.filter(item => item.category.id !== category?.id)
|
||||
);
|
||||
return;
|
||||
}
|
||||
const newValue = {
|
||||
category: category as ServicePriceCategorySchema,
|
||||
price: value,
|
||||
};
|
||||
const newInnerState = innerState.filter(
|
||||
item => item.category.id !== category?.id
|
||||
);
|
||||
setInnerState([...newInnerState, newValue]);
|
||||
};
|
||||
useEffect(() => {
|
||||
if (props.value === innerState) return;
|
||||
props.onChange(innerState);
|
||||
}, [innerState]);
|
||||
return (
|
||||
<Flex
|
||||
direction={"column"}
|
||||
gap={rem(10)}>
|
||||
<ServicePriceCategorySelect
|
||||
label={"Категория цены"}
|
||||
placeholder={"Выберите категорию цены"}
|
||||
onChange={setCategory}
|
||||
/>
|
||||
<NumberInput
|
||||
label={"Цена"}
|
||||
placeholder={"Введите цену"}
|
||||
value={getValue()}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default PriceCategoryInput;
|
||||
@@ -5,7 +5,6 @@ import { omit } from "lodash";
|
||||
export enum ServicePriceType {
|
||||
DEFAULT,
|
||||
BY_RANGE,
|
||||
BY_CATEGORY,
|
||||
}
|
||||
|
||||
type RestProps = {
|
||||
@@ -26,10 +25,6 @@ const ServicePriceTypeSegmentedControl: FC<Props> = props => {
|
||||
label: "По диапазону",
|
||||
value: ServicePriceType.BY_RANGE.toString(),
|
||||
},
|
||||
{
|
||||
label: "По категории",
|
||||
value: ServicePriceType.BY_CATEGORY.toString(),
|
||||
},
|
||||
];
|
||||
const handleChange = (value: string) => {
|
||||
onChange(Number(value));
|
||||
|
||||
@@ -5,7 +5,6 @@ export enum ServicesTab {
|
||||
DEAL_SERVICE,
|
||||
PRODUCT_SERVICE,
|
||||
SERVICES_KITS,
|
||||
SERVICES_PRICE_CATEGORIES,
|
||||
}
|
||||
|
||||
type Props = Omit<SegmentedControlProps, "data">;
|
||||
@@ -22,10 +21,6 @@ const data = [
|
||||
label: "Наборы услуг",
|
||||
value: ServicesTab.SERVICES_KITS.toString(),
|
||||
},
|
||||
{
|
||||
label: "Категории цен",
|
||||
value: ServicesTab.SERVICES_PRICE_CATEGORIES.toString(),
|
||||
},
|
||||
];
|
||||
const ServiceTypeSegmentedControl: FC<Props> = props => {
|
||||
return (
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import ObjectList from "../../../hooks/objectList.tsx";
|
||||
import { ServiceService } from "../../../client";
|
||||
|
||||
const useServicePriceCategoriesList = () =>
|
||||
ObjectList({
|
||||
queryFn: ServiceService.getAllPriceCategories,
|
||||
getObjectsFn: response => response.priceCategories,
|
||||
queryKey: "getAllPriceCategories",
|
||||
});
|
||||
|
||||
export default useServicePriceCategoriesList;
|
||||
@@ -1,83 +0,0 @@
|
||||
import UseObjectState from "../../../types/UseObjectState.ts";
|
||||
import {
|
||||
type ServicePriceCategorySchema,
|
||||
ServiceService,
|
||||
} from "../../../client";
|
||||
import useServicePriceCategoriesList from "./useServicePriceCategoriesList.tsx";
|
||||
import { modals } from "@mantine/modals";
|
||||
import { notifications } from "../../../shared/lib/notifications.ts";
|
||||
|
||||
const useServicePriceCategoryState =
|
||||
(): UseObjectState<ServicePriceCategorySchema> => {
|
||||
const { objects, refetch } = useServicePriceCategoriesList();
|
||||
const onCreateClick = () => {
|
||||
modals.openContextModal({
|
||||
modal: "servicePriceCategoryForm",
|
||||
title: "Создание категории цен",
|
||||
withCloseButton: false,
|
||||
innerProps: {
|
||||
onCreate,
|
||||
},
|
||||
});
|
||||
};
|
||||
const onCreate = (values: ServicePriceCategorySchema) => {
|
||||
console.log(ServiceService);
|
||||
ServiceService.createPriceCategory({
|
||||
requestBody: {
|
||||
name: values.name,
|
||||
},
|
||||
}).then(async ({ ok, message }) => {
|
||||
notifications.guess(ok, { message: message });
|
||||
if (!ok) return;
|
||||
await refetch();
|
||||
});
|
||||
};
|
||||
const onDelete = (item: ServicePriceCategorySchema) => {
|
||||
modals.openConfirmModal({
|
||||
title: "Удаление категории",
|
||||
children: "Вы уверены, что хотите удалить категорию?",
|
||||
onConfirm: () => {
|
||||
ServiceService.deletePriceCategory({
|
||||
requestBody: {
|
||||
id: item.id,
|
||||
},
|
||||
}).then(async ({ ok, message }) => {
|
||||
notifications.guess(ok, { message: message });
|
||||
if (!ok) return;
|
||||
await refetch();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
const onChange = (item: ServicePriceCategorySchema) => {
|
||||
modals.openContextModal({
|
||||
modal: "servicePriceCategoryForm",
|
||||
title: "Изменение категории цен",
|
||||
withCloseButton: false,
|
||||
innerProps: {
|
||||
onChange: (values: ServicePriceCategorySchema) => {
|
||||
ServiceService.updatePriceCategory({
|
||||
requestBody: {
|
||||
id: item.id,
|
||||
name: values.name,
|
||||
},
|
||||
}).then(async ({ ok, message }) => {
|
||||
notifications.guess(ok, { message: message });
|
||||
if (!ok) return;
|
||||
await refetch();
|
||||
});
|
||||
},
|
||||
element: item,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
onCreateClick,
|
||||
onCreate,
|
||||
onDelete,
|
||||
onChange,
|
||||
objects,
|
||||
};
|
||||
};
|
||||
export default useServicePriceCategoryState;
|
||||
@@ -1,9 +1,7 @@
|
||||
import { ServicePriceRangeSchema, ServiceSchema } from "../../../client";
|
||||
import { useForm } from "@mantine/form";
|
||||
import { ContextModalProps } from "@mantine/modals";
|
||||
import BaseFormModal, {
|
||||
CreateEditFormProps,
|
||||
} from "../../ClientsPage/modals/BaseFormModal/BaseFormModal.tsx";
|
||||
import BaseFormModal, { CreateEditFormProps } from "../../ClientsPage/modals/BaseFormModal/BaseFormModal.tsx";
|
||||
import { Fieldset, Flex, rem, TextInput } from "@mantine/core";
|
||||
import ServiceCategorySelect from "../components/ServiceCategorySelect/ServiceCategorySelect.tsx";
|
||||
import ServiceTypeSelect from "../components/ServiceTypeSelect/ServiceTypeSelect.tsx";
|
||||
@@ -11,13 +9,8 @@ import ServicePriceTypeSegmentedControl, {
|
||||
ServicePriceType,
|
||||
} from "../components/ServicePriceTypeSegmentedControl/ServicePriceTypeSegmentedControl.tsx";
|
||||
import { useEffect, useState } from "react";
|
||||
import RangePriceInput, {
|
||||
PriceRangeInputType,
|
||||
} from "../components/ServicePriceInput/RangePriceInput.tsx";
|
||||
import RangePriceInput, { PriceRangeInputType } from "../components/ServicePriceInput/RangePriceInput.tsx";
|
||||
import SinglePriceInput from "../components/ServicePriceInput/SinglePriceInput.tsx";
|
||||
import PriceCategoryInput, {
|
||||
PriceCategoryInputProps,
|
||||
} from "../components/ServicePriceInput/PriceCategoryInput.tsx";
|
||||
|
||||
type Props = CreateEditFormProps<ServiceSchema>;
|
||||
const CreateServiceModal = ({
|
||||
@@ -44,7 +37,6 @@ const CreateServiceModal = ({
|
||||
serviceType: -1,
|
||||
priceRanges: [] as ServicePriceRangeSchema[],
|
||||
cost: null,
|
||||
categoryPrices: [],
|
||||
rank: "",
|
||||
};
|
||||
|
||||
@@ -89,14 +81,6 @@ const CreateServiceModal = ({
|
||||
) as PriceRangeInputType)}
|
||||
/>
|
||||
);
|
||||
case ServicePriceType.BY_CATEGORY:
|
||||
return (
|
||||
<PriceCategoryInput
|
||||
{...(form.getInputProps(
|
||||
"categoryPrices",
|
||||
) as PriceCategoryInputProps)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
const onCancelClick = () => {
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
import { ServicePriceCategorySchema } from "../../../client";
|
||||
import BaseFormModal, {
|
||||
CreateEditFormProps,
|
||||
} from "../../ClientsPage/modals/BaseFormModal/BaseFormModal.tsx";
|
||||
import { ContextModalProps } from "@mantine/modals";
|
||||
import { TextInput } from "@mantine/core";
|
||||
import { useForm } from "@mantine/form";
|
||||
|
||||
type Props = CreateEditFormProps<ServicePriceCategorySchema>;
|
||||
|
||||
const ServicePriceCategoryForm = ({
|
||||
context,
|
||||
id,
|
||||
innerProps,
|
||||
}: ContextModalProps<Props>) => {
|
||||
const isEditing = "element" in innerProps;
|
||||
const initialValues: Partial<ServicePriceCategorySchema> = isEditing
|
||||
? innerProps.element
|
||||
: {
|
||||
name: "",
|
||||
};
|
||||
const form = useForm<Partial<ServicePriceCategorySchema>>({
|
||||
initialValues,
|
||||
});
|
||||
return (
|
||||
<BaseFormModal
|
||||
{...innerProps}
|
||||
form={form}
|
||||
closeOnSubmit
|
||||
onClose={() => context.closeContextModal(id)}>
|
||||
<BaseFormModal.Body>
|
||||
<>
|
||||
<TextInput
|
||||
label={"Название"}
|
||||
placeholder={"Введите название категории"}
|
||||
{...form.getInputProps("name")}
|
||||
/>
|
||||
</>
|
||||
</BaseFormModal.Body>
|
||||
</BaseFormModal>
|
||||
);
|
||||
};
|
||||
|
||||
export default ServicePriceCategoryForm;
|
||||
@@ -7,11 +7,8 @@ import ServiceTypeSegmentedControl, {
|
||||
ServicesTab,
|
||||
} from "../components/ServiceTypeSegmentedControl/ServiceTypeSegmentedControl.tsx";
|
||||
import ServicesKitsTable from "../components/ServicesKitsTable/ServicesKitsTable.tsx";
|
||||
import ServicePriceCategoryTable from "../components/ServicePriceCategoryTable/ServicePriceCategoryTable.tsx";
|
||||
import useServicesState from "../hooks/useServicesState.tsx";
|
||||
import useServicesKitsState from "../hooks/useServicesKitsState.tsx";
|
||||
import useServicePriceCategoryState from "../hooks/useServicePriceCategoryState.tsx";
|
||||
import { ObjectStateToTableProps } from "../../../types/utils.ts";
|
||||
import { IconDownload, IconFileExcel, IconFileTypePdf } from "@tabler/icons-react";
|
||||
import FileSaver from "file-saver";
|
||||
import { getCurrentDateTimeForFilename } from "../../../shared/lib/date.ts";
|
||||
@@ -28,10 +25,6 @@ export const ServicesPage: FC = () => {
|
||||
} = useServicesState();
|
||||
const { servicesKits, onKitUpdate, onKitCreateClick } =
|
||||
useServicesKitsState();
|
||||
const {
|
||||
onCreateClick: onCreatePriceCategoryClick,
|
||||
...priceCategoryRestProps
|
||||
} = useServicePriceCategoryState();
|
||||
const getBody = () => {
|
||||
switch (serviceType) {
|
||||
case ServicesTab.SERVICES_KITS:
|
||||
@@ -60,12 +53,6 @@ export const ServicesPage: FC = () => {
|
||||
/>
|
||||
);
|
||||
}
|
||||
case ServicesTab.SERVICES_PRICE_CATEGORIES:
|
||||
return (
|
||||
<ServicePriceCategoryTable
|
||||
{...ObjectStateToTableProps(priceCategoryRestProps)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
const getControls = () => {
|
||||
@@ -141,18 +128,6 @@ export const ServicesPage: FC = () => {
|
||||
/>
|
||||
</Flex>
|
||||
);
|
||||
case ServicesTab.SERVICES_PRICE_CATEGORIES:
|
||||
return (
|
||||
<Button
|
||||
variant={"default"}
|
||||
onClick={() => {
|
||||
if (onCreatePriceCategoryClick) {
|
||||
onCreatePriceCategoryClick();
|
||||
}
|
||||
}}>
|
||||
Создать категорию
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user