feat: creating chats for cards and clients, sending and deleting text messages
This commit is contained in:
		@@ -31,6 +31,7 @@ export type { BaseCardTagSchema } from './models/BaseCardTagSchema';
 | 
			
		||||
export type { BaseEnumListSchema } from './models/BaseEnumListSchema';
 | 
			
		||||
export type { BaseEnumSchema } from './models/BaseEnumSchema';
 | 
			
		||||
export type { BaseMarketplaceSchema } from './models/BaseMarketplaceSchema';
 | 
			
		||||
export type { BaseMessageSchema } from './models/BaseMessageSchema';
 | 
			
		||||
export type { BaseProjectSchema } from './models/BaseProjectSchema';
 | 
			
		||||
export type { BaseShippingWarehouseSchema } from './models/BaseShippingWarehouseSchema';
 | 
			
		||||
export type { BaseStatusSchema } from './models/BaseStatusSchema';
 | 
			
		||||
@@ -114,6 +115,7 @@ export type { CardUpdateServiceQuantityRequest } from './models/CardUpdateServic
 | 
			
		||||
export type { CardUpdateServiceQuantityResponse } from './models/CardUpdateServiceQuantityResponse';
 | 
			
		||||
export type { CardUpdateServiceRequest } from './models/CardUpdateServiceRequest';
 | 
			
		||||
export type { CardUpdateServiceResponse } from './models/CardUpdateServiceResponse';
 | 
			
		||||
export type { ChatSchema } from './models/ChatSchema';
 | 
			
		||||
export type { CityBreakdownFromExcelSchema } from './models/CityBreakdownFromExcelSchema';
 | 
			
		||||
export type { ClientCreateRequest } from './models/ClientCreateRequest';
 | 
			
		||||
export type { ClientCreateResponse } from './models/ClientCreateResponse';
 | 
			
		||||
@@ -142,6 +144,8 @@ export type { CreateCardBillResponse } from './models/CreateCardBillResponse';
 | 
			
		||||
export type { CreateCardGroupRequest } from './models/CreateCardGroupRequest';
 | 
			
		||||
export type { CreateCardsFromExcelRequest } from './models/CreateCardsFromExcelRequest';
 | 
			
		||||
export type { CreateCardsFromExcelResponse } from './models/CreateCardsFromExcelResponse';
 | 
			
		||||
export type { CreateChatRequest } from './models/CreateChatRequest';
 | 
			
		||||
export type { CreateChatResponse } from './models/CreateChatResponse';
 | 
			
		||||
export type { CreateDepartmentRequest } from './models/CreateDepartmentRequest';
 | 
			
		||||
export type { CreateDepartmentResponse } from './models/CreateDepartmentResponse';
 | 
			
		||||
export type { CreateDepartmentSectionRequest } from './models/CreateDepartmentSectionRequest';
 | 
			
		||||
@@ -185,6 +189,7 @@ export type { DeleteDepartmentResponse } from './models/DeleteDepartmentResponse
 | 
			
		||||
export type { DeleteDepartmentSectionResponse } from './models/DeleteDepartmentSectionResponse';
 | 
			
		||||
export type { DeleteMarketplaceRequest } from './models/DeleteMarketplaceRequest';
 | 
			
		||||
export type { DeleteMarketplaceResponse } from './models/DeleteMarketplaceResponse';
 | 
			
		||||
export type { DeleteMessageResponse } from './models/DeleteMessageResponse';
 | 
			
		||||
export type { DeletePalletResponse } from './models/DeletePalletResponse';
 | 
			
		||||
export type { DeletePaymentRecordRequest } from './models/DeletePaymentRecordRequest';
 | 
			
		||||
export type { DeletePaymentRecordResponse } from './models/DeletePaymentRecordResponse';
 | 
			
		||||
@@ -243,11 +248,15 @@ export type { GetBoardsResponse } from './models/GetBoardsResponse';
 | 
			
		||||
export type { GetCardBillById } from './models/GetCardBillById';
 | 
			
		||||
export type { GetCardProductsBarcodesPdfRequest } from './models/GetCardProductsBarcodesPdfRequest';
 | 
			
		||||
export type { GetCardProductsBarcodesPdfResponse } from './models/GetCardProductsBarcodesPdfResponse';
 | 
			
		||||
export type { GetChatRequest } from './models/GetChatRequest';
 | 
			
		||||
export type { GetChatResponse } from './models/GetChatResponse';
 | 
			
		||||
export type { GetClientMarketplacesRequest } from './models/GetClientMarketplacesRequest';
 | 
			
		||||
export type { GetClientMarketplacesResponse } from './models/GetClientMarketplacesResponse';
 | 
			
		||||
export type { GetDepartmentSectionsResponse } from './models/GetDepartmentSectionsResponse';
 | 
			
		||||
export type { GetDepartmentsResponse } from './models/GetDepartmentsResponse';
 | 
			
		||||
export type { GetManagersResponse } from './models/GetManagersResponse';
 | 
			
		||||
export type { GetMessagesRequest } from './models/GetMessagesRequest';
 | 
			
		||||
export type { GetMessagesResponse } from './models/GetMessagesResponse';
 | 
			
		||||
export type { GetPaymentRecordsResponse } from './models/GetPaymentRecordsResponse';
 | 
			
		||||
export type { GetPlannedWorkShiftsResponse } from './models/GetPlannedWorkShiftsResponse';
 | 
			
		||||
export type { GetProductBarcodePdfRequest } from './models/GetProductBarcodePdfRequest';
 | 
			
		||||
@@ -276,6 +285,7 @@ export type { ManageEmployeeRequest } from './models/ManageEmployeeRequest';
 | 
			
		||||
export type { ManageEmployeeResponse } from './models/ManageEmployeeResponse';
 | 
			
		||||
export type { MarketplaceCreateSchema } from './models/MarketplaceCreateSchema';
 | 
			
		||||
export type { MarketplaceSchema } from './models/MarketplaceSchema';
 | 
			
		||||
export type { MessageSchema } from './models/MessageSchema';
 | 
			
		||||
export type { ModuleSchema } from './models/ModuleSchema';
 | 
			
		||||
export type { NotificationChannel } from './models/NotificationChannel';
 | 
			
		||||
export type { OptionalShippingWarehouseSchema } from './models/OptionalShippingWarehouseSchema';
 | 
			
		||||
@@ -328,6 +338,8 @@ export type { ResidualBoxSchema } from './models/ResidualBoxSchema';
 | 
			
		||||
export type { ResidualPalletSchema } from './models/ResidualPalletSchema';
 | 
			
		||||
export type { ResidualProductSchema } from './models/ResidualProductSchema';
 | 
			
		||||
export type { RoleSchema } from './models/RoleSchema';
 | 
			
		||||
export type { SendMessageRequest } from './models/SendMessageRequest';
 | 
			
		||||
export type { SendMessageResponse } from './models/SendMessageResponse';
 | 
			
		||||
export type { ServiceCategoryReorderRequest } from './models/ServiceCategoryReorderRequest';
 | 
			
		||||
export type { ServiceCategoryReorderResponse } from './models/ServiceCategoryReorderResponse';
 | 
			
		||||
export type { ServiceCategorySchema } from './models/ServiceCategorySchema';
 | 
			
		||||
@@ -359,6 +371,8 @@ export type { SwitchTagRequest } from './models/SwitchTagRequest';
 | 
			
		||||
export type { SwitchTagResponse } from './models/SwitchTagResponse';
 | 
			
		||||
export type { SynchronizeMarketplaceRequest } from './models/SynchronizeMarketplaceRequest';
 | 
			
		||||
export type { TaskInfoResponse } from './models/TaskInfoResponse';
 | 
			
		||||
