feat: ud service, create product in deal details
This commit is contained in:
@@ -75,9 +75,13 @@ export type { ServiceCreateCategoryRequest } from './models/ServiceCreateCategor
|
|||||||
export type { ServiceCreateCategoryResponse } from './models/ServiceCreateCategoryResponse';
|
export type { ServiceCreateCategoryResponse } from './models/ServiceCreateCategoryResponse';
|
||||||
export type { ServiceCreateRequest } from './models/ServiceCreateRequest';
|
export type { ServiceCreateRequest } from './models/ServiceCreateRequest';
|
||||||
export type { ServiceCreateResponse } from './models/ServiceCreateResponse';
|
export type { ServiceCreateResponse } from './models/ServiceCreateResponse';
|
||||||
|
export type { ServiceDeleteRequest } from './models/ServiceDeleteRequest';
|
||||||
|
export type { ServiceDeleteResponse } from './models/ServiceDeleteResponse';
|
||||||
export type { ServiceGetAllCategoriesResponse } from './models/ServiceGetAllCategoriesResponse';
|
export type { ServiceGetAllCategoriesResponse } from './models/ServiceGetAllCategoriesResponse';
|
||||||
export type { ServiceGetAllResponse } from './models/ServiceGetAllResponse';
|
export type { ServiceGetAllResponse } from './models/ServiceGetAllResponse';
|
||||||
export type { ServiceSchema } from './models/ServiceSchema';
|
export type { ServiceSchema } from './models/ServiceSchema';
|
||||||
|
export type { ServiceUpdateRequest } from './models/ServiceUpdateRequest';
|
||||||
|
export type { ServiceUpdateResponse } from './models/ServiceUpdateResponse';
|
||||||
export type { UserSchema } from './models/UserSchema';
|
export type { UserSchema } from './models/UserSchema';
|
||||||
export type { ValidationError } from './models/ValidationError';
|
export type { ValidationError } from './models/ValidationError';
|
||||||
|
|
||||||
|
|||||||
8
src/client/models/ServiceDeleteRequest.ts
Normal file
8
src/client/models/ServiceDeleteRequest.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do no edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type ServiceDeleteRequest = {
|
||||||
|
serviceId: number;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/ServiceDeleteResponse.ts
Normal file
9
src/client/models/ServiceDeleteResponse.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do no edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type ServiceDeleteResponse = {
|
||||||
|
ok: boolean;
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/ServiceUpdateRequest.ts
Normal file
9
src/client/models/ServiceUpdateRequest.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do no edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { ServiceSchema } from './ServiceSchema';
|
||||||
|
export type ServiceUpdateRequest = {
|
||||||
|
data: ServiceSchema;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/ServiceUpdateResponse.ts
Normal file
9
src/client/models/ServiceUpdateResponse.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do no edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type ServiceUpdateResponse = {
|
||||||
|
ok: boolean;
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
@@ -6,8 +6,12 @@ import type { ServiceCreateCategoryRequest } from '../models/ServiceCreateCatego
|
|||||||
import type { ServiceCreateCategoryResponse } from '../models/ServiceCreateCategoryResponse';
|
import type { ServiceCreateCategoryResponse } from '../models/ServiceCreateCategoryResponse';
|
||||||
import type { ServiceCreateRequest } from '../models/ServiceCreateRequest';
|
import type { ServiceCreateRequest } from '../models/ServiceCreateRequest';
|
||||||
import type { ServiceCreateResponse } from '../models/ServiceCreateResponse';
|
import type { ServiceCreateResponse } from '../models/ServiceCreateResponse';
|
||||||
|
import type { ServiceDeleteRequest } from '../models/ServiceDeleteRequest';
|
||||||
|
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 { ServiceUpdateRequest } from '../models/ServiceUpdateRequest';
|
||||||
|
import type { ServiceUpdateResponse } from '../models/ServiceUpdateResponse';
|
||||||
import type { CancelablePromise } from '../core/CancelablePromise';
|
import type { CancelablePromise } from '../core/CancelablePromise';
|
||||||
import { OpenAPI } from '../core/OpenAPI';
|
import { OpenAPI } from '../core/OpenAPI';
|
||||||
import { request as __request } from '../core/request';
|
import { request as __request } from '../core/request';
|
||||||
@@ -43,6 +47,46 @@ export class ServiceService {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Update
|
||||||
|
* @returns ServiceUpdateResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static updateService({
|
||||||
|
requestBody,
|
||||||
|
}: {
|
||||||
|
requestBody: ServiceUpdateRequest,
|
||||||
|
}): CancelablePromise<ServiceUpdateResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/service/update',
|
||||||
|
body: requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
|
errors: {
|
||||||
|
422: `Validation Error`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Delete
|
||||||
|
* @returns ServiceDeleteResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static deleteService({
|
||||||
|
requestBody,
|
||||||
|
}: {
|
||||||
|
requestBody: ServiceDeleteRequest,
|
||||||
|
}): CancelablePromise<ServiceDeleteResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/service/delete',
|
||||||
|
body: requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
|
errors: {
|
||||||
|
422: `Validation Error`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Get All Categories
|
* Get All Categories
|
||||||
* @returns ServiceGetAllCategoriesResponse Successful Response
|
* @returns ServiceGetAllCategoriesResponse Successful Response
|
||||||
|
|||||||
@@ -2,11 +2,13 @@ import {BaseTable} from "../../../../components/BaseTable/BaseTable.tsx";
|
|||||||
import useDealProductsTableColumns from "./columns.tsx";
|
import useDealProductsTableColumns from "./columns.tsx";
|
||||||
import {FC} from "react";
|
import {FC} from "react";
|
||||||
import {CRUDTableProps} from "../../../../types/CRUDTable.tsx";
|
import {CRUDTableProps} from "../../../../types/CRUDTable.tsx";
|
||||||
import {DealProductSchema} from "../../../../client";
|
import {DealProductSchema, ProductService} from "../../../../client";
|
||||||
import {ActionIcon, Button, Flex, rem, Tooltip} from "@mantine/core";
|
import {ActionIcon, Button, Flex, rem, Tooltip} from "@mantine/core";
|
||||||
import {MRT_TableOptions} from "mantine-react-table";
|
import {MRT_TableOptions} from "mantine-react-table";
|
||||||
import {modals} from "@mantine/modals";
|
import {modals} from "@mantine/modals";
|
||||||
import {IconBarcode, IconTrash} from "@tabler/icons-react";
|
import {IconBarcode, IconTrash} from "@tabler/icons-react";
|
||||||
|
import {notifications} from "../../../../shared/lib/notifications.ts";
|
||||||
|
import {CreateProductRequest} from "../../../ProductsPage/types.ts";
|
||||||
|
|
||||||
type RestProps = {
|
type RestProps = {
|
||||||
clientId: number;
|
clientId: number;
|
||||||
@@ -51,7 +53,24 @@ const DealProductsTable: FC<Props> = (props: Props) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
const onCreateProduct = (newProduct: CreateProductRequest) => {
|
||||||
|
ProductService.createProduct({
|
||||||
|
requestBody: newProduct
|
||||||
|
}).then(({ok, message}) => {
|
||||||
|
notifications.guess(ok, {message: message});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const onCreateProductClick = () => {
|
||||||
|
modals.openContextModal({
|
||||||
|
modal: "createProduct",
|
||||||
|
title: 'Создание товара',
|
||||||
|
withCloseButton: false,
|
||||||
|
innerProps: {
|
||||||
|
clientId: clientId,
|
||||||
|
onCreate: onCreateProduct
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<BaseTable
|
<BaseTable
|
||||||
data={items}
|
data={items}
|
||||||
@@ -87,8 +106,16 @@ const DealProductsTable: FC<Props> = (props: Props) => {
|
|||||||
Удалить выбранные
|
Удалить выбранные
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<Button onClick={onCreateClick} variant={"default"}>
|
<Button
|
||||||
Добавить товар
|
variant={"default"}
|
||||||
|
onClick={onCreateProductClick}>
|
||||||
|
Создать товар
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
onClick={onCreateClick}
|
||||||
|
variant={"default"}>
|
||||||
|
Добавить товар в следку
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,35 +1,55 @@
|
|||||||
import {Select} from "@mantine/core";
|
import {Select, SelectProps} from "@mantine/core";
|
||||||
import useServiceCategoriesList from "../../hooks/useServiceCategoriesList.tsx";
|
import useServiceCategoriesList from "../../hooks/useServiceCategoriesList.tsx";
|
||||||
import {ServiceCategorySchema} from "../../../../client";
|
import {ServiceCategorySchema} from "../../../../client";
|
||||||
import {FC, ReactNode} from "react";
|
import {FC, useEffect, useMemo, useState} from "react";
|
||||||
|
|
||||||
type Props = {
|
type ControlledValueProps = {
|
||||||
|
value: ServiceCategorySchema
|
||||||
|
onChange: (value: ServiceCategorySchema) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
type RestProps = {
|
||||||
fullWidth?: boolean,
|
fullWidth?: boolean,
|
||||||
defaultValue?: ServiceCategorySchema
|
defaultValue?: ServiceCategorySchema
|
||||||
onChange: (category: ServiceCategorySchema) => void
|
onChange: (category: ServiceCategorySchema) => void
|
||||||
error?: ReactNode
|
|
||||||
}
|
}
|
||||||
const ServiceCategorySelect: FC<Props> = ({defaultValue, onChange, fullWidth, error}) => {
|
type Props = (RestProps & Partial<ControlledValueProps>) & Omit<SelectProps, 'value' | 'onChange'>;
|
||||||
|
const ServiceCategorySelect: FC<Props> = (props: Props) => {
|
||||||
const {categories} = useServiceCategoriesList();
|
const {categories} = useServiceCategoriesList();
|
||||||
|
|
||||||
return (
|
const data = useMemo(() => categories.reduce((acc, category) => {
|
||||||
<Select
|
acc.push({
|
||||||
error={error}
|
|
||||||
w={fullWidth ? "100%" : undefined}
|
|
||||||
checkIconPosition={"right"}
|
|
||||||
label={"Категория услуги"}
|
|
||||||
placeholder={"Выберите категорию услуги"}
|
|
||||||
data={categories.map(category => ({
|
|
||||||
label: category.name,
|
label: category.name,
|
||||||
value: category.id.toString()
|
value: category.id.toString()
|
||||||
}))}
|
});
|
||||||
onChange={event => {
|
return acc;
|
||||||
|
}, [] as { label: string, value: string }[]), [categories]);
|
||||||
|
|
||||||
|
const isControlled = 'value' in props;
|
||||||
|
const [internalValue, setInternalValue] = useState<ServiceCategorySchema | undefined>(props.defaultValue);
|
||||||
|
const value = isControlled ? props.value : internalValue;
|
||||||
|
|
||||||
|
const handleOnChange = (event: string | null) => {
|
||||||
if (!event) return;
|
if (!event) return;
|
||||||
const category = categories.find(category => category.id == parseInt(event))
|
const category = categories.find(category => parseInt(event) == category.id);
|
||||||
if (!category) return;
|
if (!category) return;
|
||||||
onChange(category)
|
if (isControlled) {
|
||||||
}}
|
props.onChange(category);
|
||||||
value={defaultValue && defaultValue.id.toString()}
|
return;
|
||||||
|
}
|
||||||
|
setInternalValue(category);
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isControlled || !internalValue) return;
|
||||||
|
props.onChange(internalValue);
|
||||||
|
}, [internalValue]);
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
{...props}
|
||||||
|
value={value?.id.toString()}
|
||||||
|
onChange={handleOnChange}
|
||||||
|
data={data}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,55 @@
|
|||||||
import {ServiceSchema} from "../../../../client";
|
import {ServiceSchema} from "../../../../client";
|
||||||
import {FC, RefObject} from "react";
|
import {FC} from "react";
|
||||||
import {useServicesTableColumns} from "./columns.tsx";
|
import {useServicesTableColumns} from "./columns.tsx";
|
||||||
import {BaseTable, BaseTableRef} 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 {ActionIcon, Flex, Tooltip} from "@mantine/core";
|
||||||
|
import {IconEdit, IconTrash} from "@tabler/icons-react";
|
||||||
|
import {modals} from "@mantine/modals";
|
||||||
|
|
||||||
type Props = {
|
const ServicesTable: FC<CRUDTableProps<ServiceSchema>> = ({items, onDelete, onChange}) => {
|
||||||
services: ServiceSchema[];
|
|
||||||
tableRef?: RefObject<BaseTableRef<ServiceSchema>>
|
|
||||||
}
|
|
||||||
const ServicesTable: FC<Props> = ({services, tableRef}) => {
|
|
||||||
const columns = useServicesTableColumns();
|
const columns = useServicesTableColumns();
|
||||||
|
|
||||||
|
const onEditClick = (service: ServiceSchema) => {
|
||||||
|
if (!onChange) return;
|
||||||
|
modals.openContextModal({
|
||||||
|
modal: "createService",
|
||||||
|
title: 'Создание услуги',
|
||||||
|
withCloseButton: false,
|
||||||
|
innerProps: {
|
||||||
|
onChange: (newService) => onChange(newService),
|
||||||
|
element: service,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<BaseTable
|
<BaseTable
|
||||||
ref={tableRef}
|
data={items}
|
||||||
data={services}
|
|
||||||
columns={columns}
|
columns={columns}
|
||||||
restProps={{
|
restProps={{
|
||||||
enableGrouping: true,
|
enableGrouping: true,
|
||||||
initialState: {grouping: ["category"]},
|
initialState: {grouping: ["category"]},
|
||||||
enableColumnActions: false,
|
enableColumnActions: false,
|
||||||
mantineCreateRowModalProps: {
|
enableRowActions: true,
|
||||||
transitionProps: {transition: 'rotate-left', duration: 300}
|
renderRowActions: ({row}) => (
|
||||||
},
|
<Flex gap="md">
|
||||||
|
<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>}
|
} as MRT_TableOptions<ServiceSchema>}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,51 +1,60 @@
|
|||||||
import {ServiceSchema} from "../../../client";
|
import {ServiceSchema} from "../../../client";
|
||||||
import {Button, Flex, NumberInput, rem, TextInput} from "@mantine/core";
|
|
||||||
import ServiceCategorySelect from "../components/ServiceCategorySelect/ServiceCategorySelect.tsx";
|
|
||||||
import {useForm} from "@mantine/form";
|
import {useForm} from "@mantine/form";
|
||||||
import {ContextModalProps} from "@mantine/modals";
|
import {ContextModalProps} from "@mantine/modals";
|
||||||
|
import BaseFormModal, {CreateEditFormProps} from "../../ClientsPage/modals/BaseFormModal/BaseFormModal.tsx";
|
||||||
|
import {NumberInput, TextInput} from "@mantine/core";
|
||||||
|
import ServiceCategorySelect from "../components/ServiceCategorySelect/ServiceCategorySelect.tsx";
|
||||||
|
|
||||||
type Props = {
|
type Props = CreateEditFormProps<ServiceSchema>
|
||||||
onCreate: (service: ServiceSchema) => void
|
|
||||||
}
|
|
||||||
const CreateServiceModal = ({
|
const CreateServiceModal = ({
|
||||||
context,
|
context,
|
||||||
id,
|
id,
|
||||||
innerProps,
|
innerProps,
|
||||||
}: ContextModalProps<Props>) => {
|
}: ContextModalProps<Props>) => {
|
||||||
const form = useForm({
|
|
||||||
initialValues: {
|
const isEditing = 'onChange' in innerProps;
|
||||||
|
const initialValues: ServiceSchema = isEditing ? {
|
||||||
|
id: innerProps.element.id,
|
||||||
|
name: innerProps.element.name,
|
||||||
|
price: innerProps.element.price,
|
||||||
|
category: innerProps.element.category,
|
||||||
|
} : {
|
||||||
|
id: -1,
|
||||||
|
name: '',
|
||||||
|
price: 0,
|
||||||
category: {
|
category: {
|
||||||
id: -1,
|
id: -1,
|
||||||
name: ''
|
name: ''
|
||||||
},
|
}
|
||||||
name: '',
|
}
|
||||||
price: NaN
|
const form = useForm<ServiceSchema>({
|
||||||
},
|
initialValues: initialValues,
|
||||||
validate: {
|
validate: {
|
||||||
category: (category) => category.id >= 0 ? null : "Необходимо выбрать категорию",
|
name: (name: string) => name.trim() !== '' ? null : "Необходимо ввести название услуги",
|
||||||
name: (name) => name.trim() !== '' ? null : "Необходимо ввести название услуги",
|
price: (price: number) => price > 0 ? null : "Цена должна быть больше 0",
|
||||||
price: (price) => !isNaN(price) ? null : "Небходимо ввести стоимость услуги"
|
category: (category: {
|
||||||
|
id: number,
|
||||||
|
name: string
|
||||||
|
}) => category.id !== -1 ? null : "Необходимо выбрать категорию"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const onSubmit = (values: { category: { id: number; name: string; }; name: string; price: number; }) => {
|
|
||||||
innerProps.onCreate({...values, id: -1});
|
|
||||||
context.closeContextModal(id);
|
|
||||||
}
|
|
||||||
const onCancelClick = () => {
|
const onCancelClick = () => {
|
||||||
context.closeContextModal(id);
|
context.closeContextModal(id);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
<BaseFormModal
|
||||||
|
{...innerProps}
|
||||||
|
closeOnSubmit
|
||||||
|
form={form}
|
||||||
|
onClose={onCancelClick}
|
||||||
|
>
|
||||||
|
<BaseFormModal.Body>
|
||||||
<>
|
<>
|
||||||
<form onSubmit={form.onSubmit((values) => onSubmit(values))}>
|
|
||||||
<Flex gap={rem(10)} direction={"column"}>
|
|
||||||
|
|
||||||
<ServiceCategorySelect
|
<ServiceCategorySelect
|
||||||
fullWidth
|
placeholder={"Выберите категорию"}
|
||||||
onChange={event => {
|
label={"Категория услуги"}
|
||||||
form.setFieldValue("category", event)
|
{...form.getInputProps('category')}
|
||||||
}}
|
|
||||||
error={form.getInputProps("category").error}
|
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
|
|
||||||
@@ -60,16 +69,9 @@ const CreateServiceModal = ({
|
|||||||
decimalScale={2}
|
decimalScale={2}
|
||||||
{...form.getInputProps('price')}
|
{...form.getInputProps('price')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Flex justify={"center"} mt={rem(5)} gap={rem(10)}>
|
|
||||||
<Button onClick={() => onCancelClick()} variant={"subtle"}>Отменить</Button>
|
|
||||||
<Button type={"submit"} variant={"default"}>Сохранить</Button>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
</>
|
</>
|
||||||
|
</BaseFormModal.Body>
|
||||||
|
</BaseFormModal>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import {FC, useRef} from "react";
|
import {FC} from "react";
|
||||||
import ServicesTable from "../components/ServicesTable/ServicesTable.tsx";
|
import ServicesTable from "../components/ServicesTable/ServicesTable.tsx";
|
||||||
import useServicesList from "../hooks/useServicesList.tsx";
|
import useServicesList from "../hooks/useServicesList.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, Text} from "@mantine/core";
|
||||||
import {BaseTableRef} from "../../../components/BaseTable/BaseTable.tsx";
|
|
||||||
import {ServiceCategorySchema, ServiceSchema, ServiceService} from "../../../client";
|
import {ServiceCategorySchema, ServiceSchema, ServiceService} from "../../../client";
|
||||||
import {notifications} from "../../../shared/lib/notifications.ts";
|
import {notifications} from "../../../shared/lib/notifications.ts";
|
||||||
import {modals} from "@mantine/modals";
|
import {modals} from "@mantine/modals";
|
||||||
@@ -12,8 +11,7 @@ import {modals} from "@mantine/modals";
|
|||||||
export const ServicesPage: FC = () => {
|
export const ServicesPage: FC = () => {
|
||||||
const {services, refetch} = useServicesList();
|
const {services, refetch} = useServicesList();
|
||||||
|
|
||||||
const tableRef = useRef<BaseTableRef<ServiceSchema>>(null);
|
// region Service create
|
||||||
|
|
||||||
const onCreateClick = () => {
|
const onCreateClick = () => {
|
||||||
modals.openContextModal({
|
modals.openContextModal({
|
||||||
modal: 'createService',
|
modal: 'createService',
|
||||||
@@ -32,6 +30,9 @@ export const ServicesPage: FC = () => {
|
|||||||
await refetch();
|
await refetch();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region Category create
|
||||||
const onCreateCategoryClick = () => {
|
const onCreateCategoryClick = () => {
|
||||||
modals.openContextModal({
|
modals.openContextModal({
|
||||||
modal: "createServiceCategory",
|
modal: "createServiceCategory",
|
||||||
@@ -47,7 +48,42 @@ export const ServicesPage: FC = () => {
|
|||||||
.then(({ok, message}) =>
|
.then(({ok, message}) =>
|
||||||
notifications.guess(ok, {message: message}))
|
notifications.guess(ok, {message: message}))
|
||||||
}
|
}
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
const onServiceDelete = (service: ServiceSchema) => {
|
||||||
|
modals.openConfirmModal({
|
||||||
|
title: 'Удаление услуги',
|
||||||
|
children: (<Text>
|
||||||
|
Вы уверены, что хотите удалить услугу "{service.name}"?
|
||||||
|
</Text>),
|
||||||
|
onConfirm: () => {
|
||||||
|
ServiceService.deleteService({requestBody: {serviceId: service.id}})
|
||||||
|
.then(async ({ok, message}) => {
|
||||||
|
notifications.guess(ok, {message: message});
|
||||||
|
if (!ok) return;
|
||||||
|
await refetch();
|
||||||
|
})
|
||||||
|
},
|
||||||
|
labels: {
|
||||||
|
confirm: 'Удалить',
|
||||||
|
cancel: 'Отмена'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const onServiceUpdate = (service: ServiceSchema) => {
|
||||||
|
ServiceService
|
||||||
|
.updateService({
|
||||||
|
requestBody: {
|
||||||
|
data: service
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(async ({ok, message}) => {
|
||||||
|
notifications.guess(ok, {message: message});
|
||||||
|
if (!ok) return;
|
||||||
|
await refetch();
|
||||||
|
})
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div className={styles['container']}>
|
<div className={styles['container']}>
|
||||||
<PageBlock>
|
<PageBlock>
|
||||||
@@ -58,8 +94,9 @@ export const ServicesPage: FC = () => {
|
|||||||
</PageBlock>
|
</PageBlock>
|
||||||
<PageBlock>
|
<PageBlock>
|
||||||
<ServicesTable
|
<ServicesTable
|
||||||
tableRef={tableRef}
|
onDelete={onServiceDelete}
|
||||||
services={services}
|
onChange={onServiceUpdate}
|
||||||
|
items={services}
|
||||||
/>
|
/>
|
||||||
</PageBlock>
|
</PageBlock>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user