feat: crappy reordering
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite --force",
|
||||||
"build": "tsc && vite build",
|
"build": "tsc && vite build",
|
||||||
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
"@fortawesome/free-regular-svg-icons": "^6.6.0",
|
"@fortawesome/free-regular-svg-icons": "^6.6.0",
|
||||||
"@fortawesome/free-solid-svg-icons": "^6.6.0",
|
"@fortawesome/free-solid-svg-icons": "^6.6.0",
|
||||||
"@fortawesome/react-fontawesome": "^0.2.2",
|
"@fortawesome/react-fontawesome": "^0.2.2",
|
||||||
"@hello-pangea/dnd": "^16.6.0",
|
"@hello-pangea/dnd": "^17.0.0",
|
||||||
"@mantine/core": "^7.11.2",
|
"@mantine/core": "^7.11.2",
|
||||||
"@mantine/dates": "^7.11.2",
|
"@mantine/dates": "^7.11.2",
|
||||||
"@mantine/dropzone": "^7.11.2",
|
"@mantine/dropzone": "^7.11.2",
|
||||||
|
|||||||
@@ -182,6 +182,8 @@ export type { ProductUpdateResponse } from './models/ProductUpdateResponse';
|
|||||||
export type { ProductUploadImageResponse } from './models/ProductUploadImageResponse';
|
export type { ProductUploadImageResponse } from './models/ProductUploadImageResponse';
|
||||||
export type { RoleSchema } from './models/RoleSchema';
|
export type { RoleSchema } from './models/RoleSchema';
|
||||||
export type { ServiceCategoryPriceSchema } from './models/ServiceCategoryPriceSchema';
|
export type { ServiceCategoryPriceSchema } from './models/ServiceCategoryPriceSchema';
|
||||||
|
export type { ServiceCategoryReorderRequest } from './models/ServiceCategoryReorderRequest';
|
||||||
|
export type { ServiceCategoryReorderResponse } from './models/ServiceCategoryReorderResponse';
|
||||||
export type { ServiceCategorySchema } from './models/ServiceCategorySchema';
|
export type { ServiceCategorySchema } from './models/ServiceCategorySchema';
|
||||||
export type { ServiceCreateCategoryRequest } from './models/ServiceCreateCategoryRequest';
|
export type { ServiceCreateCategoryRequest } from './models/ServiceCreateCategoryRequest';
|
||||||
export type { ServiceCreateCategoryResponse } from './models/ServiceCreateCategoryResponse';
|
export type { ServiceCreateCategoryResponse } from './models/ServiceCreateCategoryResponse';
|
||||||
@@ -193,6 +195,8 @@ export type { ServiceGetAllCategoriesResponse } from './models/ServiceGetAllCate
|
|||||||
export type { ServiceGetAllResponse } from './models/ServiceGetAllResponse';
|
export type { ServiceGetAllResponse } from './models/ServiceGetAllResponse';
|
||||||
export type { ServicePriceCategorySchema } from './models/ServicePriceCategorySchema';
|
export type { ServicePriceCategorySchema } from './models/ServicePriceCategorySchema';
|
||||||
export type { ServicePriceRangeSchema } from './models/ServicePriceRangeSchema';
|
export type { ServicePriceRangeSchema } from './models/ServicePriceRangeSchema';
|
||||||
|
export type { ServiceReorderRequest } from './models/ServiceReorderRequest';
|
||||||
|
export type { ServiceReorderResponse } from './models/ServiceReorderResponse';
|
||||||
export type { ServiceSchema } from './models/ServiceSchema';
|
export type { ServiceSchema } from './models/ServiceSchema';
|
||||||
export type { ServiceUpdateRequest } from './models/ServiceUpdateRequest';
|
export type { ServiceUpdateRequest } from './models/ServiceUpdateRequest';
|
||||||
export type { ServiceUpdateResponse } from './models/ServiceUpdateResponse';
|
export type { ServiceUpdateResponse } from './models/ServiceUpdateResponse';
|
||||||
|
|||||||
11
src/client/models/ServiceCategoryReorderRequest.ts
Normal file
11
src/client/models/ServiceCategoryReorderRequest.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type ServiceCategoryReorderRequest = {
|
||||||
|
moveDown: boolean;
|
||||||
|
moveUp: boolean;
|
||||||
|
categoryId: number;
|
||||||
|
serviceType: number;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/ServiceCategoryReorderResponse.ts
Normal file
9
src/client/models/ServiceCategoryReorderResponse.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type ServiceCategoryReorderResponse = {
|
||||||
|
ok: boolean;
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
@@ -5,5 +5,7 @@
|
|||||||
export type ServiceCategorySchema = {
|
export type ServiceCategorySchema = {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
|
dealServiceRank: string;
|
||||||
|
productServiceRank: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
9
src/client/models/ServiceReorderRequest.ts
Normal file
9
src/client/models/ServiceReorderRequest.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type ServiceReorderRequest = {
|
||||||
|
drainingServiceId: number;
|
||||||
|
hoveredServiceId: number;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/ServiceReorderResponse.ts
Normal file
9
src/client/models/ServiceReorderResponse.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type ServiceReorderResponse = {
|
||||||
|
ok: boolean;
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
@@ -14,5 +14,6 @@ export type ServiceSchema = {
|
|||||||
priceRanges: Array<ServicePriceRangeSchema>;
|
priceRanges: Array<ServicePriceRangeSchema>;
|
||||||
categoryPrices: Array<ServiceCategoryPriceSchema>;
|
categoryPrices: Array<ServiceCategoryPriceSchema>;
|
||||||
cost: (number | null);
|
cost: (number | null);
|
||||||
|
rank: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import type { DeletePriceCategoryRequest } from '../models/DeletePriceCategoryRe
|
|||||||
import type { DeletePriceCategoryResponse } from '../models/DeletePriceCategoryResponse';
|
import type { DeletePriceCategoryResponse } from '../models/DeletePriceCategoryResponse';
|
||||||
import type { GetAllPriceCategoriesResponse } from '../models/GetAllPriceCategoriesResponse';
|
import type { GetAllPriceCategoriesResponse } from '../models/GetAllPriceCategoriesResponse';
|
||||||
import type { GetAllServicesKitsResponse } from '../models/GetAllServicesKitsResponse';
|
import type { GetAllServicesKitsResponse } from '../models/GetAllServicesKitsResponse';
|
||||||
|
import type { ServiceCategoryReorderRequest } from '../models/ServiceCategoryReorderRequest';
|
||||||
|
import type { ServiceCategoryReorderResponse } from '../models/ServiceCategoryReorderResponse';
|
||||||
import type { ServiceCreateCategoryRequest } from '../models/ServiceCreateCategoryRequest';
|
import type { ServiceCreateCategoryRequest } from '../models/ServiceCreateCategoryRequest';
|
||||||
import type { ServiceCreateCategoryResponse } from '../models/ServiceCreateCategoryResponse';
|
import type { ServiceCreateCategoryResponse } from '../models/ServiceCreateCategoryResponse';
|
||||||
import type { ServiceCreateRequest } from '../models/ServiceCreateRequest';
|
import type { ServiceCreateRequest } from '../models/ServiceCreateRequest';
|
||||||
@@ -19,6 +21,8 @@ import type { ServiceDeleteRequest } from '../models/ServiceDeleteRequest';
|
|||||||
import type { ServiceDeleteResponse } from '../models/ServiceDeleteResponse';
|
import type { ServiceDeleteResponse } from '../models/ServiceDeleteResponse';
|
||||||
import type { ServiceGetAllCategoriesResponse } from '../models/ServiceGetAllCategoriesResponse';
|
import type { ServiceGetAllCategoriesResponse } from '../models/ServiceGetAllCategoriesResponse';
|
||||||
import type { ServiceGetAllResponse } from '../models/ServiceGetAllResponse';
|
import type { ServiceGetAllResponse } from '../models/ServiceGetAllResponse';
|
||||||
|
import type { ServiceReorderRequest } from '../models/ServiceReorderRequest';
|
||||||
|
import type { ServiceReorderResponse } from '../models/ServiceReorderResponse';
|
||||||
import type { ServiceUpdateRequest } from '../models/ServiceUpdateRequest';
|
import type { ServiceUpdateRequest } from '../models/ServiceUpdateRequest';
|
||||||
import type { ServiceUpdateResponse } from '../models/ServiceUpdateResponse';
|
import type { ServiceUpdateResponse } from '../models/ServiceUpdateResponse';
|
||||||
import type { UpdatePriceCategoryRequest } from '../models/UpdatePriceCategoryRequest';
|
import type { UpdatePriceCategoryRequest } from '../models/UpdatePriceCategoryRequest';
|
||||||
@@ -100,6 +104,26 @@ export class ServiceService {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Reorder
|
||||||
|
* @returns ServiceReorderResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static reorderService({
|
||||||
|
requestBody,
|
||||||
|
}: {
|
||||||
|
requestBody: ServiceReorderRequest,
|
||||||
|
}): CancelablePromise<ServiceReorderResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/service/reorder',
|
||||||
|
body: requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
|
errors: {
|
||||||
|
422: `Validation Error`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Get All Categories
|
* Get All Categories
|
||||||
* @returns ServiceGetAllCategoriesResponse Successful Response
|
* @returns ServiceGetAllCategoriesResponse Successful Response
|
||||||
@@ -131,6 +155,26 @@ export class ServiceService {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Reorder Category
|
||||||
|
* @returns ServiceCategoryReorderResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static reorderServiceCategory({
|
||||||
|
requestBody,
|
||||||
|
}: {
|
||||||
|
requestBody: ServiceCategoryReorderRequest,
|
||||||
|
}): CancelablePromise<ServiceCategoryReorderResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/service/categories/reorder',
|
||||||
|
body: requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
|
errors: {
|
||||||
|
422: `Validation Error`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Get All Service Types
|
* Get All Service Types
|
||||||
* @returns BaseEnumListSchema Successful Response
|
* @returns BaseEnumListSchema Successful Response
|
||||||
|
|||||||
@@ -1,19 +1,42 @@
|
|||||||
import { ServiceSchema } from "../../../../client";
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
|
import { ServiceSchema, ServiceService } from "../../../../client";
|
||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { useServicesTableColumns } from "./columns.tsx";
|
import { useServicesTableColumns } from "./columns.tsx";
|
||||||
import { BaseTable } from "../../../../components/BaseTable/BaseTable.tsx";
|
import { BaseTable } from "../../../../components/BaseTable/BaseTable.tsx";
|
||||||
import { MRT_TableOptions } from "mantine-react-table";
|
import { MRT_TableOptions } from "mantine-react-table";
|
||||||
import { CRUDTableProps } from "../../../../types/CRUDTable.tsx";
|
import { CRUDTableProps } from "../../../../types/CRUDTable.tsx";
|
||||||
import { ActionIcon, Flex, Tooltip } from "@mantine/core";
|
import { ActionIcon, Flex, Tooltip } from "@mantine/core";
|
||||||
import { IconEdit, IconTrash } from "@tabler/icons-react";
|
import { IconArrowDown, IconArrowUp, IconEdit, IconTrash } from "@tabler/icons-react";
|
||||||
import { modals } from "@mantine/modals";
|
import { modals } from "@mantine/modals";
|
||||||
|
import { notifications } from "../../../../shared/lib/notifications.ts";
|
||||||
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
|
import { ServicesTab } from "../ServiceTypeSegmentedControl/ServiceTypeSegmentedControl.tsx";
|
||||||
|
|
||||||
const ServicesTable: FC<CRUDTableProps<ServiceSchema>> = ({
|
type RestProps = {
|
||||||
items,
|
serviceType: ServicesTab;
|
||||||
onDelete,
|
editMode: boolean;
|
||||||
onChange,
|
}
|
||||||
}) => {
|
type Props = CRUDTableProps<ServiceSchema> & RestProps;
|
||||||
|
const ServicesTable: FC<Props> = ({
|
||||||
|
items,
|
||||||
|
onDelete,
|
||||||
|
onChange,
|
||||||
|
serviceType,
|
||||||
|
editMode,
|
||||||
|
}) => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
const columns = useServicesTableColumns();
|
const columns = useServicesTableColumns();
|
||||||
|
const categoryRanks = items.map(item => item.category).map(category => {
|
||||||
|
if (serviceType === ServicesTab.DEAL_SERVICE) {
|
||||||
|
return category.dealServiceRank;
|
||||||
|
}
|
||||||
|
return category.productServiceRank;
|
||||||
|
});
|
||||||
|
const minRank = categoryRanks.sort()[0];
|
||||||
|
const maxRank = categoryRanks.sort()[categoryRanks.length - 1];
|
||||||
|
console.log(minRank, maxRank);
|
||||||
|
|
||||||
const onEditClick = (service: ServiceSchema) => {
|
const onEditClick = (service: ServiceSchema) => {
|
||||||
if (!onChange) return;
|
if (!onChange) return;
|
||||||
@@ -31,33 +54,125 @@ const ServicesTable: FC<CRUDTableProps<ServiceSchema>> = ({
|
|||||||
<BaseTable
|
<BaseTable
|
||||||
data={items}
|
data={items}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
restProps={
|
|
||||||
{
|
restProps={{
|
||||||
enableGrouping: true,
|
enableGrouping: true,
|
||||||
initialState: { grouping: ["category"] },
|
initialState: {
|
||||||
enableColumnActions: false,
|
grouping: ["category"],
|
||||||
enableRowActions: true,
|
},
|
||||||
renderRowActions: ({ row }) => (
|
state: {
|
||||||
<Flex gap="md">
|
columnVisibility: {
|
||||||
<Tooltip label="Редактировать">
|
"mrt-row-drag": editMode,
|
||||||
<ActionIcon
|
},
|
||||||
onClick={() => onEditClick(row.original)}
|
},
|
||||||
variant={"default"}>
|
enableColumnActions: false,
|
||||||
<IconEdit />
|
enableRowOrdering: true,
|
||||||
</ActionIcon>
|
mantineRowDragHandleProps: ({ table }) => ({
|
||||||
</Tooltip>
|
onDragEnd: () => {
|
||||||
<Tooltip label="Удалить">
|
const { draggingRow, hoveredRow } = table.getState();
|
||||||
<ActionIcon
|
if (!hoveredRow?.original || !draggingRow?.original) return;
|
||||||
onClick={() => {
|
ServiceService.reorderService({
|
||||||
if (onDelete) onDelete(row.original);
|
requestBody: {
|
||||||
}}
|
drainingServiceId: draggingRow.original.id,
|
||||||
variant={"default"}>
|
hoveredServiceId: hoveredRow.original.id,
|
||||||
<IconTrash />
|
},
|
||||||
</ActionIcon>
|
}).then(({ ok, message }) => {
|
||||||
</Tooltip>
|
if (!ok) {
|
||||||
</Flex>
|
notifications.guess(ok, { message });
|
||||||
),
|
return;
|
||||||
} as MRT_TableOptions<ServiceSchema>
|
}
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: ["getAllServices"],
|
||||||
|
}).then(() => {
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
displayColumnDefOptions: {
|
||||||
|
"mrt-row-drag": {
|
||||||
|
AggregatedCell: ({ row }) => {
|
||||||
|
const rank = serviceType === ServicesTab.DEAL_SERVICE ? row.original.category.dealServiceRank : row.original.category.productServiceRank;
|
||||||
|
return (
|
||||||
|
<Flex gap={"xs"}>
|
||||||
|
<Tooltip label="Поднять вверх">
|
||||||
|
<ActionIcon
|
||||||
|
disabled={rank === minRank}
|
||||||
|
onClick={() => {
|
||||||
|
ServiceService.reorderServiceCategory({
|
||||||
|
requestBody: {
|
||||||
|
serviceType,
|
||||||
|
categoryId: row.original.category.id,
|
||||||
|
moveDown: false,
|
||||||
|
moveUp: true,
|
||||||
|
},
|
||||||
|
}).then(({ ok, message }) => {
|
||||||
|
if (!ok) {
|
||||||
|
notifications.guess(ok, { message });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: ["getAllServices"],
|
||||||
|
}).then(() => {
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
variant={"default"}>
|
||||||
|
<IconArrowUp />
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip label="Опустить вниз">
|
||||||
|
<ActionIcon
|
||||||
|
disabled={rank === maxRank}
|
||||||
|
onClick={() => {
|
||||||
|
ServiceService.reorderServiceCategory({
|
||||||
|
requestBody: {
|
||||||
|
serviceType,
|
||||||
|
categoryId: row.original.category.id,
|
||||||
|
moveDown: true,
|
||||||
|
moveUp: false,
|
||||||
|
},
|
||||||
|
}).then(({ ok, message }) => {
|
||||||
|
if (!ok) {
|
||||||
|
notifications.guess(ok, { message });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: ["getAllServices"],
|
||||||
|
}).then(() => {
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
variant={"default"}>
|
||||||
|
<IconArrowDown />
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
enableRowActions: true,
|
||||||
|
renderRowActions: ({ row }) => (
|
||||||
|
<Flex gap="xs">
|
||||||
|
<Tooltip label="Редактировать">
|
||||||
|
<ActionIcon
|
||||||
|
onClick={() => onEditClick(row.original)}
|
||||||
|
variant={"default"}>
|
||||||
|
<IconEdit />
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip label="Удалить">
|
||||||
|
<ActionIcon
|
||||||
|
onClick={() => {
|
||||||
|
if (onDelete) onDelete(row.original);
|
||||||
|
}}
|
||||||
|
variant={"default"}>
|
||||||
|
<IconTrash />
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
</Flex>
|
||||||
|
),
|
||||||
|
} as MRT_TableOptions<ServiceSchema>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export const useServicesTableColumns = () => {
|
|||||||
<>
|
<>
|
||||||
<List>
|
<List>
|
||||||
{service.priceRanges.map(range => (
|
{service.priceRanges.map(range => (
|
||||||
<List.Item>
|
<List.Item key={range.id}>
|
||||||
{`${range.fromQuantity} - ${range.toQuantity}: ${range.price}₽`}
|
{`${range.fromQuantity} - ${range.toQuantity}: ${range.price}₽`}
|
||||||
</List.Item>
|
</List.Item>
|
||||||
))}
|
))}
|
||||||
@@ -24,9 +24,9 @@ export const useServicesTableColumns = () => {
|
|||||||
{
|
{
|
||||||
accessorKey: "category",
|
accessorKey: "category",
|
||||||
header: "Категория",
|
header: "Категория",
|
||||||
enableGrouping: false,
|
accessorFn: row => `${row.category.name}`,
|
||||||
|
enableColumnOrdering: true,
|
||||||
enableSorting: false,
|
enableSorting: false,
|
||||||
accessorFn: row => row.category.name,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "name",
|
accessorKey: "name",
|
||||||
@@ -47,7 +47,8 @@ export const useServicesTableColumns = () => {
|
|||||||
enableGrouping: false,
|
enableGrouping: false,
|
||||||
enableSorting: false,
|
enableSorting: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
],
|
],
|
||||||
[]
|
[],
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,29 +21,32 @@ import PriceCategoryInput, {
|
|||||||
|
|
||||||
type Props = CreateEditFormProps<ServiceSchema>;
|
type Props = CreateEditFormProps<ServiceSchema>;
|
||||||
const CreateServiceModal = ({
|
const CreateServiceModal = ({
|
||||||
context,
|
context,
|
||||||
id,
|
id,
|
||||||
innerProps,
|
innerProps,
|
||||||
}: ContextModalProps<Props>) => {
|
}: ContextModalProps<Props>) => {
|
||||||
const [priceType, setPriceType] = useState<ServicePriceType>(
|
const [priceType, setPriceType] = useState<ServicePriceType>(
|
||||||
ServicePriceType.DEFAULT
|
ServicePriceType.DEFAULT,
|
||||||
);
|
);
|
||||||
const isEditing = "onChange" in innerProps;
|
const isEditing = "onChange" in innerProps;
|
||||||
const initialValues: ServiceSchema = isEditing
|
const initialValues: ServiceSchema = isEditing
|
||||||
? innerProps.element
|
? innerProps.element
|
||||||
: {
|
: {
|
||||||
id: -1,
|
id: -1,
|
||||||
name: "",
|
name: "",
|
||||||
price: 0,
|
price: 0,
|
||||||
category: {
|
category: {
|
||||||
id: -1,
|
id: -1,
|
||||||
name: "",
|
name: "",
|
||||||
},
|
dealServiceRank: "",
|
||||||
serviceType: -1,
|
productServiceRank: "",
|
||||||
priceRanges: [] as ServicePriceRangeSchema[],
|
},
|
||||||
cost: null,
|
serviceType: -1,
|
||||||
categoryPrices: [],
|
priceRanges: [] as ServicePriceRangeSchema[],
|
||||||
};
|
cost: null,
|
||||||
|
categoryPrices: [],
|
||||||
|
rank: "",
|
||||||
|
};
|
||||||
|
|
||||||
const form = useForm<ServiceSchema>({
|
const form = useForm<ServiceSchema>({
|
||||||
initialValues: initialValues,
|
initialValues: initialValues,
|
||||||
@@ -82,7 +85,7 @@ const CreateServiceModal = ({
|
|||||||
return (
|
return (
|
||||||
<RangePriceInput
|
<RangePriceInput
|
||||||
{...(form.getInputProps(
|
{...(form.getInputProps(
|
||||||
"priceRanges"
|
"priceRanges",
|
||||||
) as PriceRangeInputType)}
|
) as PriceRangeInputType)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -90,7 +93,7 @@ const CreateServiceModal = ({
|
|||||||
return (
|
return (
|
||||||
<PriceCategoryInput
|
<PriceCategoryInput
|
||||||
{...(form.getInputProps(
|
{...(form.getInputProps(
|
||||||
"categoryPrices"
|
"categoryPrices",
|
||||||
) as PriceCategoryInputProps)}
|
) as PriceCategoryInputProps)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { FC, useState } from "react";
|
|||||||
import ServicesTable from "../components/ServicesTable/ServicesTable.tsx";
|
import ServicesTable from "../components/ServicesTable/ServicesTable.tsx";
|
||||||
import PageBlock from "../../../components/PageBlock/PageBlock.tsx";
|
import PageBlock from "../../../components/PageBlock/PageBlock.tsx";
|
||||||
import styles from "./ServicesPage.module.css";
|
import styles from "./ServicesPage.module.css";
|
||||||
import { Button } from "@mantine/core";
|
import { Button, Flex, rem, Switch } from "@mantine/core";
|
||||||
import ServiceTypeSegmentedControl, {
|
import ServiceTypeSegmentedControl, {
|
||||||
ServicesTab,
|
ServicesTab,
|
||||||
} from "../components/ServiceTypeSegmentedControl/ServiceTypeSegmentedControl.tsx";
|
} from "../components/ServiceTypeSegmentedControl/ServiceTypeSegmentedControl.tsx";
|
||||||
@@ -15,6 +15,7 @@ import { ObjectStateToTableProps } from "../../../types/utils.ts";
|
|||||||
|
|
||||||
export const ServicesPage: FC = () => {
|
export const ServicesPage: FC = () => {
|
||||||
const [serviceType, setServiceType] = useState(ServicesTab.DEAL_SERVICE);
|
const [serviceType, setServiceType] = useState(ServicesTab.DEAL_SERVICE);
|
||||||
|
const [isEditMode, setIsEditMode] = useState(false);
|
||||||
const {
|
const {
|
||||||
services,
|
services,
|
||||||
onServiceDelete,
|
onServiceDelete,
|
||||||
@@ -38,16 +39,24 @@ export const ServicesPage: FC = () => {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
case ServicesTab.DEAL_SERVICE:
|
case ServicesTab.DEAL_SERVICE:
|
||||||
case ServicesTab.PRODUCT_SERVICE:
|
case ServicesTab.PRODUCT_SERVICE: {
|
||||||
|
const servicesOrdered = services.filter(service => service.serviceType === serviceType).sort((a, b) => {
|
||||||
|
if (serviceType === ServicesTab.DEAL_SERVICE) {
|
||||||
|
return a.category.dealServiceRank.localeCompare(b.category.dealServiceRank);
|
||||||
|
}
|
||||||
|
return a.category.productServiceRank.localeCompare(b.category.productServiceRank);
|
||||||
|
},
|
||||||
|
);
|
||||||
return (
|
return (
|
||||||
<ServicesTable
|
<ServicesTable
|
||||||
onDelete={onServiceDelete}
|
onDelete={onServiceDelete}
|
||||||
onChange={onServiceUpdate}
|
onChange={onServiceUpdate}
|
||||||
items={services.filter(
|
items={servicesOrdered}
|
||||||
service => service.serviceType == serviceType
|
serviceType={serviceType}
|
||||||
)}
|
editMode={isEditMode}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
case ServicesTab.SERVICES_PRICE_CATEGORIES:
|
case ServicesTab.SERVICES_PRICE_CATEGORIES:
|
||||||
return (
|
return (
|
||||||
<ServicePriceCategoryTable
|
<ServicePriceCategoryTable
|
||||||
@@ -70,7 +79,7 @@ export const ServicesPage: FC = () => {
|
|||||||
case ServicesTab.DEAL_SERVICE:
|
case ServicesTab.DEAL_SERVICE:
|
||||||
case ServicesTab.PRODUCT_SERVICE:
|
case ServicesTab.PRODUCT_SERVICE:
|
||||||
return (
|
return (
|
||||||
<>
|
<Flex align={"center"} gap={rem(10)}>
|
||||||
<Button
|
<Button
|
||||||
onClick={onCreateClick}
|
onClick={onCreateClick}
|
||||||
variant={"default"}>
|
variant={"default"}>
|
||||||
@@ -81,7 +90,14 @@ export const ServicesPage: FC = () => {
|
|||||||
variant={"default"}>
|
variant={"default"}>
|
||||||
Создать категорию
|
Создать категорию
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
<Switch
|
||||||
|
variant={"default"}
|
||||||
|
label={"Режим редактирования"}
|
||||||
|
checked={isEditMode}
|
||||||
|
onChange={() => setIsEditMode(!isEditMode)}
|
||||||
|
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
);
|
);
|
||||||
case ServicesTab.SERVICES_PRICE_CATEGORIES:
|
case ServicesTab.SERVICES_PRICE_CATEGORIES:
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user