export type { TgGroupSchema } from './models/TgGroupSchema';
 | 
			
		||||
export type { TgUserSchema } from './models/TgUserSchema';
 | 
			
		||||
export type { TimeTrackingData } from './models/TimeTrackingData';
 | 
			
		||||
export type { TimeTrackingRecord } from './models/TimeTrackingRecord';
 | 
			
		||||
export type { TransactionSchemaBase } from './models/TransactionSchemaBase';
 | 
			
		||||
@@ -435,6 +449,7 @@ export { BoardService } from './services/BoardService';
 | 
			
		||||
export { CardService } from './services/CardService';
 | 
			
		||||
export { CardGroupService } from './services/CardGroupService';
 | 
			
		||||
export { CardTagService } from './services/CardTagService';
 | 
			
		||||
export { ChatService } from './services/ChatService';
 | 
			
		||||
export { ClientService } from './services/ClientService';
 | 
			
		||||
export { DepartmentService } from './services/DepartmentService';
 | 
			
		||||
export { MarketplaceService } from './services/MarketplaceService';
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								src/client/models/BaseMessageSchema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/client/models/BaseMessageSchema.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
/* generated using openapi-typescript-codegen -- do not edit */
 | 
			
		||||
/* istanbul ignore file */
 | 
			
		||||
