feat: complete deal

This commit is contained in:
2024-09-10 18:32:52 +03:00
parent 61a0e4e306
commit 6fc6443e89
5 changed files with 179 additions and 63 deletions

View File

@@ -71,6 +71,8 @@ export type { DealAddServicesResponse } from './models/DealAddServicesResponse';
export type { DealBillRequestSchema } from './models/DealBillRequestSchema'; export type { DealBillRequestSchema } from './models/DealBillRequestSchema';
export type { DealChangeStatusRequest } from './models/DealChangeStatusRequest'; export type { DealChangeStatusRequest } from './models/DealChangeStatusRequest';
export type { DealChangeStatusResponse } from './models/DealChangeStatusResponse'; export type { DealChangeStatusResponse } from './models/DealChangeStatusResponse';
export type { DealCompleteRequest } from './models/DealCompleteRequest';
export type { DealCompleteResponse } from './models/DealCompleteResponse';
export type { DealCreateGuestUrlRequest } from './models/DealCreateGuestUrlRequest'; export type { DealCreateGuestUrlRequest } from './models/DealCreateGuestUrlRequest';
export type { DealCreateGuestUrlResponse } from './models/DealCreateGuestUrlResponse'; export type { DealCreateGuestUrlResponse } from './models/DealCreateGuestUrlResponse';
export type { DealCreateRequest } from './models/DealCreateRequest'; export type { DealCreateRequest } from './models/DealCreateRequest';

View File

@@ -0,0 +1,8 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type DealCompleteRequest = {
dealId: number;
};

View File

@@ -0,0 +1,9 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type DealCompleteResponse = {
ok: boolean;
message: string;
};

View File

@@ -12,6 +12,8 @@ import type { DealAddServicesRequest } from '../models/DealAddServicesRequest';
import type { DealAddServicesResponse } from '../models/DealAddServicesResponse'; import type { DealAddServicesResponse } from '../models/DealAddServicesResponse';
import type { DealChangeStatusRequest } from '../models/DealChangeStatusRequest'; import type { DealChangeStatusRequest } from '../models/DealChangeStatusRequest';
import type { DealChangeStatusResponse } from '../models/DealChangeStatusResponse'; import type { DealChangeStatusResponse } from '../models/DealChangeStatusResponse';
import type { DealCompleteRequest } from '../models/DealCompleteRequest';
import type { DealCompleteResponse } from '../models/DealCompleteResponse';
import type { DealCreateGuestUrlRequest } from '../models/DealCreateGuestUrlRequest'; import type { DealCreateGuestUrlRequest } from '../models/DealCreateGuestUrlRequest';
import type { DealCreateGuestUrlResponse } from '../models/DealCreateGuestUrlResponse'; import type { DealCreateGuestUrlResponse } from '../models/DealCreateGuestUrlResponse';
import type { DealCreateRequest } from '../models/DealCreateRequest'; import type { DealCreateRequest } from '../models/DealCreateRequest';
@@ -89,6 +91,26 @@ export class DealService {
}, },
}); });
} }
/**
* Complete
* @returns DealCompleteResponse Successful Response
* @throws ApiError
*/
public static completeDeal({
requestBody,
}: {
requestBody: DealCompleteRequest,
}): CancelablePromise<DealCompleteResponse> {
return __request(OpenAPI, {
method: 'POST',
url: '/deal/complete',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/** /**
* Quick Create * Quick Create
* @returns DealQuickCreateResponse Successful Response * @returns DealQuickCreateResponse Successful Response

View File

@@ -59,6 +59,29 @@ export const LeadsPage: FC = () => {
} }
}); });
} }
const onSuccess = (dealId: number) => {
const summary = summaries.find(summary => summary.id == dealId);
if (!summary) return;
modals.openConfirmModal({
title: "Завершение сделки",
children:
<Flex>
Вы действительно хотите завершить сделку {summary.name}?
</Flex>,
onConfirm: () => {
DealService.completeDeal({requestBody: {dealId: dealId}})
.then(async ({ok, message}) => {
notifications.guess(ok, {message});
if (!ok) return;
await refetch();
})
},
labels: {
confirm: "Завершить",
cancel: "Отмена"
}
});
}
const onDragEnd = async (result: DropResult) => { const onDragEnd = async (result: DropResult) => {
setIsDragEnded(true); setIsDragEnded(true);
// If there is no changes // If there is no changes
@@ -78,6 +101,10 @@ export const LeadsPage: FC = () => {
onDelete(dealId); onDelete(dealId);
return; return;
} }
if (droppableId === 'SUCCESS') {
onSuccess(dealId);
return;
}
const status = getDealStatusByName(droppableId); const status = getDealStatusByName(droppableId);
const request: Partial<DealSummaryReorderRequest> = { const request: Partial<DealSummaryReorderRequest> = {
dealId: dealId, dealId: dealId,
@@ -122,7 +149,13 @@ export const LeadsPage: FC = () => {
} }
const getBoardBody = () => { const getBoardBody = () => {
return ( return (
<motion.div <motion.div
style={{
display: "flex",
height: "100%",
flex: 1
}}
key={displayMode} key={displayMode}
initial={{opacity: 0}} initial={{opacity: 0}}
animate={{opacity: 1}} animate={{opacity: 1}}
@@ -134,6 +167,12 @@ export const LeadsPage: FC = () => {
setIsDragEnded(false); setIsDragEnded(false);
}} }}
onDragEnd={onDragEnd}> onDragEnd={onDragEnd}>
<Flex
justify={"space-between"}
direction={"column"}
style={{flex: 1}}
>
<div className={styles['boards']}> <div className={styles['boards']}>
<Board <Board
withCreateButton withCreateButton
@@ -175,7 +214,7 @@ export const LeadsPage: FC = () => {
color={'#417505'} color={'#417505'}
/> />
</div> </div>
<Flex justify={"flex-end"}> <Flex justify={"space-between"} gap={rem(10)}>
<div <div
className={ className={
classNames( classNames(
@@ -185,13 +224,16 @@ export const LeadsPage: FC = () => {
} }
> >
<Droppable droppableId={"DELETE"}> <Droppable droppableId={"DELETE"}>
{(provided) => ( {(provided, snapshot) => (
<> <>
<div <div
{...provided.droppableProps} {...provided.droppableProps}
ref={provided.innerRef} ref={provided.innerRef}
> >
{!isDragEnded && {
!isDragEnded
&&
!snapshot.isDraggingOver &&
<span> <span>
Удалить Удалить
</span> </span>
@@ -205,7 +247,40 @@ export const LeadsPage: FC = () => {
)} )}
</Droppable> </Droppable>
</div> </div>
<div
className={
classNames(
styles['delete'],
isDragEnded && styles['delete-hidden']
)
}
>
<Droppable droppableId={"SUCCESS"}>
{(provided, snapshot) => (
<>
<div
{...provided.droppableProps}
ref={provided.innerRef}
>
{
!isDragEnded
&&
!snapshot.isDraggingOver &&
<span>
Успешно завершена
</span>
}
</div>
{provided.placeholder}
</>
)}
</Droppable>
</div>
</Flex> </Flex>
</Flex>
</DragDropContext> </DragDropContext>
</motion.div> </motion.div>