crap
This commit is contained in:
		@@ -27,8 +27,12 @@ export type { HTTPValidationError } from './models/HTTPValidationError';
 | 
				
			|||||||
export type { PaginationInfoSchema } from './models/PaginationInfoSchema';
 | 
					export type { PaginationInfoSchema } from './models/PaginationInfoSchema';
 | 
				
			||||||
export type { ProductCreateRequest } from './models/ProductCreateRequest';
 | 
					export type { ProductCreateRequest } from './models/ProductCreateRequest';
 | 
				
			||||||
export type { ProductCreateResponse } from './models/ProductCreateResponse';
 | 
					export type { ProductCreateResponse } from './models/ProductCreateResponse';
 | 
				
			||||||
 | 
					export type { ProductDeleteRequest } from './models/ProductDeleteRequest';
 | 
				
			||||||
 | 
					export type { ProductDeleteResponse } from './models/ProductDeleteResponse';
 | 
				
			||||||
export type { ProductGetResponse } from './models/ProductGetResponse';
 | 
					export type { ProductGetResponse } from './models/ProductGetResponse';
 | 
				
			||||||
export type { ProductSchema } from './models/ProductSchema';
 | 
					export type { ProductSchema } from './models/ProductSchema';
 | 
				
			||||||
 | 
					export type { ProductUpdateRequest } from './models/ProductUpdateRequest';
 | 
				
			||||||
 | 
					export type { ProductUpdateResponse } from './models/ProductUpdateResponse';
 | 
				
			||||||
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';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,6 @@
 | 
				
			|||||||
/* tslint:disable */
 | 
					/* tslint:disable */
 | 
				
			||||||
/* eslint-disable */
 | 
					/* eslint-disable */
 | 
				
			||||||