/* tslint:disable */
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
export type BaseMessageSchema = {
 | 
			
		||||
    text: string;
 | 
			
		||||
    chatId: number;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -12,6 +12,7 @@ import type { CardProductSchema } from './CardProductSchema';
 | 
			
		||||
import type { CardServiceSchema } from './CardServiceSchema';
 | 
			
		||||
import type { CardStatusHistorySchema } from './CardStatusHistorySchema';
 | 
			
		||||
import type { CardTagSchema } from './CardTagSchema';
 | 
			
		||||
import type { ChatSchema } from './ChatSchema';
 | 
			
		||||
import type { ClientSchema } from './ClientSchema';
 | 
			
		||||
import type { PalletSchema } from './PalletSchema';
 | 
			
		||||
import type { ShippingWarehouseSchema } from './ShippingWarehouseSchema';
 | 
			
		||||
@@ -42,5 +43,6 @@ export type CardSchema = {
 | 
			
		||||
    employees?: Array<CardEmployeesSchema>;
 | 
			
		||||
    tags?: Array<CardTagSchema>;
 | 
			
		||||
    attributes: Array<CardAttributeSchema>;
 | 
			
		||||
    chat: (ChatSchema | null);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								src/client/models/ChatSchema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/client/models/ChatSchema.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
/* generated using openapi-typescript-codegen -- do not edit */
 | 
			
		||||
/* istanbul ignore file */
 | 
			
		||||
/* tslint:disable */
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
import type { TgGroupSchema } from './TgGroupSchema';
 | 
			
		||||
export type ChatSchema = {
 | 
			
		||||
    id: number;
 | 
			
		||||
    clientId: (number | null);
 | 
			
		||||
    cardId: (number | null);
 | 
			
		||||
    tgGroup: (TgGroupSchema | null);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
/* tslint:disable */
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
import type { BarcodeTemplateSchema } from './BarcodeTemplateSchema';
 | 
			
		||||
import type { ChatSchema } from './ChatSchema';
 | 
			
		||||
import type { ClientDetailsSchema } from './ClientDetailsSchema';
 | 
			
		||||
import type { ResidualBoxSchema } from './ResidualBoxSchema';
 | 
			
		||||
import type { ResidualPalletSchema } from './ResidualPalletSchema';
 | 
			
		||||
@@ -13,6 +14,7 @@ export type ClientDetailedSchema = {
 | 
			
		||||
    barcodeTemplate?: (BarcodeTemplateSchema | null);
 | 
			
		||||
    comment?: (string | null);
 | 
			
		||||
    details?: (ClientDetailsSchema | null);
 | 
			
		||||
    chat?: (ChatSchema | null);
 | 
			
		||||
    pallets?: Array<ResidualPalletSchema>;
 | 
			
		||||
    boxes?: Array<ResidualBoxSchema>;
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
/* tslint:disable */
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
import type { BarcodeTemplateSchema } from './BarcodeTemplateSchema';
 | 
			
		||||
import type { ChatSchema } from './ChatSchema';
 | 
			
		||||
import type { ClientDetailsSchema } from './ClientDetailsSchema';
 | 
			
		||||
export type ClientSchema = {
 | 
			
		||||
    id: number;
 | 
			
		||||
@@ -11,5 +12,6 @@ export type ClientSchema = {
 | 
			
		||||
    barcodeTemplate?: (BarcodeTemplateSchema | null);
 | 
			
		||||
    comment?: (string | null);
 | 
			
		||||
    details?: (ClientDetailsSchema | null);
 | 
			
		||||
    chat?: (ChatSchema | null);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								src/client/models/CreateChatRequest.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/client/models/CreateChatRequest.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
/* generated using openapi-typescript-codegen -- do not edit */
 | 
			
		||||
/* istanbul ignore file */
 | 
			
		||||
/* tslint:disable */
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
export type CreateChatRequest = {
 | 
			
		||||
    clientId: number;
 | 
			
		||||
    cardId: (number | null);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								src/client/models/CreateChatResponse.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/client/models/CreateChatResponse.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
/* generated using openapi-typescript-codegen -- do not edit */
 | 
			
		||||
/* istanbul ignore file */
 | 
			
		||||
/* tslint:disable */
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
export type CreateChatResponse = {
 | 
			
		||||
    ok: boolean;
 | 
			
		||||
    message: string;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								src/client/models/DeleteMessageResponse.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/client/models/DeleteMessageResponse.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
/* generated using openapi-typescript-codegen -- do not edit */
 | 
			
		||||
/* istanbul ignore file */
 | 
			
		||||
/* tslint:disable */
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
export type DeleteMessageResponse = {
 | 
			
		||||
    ok: boolean;
 | 
			
		||||
    message: string;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								src/client/models/GetChatRequest.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/client/models/GetChatRequest.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
/* generated using openapi-typescript-codegen -- do not edit */
 | 
			
		||||
/* istanbul ignore file */
 | 
			
		||||
/* tslint:disable */
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
export type GetChatRequest = {
 | 
			
		||||
    clientId: number;
 | 
			
		||||
    cardId: (number | null);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								src/client/models/GetChatResponse.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/client/models/GetChatResponse.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
/* generated using openapi-typescript-codegen -- do not edit */
 | 
			
		||||
/* istanbul ignore file */
 | 
			
		||||
/* tslint:disable */
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
import type { ChatSchema } from './ChatSchema';
 | 
			
		||||
export type GetChatResponse = {
 | 
			
		||||
    chat: (ChatSchema | null);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								src/client/models/GetMessagesRequest.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/client/models/GetMessagesRequest.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
/* generated using openapi-typescript-codegen -- do not edit */
 | 
			
		||||
/* istanbul ignore file */
 | 
			
		||||
/* tslint:disable */
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
export type GetMessagesRequest = {
 | 
			
		||||
    chatId: number;
 | 
			
		||||
    offset: number;
 | 
			
		||||
    limit: number;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								src/client/models/GetMessagesResponse.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/client/models/GetMessagesResponse.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
/* generated using openapi-typescript-codegen -- do not edit */
 | 
			
		||||
/* istanbul ignore file */
 | 
			
		||||
/* tslint:disable */
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
import type { MessageSchema } from './MessageSchema';
 | 
			
		||||
export type GetMessagesResponse = {
 | 
			
		||||
    messages: Array<MessageSchema>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										14
									
								
								src/client/models/MessageSchema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/client/models/MessageSchema.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
/* generated using openapi-typescript-codegen -- do not edit */
 | 
			
		||||
/* istanbul ignore file */
 | 
			
		||||
/* tslint:disable */
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
import type { TgUserSchema } from './TgUserSchema';
 | 
			
		||||
export type MessageSchema = {
 | 
			
		||||
    text: string;
 | 
			
		||||
    chatId: number;
 | 
			
		||||
    id: number;
 | 
			
		||||
    createdAt: string;
 | 
			
		||||
    tgSender: (TgUserSchema | null);
 | 
			
		||||
    status: string;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								src/client/models/SendMessageRequest.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/client/models/SendMessageRequest.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
/* generated using openapi-typescript-codegen -- do not edit */
 | 
			
		||||
/* istanbul ignore file */
 | 
			
		||||
/* tslint:disable */
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
import type { BaseMessageSchema } from './BaseMessageSchema';
 | 
			
		||||
export type SendMessageRequest = {
 | 
			
		||||
    message: BaseMessageSchema;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								src/client/models/SendMessageResponse.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/client/models/SendMessageResponse.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
/* generated using openapi-typescript-codegen -- do not edit */
 | 
			
		||||
/* istanbul ignore file */
 | 
			
		||||
/* tslint:disable */
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
export type SendMessageResponse = {
 | 
			
		||||
    ok: boolean;
 | 
			
		||||
    message: string;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								src/client/models/TgGroupSchema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/client/models/TgGroupSchema.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
/* generated using openapi-typescript-codegen -- do not edit */
 | 
			
		||||
/* istanbul ignore file */
 | 
			
		||||
/* tslint:disable */
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
export type TgGroupSchema = {
 | 
			
		||||
    tgGroupId: number;
 | 
			
		||||
    tgInviteLink: string;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								src/client/models/TgUserSchema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/client/models/TgUserSchema.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
/* generated using openapi-typescript-codegen -- do not edit */
 | 
			
		||||
/* istanbul ignore file */
 | 
			
		||||
/* tslint:disable */
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
export type TgUserSchema = {
 | 
			
		||||
    id: number;
 | 
			
		||||
    firstName: string;
 | 
			
		||||
    lastName: string;
 | 
			
		||||
    username: string;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										119
									
								
								src/client/services/ChatService.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								src/client/services/ChatService.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,119 @@
 | 
			
		||||
/* generated using openapi-typescript-codegen -- do not edit */
 | 
			
		||||
/* istanbul ignore file */
 | 
			
		||||
/* tslint:disable */
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
import type { CreateChatRequest } from '../models/CreateChatRequest';
 | 
			
		||||
import type { CreateChatResponse } from '../models/CreateChatResponse';
 | 
			
		||||
import type { DeleteMessageResponse } from '../models/DeleteMessageResponse';
 | 
			
		||||
import type { GetChatRequest } from '../models/GetChatRequest';
 | 
			
		||||
import type { GetChatResponse } from '../models/GetChatResponse';
 | 
			
		||||
import type { GetMessagesRequest } from '../models/GetMessagesRequest';
 | 
			
		||||
import type { GetMessagesResponse } from '../models/GetMessagesResponse';
 | 
			
		||||
import type { SendMessageRequest } from '../models/SendMessageRequest';
 | 
			
		||||
import type { SendMessageResponse } from '../models/SendMessageResponse';
 | 
			
		||||
import type { CancelablePromise } from '../core/CancelablePromise';
 | 
			
		||||
import { OpenAPI } from '../core/OpenAPI';
 | 
			
		||||
import { request as __request } from '../core/request';
 | 
			
		||||
export class ChatService {
 | 
			
		||||
    /**
 | 
			
		||||
     * Send Message
 | 
			
		||||
     * @returns SendMessageResponse Successful Response
 | 
			
		||||
     * @throws ApiError
 | 
			
		||||
     */
 | 
			
		||||
    public static sendMessage({
 | 
			
		||||
        requestBody,
 | 
			
		||||
    }: {
 | 
			
		||||
        requestBody: SendMessageRequest,
 | 
			
		||||
    }): CancelablePromise<SendMessageResponse> {
 | 
			
		||||
        return __request(OpenAPI, {
 | 
			
		||||
            method: 'POST',
 | 
			
		||||
            url: '/chat/message',
 | 
			
		||||
            body: requestBody,
 | 
			
		||||
            mediaType: 'application/json',
 | 
			
		||||
            errors: {
 | 
			
		||||
                422: `Validation Error`,
 | 
			
		||||
            },
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Delete Message
 | 
			
		||||
     * @returns DeleteMessageResponse Successful Response
 | 
			
		||||
     * @throws ApiError
 | 
			
		||||
     */
 | 
			
		||||
    public static deleteMessage({
 | 
			
		||||
        messageId,
 | 
			
		||||
    }: {
 | 
			
		||||
        messageId: number,
 | 
			
		||||
    }): CancelablePromise<DeleteMessageResponse> {
 | 
			
		||||
        return __request(OpenAPI, {
 | 
			
		||||
            method: 'DELETE',
 | 
			
		||||
            url: '/chat/message/{message_id}',
 | 
			
		||||
            path: {
 | 
			
		||||
                'message_id': messageId,
 | 
			
		||||
            },
 | 
			
		||||
            errors: {
 | 
			
		||||
                422: `Validation Error`,
 | 
			
		||||
            },
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Get Chat
 | 
			
		||||
     * @returns GetChatResponse Successful Response
 | 
			
		||||
     * @throws ApiError
 | 
			
		||||
     */
 | 
			
		||||
    public static getChat({
 | 
			
		||||
        requestBody,
 | 
			
		||||
    }: {
 | 
			
		||||
        requestBody: GetChatRequest,
 | 
			
		||||
    }): CancelablePromise<GetChatResponse> {
 | 
			
		||||
        return __request(OpenAPI, {
 | 
			
		||||
            method: 'POST',
 | 
			
		||||
            url: '/chat/',
 | 
			
		||||
            body: requestBody,
 | 
			
		||||
            mediaType: 'application/json',
 | 
			
		||||
            errors: {
 | 
			
		||||
                422: `Validation Error`,
 | 
			
		||||
            },
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Create Chat
 | 
			
		||||
     * @returns CreateChatResponse Successful Response
 | 
			
		||||
     * @throws ApiError
 | 
			
		||||
     */
 | 
			
		||||
    public static createChat({
 | 
			
		||||
        requestBody,
 | 
			
		||||
    }: {
 | 
			
		||||
        requestBody: CreateChatRequest,
 | 
			
		||||
    }): CancelablePromise<CreateChatResponse> {
 | 
			
		||||
        return __request(OpenAPI, {
 | 
			
		||||
            method: 'POST',
 | 
			
		||||
            url: '/chat/create',
 | 
			
		||||
            body: requestBody,
 | 
			
		||||
            mediaType: 'application/json',
 | 
			
		||||
            errors: {
 | 
			
		||||
                422: `Validation Error`,
 | 
			
		||||
            },
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Get Messages
 | 
			
		||||
     * @returns GetMessagesResponse Successful Response
 | 
			
		||||
     * @throws ApiError
 | 
			
		||||
     */
 | 
			
		||||
    public static getMessages({
 | 
			
		||||
        requestBody,
 | 
			
		||||
    }: {
 | 
			
		||||
        requestBody: GetMessagesRequest,
 | 
			
		||||
    }): CancelablePromise<GetMessagesResponse> {
 | 
			
		||||
        return __request(OpenAPI, {
 | 
			
		||||
            method: 'POST',
 | 
			
		||||
            url: '/chat/messages',
 | 
			
		||||
            body: requestBody,
 | 
			
		||||
            mediaType: 'application/json',
 | 
			
		||||
            errors: {
 | 
			
		||||
                422: `Validation Error`,
 | 
			
		||||
            },
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										45
									
								
								src/components/ActionIconCopy/ActionIconCopy.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/components/ActionIconCopy/ActionIconCopy.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
import { ActionIcon, rem, Tooltip } from "@mantine/core";
 | 
			
		||||
import { IconCheck, IconCopy } from "@tabler/icons-react";
 | 
			
		||||
import { FC } from "react";
 | 
			
		||||
import { useClipboard } from "@mantine/hooks";
 | 
			
		||||
 | 
			
		||||
type Props = {
 | 
			
		||||
    value: string;
 | 
			
		||||
    onCopiedLabel: string;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const ActionIconCopy: FC<Props> = ({ onCopiedLabel, value }) => {
 | 
			
		||||
    const clipboard = useClipboard();
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <Tooltip
 | 
			
		||||
            label={onCopiedLabel}
 | 
			
		||||
            offset={5}
 | 
			
		||||
            position="bottom"
 | 
			
		||||
            radius="xl"
 | 
			
		||||
            transitionProps={{ duration: 100, transition: "slide-down" }}
 | 
			
		||||
            opened={clipboard.copied}>
 | 
			
		||||
            <ActionIcon
 | 
			
		||||
                variant={"default"}
 | 
			
		||||
                size="lg"
 | 
			
		||||
                onClick={() => {
 | 
			
		||||
                    console.log("AKLSKLSKSM");
 | 
			
		||||
                    return clipboard.copy(value);
 | 
			
		||||
                }}
 | 
			
		||||
            >
 | 
			
		||||
                {clipboard.copied ? (
 | 
			
		||||
                    <IconCheck
 | 
			
		||||
                        style={{ width: rem(20), height: rem(20) }}
 | 
			
		||||
                        stroke={1.5}
 | 
			
		||||
                    />
 | 
			
		||||
                ) : (
 | 
			
		||||
                    <IconCopy
 | 
			
		||||
                        style={{ width: rem(20), height: rem(20) }}
 | 
			
		||||
                        stroke={1.5}
 | 
			
		||||
                    />
 | 
			
		||||
                )}
 | 
			
		||||
            </ActionIcon>
 | 
			
		||||
        </Tooltip>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
export default ActionIconCopy;
 | 
			
		||||
							
								
								
									
										20
									
								
								src/components/Chat/Chat.module.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/components/Chat/Chat.module.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
 | 
			
		||||
.message {
 | 
			
		||||
    @mixin light {
 | 
			
		||||
        background-color: var(--mantine-color-gray-2);
 | 
			
		||||
    }
 | 
			
		||||
    @mixin dark {
 | 
			
		||||
        background-color: var(--mantine-color-dark-5);
 | 
			
		||||
    }
 | 
			
		||||
    border-radius: 1em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.other-message {
 | 
			
		||||
    @mixin light {
 | 
			
		||||
        background-color: var(--mantine-color-gray-3);
 | 
			
		||||
    }
 | 
			
		||||
    @mixin dark {
 | 
			
		||||
        background-color: var(--mantine-color-dark-6);
 | 
			
		||||
    }
 | 
			
		||||
    border-radius: 1em;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								src/components/Chat/Chat.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/components/Chat/Chat.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
import { ScrollArea, Stack } from "@mantine/core";
 | 
			
		||||
import Message from "./components/Message/Message.tsx";
 | 
			
		||||
import MessageInput from "./components/MessageInput/MessageInput.tsx";
 | 
			
		||||
import { useChatContext } from "../../pages/ClientsPage/contexts/ChatContext.tsx";
 | 
			
		||||
import { MessageSchema } from "../../client";
 | 
			
		||||
import { ReactNode } from "react";
 | 
			
		||||
import ChatDate from "./components/ChatDate/ChatDate.tsx";
 | 
			
		||||
 | 
			
		||||
const Chat = () => {
 | 
			
		||||
    const {
 | 
			
		||||
        messages,
 | 
			
		||||
        scrollRef,
 | 
			
		||||
        onScrollPositionChange,
 | 
			
		||||
    } = useChatContext();
 | 
			
		||||
 | 
			
		||||
    const getChatElements = (): ReactNode[] => {
 | 
			
		||||
        const elements: ReactNode[] = [];
 | 
			
		||||
        let prevMessage: MessageSchema | null = null;
 | 
			
		||||
 | 
			
		||||
        for (let i = messages.length - 1; i >= 0; i--) {
 | 
			
		||||
            const currMessage = messages[i];
 | 
			
		||||
 | 
			
		||||
            if (!prevMessage || prevMessage.createdAt.substring(5, 10) != currMessage.createdAt.substring(5, 10)) {
 | 
			
		||||
                elements.push((
 | 
			
		||||
                    <ChatDate
 | 
			
		||||
                        key={currMessage.id + "date"}
 | 
			
		||||
                        date={new Date(currMessage.createdAt)}
 | 
			
		||||
                    />
 | 
			
		||||
                ));
 | 
			
		||||
            }
 | 
			
		||||
            elements.push((
 | 
			
		||||
                <Message key={currMessage.id + "msg"} message={currMessage} />
 | 
			
		||||
            ));
 | 
			
		||||
            prevMessage = currMessage;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return elements;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <Stack>
 | 
			
		||||
            <ScrollArea
 | 
			
		||||
                viewportRef={scrollRef}
 | 
			
		||||
                onScrollPositionChange={onScrollPositionChange}
 | 
			
		||||
            >
 | 
			
		||||
                <Stack h={"91vh"} pr={"md"} gap={"sm"}>
 | 
			
		||||
                    {getChatElements()}
 | 
			
		||||
                </Stack>
 | 
			
		||||
            </ScrollArea>
 | 
			
		||||
            <MessageInput />
 | 
			
		||||
        </Stack>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default Chat;
 | 
			
		||||
							
								
								
									
										20
									
								
								src/components/Chat/components/ChatDate/ChatDate.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/components/Chat/components/ChatDate/ChatDate.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
import { Box, Center, Pill } from "@mantine/core";
 | 
			
		||||
import styles from "../../Chat.module.css";
 | 
			
		||||
 | 
			
		||||
type Props = {
 | 
			
		||||
    date: Date;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const ChatDate = ({ date }: Props) => {
 | 
			
		||||
    return (
 | 
			
		||||
        <Center>
 | 
			
		||||
            <Pill size={"md"} className={styles["message"]}>
 | 
			
		||||
                <Box>
 | 
			
		||||
                    {date.toLocaleDateString("ru-RU", { day: "numeric", month: "long" })}
 | 
			
		||||
                </Box>
 | 
			
		||||
            </Pill>
 | 
			
		||||
        </Center>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default ChatDate;
 | 
			
		||||
							
								
								
									
										78
									
								
								src/components/Chat/components/Message/Message.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								src/components/Chat/components/Message/Message.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
import { MessageSchema } from "../../../../client";
 | 
			
		||||
import { Box, Center, em, Flex, Group, rem } from "@mantine/core";
 | 
			
		||||
import { formatDateTime } from "../../../../types/utils.ts";
 | 
			
		||||
import { IconAlertCircle, IconCheck, IconClock, IconTrash } from "@tabler/icons-react";
 | 
			
		||||
import { useContextMenu } from "mantine-contextmenu";
 | 
			
		||||
import useMessage from "./hooks/useMessage.tsx";
 | 
			
		||||
import styles from "../../Chat.module.css";
 | 
			
		||||
import classNames from "classnames";
 | 
			
		||||
 | 
			
		||||
type Props = {
 | 
			
		||||
    message: MessageSchema;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum MessageStatuses {
 | 
			
		||||
    SUCCESS = "SUCCESS",
 | 
			
		||||
    ERROR = "ERROR",
 | 
			
		||||
    SENDING = "SENDING",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Message = ({ message }: Props) => {
 | 
			
		||||
    const isMine = !message.tgSender;
 | 
			
		||||
    const isSuccess = message.status == MessageStatuses.SUCCESS;
 | 
			
		||||
    const { onDeleteMessageClick } = useMessage();
 | 
			
		||||
    const { showContextMenu } = useContextMenu();
 | 
			
		||||
 | 
			
		||||
    const contextMenu = () => showContextMenu([
 | 
			
		||||
        {
 | 
			
		||||
            key: "delete",
 | 
			
		||||
            onClick: () => onDeleteMessageClick(message),
 | 
			
		||||
            title: "Удалить",
 | 
			
		||||
            icon: <IconTrash />,
 | 
			
		||||
        },
 | 
			
		||||
    ]);
 | 
			
		||||
 | 
			
		||||
    const getStatusIcon = () => {
 | 
			
		||||
        const size = em(18);
 | 
			
		||||
        if (message.status == MessageStatuses.ERROR) {
 | 
			
		||||
            return <IconAlertCircle size={size} />;
 | 
			
		||||
        }
 | 
			
		||||
        if (message.status == MessageStatuses.SENDING) {
 | 
			
		||||
            return <IconClock size={size} />;
 | 
			
		||||
        }
 | 
			
		||||
        return <IconCheck size={size} />;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <Flex justify={isMine ? "flex-end" : "flex-start"}>
 | 
			
		||||
            <Box
 | 
			
		||||
                py={rem(5)}
 | 
			
		||||
                px={rem(15)}
 | 
			
		||||
                className={classNames(isMine ? styles["message"] : styles["other-message"])}
 | 
			
		||||
                onContextMenu={isMine && isSuccess ? contextMenu() : undefined}
 | 
			
		||||
            >
 | 
			
		||||
                {!isMine && (
 | 
			
		||||
                    <div>{message.tgSender!.lastName} {message.tgSender!.firstName}</div>
 | 
			
		||||
                )}
 | 
			
		||||
                <div>{message.text}</div>
 | 
			
		||||
                <Group
 | 
			
		||||
                    gap={em(5)}
 | 
			
		||||
                    justify={"flex-end"}
 | 
			
		||||
                    align={"center"}
 | 
			
		||||
                    wrap={"nowrap"}
 | 
			
		||||
                >
 | 
			
		||||
                    <Center>
 | 
			
		||||
                        {formatDateTime(message.createdAt).substring(11, 16)}
 | 
			
		||||
                    </Center>
 | 
			
		||||
                    {isMine && (
 | 
			
		||||
                        <Center>
 | 
			
		||||
                            {getStatusIcon()}
 | 
			
		||||
                        </Center>
 | 
			
		||||
                    )}
 | 
			
		||||
                </Group>
 | 
			
		||||
            </Box>
 | 
			
		||||
        </Flex>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default Message;
 | 
			
		||||
							
								
								
									
										23
									
								
								src/components/Chat/components/Message/hooks/useMessage.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/components/Chat/components/Message/hooks/useMessage.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
import { ChatService, MessageSchema } from "../../../../../client";
 | 
			
		||||
import { notifications } from "../../../../../shared/lib/notifications.ts";
 | 
			
		||||
 | 
			
		||||
const useMessage = () => {
 | 
			
		||||
 | 
			
		||||
    const onDeleteMessageClick = (message: MessageSchema) => {
 | 
			
		||||
        ChatService.deleteMessage({
 | 
			
		||||
            messageId: message.id,
 | 
			
		||||
        })
 | 
			
		||||
            .then(({ ok, message }) => {
 | 
			
		||||
                if (!ok) {
 | 
			
		||||
                    notifications.error({ message });
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .catch(err => console.log(err));
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        onDeleteMessageClick,
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default useMessage;
 | 
			
		||||
							
								
								
									
										45
									
								
								src/components/Chat/components/MessageInput/MessageInput.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/components/Chat/components/MessageInput/MessageInput.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
import { Button, Group, TextInput, Tooltip } from "@mantine/core";
 | 
			
		||||
import { IconSend2 } from "@tabler/icons-react";
 | 
			
		||||
import { useChatContext } from "../../../../pages/ClientsPage/contexts/ChatContext.tsx";
 | 
			
		||||
import { useForm } from "@mantine/form";
 | 
			
		||||
import ActionIconCopy from "../../../ActionIconCopy/ActionIconCopy.tsx";
 | 
			
		||||
 | 
			
		||||
export type MessageForm = {
 | 
			
		||||
    message: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const MessageInput = () => {
 | 
			
		||||
    const { sendMessage, chat } = useChatContext();
 | 
			
		||||
    const form = useForm<MessageForm>({
 | 
			
		||||
        initialValues: {
 | 
			
		||||
            message: "",
 | 
			
		||||
        },
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <form onSubmit={form.onSubmit(values => sendMessage(values, form))}>
 | 
			
		||||
            <Group wrap={"nowrap"} align={"center"}>
 | 
			
		||||
                {chat?.tgGroup?.tgInviteLink && (
 | 
			
		||||
                    <Tooltip label={"Ссылка-приглашение"}>
 | 
			
		||||
                        <ActionIconCopy
 | 
			
		||||
                            onCopiedLabel={"Ссылка скопирована в буфер обмена"}
 | 
			
		||||
                            value={chat.tgGroup.tgInviteLink}
 | 
			
		||||
                        />
 | 
			
		||||
                    </Tooltip>
 | 
			
		||||
                )}
 | 
			
		||||
                <TextInput
 | 
			
		||||
                    {...form.getInputProps("message")}
 | 
			
		||||
                    w={"100%"}
 | 
			
		||||
                />
 | 
			
		||||
                <Button
 | 
			
		||||
                    variant={"default"}
 | 
			
		||||
                    type="submit"
 | 
			
		||||
                >
 | 
			
		||||
                    <IconSend2 />
 | 
			
		||||
                </Button>
 | 
			
		||||
            </Group>
 | 
			
		||||
        </form>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default MessageInput;
 | 
			
		||||
							
								
								
									
										33
									
								
								src/modules/cardModules/cardEditorTabs/ChatTab/ChatTab.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/modules/cardModules/cardEditorTabs/ChatTab/ChatTab.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
import { ChatContextProvider } from "../../../../pages/ClientsPage/contexts/ChatContext.tsx";
 | 
			
		||||
import ChatWrapper from "./components/ChatWrapper.tsx";
 | 
			
		||||
import { useCardPageContext } from "../../../../pages/CardsPage/contexts/CardPageContext.tsx";
 | 
			
		||||
import { Stack } from "@mantine/core";
 | 
			
		||||
import InlineButton from "../../../../components/InlineButton/InlineButton.tsx";
 | 
			
		||||
import { IconMessagePlus } from "@tabler/icons-react";
 | 
			
		||||
import useChatTab from "./hooks/useChatTab.tsx";
 | 
			
		||||
 | 
			
		||||
const ChatTab = () => {
 | 
			
		||||
    const { selectedCard } = useCardPageContext();
 | 
			
		||||
    const { onChatCreateClick } = useChatTab();
 | 
			
		||||
 | 
			
		||||
    if (!selectedCard?.chat) {
 | 
			
		||||
        return (
 | 
			
		||||
            <Stack>
 | 
			
		||||
                <InlineButton
 | 
			
		||||
                    onClick={onChatCreateClick}
 | 
			
		||||
                >
 | 
			
		||||
                    <IconMessagePlus />
 | 
			
		||||
                    Создать чат
 | 
			
		||||
                </InlineButton>
 | 
			
		||||
            </Stack>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <ChatContextProvider>
 | 
			
		||||
            <ChatWrapper />
 | 
			
		||||
        </ChatContextProvider>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default ChatTab;
 | 
			
		||||
@@ -0,0 +1,21 @@
 | 
			
		||||
import { useChatContext } from "../../../../../pages/ClientsPage/contexts/ChatContext.tsx";
 | 
			
		||||
import { useEffect } from "react";
 | 
			
		||||
import { useCardPageContext } from "../../../../../pages/CardsPage/contexts/CardPageContext.tsx";
 | 
			
		||||
import Chat from "../../../../../components/Chat/Chat.tsx";
 | 
			
		||||
 | 
			
		||||
const ChatWrapper = () => {
 | 
			
		||||
    const { setChat } = useChatContext();
 | 
			
		||||
    const { selectedCard } = useCardPageContext();
 | 
			
		||||
 | 
			
		||||
    if (!selectedCard) return;
 | 
			
		||||
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        setChat(selectedCard.chat);
 | 
			
		||||
    }, []);
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <Chat />
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default ChatWrapper;
 | 
			
		||||
@@ -0,0 +1,49 @@
 | 
			
		||||
import { notifications } from "../../../../../shared/lib/notifications.ts";
 | 
			
		||||
import { ChatService } from "../../../../../client";
 | 
			
		||||
import { modals } from "@mantine/modals";
 | 
			
		||||
import { Text } from "@mantine/core";
 | 
			
		||||
import { useCardPageContext } from "../../../../../pages/CardsPage/contexts/CardPageContext.tsx";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const useChatTab = () => {
 | 
			
		||||
    const { selectedCard, refetchCard } = useCardPageContext();
 | 
			
		||||
 | 
			
		||||
    const createChat = () => {
 | 
			
		||||
        if (!selectedCard?.clientId) {
 | 
			
		||||
            notifications.error({ message: "Ошибка создания чата, не указан клиент" });
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ChatService.createChat({
 | 
			
		||||
            requestBody: {
 | 
			
		||||
                clientId: selectedCard.clientId,
 | 
			
		||||
                cardId: selectedCard.id,
 | 
			
		||||
            },
 | 
			
		||||
        })
 | 
			
		||||
            .then(({ ok, message }) => {
 | 
			
		||||
                notifications.guess(ok, { message });
 | 
			
		||||
                refetchCard();
 | 
			
		||||
            })
 | 
			
		||||
            .catch(err => console.log(err));
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const onChatCreateClick = () => {
 | 
			
		||||
        modals.openConfirmModal({
 | 
			
		||||
            title: "Создание чата",
 | 
			
		||||
            children: (
 | 
			
		||||
                <Text size="sm">
 | 
			
		||||
                    Вы уверены что хотите создать чат для сделки {selectedCard?.name}?
 | 
			
		||||
                </Text>
 | 
			
		||||
            ),
 | 
			
		||||
            labels: { confirm: "Да", cancel: "Нет" },
 | 
			
		||||
            confirmProps: { color: "green" },
 | 
			
		||||
            onConfirm: createChat,
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        onChatCreateClick,
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default useChatTab;
 | 
			
		||||
@@ -128,16 +128,18 @@ const ClientTab = () => {
 | 
			
		||||
                        value={client}
 | 
			
		||||
                        onChange={setClient}
 | 
			
		||||
                        withLabel
 | 
			
		||||
                        disabled={!isEqual(initialValues, form.values)}
 | 
			
		||||
                        disabled={!isEqual(initialValues, form.values) || !!card?.chat}
 | 
			
		||||
                    />
 | 
			
		||||
                    <Group>
 | 
			
		||||
                        <InlineButton
 | 
			
		||||
                            onClick={handleSelectClient}
 | 
			
		||||
                            disabled={!isEditorDisabled()}
 | 
			
		||||
                        >
 | 
			
		||||
                            Сохранить
 | 
			
		||||
                        </InlineButton>
 | 
			
		||||
                    </Group>
 | 
			
		||||
                    {!card?.chat && (
 | 
			
		||||
                        <Group>
 | 
			
		||||
                            <InlineButton
 | 
			
		||||
                                onClick={handleSelectClient}
 | 
			
		||||
                                disabled={!isEditorDisabled()}
 | 
			
		||||
                            >
 | 
			
		||||
                                Сохранить
 | 
			
		||||
                            </InlineButton>
 | 
			
		||||
                        </Group>
 | 
			
		||||
                    )}
 | 
			
		||||
                </Stack>
 | 
			
		||||
            </Fieldset>
 | 
			
		||||
            {clientDataEditor}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import ProductAndServiceTab from "./cardModules/cardEditorTabs/ProductAndService
 | 
			
		||||
import EmployeesTab from "./cardModules/cardEditorTabs/EmployeesTab/EmployeesTab.tsx";
 | 
			
		||||
import ShippingTab from "./cardModules/cardEditorTabs/ShippingTab/ShippingTab.tsx";
 | 
			
		||||
import ManagerTab from "./cardModules/cardEditorTabs/ManagersTab/ManagersTab.tsx";
 | 
			
		||||
import ChatTab from "./cardModules/cardEditorTabs/ChatTab/ChatTab.tsx";
 | 
			
		||||
 | 
			
		||||
const connectModules = (modules: ModulesType) => {
 | 
			
		||||
 | 
			
		||||
@@ -13,6 +14,7 @@ const connectModules = (modules: ModulesType) => {
 | 
			
		||||
    modules[ModuleNames.EMPLOYEES].tab = <EmployeesTab />;
 | 
			
		||||
    modules[ModuleNames.SHIPMENT].tab = <ShippingTab />;
 | 
			
		||||
    modules[ModuleNames.MANAGERS].tab = <ManagerTab />;
 | 
			
		||||
    modules[ModuleNames.CHAT].tab = <ChatTab />;
 | 
			
		||||
 | 
			
		||||
    return modules;
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import {
 | 
			
		||||
    IconCubeSend,
 | 
			
		||||
    IconUsersGroup,
 | 
			
		||||
    IconUserCog,
 | 
			
		||||
    IconMessage,
 | 
			
		||||
} from "@tabler/icons-react";
 | 
			
		||||
import ModulesType from "./types.tsx";
 | 
			
		||||
import connectModules from "./connectModules.tsx";
 | 
			
		||||
@@ -14,6 +15,7 @@ export enum ModuleNames {
 | 
			
		||||
    SHIPMENT = "shipment",
 | 
			
		||||
    EMPLOYEES = "employees",
 | 
			
		||||
    MANAGERS = "managers",
 | 
			
		||||
    CHAT = "chat",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const modules: ModulesType = {
 | 
			
		||||
@@ -52,6 +54,13 @@ const modules: ModulesType = {
 | 
			
		||||
            icon: <IconUserCog />,
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    [ModuleNames.CHAT]: {
 | 
			
		||||
        info: {
 | 
			
		||||
            label: "Чат",
 | 
			
		||||
            key: "chat",
 | 
			
		||||
            icon: <IconMessage />,
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const MODULES = connectModules(modules);
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,8 @@ import { Button } from "@mantine/core";
 | 
			
		||||
import { modals } from "@mantine/modals";
 | 
			
		||||
import { ClientSchema, ClientService } from "../../client";
 | 
			
		||||
import { notifications } from "../../shared/lib/notifications.ts";
 | 
			
		||||
import { ChatContextProvider } from "./contexts/ChatContext.tsx";
 | 
			
		||||
import ClientChatDrawer from "./drawers/ClientChatDrawer.tsx";
 | 
			
		||||
 | 
			
		||||
const ClientsPage: FC = () => {
 | 
			
		||||
    const { clients, refetch } = useClientsList();
 | 
			
		||||
@@ -62,11 +64,15 @@ const ClientsPage: FC = () => {
 | 
			
		||||
                </div>
 | 
			
		||||
            </PageBlock>
 | 
			
		||||
            <PageBlock>
 | 
			
		||||
                <ClientsTable
 | 
			
		||||
                    onChange={onChange}
 | 
			
		||||
                    onDelete={onDelete}
 | 
			
		||||
                    items={clients}
 | 
			
		||||
                />
 | 
			
		||||
                <ChatContextProvider>
 | 
			
		||||
                    <ClientsTable
 | 
			
		||||
                        onChange={onChange}
 | 
			
		||||
                        onDelete={onDelete}
 | 
			
		||||
                        items={clients}
 | 
			
		||||
                        refetch={refetch}
 | 
			
		||||
                    />
 | 
			
		||||
                    <ClientChatDrawer />
 | 
			
		||||
                </ChatContextProvider>
 | 
			
		||||
            </PageBlock>
 | 
			
		||||
        </div>
 | 
			
		||||
    );
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,68 @@
 | 
			
		||||
import { ChatService, ClientSchema } from "../../../../client";
 | 
			
		||||
import { ActionIcon, Text, Tooltip } from "@mantine/core";
 | 
			
		||||
import { IconMessage, IconMessagePlus } from "@tabler/icons-react";
 | 
			
		||||
import { useChatContext } from "../../contexts/ChatContext.tsx";
 | 
			
		||||
import { modals } from "@mantine/modals";
 | 
			
		||||
import { notifications } from "../../../../shared/lib/notifications.ts";
 | 
			
		||||
 | 
			
		||||
type Props = {
 | 
			
		||||
    client: ClientSchema;
 | 
			
		||||
    refetch: () => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const ClientChatButton = ({ client, refetch }: Props) => {
 | 
			
		||||
    const { setChat } = useChatContext();
 | 
			
		||||
 | 
			
		||||
    const createChat = () => {
 | 
			
		||||
        console.log("Creating chat")
 | 
			
		||||
        ChatService.createChat({
 | 
			
		||||
            requestBody: {
 | 
			
		||||
                clientId: client.id,
 | 
			
		||||
                cardId: null,
 | 
			
		||||
            },
 | 
			
		||||
        })
 | 
			
		||||
            .then(({ ok, message }) => {
 | 
			
		||||
                notifications.guess(ok, { message });
 | 
			
		||||
                refetch();
 | 
			
		||||
            })
 | 
			
		||||
            .catch(err => console.log(err));
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const onCreateChatClick = () => {
 | 
			
		||||
        modals.openConfirmModal({
 | 
			
		||||
            title: "Создание чата",
 | 
			
		||||
            children: (
 | 
			
		||||
                <Text size="sm">
 | 
			
		||||
                    Вы уверены что хотите создать чат с {client.name}?
 | 
			
		||||
                </Text>
 | 
			
		||||
            ),
 | 
			
		||||
            labels: { confirm: "Да", cancel: "Нет" },
 | 
			
		||||
            confirmProps: { color: "green" },
 | 
			
		||||
            onConfirm: createChat,
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if (client.chat) {
 | 
			
		||||
        return (
 | 
			
		||||
            <Tooltip label="Открыть чат">
 | 
			
		||||
                <ActionIcon
 | 
			
		||||
                    onClick={() => setChat(client.chat!)}
 | 
			
		||||
                    variant={"default"}>
 | 
			
		||||
                    <IconMessage />
 | 
			
		||||
                </ActionIcon>
 | 
			
		||||
            </Tooltip>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <Tooltip label="Создать чат">
 | 
			
		||||
            <ActionIcon
 | 
			
		||||
                onClick={onCreateChatClick}
 | 
			
		||||
                variant={"default"}>
 | 
			
		||||
                <IconMessagePlus />
 | 
			
		||||
            </ActionIcon>
 | 
			
		||||
        </Tooltip>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default ClientChatButton;
 | 
			
		||||
@@ -7,13 +7,20 @@ 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";
 | 
			
		||||
import ClientChatButton from "../ClientChatButton/ClientChatButton.tsx";
 | 
			
		||||
 | 
			
		||||
const ClientsTable: FC<CRUDTableProps<ClientSchema>> = ({
 | 
			
		||||
    items,
 | 
			
		||||
    onDelete,
 | 
			
		||||
    onChange,
 | 
			
		||||
}) => {
 | 
			
		||||
type RefetchProps = {
 | 
			
		||||
    refetch: () => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const ClientsTable: FC<CRUDTableProps<ClientSchema> & RefetchProps> = ({
 | 
			
		||||
                                                                           items,
 | 
			
		||||
                                                                           onDelete,
 | 
			
		||||
                                                                           onChange,
 | 
			
		||||
                                                                           refetch,
 | 
			
		||||
                                                                       }) => {
 | 
			
		||||
    const columns = useClientsTableColumns();
 | 
			
		||||
 | 
			
		||||
    const onEditClick = (client: ClientSchema) => {
 | 
			
		||||
        if (!onChange) return;
 | 
			
		||||
        modals.openContextModal({
 | 
			
		||||
@@ -26,6 +33,7 @@ const ClientsTable: FC<CRUDTableProps<ClientSchema>> = ({
 | 
			
		||||
            },
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <>
 | 
			
		||||
            <BaseTable
 | 
			
		||||
@@ -38,6 +46,7 @@ const ClientsTable: FC<CRUDTableProps<ClientSchema>> = ({
 | 
			
		||||
                        enableRowActions: true,
 | 
			
		||||
                        renderRowActions: ({ row }) => (
 | 
			
		||||
                            <Flex gap="md">
 | 
			
		||||
                                <ClientChatButton client={row.original} refetch={refetch}/>
 | 
			
		||||
                                <Tooltip label="Редактировать">
 | 
			
		||||
                                    <ActionIcon
 | 
			
		||||
                                        onClick={() =>
 | 
			
		||||
@@ -50,8 +59,7 @@ const ClientsTable: FC<CRUDTableProps<ClientSchema>> = ({
 | 
			
		||||
                                <Tooltip label="Удалить">
 | 
			
		||||
                                    <ActionIcon
 | 
			
		||||
                                        onClick={() => {
 | 
			
		||||
                                            if (onDelete)
 | 
			
		||||
                                                onDelete(row.original);
 | 
			
		||||
                                            if (onDelete) onDelete(row.original);
 | 
			
		||||
                                        }}
 | 
			
		||||
                                        variant={"default"}>
 | 
			
		||||
                                        <IconTrash />
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										161
									
								
								src/pages/ClientsPage/contexts/ChatContext.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								src/pages/ClientsPage/contexts/ChatContext.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,161 @@
 | 
			
		||||
import React, { createContext, FC, MutableRefObject, useContext, useEffect, useRef, useState } from "react";
 | 
			
		||||
import { ChatSchema, ChatService, MessageSchema } from "../../../client";
 | 
			
		||||
import { notifications } from "../../../shared/lib/notifications.ts";
 | 
			
		||||
import { MessageForm } from "../../../components/Chat/components/MessageInput/MessageInput.tsx";
 | 
			
		||||
import { UseFormReturnType } from "@mantine/form";
 | 
			
		||||
import { useDebouncedState } from "@mantine/hooks";
 | 
			
		||||
 | 
			
		||||
type ChatContextState = {
 | 
			
		||||
    chat: ChatSchema | null;
 | 
			
		||||
    setChat: (chat: ChatSchema | null) => void;
 | 
			
		||||
    messages: MessageSchema[];
 | 
			
		||||
    onScrollPositionChange: (values: { x: number, y: number }) => void;
 | 
			
		||||
    scrollRef: MutableRefObject<HTMLDivElement | null>;
 | 
			
		||||
    sendMessage: (values: MessageForm, form: UseFormReturnType<MessageForm>) => void;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const ChatContext = createContext<ChatContextState | undefined>(undefined);
 | 
			
		||||
 | 
			
		||||
const useChatContextState = () => {
 | 
			
		||||
    const [chat, setChat] = useState<ChatSchema | null>(null);
 | 
			
		||||
    const [messages, setMessages] = useState<MessageSchema[]>([]);
 | 
			
		||||
    const [offset, setOffset] = useState(0);
 | 
			
		||||
    const limit = 20;
 | 
			
		||||
    const [hasMore, setHasMore] = useState(true);
 | 
			
		||||
    const scrollRef = useRef<HTMLDivElement | null>(null);
 | 
			
		||||
    const [isScrollToBottom, setIsScrollToBottom] = useState(true);
 | 
			
		||||
    const [scrollPosition, setScrollPosition] = useDebouncedState<{ x: number, y: number }>({ x: 0, y: 0 }, 400);
 | 
			
		||||
 | 
			
		||||
    const setChatValue = (chat: ChatSchema | null) => {
 | 
			
		||||
        if (chat) {
 | 
			
		||||
            setOffset(0);
 | 
			
		||||
            setHasMore(true);
 | 
			
		||||
            setScrollPosition({ x: 0, y: 0 });
 | 
			
		||||
        }
 | 
			
		||||
        setChat(chat);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    console.log(`has more = ${hasMore}`);
 | 
			
		||||
 | 
			
		||||
    const fetchMessages = () => {
 | 
			
		||||
        if (!chat) return;
 | 
			
		||||
 | 
			
		||||
        ChatService.getMessages({
 | 
			
		||||
            requestBody: {
 | 
			
		||||
                chatId: chat.id,
 | 
			
		||||
                offset,
 | 
			
		||||
                limit,
 | 
			
		||||
            },
 | 
			
		||||
        })
 | 
			
		||||
            .then(({ messages: newMessages }) => {
 | 
			
		||||
                if (newMessages.length < limit) setHasMore(false);
 | 
			
		||||
                setMessages([...newMessages]);
 | 
			
		||||
                setOffset((prev) => prev + limit);
 | 
			
		||||
            })
 | 
			
		||||
            .catch(err => console.log(err));
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const fetchMessagesOnScroll = () => {
 | 
			
		||||
        if (!chat) return;
 | 
			
		||||
 | 
			
		||||
        ChatService.getMessages({
 | 
			
		||||
            requestBody: {
 | 
			
		||||
                chatId: chat.id,
 | 
			
		||||
                offset,
 | 
			
		||||
                limit,
 | 
			
		||||
            },
 | 
			
		||||
        })
 | 
			
		||||
            .then(({ messages: newMessages }) => {
 | 
			
		||||
                console.log(newMessages);
 | 
			
		||||
                if (newMessages.length < limit) setHasMore(false);
 | 
			
		||||
                setMessages((prev) => [...prev, ...newMessages]);
 | 
			
		||||
                setOffset((prev) => prev + limit);
 | 
			
		||||
                if (scrollRef.current) {
 | 
			
		||||
                    console.log("FETCH ON SCROLL")
 | 
			
		||||
                    const prevPosition = limit / offset * scrollRef.current.scrollHeight;
 | 
			
		||||
                    console.log(`PREV POSITION = ${prevPosition}`)
 | 
			
		||||
                    scrollRef.current.scrollTo({ top: prevPosition, behavior: "instant" });
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .catch(err => console.log(err));
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        fetchMessages();
 | 
			
		||||
 | 
			
		||||
        const interval = setInterval(fetchMessages, 2000);
 | 
			
		||||
 | 
			
		||||
        return () => clearInterval(interval);
 | 
			
		||||
    }, [chat]);
 | 
			
		||||
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        if (scrollRef.current && isScrollToBottom && chat) {
 | 
			
		||||
            setIsScrollToBottom(false);
 | 
			
		||||
            console.log("Scroll to the bottom");
 | 
			
		||||
            console.log(`scrollHeight = ${scrollRef.current.scrollHeight}`);
 | 
			
		||||
            scrollRef.current.scrollTo({ top: scrollRef.current.scrollHeight, behavior: "smooth" });
 | 
			
		||||
        }
 | 
			
		||||
    }, [messages, isScrollToBottom]);
 | 
			
		||||
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        if (!chat) return;
 | 
			
		||||
        console.log(`handleScroll ${Math.abs(scrollPosition.y - 200)}`);
 | 
			
		||||
        if (Math.abs(scrollPosition.y - 200) <= 200 && hasMore) {
 | 
			
		||||
            console.log("handleScroll WORK");
 | 
			
		||||
            fetchMessagesOnScroll();
 | 
			
		||||
        }
 | 
			
		||||
    }, [scrollPosition]);
 | 
			
		||||
 | 
			
		||||
    const sendMessage = (values: MessageForm, form: UseFormReturnType<MessageForm>) => {
 | 
			
		||||
        if (!chat) return;
 | 
			
		||||
 | 
			
		||||
        ChatService.sendMessage({
 | 
			
		||||
            requestBody: {
 | 
			
		||||
                message: {
 | 
			
		||||
                    text: values.message,
 | 
			
		||||
                    chatId: chat.id,
 | 
			
		||||
                },
 | 
			
		||||
            },
 | 
			
		||||
        })
 | 
			
		||||
            .then(({ ok, message }) => {
 | 
			
		||||
                if (!ok) {
 | 
			
		||||
                    notifications.error({ message });
 | 
			
		||||
                }
 | 
			
		||||
                form.reset();
 | 
			
		||||
                setIsScrollToBottom(true);
 | 
			
		||||
            })
 | 
			
		||||
            .catch(err => console.log(err));
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        chat,
 | 
			
		||||
        setChat: setChatValue,
 | 
			
		||||
        messages,
 | 
			
		||||
        onScrollPositionChange: setScrollPosition,
 | 
			
		||||
        scrollRef,
 | 
			
		||||
        sendMessage,
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
type ChatContextProviderProps = {
 | 
			
		||||
    children: React.ReactNode;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const ChatContextProvider: FC<ChatContextProviderProps> = ({ children }) => {
 | 
			
		||||
    const state = useChatContextState();
 | 
			
		||||
    return (
 | 
			
		||||
        <ChatContext.Provider value={state}>
 | 
			
		||||
            {children}
 | 
			
		||||
        </ChatContext.Provider>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const useChatContext = () => {
 | 
			
		||||
    const context = useContext(ChatContext);
 | 
			
		||||
    if (!context) {
 | 
			
		||||
        throw new Error(
 | 
			
		||||
            "useChatContext must be used within a ChatContextProvider",
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    return context;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										24
									
								
								src/pages/ClientsPage/drawers/ClientChatDrawer.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/pages/ClientsPage/drawers/ClientChatDrawer.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
import { useChatContext } from "../contexts/ChatContext.tsx";
 | 
			
		||||
import { Drawer } from "@mantine/core";
 | 
			
		||||
import Chat from "../../../components/Chat/Chat.tsx";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const ClientChatDrawer = () => {
 | 
			
		||||
    const { chat, setChat } = useChatContext();
 | 
			
		||||
 | 
			
		||||
    if (!chat) return;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <Drawer
 | 
			
		||||
            opened={!!chat}
 | 
			
		||||
            onClose={() => setChat(null)}
 | 
			
		||||
            position={"right"}
 | 
			
		||||
            size={"calc(50vw)"}
 | 
			
		||||
            withCloseButton={false}
 | 
			
		||||
        >
 | 
			
		||||
            <Chat />
 | 
			
		||||
        </Drawer>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default ClientChatDrawer;
 | 
			
		||||
		Reference in New Issue
	
	Block a user