export type AuthLoginResponse = {
 | 
					export type AuthLoginResponse = {
 | 
				
			||||||
    access_token: string;
 | 
					    accessToken: string;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@
 | 
				
			|||||||
/* eslint-disable */
 | 
					/* eslint-disable */
 | 
				
			||||||
export type ClientDetailsSchema = {
 | 
					export type ClientDetailsSchema = {
 | 
				
			||||||
    address?: (string | null);
 | 
					    address?: (string | null);
 | 
				
			||||||
    phone_number?: (string | null);
 | 
					    phoneNumber?: (string | null);
 | 
				
			||||||
    inn?: (number | null);
 | 
					    inn?: (number | null);
 | 
				
			||||||
    email?: (string | null);
 | 
					    email?: (string | null);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@
 | 
				
			|||||||
/* eslint-disable */
 | 
					/* eslint-disable */
 | 
				
			||||||
import type { ClientDetailsSchema } from './ClientDetailsSchema';
 | 
					import type { ClientDetailsSchema } from './ClientDetailsSchema';
 | 
				
			||||||
export type ClientUpdateDetailsRequest = {
 | 
					export type ClientUpdateDetailsRequest = {
 | 
				
			||||||
    client_id: number;
 | 
					    clientId: number;
 | 
				
			||||||
    details: ClientDetailsSchema;
 | 
					    details: ClientDetailsSchema;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@
 | 
				
			|||||||
/* eslint-disable */
 | 
					/* eslint-disable */
 | 
				
			||||||
import type { DealServiceSchema } from './DealServiceSchema';
 | 
					import type { DealServiceSchema } from './DealServiceSchema';
 | 
				
			||||||
export type DealAddServicesRequest = {
 | 
					export type DealAddServicesRequest = {
 | 
				
			||||||
    deal_id: number;
 | 
					    dealId: number;
 | 
				
			||||||
    services: Array<DealServiceSchema>;
 | 
					    services: Array<DealServiceSchema>;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/* tslint:disable */
 | 
					/* tslint:disable */
 | 
				
			||||||
/* eslint-disable */
 | 
					/* eslint-disable */
 | 
				
			||||||
export type DealChangeStatusRequest = {
 | 
					export type DealChangeStatusRequest = {
 | 
				
			||||||
    deal_id: number;
 | 
					    dealId: number;
 | 
				
			||||||
    new_status: number;
 | 
					    newStatus: number;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,9 +4,9 @@
 | 
				
			|||||||
/* eslint-disable */
 | 
					/* eslint-disable */
 | 
				
			||||||
export type DealQuickCreateRequest = {
 | 
					export type DealQuickCreateRequest = {
 | 
				
			||||||
    name: string;
 | 
					    name: string;
 | 
				
			||||||
    client_name: string;
 | 
					    clientName: string;
 | 
				
			||||||
    client_address: string;
 | 
					    clientAddress: string;
 | 
				
			||||||
    comment: string;
 | 
					    comment: string;
 | 
				
			||||||
    acceptance_date: string;
 | 
					    acceptanceDate: string;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,6 @@
 | 
				
			|||||||
/* tslint:disable */
 | 
					/* tslint:disable */
 | 
				
			||||||
/* eslint-disable */
 | 
					/* eslint-disable */
 | 
				
			||||||
export type DealQuickCreateResponse = {
 | 
					export type DealQuickCreateResponse = {
 | 
				
			||||||
    deal_id: number;
 | 
					    dealId: number;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,9 +5,9 @@
 | 
				
			|||||||
export type DealSummary = {
 | 
					export type DealSummary = {
 | 
				
			||||||
    id: number;
 | 
					    id: number;
 | 
				
			||||||
    name: string;
 | 
					    name: string;
 | 
				
			||||||
    client_name: string;
 | 
					    clientName: string;
 | 
				
			||||||
    changed_at: string;
 | 
					    changedAt: string;
 | 
				
			||||||
    status: number;
 | 
					    status: number;
 | 
				
			||||||
    total_price: number;
 | 
					    totalPrice: number;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/* tslint:disable */
 | 
					/* tslint:disable */
 | 
				
			||||||
/* eslint-disable */
 | 
					/* eslint-disable */
 | 
				
			||||||
export type PaginationInfoSchema = {
 | 
					export type PaginationInfoSchema = {
 | 
				
			||||||
    total_pages: number;
 | 
					    totalPages: number;
 | 
				
			||||||
    total_items: number;
 | 
					    totalItems: number;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@
 | 
				
			|||||||
export type ProductCreateRequest = {
 | 
					export type ProductCreateRequest = {
 | 
				
			||||||
    name: string;
 | 
					    name: string;
 | 
				
			||||||
    article: string;
 | 
					    article: string;
 | 
				
			||||||
    client_id: number;
 | 
					    clientId: number;
 | 
				
			||||||
 | 
					    barcodes: Array<string>;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,8 @@
 | 
				
			|||||||
/* tslint:disable */
 | 
					/* tslint:disable */
 | 
				
			||||||
/* eslint-disable */
 | 
					/* eslint-disable */
 | 
				
			||||||
export type ProductCreateResponse = {
 | 
					export type ProductCreateResponse = {
 | 
				
			||||||
    product_id: number;
 | 
					    ok: boolean;
 | 
				
			||||||
 | 
					    message: string;
 | 
				
			||||||
 | 
					    productId?: (number | null);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								src/client/models/ProductDeleteRequest.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/client/models/ProductDeleteRequest.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					/* generated using openapi-typescript-codegen -- do no edit */
 | 
				
			||||||
 | 
					/* istanbul ignore file */
 | 
				
			||||||
 | 
					/* tslint:disable */
 | 
				
			||||||
 | 
					/* eslint-disable */
 | 
				
			||||||
 | 
					export type ProductDeleteRequest = {
 | 
				
			||||||
 | 
					    productId: number;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										9
									
								
								src/client/models/ProductDeleteResponse.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/client/models/ProductDeleteResponse.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					/* generated using openapi-typescript-codegen -- do no edit */
 | 
				
			||||||
 | 
					/* istanbul ignore file */
 | 
				
			||||||
 | 
					/* tslint:disable */
 | 
				
			||||||
 | 
					/* eslint-disable */
 | 
				
			||||||
 | 
					export type ProductDeleteResponse = {
 | 
				
			||||||
 | 
					    ok: boolean;
 | 
				
			||||||
 | 
					    message: string;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -6,6 +6,6 @@ import type { PaginationInfoSchema } from './PaginationInfoSchema';
 | 
				
			|||||||
import type { ProductSchema } from './ProductSchema';
 | 
					import type { ProductSchema } from './ProductSchema';
 | 
				
			||||||
export type ProductGetResponse = {
 | 
					export type ProductGetResponse = {
 | 
				
			||||||
    products: Array<ProductSchema>;
 | 
					    products: Array<ProductSchema>;
 | 
				
			||||||
    pagination_info: PaginationInfoSchema;
 | 
					    paginationInfo: PaginationInfoSchema;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,7 @@ export type ProductSchema = {
 | 
				
			|||||||
    id: number;
 | 
					    id: number;
 | 
				
			||||||
    name: string;
 | 
					    name: string;
 | 
				
			||||||
    article: string;
 | 
					    article: string;
 | 
				
			||||||
    client_id: number;
 | 
					    clientId: number;
 | 
				
			||||||
 | 
					    barcodes: Array<string>;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										9
									
								
								src/client/models/ProductUpdateRequest.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/client/models/ProductUpdateRequest.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					/* generated using openapi-typescript-codegen -- do no edit */
 | 
				
			||||||
 | 
					/* istanbul ignore file */
 | 
				
			||||||
 | 
					/* tslint:disable */
 | 
				
			||||||
 | 
					/* eslint-disable */
 | 
				
			||||||
 | 
					import type { ProductSchema } from './ProductSchema';
 | 
				
			||||||
 | 
					export type ProductUpdateRequest = {
 | 
				
			||||||
 | 
					    product: ProductSchema;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										9
									
								
								src/client/models/ProductUpdateResponse.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/client/models/ProductUpdateResponse.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					/* generated using openapi-typescript-codegen -- do no edit */
 | 
				
			||||||
 | 
					/* istanbul ignore file */
 | 
				
			||||||
 | 
					/* tslint:disable */
 | 
				
			||||||
 | 
					/* eslint-disable */
 | 
				
			||||||
 | 
					export type ProductUpdateResponse = {
 | 
				
			||||||
 | 
					    ok: boolean;
 | 
				
			||||||
 | 
					    message: string;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -4,7 +4,11 @@
 | 
				
			|||||||
/* eslint-disable */
 | 
					/* eslint-disable */
 | 
				
			||||||
import type { ProductCreateRequest } from '../models/ProductCreateRequest';
 | 
					import type { ProductCreateRequest } from '../models/ProductCreateRequest';
 | 
				
			||||||
import type { ProductCreateResponse } from '../models/ProductCreateResponse';
 | 
					import type { ProductCreateResponse } from '../models/ProductCreateResponse';
 | 
				
			||||||
 | 
					import type { ProductDeleteRequest } from '../models/ProductDeleteRequest';
 | 
				
			||||||
 | 
					import type { ProductDeleteResponse } from '../models/ProductDeleteResponse';
 | 
				
			||||||
import type { ProductGetResponse } from '../models/ProductGetResponse';
 | 
					import type { ProductGetResponse } from '../models/ProductGetResponse';
 | 
				
			||||||
 | 
					import type { ProductUpdateRequest } from '../models/ProductUpdateRequest';
 | 
				
			||||||
 | 
					import type { ProductUpdateResponse } from '../models/ProductUpdateResponse';
 | 
				
			||||||
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';
 | 
				
			||||||
@@ -14,7 +18,7 @@ export class ProductService {
 | 
				
			|||||||
     * @returns ProductCreateResponse Successful Response
 | 
					     * @returns ProductCreateResponse Successful Response
 | 
				
			||||||
     * @throws ApiError
 | 
					     * @throws ApiError
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static createProductProductCreatePost({
 | 
					    public static createProduct({
 | 
				
			||||||
        requestBody,
 | 
					        requestBody,
 | 
				
			||||||
    }: {
 | 
					    }: {
 | 
				
			||||||
        requestBody: ProductCreateRequest,
 | 
					        requestBody: ProductCreateRequest,
 | 
				
			||||||
@@ -29,6 +33,46 @@ export class ProductService {
 | 
				
			|||||||
            },
 | 
					            },
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Delete Product
 | 
				
			||||||
 | 
					     * @returns ProductDeleteResponse Successful Response
 | 
				
			||||||
 | 
					     * @throws ApiError
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static deleteProduct({
 | 
				
			||||||
 | 
					        requestBody,
 | 
				
			||||||
 | 
					    }: {
 | 
				
			||||||
 | 
					        requestBody: ProductDeleteRequest,
 | 
				
			||||||
 | 
					    }): CancelablePromise<ProductDeleteResponse> {
 | 
				
			||||||
 | 
					        return __request(OpenAPI, {
 | 
				
			||||||
 | 
					            method: 'POST',
 | 
				
			||||||
 | 
					            url: '/product/delete',
 | 
				
			||||||
 | 
					            body: requestBody,
 | 
				
			||||||
 | 
					            mediaType: 'application/json',
 | 
				
			||||||
 | 
					            errors: {
 | 
				
			||||||
 | 
					                422: `Validation Error`,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Delete Product
 | 
				
			||||||
 | 
					     * @returns ProductUpdateResponse Successful Response
 | 
				
			||||||
 | 
					     * @throws ApiError
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static updateProduct({
 | 
				
			||||||
 | 
					        requestBody,
 | 
				
			||||||
 | 
					    }: {
 | 
				
			||||||
 | 
					        requestBody: ProductUpdateRequest,
 | 
				
			||||||
 | 
					    }): CancelablePromise<ProductUpdateResponse> {
 | 
				
			||||||
 | 
					        return __request(OpenAPI, {
 | 
				
			||||||
 | 
					            method: 'POST',
 | 
				
			||||||
 | 
					            url: '/product/update',
 | 
				
			||||||
 | 
					            body: requestBody,
 | 
				
			||||||
 | 
					            mediaType: 'application/json',
 | 
				
			||||||
 | 
					            errors: {
 | 
				
			||||||
 | 
					                422: `Validation Error`,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Get Product
 | 
					     * Get Product
 | 
				
			||||||
     * @returns ProductGetResponse Successful Response
 | 
					     * @returns ProductGetResponse Successful Response
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,13 +2,12 @@ import {
 | 
				
			|||||||
    MantineReactTable,
 | 
					    MantineReactTable,
 | 
				
			||||||
    MRT_ColumnDef,
 | 
					    MRT_ColumnDef,
 | 
				
			||||||
    MRT_RowData,
 | 
					    MRT_RowData,
 | 
				
			||||||
    MRT_Table,
 | 
					 | 
				
			||||||
    MRT_TableInstance,
 | 
					    MRT_TableInstance,
 | 
				
			||||||
    MRT_TableOptions,
 | 
					    MRT_TableOptions,
 | 
				
			||||||
    useMantineReactTable
 | 
					    useMantineReactTable
 | 
				
			||||||
} from "mantine-react-table";
 | 
					} from "mantine-react-table";
 | 
				
			||||||
import {MRT_Localization_RU} from "mantine-react-table/locales/ru/index.cjs";
 | 
					import {MRT_Localization_RU} from "mantine-react-table/locales/ru/index.cjs";
 | 
				
			||||||
import {forwardRef, useEffect, useImperativeHandle} from 'react';
 | 
					import {forwardRef, useImperativeHandle} from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Props<T extends Record<string, any>, K extends keyof T> = {
 | 
					type Props<T extends Record<string, any>, K extends keyof T> = {
 | 
				
			||||||
    data: T[],
 | 
					    data: T[],
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,7 +39,7 @@ const CreateDealButton: FC<Props> = () => {
 | 
				
			|||||||
                                DealService.quickCreateDealQuickCreatePost({
 | 
					                                DealService.quickCreateDealQuickCreatePost({
 | 
				
			||||||
                                    requestBody: {
 | 
					                                    requestBody: {
 | 
				
			||||||
                                        ...quickDeal,
 | 
					                                        ...quickDeal,
 | 
				
			||||||
                                        acceptance_date: dateWithoutTimezone(quickDeal.acceptance_date)
 | 
					                                        acceptanceDate: dateWithoutTimezone(quickDeal.acceptanceDate)
 | 
				
			||||||
                                    }
 | 
					                                    }
 | 
				
			||||||
                                })
 | 
					                                })
 | 
				
			||||||
                            }}
 | 
					                            }}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,10 +14,10 @@ const CreateDealFrom: FC<Props> = ({onSubmit, onCancel}) => {
 | 
				
			|||||||
    const form = useForm({
 | 
					    const form = useForm({
 | 
				
			||||||
        initialValues: {
 | 
					        initialValues: {
 | 
				
			||||||
            name: '',
 | 
					            name: '',
 | 
				
			||||||
            client_name: '',
 | 
					            clientName: '',
 | 
				
			||||||
            client_address: '',
 | 
					            clientAddress: '',
 | 
				
			||||||
            comment: '',
 | 
					            comment: '',
 | 
				
			||||||
            acceptance_date: new Date()
 | 
					            acceptanceDate: new Date()
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
@@ -43,8 +43,8 @@ const CreateDealFrom: FC<Props> = ({onSubmit, onCancel}) => {
 | 
				
			|||||||
                <div className={styles['inputs']}>
 | 
					                <div className={styles['inputs']}>
 | 
				
			||||||
                    <ClientAutocomplete
 | 
					                    <ClientAutocomplete
 | 
				
			||||||
                        withAddress
 | 
					                        withAddress
 | 
				
			||||||
                        nameRestProps={form.getInputProps('client_name')}
 | 
					                        nameRestProps={form.getInputProps('clientName')}
 | 
				
			||||||
                        addressRestProps={form.getInputProps('client_address')}
 | 
					                        addressRestProps={form.getInputProps('clientAddress')}
 | 
				
			||||||
                    />
 | 
					                    />
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -60,7 +60,7 @@ const CreateDealFrom: FC<Props> = ({onSubmit, onCancel}) => {
 | 
				
			|||||||
                <div className={styles['inputs']}>
 | 
					                <div className={styles['inputs']}>
 | 
				
			||||||
                    <DateTimePicker
 | 
					                    <DateTimePicker
 | 
				
			||||||
                        placeholder={'Дата приемки'}
 | 
					                        placeholder={'Дата приемки'}
 | 
				
			||||||
                        {...form.getInputProps('acceptance_date')}
 | 
					                        {...form.getInputProps('acceptanceDate')}
 | 
				
			||||||
                    />
 | 
					                    />
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ const DealSummaryCard: FC<Props> = ({dealSummary}) => {
 | 
				
			|||||||
            <div className={styles['flex-row']}>
 | 
					            <div className={styles['flex-row']}>
 | 
				
			||||||
                <div className={styles['flex-item']}>
 | 
					                <div className={styles['flex-item']}>
 | 
				
			||||||
                    <Text size={"sm"} c={"gray.6"}>
 | 
					                    <Text size={"sm"} c={"gray.6"}>
 | 
				
			||||||
                        {dealSummary.client_name}
 | 
					                        {dealSummary.clientName}
 | 
				
			||||||
                    </Text>
 | 
					                    </Text>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                <div className={styles['flex-item']}>
 | 
					                <div className={styles['flex-item']}>
 | 
				
			||||||
@@ -23,14 +23,14 @@ const DealSummaryCard: FC<Props> = ({dealSummary}) => {
 | 
				
			|||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                <div className={styles['flex-item']}>
 | 
					                <div className={styles['flex-item']}>
 | 
				
			||||||
                    <Text size={"sm"} c={"gray.6"}>
 | 
					                    <Text size={"sm"} c={"gray.6"}>
 | 
				
			||||||
                        {dealSummary.total_price.toLocaleString('ru-RU')} руб
 | 
					                        {dealSummary.totalPrice.toLocaleString('ru-RU')} руб
 | 
				
			||||||
                    </Text>
 | 
					                    </Text>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <div className={classNames(styles['flex-row'], styles['flex-row-right'])}>
 | 
					            <div className={classNames(styles['flex-row'], styles['flex-row-right'])}>
 | 
				
			||||||
                <div className={styles['flex-item']}>
 | 
					                <div className={styles['flex-item']}>
 | 
				
			||||||
                    <Text size={"sm"} c={"gray.6"}>
 | 
					                    <Text size={"sm"} c={"gray.6"}>
 | 
				
			||||||
                        {new Date(dealSummary.changed_at).toLocaleString('ru-RU')}
 | 
					                        {new Date(dealSummary.changedAt).toLocaleString('ru-RU')}
 | 
				
			||||||
                    </Text>
 | 
					                    </Text>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                <div className={styles['flex-item']}>
 | 
					                <div className={styles['flex-item']}>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,26 +0,0 @@
 | 
				
			|||||||
import {ContextModalProps} from "@mantine/modals";
 | 
					 | 
				
			||||||
import {Button, Text} from "@mantine/core";
 | 
					 | 
				
			||||||
import {useForm} from "@mantine/form";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const CreateProductModal = ({
 | 
					 | 
				
			||||||
                                context,
 | 
					 | 
				
			||||||
                                id,
 | 
					 | 
				
			||||||
                                innerProps,
 | 
					 | 
				
			||||||
                            }: ContextModalProps<{ clientId: number }>) => {
 | 
					 | 
				
			||||||
    const form = useForm({
 | 
					 | 
				
			||||||
        initialValues: {
 | 
					 | 
				
			||||||
            name: '',
 | 
					 | 
				
			||||||
            article: '',
 | 
					 | 
				
			||||||
            barcode: ''
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
    return (
 | 
					 | 
				
			||||||
        <>
 | 
					 | 
				
			||||||
            <Button fullWidth mt="md" onClick={() => context.closeModal(id)}>
 | 
					 | 
				
			||||||
                Close modal
 | 
					 | 
				
			||||||
            </Button>
 | 
					 | 
				
			||||||
        </>
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
export default CreateProductModal;
 | 
					 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
import EnterDeadlineModal from "./EnterDeadlineModal/EnterDeadlineModal.tsx";
 | 
					import EnterDeadlineModal from "./EnterDeadlineModal/EnterDeadlineModal.tsx";
 | 
				
			||||||
import CreateServiceCategoryModal from "../pages/ServicesPage/modals/CreateServiceCategoryModal.tsx";
 | 
					import CreateServiceCategoryModal from "../pages/ServicesPage/modals/CreateServiceCategoryModal.tsx";
 | 
				
			||||||
import CreateServiceModal from "../pages/ServicesPage/modals/CreateServiceModal.tsx";
 | 
					import CreateServiceModal from "../pages/ServicesPage/modals/CreateServiceModal.tsx";
 | 
				
			||||||
import createProductModal from "./CreateProductModal/CreateProductModal.tsx";
 | 
					import createProductModal from "../pages/ProductsPage/modals/CreateProductModal/CreateProductModal.tsx";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const modals = {
 | 
					export const modals = {
 | 
				
			||||||
    enterDeadline: EnterDeadlineModal,
 | 
					    enterDeadline: EnterDeadlineModal,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
import React, {FC, useEffect, useState} from "react";
 | 
					import {FC, useEffect, useState} from "react";
 | 
				
			||||||
import styles from './LeadsPage.module.css';
 | 
					import styles from './LeadsPage.module.css';
 | 
				
			||||||
import Board from "../../../components/Dnd/Board/Board.tsx";
 | 
					import Board from "../../../components/Dnd/Board/Board.tsx";
 | 
				
			||||||
import {DragDropContext} from "@hello-pangea/dnd";
 | 
					import {DragDropContext} from "@hello-pangea/dnd";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,8 +39,8 @@ const LoginPage = () => {
 | 
				
			|||||||
                        },
 | 
					                        },
 | 
				
			||||||
                        (data: TelegramUser) => {
 | 
					                        (data: TelegramUser) => {
 | 
				
			||||||
                            AuthService.loginAuthLoginPost({requestBody: data})
 | 
					                            AuthService.loginAuthLoginPost({requestBody: data})
 | 
				
			||||||
                                .then(({access_token}) => {
 | 
					                                .then(({accessToken}) => {
 | 
				
			||||||
                                    dispatch(login({accessToken: access_token}));
 | 
					                                    dispatch(login({accessToken: accessToken}));
 | 
				
			||||||
                                    navigate({to: "/"}).then(() => {
 | 
					                                    navigate({to: "/"}).then(() => {
 | 
				
			||||||
                                        notifications.success({message: "Вы успешно вошли!"})
 | 
					                                        notifications.success({message: "Вы успешно вошли!"})
 | 
				
			||||||
                                    })
 | 
					                                    })
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,5 +10,4 @@
 | 
				
			|||||||
.container {
 | 
					.container {
 | 
				
			||||||
    padding: rem(20);
 | 
					    padding: rem(20);
 | 
				
			||||||
    display: flex;
 | 
					    display: flex;
 | 
				
			||||||
    //min-height: 100vh;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,20 +14,17 @@ const PageWrapper: FC<Props> = ({children}) => {
 | 
				
			|||||||
        <AppShell
 | 
					        <AppShell
 | 
				
			||||||
            layout={"alt"}
 | 
					            layout={"alt"}
 | 
				
			||||||
            navbar={{width: rem('80px'), breakpoint: "sm"}}
 | 
					            navbar={{width: rem('80px'), breakpoint: "sm"}}
 | 
				
			||||||
            // header={{height:rem(60)}}
 | 
					 | 
				
			||||||
        >
 | 
					        >
 | 
				
			||||||
            {/*<AppShell.Header>*/}
 | 
					
 | 
				
			||||||
            {/*    <Header/>*/}
 | 
					 | 
				
			||||||
            {/*</AppShell.Header>*/}
 | 
					 | 
				
			||||||
            <AppShell.Navbar>
 | 
					            <AppShell.Navbar>
 | 
				
			||||||
                <Navbar/>
 | 
					                {authState.isAuthorized &&
 | 
				
			||||||
 | 
					                    <Navbar/>
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            </AppShell.Navbar>
 | 
					            </AppShell.Navbar>
 | 
				
			||||||
            <AppShell.Main className={styles['main-container']}>
 | 
					            <AppShell.Main className={styles['main-container']}>
 | 
				
			||||||
                <div className={styles['container']}>
 | 
					                <div className={styles['container']}>
 | 
				
			||||||
                    {children}
 | 
					                    {children}
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            </AppShell.Main>
 | 
					            </AppShell.Main>
 | 
				
			||||||
        </AppShell>
 | 
					        </AppShell>
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,24 +1,56 @@
 | 
				
			|||||||
import {ProductSchema} from "../../../../client";
 | 
					import {ProductSchema} from "../../../../client";
 | 
				
			||||||
import {FC, RefObject} from "react";
 | 
					import {FC} from "react";
 | 
				
			||||||
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 {useProductsTableColumns} from "./columns.tsx";
 | 
					import {useProductsTableColumns} from "./columns.tsx";
 | 
				
			||||||
 | 
					import {ActionIcon, Flex, Tooltip} from "@mantine/core";
 | 
				
			||||||
 | 
					import {IconEdit, IconTrash} from "@tabler/icons-react";
 | 
				
			||||||
 | 
					import {CRUDTableProps} from "../../../../types/CRUDTable.tsx";
 | 
				
			||||||
 | 
					import {modals} from "@mantine/modals";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Props = {
 | 
					
 | 
				
			||||||
    products: ProductSchema[];
 | 
					const ProductsTable: FC<CRUDTableProps<ProductSchema>> = ({items, onDelete, onChange, tableRef}) => {
 | 
				
			||||||
    tableRef?: RefObject<BaseTableRef<ProductSchema>>
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
const ProductsTable: FC<Props> = ({products, tableRef}) => {
 | 
					 | 
				
			||||||
    const columns = useProductsTableColumns();
 | 
					    const columns = useProductsTableColumns();
 | 
				
			||||||
 | 
					    const onEditClick = (product: ProductSchema) => {
 | 
				
			||||||
 | 
					        if (!onChange) return;
 | 
				
			||||||
 | 
					        modals.openContextModal({
 | 
				
			||||||
 | 
					            modal: "createProduct",
 | 
				
			||||||
 | 
					            title: 'Создание товара',
 | 
				
			||||||
 | 
					            withCloseButton: false,
 | 
				
			||||||
 | 
					            innerProps: {
 | 
				
			||||||
 | 
					                onChange: (newProduct) => onChange(newProduct),
 | 
				
			||||||
 | 
					                product: product,
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
            <BaseTable
 | 
					        <BaseTable
 | 
				
			||||||
                ref={tableRef}
 | 
					            ref={tableRef}
 | 
				
			||||||
                data={products}
 | 
					            data={items}
 | 
				
			||||||
                columns={columns}
 | 
					            columns={columns}
 | 
				
			||||||
                restProps={{
 | 
					            restProps={{
 | 
				
			||||||
                    enableColumnActions: false,
 | 
					                enableColumnActions: false,
 | 
				
			||||||
                } as MRT_TableOptions<ProductSchema>}
 | 
					                enableRowActions: true,
 | 
				
			||||||
            />
 | 
					                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<ProductSchema>}
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,10 @@
 | 
				
			|||||||
import {useMemo} from "react";
 | 
					import {useMemo} from "react";
 | 
				
			||||||
import {MRT_ColumnDef} from "mantine-react-table";
 | 
					import {MRT_ColumnDef} from "mantine-react-table";
 | 
				
			||||||
import {ProductSchema} from "../../../../client";
 | 
					import {ProductSchema} from "../../../../client";
 | 
				
			||||||
 | 
					import {List, Spoiler, useMantineTheme} from "@mantine/core";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const useProductsTableColumns = () => {
 | 
					export const useProductsTableColumns = () => {
 | 
				
			||||||
 | 
					    const theme = useMantineTheme();
 | 
				
			||||||
    return useMemo<MRT_ColumnDef<ProductSchema>[]>(() => [
 | 
					    return useMemo<MRT_ColumnDef<ProductSchema>[]>(() => [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            accessorKey: "article",
 | 
					            accessorKey: "article",
 | 
				
			||||||
@@ -13,8 +15,27 @@ export const useProductsTableColumns = () => {
 | 
				
			|||||||
            accessorKey: "name",
 | 
					            accessorKey: "name",
 | 
				
			||||||
            header: "Название",
 | 
					            header: "Название",
 | 
				
			||||||
            enableSorting: false,
 | 
					            enableSorting: false,
 | 
				
			||||||
 | 
					 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            accessorKey: "barcodes",
 | 
				
			||||||
 | 
					            header: "Штрихкоды",
 | 
				
			||||||
 | 
					            Cell: ({cell}) => {
 | 
				
			||||||
 | 
					                return (
 | 
				
			||||||
 | 
					                    <List size={"sm"}>
 | 
				
			||||||
 | 
					                        <Spoiler maxHeight={parseFloat(theme.lineHeights.sm) * 25}
 | 
				
			||||||
 | 
					                                 showLabel={"Показать все"}
 | 
				
			||||||
 | 
					                                 hideLabel={"Скрыть"}>
 | 
				
			||||||
 | 
					                            {cell.getValue<string[]>().map(barcode => (
 | 
				
			||||||
 | 
					                                <List.Item key={barcode}>
 | 
				
			||||||
 | 
					                                    {barcode}
 | 
				
			||||||
 | 
					                                </List.Item>
 | 
				
			||||||
 | 
					                            ))}
 | 
				
			||||||
 | 
					                        </Spoiler>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    </List>
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    ], []);
 | 
					    ], []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -8,12 +8,12 @@ type Props = {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
const useServicesList = (props: Props) => {
 | 
					const useServicesList = (props: Props) => {
 | 
				
			||||||
    const {clientId, page, itemsPerPage} = props;
 | 
					    const {clientId, page, itemsPerPage} = props;
 | 
				
			||||||
    const {isPending, error, data, refetch} = useQuery({
 | 
					    const {data, refetch} = useQuery({
 | 
				
			||||||
        queryKey: ['getAllServices', clientId, page, itemsPerPage],
 | 
					        queryKey: ['getAllServices', clientId, page, itemsPerPage],
 | 
				
			||||||
        queryFn: () => ProductService.getProductsByClientId({clientId, page, itemsPerPage})
 | 
					        queryFn: () => ProductService.getProductsByClientId({clientId, page, itemsPerPage})
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    const products = isPending || error || !data ? [] : data.products;
 | 
					    const products = !data ? [] : data.products;
 | 
				
			||||||
    const paginationInfo = data?.pagination_info;
 | 
					    const paginationInfo = data?.paginationInfo;
 | 
				
			||||||
    return {products, paginationInfo, refetch}
 | 
					    return {products, paginationInfo, refetch}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
export default useServicesList;
 | 
					export default useServicesList;
 | 
				
			||||||
@@ -0,0 +1,97 @@
 | 
				
			|||||||
 | 
					import {ContextModalProps} from "@mantine/modals";
 | 
				
			||||||
 | 
					import {Button, Flex, rem, TagsInput, TextInput} from "@mantine/core";
 | 
				
			||||||
 | 
					import {useForm} from "@mantine/form";
 | 
				
			||||||
 | 
					import {BaseProduct, CreateProductRequest} from "../../types.ts";
 | 
				
			||||||
 | 
					import {ProductSchema} from "../../../../client";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CreateProps = {
 | 
				
			||||||
 | 
					    clientId: number;
 | 
				
			||||||
 | 
					    onCreate: (values: CreateProductRequest) => void
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type EditProps = {
 | 
				
			||||||
 | 
					    product: ProductSchema,
 | 
				
			||||||
 | 
					    onChange: (values: ProductSchema) => void
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					type Props = CreateProps | EditProps;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const CreateProductModal = ({
 | 
				
			||||||
 | 
					                                context,
 | 
				
			||||||
 | 
					                                id,
 | 
				
			||||||
 | 
					                                innerProps,
 | 
				
			||||||
 | 
					                            }: ContextModalProps<Props>) => {
 | 
				
			||||||
 | 
					    const isEditProps = 'product' in innerProps;
 | 
				
			||||||
 | 
					    const isCreatingProps = 'clientId' in innerProps;
 | 
				
			||||||
 | 
					    const initialValues = isEditProps ? {
 | 
				
			||||||
 | 
					        name: innerProps.product.name,
 | 
				
			||||||
 | 
					        article: innerProps.product.article,
 | 
				
			||||||
 | 
					        barcodes: innerProps.product.barcodes
 | 
				
			||||||
 | 
					    } : {
 | 
				
			||||||
 | 
					        name: '',
 | 
				
			||||||
 | 
					        article: '',
 | 
				
			||||||
 | 
					        barcodes: []
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    const form = useForm({
 | 
				
			||||||
 | 
					        initialValues: initialValues,
 | 
				
			||||||
 | 
					        validate: {
 | 
				
			||||||
 | 
					            name: (name) => name.trim() !== '' ? null : "Необходимо ввести название товара",
 | 
				
			||||||
 | 
					            article: (article) => article.trim() !== '' ? null : "Необходимо ввести артикул",
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    const onCancelClick = () => {
 | 
				
			||||||
 | 
					        context.closeContextModal(id);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const onSubmit = (values: BaseProduct) => {
 | 
				
			||||||
 | 
					        if (isEditProps) innerProps.onChange({...innerProps.product, ...values})
 | 
				
			||||||
 | 
					        if (isCreatingProps) {
 | 
				
			||||||
 | 
					            innerProps.onCreate({...values, clientId: innerProps.clientId});
 | 
				
			||||||
 | 
					            form.reset();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <>
 | 
				
			||||||
 | 
					            <form onSubmit={form.onSubmit((values) => onSubmit(values))}>
 | 
				
			||||||
 | 
					                <Flex gap={rem(10)} direction={"column"}>
 | 
				
			||||||
 | 
					                    <TextInput
 | 
				
			||||||
 | 
					                        placeholder={"Введите название товара"}
 | 
				
			||||||
 | 
					                        label={"Название товара"}
 | 
				
			||||||
 | 
					                        {...form.getInputProps('name')}
 | 
				
			||||||
 | 
					                    />
 | 
				
			||||||
 | 
					                    <TextInput
 | 
				
			||||||
 | 
					                        placeholder={"Введите артикул"}
 | 
				
			||||||
 | 
					                        label={"Артикул"}
 | 
				
			||||||
 | 
					                        {...form.getInputProps('article')}
 | 
				
			||||||
 | 
					                    />
 | 
				
			||||||
 | 
					                    <TagsInput
 | 
				
			||||||
 | 
					                        placeholder={!form.values.barcodes.length ? "Добавьте штрихкоды к товару" : ""}
 | 
				
			||||||
 | 
					                        label={"Штрихкоды"}
 | 
				
			||||||
 | 
					                        {...form.getInputProps('barcodes')}
 | 
				
			||||||
 | 
					                    />
 | 
				
			||||||
 | 
					                    <Flex justify={"flex-end"} mt={rem(5)} gap={rem(10)}>
 | 
				
			||||||
 | 
					                        <Button onClick={() => onCancelClick()} variant={"subtle"}>Отменить</Button>
 | 
				
			||||||
 | 
					                        {isEditProps ?
 | 
				
			||||||
 | 
					                            <Button
 | 
				
			||||||
 | 
					                                onClick={() => context.closeContextModal(id)}
 | 
				
			||||||
 | 
					                                type={"submit"}
 | 
				
			||||||
 | 
					                                variant={"default"}
 | 
				
			||||||
 | 
					                            >Сохранить и закрыть</Button> :
 | 
				
			||||||
 | 
					                            <>
 | 
				
			||||||
 | 
					                                <Button
 | 
				
			||||||
 | 
					                                    onClick={() => context.closeContextModal(id)}
 | 
				
			||||||
 | 
					                                    type={"submit"}
 | 
				
			||||||
 | 
					                                    variant={"default"}
 | 
				
			||||||
 | 
					                                >Создать и закрыть</Button>
 | 
				
			||||||
 | 
					                                <Button
 | 
				
			||||||
 | 
					                                    type={"submit"}
 | 
				
			||||||
 | 
					                                    variant={"default"}
 | 
				
			||||||
 | 
					                                >Создать</Button>
 | 
				
			||||||
 | 
					                            </>}
 | 
				
			||||||
 | 
					                    </Flex>
 | 
				
			||||||
 | 
					                </Flex>
 | 
				
			||||||
 | 
					            </form>
 | 
				
			||||||
 | 
					        </>
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					export default CreateProductModal;
 | 
				
			||||||
							
								
								
									
										6
									
								
								src/pages/ProductsPage/types.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/pages/ProductsPage/types.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					export type BaseProduct = {
 | 
				
			||||||
 | 
					    name: string;
 | 
				
			||||||
 | 
					    article: string;
 | 
				
			||||||
 | 
					    barcodes: string[];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					export type CreateProductRequest = BaseProduct & { clientId: number }
 | 
				
			||||||
@@ -1,37 +1,83 @@
 | 
				
			|||||||
import PageBlock from "../../../components/PageBlock/PageBlock.tsx";
 | 
					import PageBlock from "../../../components/PageBlock/PageBlock.tsx";
 | 
				
			||||||
import {FC, useEffect, useState} from "react";
 | 
					import {FC, useEffect, useState} from "react";
 | 
				
			||||||
import styles from './ProductsPage.module.css';
 | 
					import styles from './ProductsPage.module.css';
 | 
				
			||||||
import {Button, Drawer, Pagination} from "@mantine/core";
 | 
					import {Button, Text, Pagination} from "@mantine/core";
 | 
				
			||||||
import {useDisclosure, usePagination} from "@mantine/hooks";
 | 
					 | 
				
			||||||
import ClientSelect from "../../../components/Selects/ClientSelect/ClientSelect.tsx";
 | 
					import ClientSelect from "../../../components/Selects/ClientSelect/ClientSelect.tsx";
 | 
				
			||||||
import ProductsTable from "../components/ProductsTable/ProductsTable.tsx";
 | 
					import ProductsTable from "../components/ProductsTable/ProductsTable.tsx";
 | 
				
			||||||
import useProductsList from "../hooks/useProductsList.tsx";
 | 
					import useProductsList from "../hooks/useProductsList.tsx";
 | 
				
			||||||
import {notifications} from "../../../shared/lib/notifications.ts";
 | 
					 | 
				
			||||||
import {modals} from "@mantine/modals";
 | 
					import {modals} from "@mantine/modals";
 | 
				
			||||||
 | 
					import {notifications} from "../../../shared/lib/notifications.ts";
 | 
				
			||||||
 | 
					import {CreateProductRequest} from "../types.ts";
 | 
				
			||||||
 | 
					import {ProductSchema, ProductService} from "../../../client";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ProductsPage: FC = () => {
 | 
					export const ProductsPage: FC = () => {
 | 
				
			||||||
    // const [opened, {open, close}] = useDisclosure(false);
 | 
					 | 
				
			||||||
    const [clientId, setClientId] = useState(-1);
 | 
					    const [clientId, setClientId] = useState(-1);
 | 
				
			||||||
    const [totalPages, setTotalPages] = useState(1);
 | 
					    const [totalPages, setTotalPages] = useState(1);
 | 
				
			||||||
    const pagination = usePagination({total: totalPages});
 | 
					    const [currentPage, setCurrentPage] = useState(1);
 | 
				
			||||||
    const {products, paginationInfo} = useProductsList({
 | 
					
 | 
				
			||||||
 | 
					    const {products, paginationInfo, refetch} = useProductsList({
 | 
				
			||||||
        clientId,
 | 
					        clientId,
 | 
				
			||||||
        page: pagination.active - 1,
 | 
					        page: currentPage - 1,
 | 
				
			||||||
        itemsPerPage: 10
 | 
					        itemsPerPage: 10
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					    const onProductCreate = (request: CreateProductRequest) => {
 | 
				
			||||||
 | 
					        ProductService.createProduct({requestBody: request})
 | 
				
			||||||
 | 
					            .then(async ({ok, message}) => {
 | 
				
			||||||
 | 
					                notifications.guess(ok, {message: message});
 | 
				
			||||||
 | 
					                if (!ok) return;
 | 
				
			||||||
 | 
					                await refetch();
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const onProductChange = (product: ProductSchema) => {
 | 
				
			||||||
 | 
					        ProductService.updateProduct({requestBody: {product}})
 | 
				
			||||||
 | 
					            .then(async ({ok, message}) => {
 | 
				
			||||||
 | 
					                notifications.guess(ok, {message});
 | 
				
			||||||
 | 
					                if (!ok) return;
 | 
				
			||||||
 | 
					                await refetch();
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const onCreateProductClick = () => {
 | 
					    const onCreateProductClick = () => {
 | 
				
			||||||
 | 
					        if (clientId < 0) {
 | 
				
			||||||
 | 
					            notifications.error({message: "Необходимо выбрать клиента"});
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        modals.openContextModal({
 | 
					        modals.openContextModal({
 | 
				
			||||||
            modal: "createProduct",
 | 
					            modal: "createProduct",
 | 
				
			||||||
            title: 'Создание категории',
 | 
					            title: 'Создание товара',
 | 
				
			||||||
            withCloseButton: false,
 | 
					            withCloseButton: false,
 | 
				
			||||||
            innerProps: {
 | 
					            innerProps: {
 | 
				
			||||||
                clientId
 | 
					                clientId,
 | 
				
			||||||
 | 
					                onCreate: onProductCreate
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const onDeleteClick = (product: ProductSchema) => {
 | 
				
			||||||
 | 
					        modals.openConfirmModal({
 | 
				
			||||||
 | 
					            title: 'Удаление товара',
 | 
				
			||||||
 | 
					            centered: true,
 | 
				
			||||||
 | 
					            children: (
 | 
				
			||||||
 | 
					                <Text size="sm">
 | 
				
			||||||
 | 
					                    Вы уверены что хотите удалить товар {product.name}
 | 
				
			||||||
 | 
					                </Text>
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            labels: {confirm: 'Да', cancel: "Нет"},
 | 
				
			||||||
 | 
					            confirmProps: {color: 'red'},
 | 
				
			||||||
 | 
					            onConfirm: () =>
 | 
				
			||||||
 | 
					                ProductService.deleteProduct({requestBody: {productId: product.id}})
 | 
				
			||||||
 | 
					                    .then(async ({ok, message}) => {
 | 
				
			||||||
 | 
					                        notifications.guess(ok, {message: message});
 | 
				
			||||||
 | 
					                        if (!ok) return;
 | 
				
			||||||
 | 
					                        await refetch();
 | 
				
			||||||
 | 
					                    })
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    useEffect(() => {
 | 
					    useEffect(() => {
 | 
				
			||||||
        if (!paginationInfo) return;
 | 
					        if (!paginationInfo) return;
 | 
				
			||||||
        setTotalPages(paginationInfo.total_pages);
 | 
					        setTotalPages(paginationInfo.totalPages);
 | 
				
			||||||
    }, [paginationInfo]);
 | 
					    }, [paginationInfo]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -50,8 +96,18 @@ export const ProductsPage: FC = () => {
 | 
				
			|||||||
                <PageBlock>
 | 
					                <PageBlock>
 | 
				
			||||||
                    <div className={styles['body-container']}>
 | 
					                    <div className={styles['body-container']}>
 | 
				
			||||||
                        <div className={styles['table-container']}>
 | 
					                        <div className={styles['table-container']}>
 | 
				
			||||||
                            <ProductsTable products={products}/>
 | 
					                            <ProductsTable
 | 
				
			||||||
                            <Pagination className={styles['table-pagination']} total={100}/>
 | 
					                                onChange={onProductChange}
 | 
				
			||||||
 | 
					                                onDelete={onDeleteClick}
 | 
				
			||||||
 | 
					                                items={products}
 | 
				
			||||||
 | 
					                            />
 | 
				
			||||||
 | 
					                            <Pagination
 | 
				
			||||||
 | 
					                                className={styles['table-pagination']}
 | 
				
			||||||
 | 
					                                withEdges
 | 
				
			||||||
 | 
					                                onChange={event => setCurrentPage(event)}
 | 
				
			||||||
 | 
					                                total={totalPages}
 | 
				
			||||||
 | 
					                                value={currentPage}
 | 
				
			||||||
 | 
					                            />
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </PageBlock>
 | 
					                </PageBlock>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,10 +26,10 @@ export const ServicesPage: FC = () => {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    const onCreate = (values: ServiceSchema) => {
 | 
					    const onCreate = (values: ServiceSchema) => {
 | 
				
			||||||
        ServiceService.createService({requestBody: {service: values}})
 | 
					        ServiceService.createService({requestBody: {service: values}})
 | 
				
			||||||
            .then(({ok, message}) => {
 | 
					            .then(async ({ok, message}) => {
 | 
				
			||||||
                notifications.guess(ok, {message: message});
 | 
					                notifications.guess(ok, {message: message});
 | 
				
			||||||
                if (!ok) return;
 | 
					                if (!ok) return;
 | 
				
			||||||
                refetch();
 | 
					                await refetch();
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    const onCreateCategoryClick = () => {
 | 
					    const onCreateCategoryClick = () => {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								src/types/CRUDTable.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/types/CRUDTable.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					import {RefObject} from "react";
 | 
				
			||||||
 | 
					import {BaseTableRef} from "../components/BaseTable/BaseTable.tsx";
 | 
				
			||||||
 | 
					import {MRT_RowData} from "mantine-react-table";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface CRUDTableProps<T extends MRT_RowData> {
 | 
				
			||||||
 | 
					    items: T[];
 | 
				
			||||||
 | 
					    onCreate?: (item: T) => void;
 | 
				
			||||||
 | 
					    onDelete?: (item: T) => void;
 | 
				
			||||||
 | 
					    onChange?: (item: T) => void;
 | 
				
			||||||
 | 
					    tableRef?: RefObject<BaseTableRef<T>>
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
export type QuickDeal = {
 | 
					export type QuickDeal = {
 | 
				
			||||||
    name: string
 | 
					    name: string
 | 
				
			||||||
    client_name: string
 | 
					    clientName: string
 | 
				
			||||||
    client_address: string
 | 
					    clientAddress: string
 | 
				
			||||||
    comment:string
 | 
					    comment:string
 | 
				
			||||||
    acceptance_date: Date
 | 
					    acceptanceDate: Date
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user