@trustless-work/blocks 0.0.7 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/index.js +485 -17
- package/package.json +1 -1
- package/templates/escrows/details/Actions.tsx +144 -149
- package/templates/escrows/details/Entities.tsx +1 -1
- package/templates/escrows/details/EntityCard.tsx +1 -3
- package/templates/escrows/details/EscrowDetailDialog.tsx +16 -16
- package/templates/escrows/details/GeneralInformation.tsx +19 -22
- package/templates/escrows/details/MilestoneCard.tsx +46 -47
- package/templates/escrows/details/MilestoneDetailDialog.tsx +1 -2
- package/templates/escrows/details/Milestones.tsx +0 -5
- package/templates/escrows/details/SuccessReleaseDialog.tsx +4 -6
- package/templates/escrows/escrows-by-role/cards/EscrowsCards.tsx +84 -49
- package/templates/escrows/escrows-by-role/cards/Filters.tsx +3 -5
- package/templates/escrows/escrows-by-role/table/EscrowsTable.tsx +8 -26
- package/templates/escrows/escrows-by-role/table/Filters.tsx +3 -5
- package/templates/escrows/escrows-by-signer/cards/EscrowsCards.tsx +89 -55
- package/templates/escrows/escrows-by-signer/cards/Filters.tsx +3 -5
- package/templates/escrows/escrows-by-signer/table/EscrowsTable.tsx +8 -24
- package/templates/escrows/escrows-by-signer/table/Filters.tsx +3 -5
- package/templates/escrows/multi-release/dispute-milestone/button/DisputeEscrow.tsx +98 -0
- package/templates/escrows/multi-release/initialize-escrow/dialog/InitializeEscrow.tsx +528 -0
- package/templates/escrows/multi-release/initialize-escrow/form/InitializeEscrow.tsx +506 -0
- package/templates/escrows/multi-release/initialize-escrow/shared/schema.ts +179 -0
- package/templates/escrows/multi-release/initialize-escrow/shared/useInitializeEscrow.ts +175 -0
- package/templates/escrows/multi-release/release-milestone/button/ReleaseEscrow.tsx +116 -0
- package/templates/escrows/multi-release/resolve-dispute/button/ResolveDispute.tsx +122 -0
- package/templates/escrows/multi-release/resolve-dispute/dialog/ResolveDispute.tsx +178 -0
- package/templates/escrows/multi-release/resolve-dispute/form/ResolveDispute.tsx +156 -0
- package/templates/escrows/multi-release/resolve-dispute/shared/schema.ts +85 -0
- package/templates/escrows/multi-release/resolve-dispute/shared/useResolveDispute.ts +105 -0
- package/templates/escrows/multi-release/update-escrow/dialog/UpdateEscrow.tsx +471 -0
- package/templates/escrows/multi-release/update-escrow/form/UpdateEscrow.tsx +449 -0
- package/templates/escrows/multi-release/update-escrow/shared/schema.ts +152 -0
- package/templates/escrows/multi-release/update-escrow/shared/useUpdateEscrow.ts +254 -0
- package/templates/escrows/{single-release → single-multi-release}/approve-milestone/button/ApproveMilestone.tsx +20 -7
- package/templates/escrows/{single-release → single-multi-release}/approve-milestone/dialog/ApproveMilestone.tsx +3 -3
- package/templates/escrows/{single-release → single-multi-release}/approve-milestone/form/ApproveMilestone.tsx +3 -3
- package/templates/escrows/{single-release/approve-milestone/shared → single-multi-release/approve-milestone}/useApproveMilestone.ts +16 -16
- package/templates/escrows/{single-release → single-multi-release}/change-milestone-status/button/ChangeMilestoneStatus.tsx +4 -4
- package/templates/escrows/{single-release → single-multi-release}/change-milestone-status/dialog/ChangeMilestoneStatus.tsx +4 -4
- package/templates/escrows/{single-release → single-multi-release}/change-milestone-status/form/ChangeMilestoneStatus.tsx +3 -3
- package/templates/escrows/{single-release/change-milestone-status/shared → single-multi-release/change-milestone-status}/useChangeMilestoneStatus.ts +1 -1
- package/templates/escrows/{single-release → single-multi-release}/fund-escrow/button/FundEscrow.tsx +3 -3
- package/templates/escrows/{single-release → single-multi-release}/fund-escrow/dialog/FundEscrow.tsx +3 -3
- package/templates/escrows/{single-release → single-multi-release}/fund-escrow/form/FundEscrow.tsx +3 -3
- package/templates/escrows/{single-release/fund-escrow/shared → single-multi-release/fund-escrow}/useFundEscrow.ts +1 -1
- package/templates/escrows/single-release/dispute-escrow/button/DisputeEscrow.tsx +2 -2
- package/templates/escrows/single-release/initialize-escrow/dialog/InitializeEscrow.tsx +14 -6
- package/templates/escrows/single-release/initialize-escrow/form/InitializeEscrow.tsx +14 -6
- package/templates/escrows/single-release/initialize-escrow/shared/schema.ts +0 -57
- package/templates/escrows/single-release/initialize-escrow/shared/useInitializeEscrow.ts +42 -1
- package/templates/escrows/single-release/release-escrow/button/ReleaseEscrow.tsx +2 -2
- package/templates/escrows/single-release/resolve-dispute/button/ResolveDispute.tsx +3 -3
- package/templates/escrows/single-release/resolve-dispute/dialog/ResolveDispute.tsx +3 -6
- package/templates/escrows/single-release/resolve-dispute/form/ResolveDispute.tsx +2 -2
- package/templates/escrows/single-release/resolve-dispute/shared/useResolveDispute.ts +14 -1
- package/templates/escrows/single-release/update-escrow/dialog/UpdateEscrow.tsx +2 -2
- package/templates/escrows/single-release/update-escrow/form/UpdateEscrow.tsx +2 -2
- package/templates/escrows/single-release/update-escrow/shared/useUpdateEscrow.ts +12 -7
- package/templates/providers/EscrowDialogsProvider.tsx +1 -3
- package/templates/providers/EscrowProvider.tsx +27 -4
- package/templates/providers/TrustlessWork.tsx +1 -1
- package/templates/escrows/details/ProgressEscrow.tsx +0 -191
- /package/templates/escrows/{single-release/approve-milestone/shared → single-multi-release/approve-milestone}/schema.ts +0 -0
- /package/templates/escrows/{single-release/change-milestone-status/shared → single-multi-release/change-milestone-status}/schema.ts +0 -0
- /package/templates/escrows/{single-release/fund-escrow/shared → single-multi-release/fund-escrow}/schema.ts +0 -0
|
@@ -5,14 +5,14 @@ import { Button } from "__UI_BASE__/button";
|
|
|
5
5
|
import type {
|
|
6
6
|
GetEscrowsFromIndexerResponse as Escrow,
|
|
7
7
|
MultiReleaseMilestone,
|
|
8
|
-
Role,
|
|
9
8
|
SingleReleaseMilestone,
|
|
10
9
|
} from "@trustless-work/escrow/types";
|
|
11
|
-
import Filters from "./Filters";
|
|
10
|
+
import { Filters } from "./Filters";
|
|
12
11
|
import { useEscrowsBySigner } from "../useEscrowsBySigner.shared";
|
|
13
12
|
import { Card, CardContent, CardHeader, CardTitle } from "__UI_BASE__/card";
|
|
14
13
|
import { Badge } from "__UI_BASE__/badge";
|
|
15
14
|
import { Separator } from "__UI_BASE__/separator";
|
|
15
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from "__UI_BASE__/tooltip";
|
|
16
16
|
import {
|
|
17
17
|
Goal,
|
|
18
18
|
Wallet,
|
|
@@ -23,10 +23,13 @@ import {
|
|
|
23
23
|
} from "lucide-react";
|
|
24
24
|
import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvider";
|
|
25
25
|
import { useEscrowDialogs } from "@/components/tw-blocks/providers/EscrowDialogsProvider";
|
|
26
|
-
import EscrowDetailDialog from "
|
|
27
|
-
import {
|
|
26
|
+
import { EscrowDetailDialog } from "../details/EscrowDetailDialog";
|
|
27
|
+
import {
|
|
28
|
+
formatCurrency,
|
|
29
|
+
formatTimestamp,
|
|
30
|
+
} from "../../../helpers/format.helper";
|
|
28
31
|
|
|
29
|
-
export
|
|
32
|
+
export const EscrowsBySignerCards = () => {
|
|
30
33
|
const {
|
|
31
34
|
walletAddress,
|
|
32
35
|
data,
|
|
@@ -74,10 +77,6 @@ export function EscrowsBySignerCards() {
|
|
|
74
77
|
void refetch();
|
|
75
78
|
}, [refetch]);
|
|
76
79
|
|
|
77
|
-
const formatCurrency = (value: number, currency: string) => {
|
|
78
|
-
return `${currency} ${value.toFixed(2)}`;
|
|
79
|
-
};
|
|
80
|
-
|
|
81
80
|
function allMilestonesReleasedOrResolved(
|
|
82
81
|
milestones: MultiReleaseMilestone[]
|
|
83
82
|
) {
|
|
@@ -120,18 +119,6 @@ export function EscrowsBySignerCards() {
|
|
|
120
119
|
dialogStates.second.setIsOpen(true);
|
|
121
120
|
};
|
|
122
121
|
|
|
123
|
-
/**
|
|
124
|
-
* Based on the provided roles -> https://docs.trustlesswork.com/trustless-work/technology-overview/roles-in-trustless-work
|
|
125
|
-
*
|
|
126
|
-
* You must pass one or more roles according to requirements
|
|
127
|
-
*
|
|
128
|
-
* For example:
|
|
129
|
-
* - If the user is a freelancer, you must pass the "serviceProvider" and "receiver" role
|
|
130
|
-
*
|
|
131
|
-
* Depending of the role, you'll have different actions buttons
|
|
132
|
-
*/
|
|
133
|
-
const activeRole: Role[] = React.useMemo(() => ["approver"] as Role[], []);
|
|
134
|
-
|
|
135
122
|
const escrows: Escrow[] = data ?? [];
|
|
136
123
|
|
|
137
124
|
return (
|
|
@@ -262,7 +249,7 @@ export function EscrowsBySignerCards() {
|
|
|
262
249
|
{escrows.map((escrow) => (
|
|
263
250
|
<React.Fragment key={escrow.contractId}>
|
|
264
251
|
<Card
|
|
265
|
-
className="w-full max-w-md mx-auto hover:shadow-lg transition-shadow duration-200"
|
|
252
|
+
className="w-full max-w-md mx-auto hover:shadow-lg transition-shadow duration-200 cursor-pointer"
|
|
266
253
|
onClick={(e) => {
|
|
267
254
|
e.stopPropagation();
|
|
268
255
|
onCardClick(escrow);
|
|
@@ -347,9 +334,9 @@ export function EscrowsBySignerCards() {
|
|
|
347
334
|
<ul className="list-disc list-inside flex flex-col gap-1">
|
|
348
335
|
{escrow.milestones
|
|
349
336
|
.slice(0, 3)
|
|
350
|
-
.map((milestone) => (
|
|
337
|
+
.map((milestone, index) => (
|
|
351
338
|
<li
|
|
352
|
-
key={milestone.description.
|
|
339
|
+
key={`milestone-${milestone.description}-${milestone.status}-${index}`}
|
|
353
340
|
className="text-xs flex justify-between"
|
|
354
341
|
>
|
|
355
342
|
{milestone.description}
|
|
@@ -365,33 +352,83 @@ export function EscrowsBySignerCards() {
|
|
|
365
352
|
)}
|
|
366
353
|
</span>
|
|
367
354
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
355
|
+
{milestone.flags?.disputed && (
|
|
356
|
+
<Tooltip>
|
|
357
|
+
<TooltipTrigger>
|
|
358
|
+
<span
|
|
359
|
+
className={`bg-red-800 rounded-full h-2 w-2 ml-1 ${
|
|
360
|
+
milestone.flags?.disputed
|
|
361
|
+
? "block"
|
|
362
|
+
: "hidden"
|
|
363
|
+
}`}
|
|
364
|
+
/>
|
|
365
|
+
</TooltipTrigger>
|
|
366
|
+
<TooltipContent>
|
|
367
|
+
Disputed
|
|
368
|
+
</TooltipContent>
|
|
369
|
+
</Tooltip>
|
|
370
|
+
)}
|
|
371
|
+
|
|
372
|
+
{milestone.flags?.resolved && (
|
|
373
|
+
<Tooltip>
|
|
374
|
+
<TooltipTrigger>
|
|
375
|
+
<span
|
|
376
|
+
className={`bg-green-800 rounded-full h-2 w-2 ml-1 ${
|
|
377
|
+
milestone.flags?.resolved
|
|
378
|
+
? "block"
|
|
379
|
+
: "hidden"
|
|
380
|
+
}`}
|
|
381
|
+
/>
|
|
382
|
+
</TooltipTrigger>
|
|
383
|
+
<TooltipContent>
|
|
384
|
+
Resolved
|
|
385
|
+
</TooltipContent>
|
|
386
|
+
</Tooltip>
|
|
387
|
+
)}
|
|
388
|
+
|
|
389
|
+
{milestone.flags?.released && (
|
|
390
|
+
<Tooltip>
|
|
391
|
+
<TooltipTrigger>
|
|
392
|
+
<span
|
|
393
|
+
className={`bg-green-800 rounded-full h-2 w-2 ml-1 ${
|
|
394
|
+
milestone.flags?.released
|
|
395
|
+
? "block"
|
|
396
|
+
: "hidden"
|
|
397
|
+
}`}
|
|
398
|
+
/>
|
|
399
|
+
</TooltipTrigger>
|
|
400
|
+
<TooltipContent>
|
|
401
|
+
Released
|
|
402
|
+
</TooltipContent>
|
|
403
|
+
</Tooltip>
|
|
404
|
+
)}
|
|
405
|
+
|
|
406
|
+
{milestone.flags?.approved &&
|
|
407
|
+
!milestone.flags?.disputed &&
|
|
408
|
+
!milestone.flags?.resolved &&
|
|
409
|
+
!milestone.flags?.released && (
|
|
410
|
+
<Tooltip>
|
|
411
|
+
<TooltipTrigger>
|
|
412
|
+
<span
|
|
413
|
+
className={`bg-yellow-600 rounded-full h-2 w-2 ml-1 ${
|
|
414
|
+
milestone.flags
|
|
415
|
+
?.approved &&
|
|
416
|
+
!milestone.flags
|
|
417
|
+
?.disputed &&
|
|
418
|
+
!milestone.flags
|
|
419
|
+
?.resolved &&
|
|
420
|
+
!milestone.flags
|
|
421
|
+
?.released
|
|
422
|
+
? "block"
|
|
423
|
+
: "hidden"
|
|
424
|
+
}`}
|
|
425
|
+
/>
|
|
426
|
+
</TooltipTrigger>
|
|
427
|
+
<TooltipContent>
|
|
428
|
+
Pending Release
|
|
429
|
+
</TooltipContent>
|
|
430
|
+
</Tooltip>
|
|
431
|
+
)}
|
|
395
432
|
</div>
|
|
396
433
|
</>
|
|
397
434
|
)}
|
|
@@ -508,7 +545,6 @@ export function EscrowsBySignerCards() {
|
|
|
508
545
|
{/* Dialog */}
|
|
509
546
|
{dialogStates.second.isOpen ? (
|
|
510
547
|
<EscrowDetailDialog
|
|
511
|
-
activeRole={activeRole}
|
|
512
548
|
isDialogOpen={dialogStates.second.isOpen}
|
|
513
549
|
setIsDialogOpen={dialogStates.second.setIsOpen}
|
|
514
550
|
setSelectedEscrow={setSelectedEscrow}
|
|
@@ -516,6 +552,4 @@ export function EscrowsBySignerCards() {
|
|
|
516
552
|
) : null}
|
|
517
553
|
</>
|
|
518
554
|
);
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
export default React.memo(EscrowsBySignerCards);
|
|
555
|
+
};
|
|
@@ -81,7 +81,7 @@ type FiltersProps = {
|
|
|
81
81
|
setOrderDirection: (v: "asc" | "desc") => void;
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
export const Filters = ({
|
|
85
85
|
title,
|
|
86
86
|
engagementId,
|
|
87
87
|
isActive,
|
|
@@ -108,7 +108,7 @@ function Filters({
|
|
|
108
108
|
onRefresh,
|
|
109
109
|
setOrderBy,
|
|
110
110
|
setOrderDirection,
|
|
111
|
-
}: FiltersProps) {
|
|
111
|
+
}: FiltersProps) => {
|
|
112
112
|
return (
|
|
113
113
|
<div className="w-full bg-card/50 backdrop-blur-sm border border-border/50 rounded-lg p-4 shadow-sm">
|
|
114
114
|
{/* Header Section */}
|
|
@@ -384,6 +384,4 @@ function Filters({
|
|
|
384
384
|
</div>
|
|
385
385
|
</div>
|
|
386
386
|
);
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
export default React.memo(Filters);
|
|
387
|
+
};
|
|
@@ -6,7 +6,6 @@ import { Button } from "__UI_BASE__/button";
|
|
|
6
6
|
import type {
|
|
7
7
|
GetEscrowsFromIndexerResponse as Escrow,
|
|
8
8
|
MultiReleaseMilestone,
|
|
9
|
-
Role,
|
|
10
9
|
} from "@trustless-work/escrow/types";
|
|
11
10
|
import {
|
|
12
11
|
ColumnDef,
|
|
@@ -23,14 +22,14 @@ import {
|
|
|
23
22
|
TableRow,
|
|
24
23
|
} from "__UI_BASE__/table";
|
|
25
24
|
import { FileX, Loader2, Wallet, RefreshCw, AlertTriangle } from "lucide-react";
|
|
26
|
-
import Filters from "./Filters";
|
|
25
|
+
import { Filters } from "./Filters";
|
|
27
26
|
import { useEscrowsBySigner } from "../useEscrowsBySigner.shared";
|
|
28
27
|
import { useEscrowDialogs } from "@/components/tw-blocks/providers/EscrowDialogsProvider";
|
|
29
28
|
import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvider";
|
|
30
|
-
import EscrowDetailDialog from "
|
|
29
|
+
import { EscrowDetailDialog } from "../details/EscrowDetailDialog";
|
|
31
30
|
import { formatTimestamp } from "../../../helpers/format.helper";
|
|
32
31
|
|
|
33
|
-
export
|
|
32
|
+
export const EscrowsBySignerTable = () => {
|
|
34
33
|
const {
|
|
35
34
|
walletAddress,
|
|
36
35
|
data,
|
|
@@ -203,18 +202,6 @@ export function EscrowsBySignerTable() {
|
|
|
203
202
|
enableSortingRemoval: true,
|
|
204
203
|
});
|
|
205
204
|
|
|
206
|
-
/**
|
|
207
|
-
* Based on the provided roles -> https://docs.trustlesswork.com/trustless-work/technology-overview/roles-in-trustless-work
|
|
208
|
-
*
|
|
209
|
-
* You must pass one or more roles according to requirements
|
|
210
|
-
*
|
|
211
|
-
* For example:
|
|
212
|
-
* - If the user is a freelancer, you must pass the "serviceProvider" and "receiver" role
|
|
213
|
-
*
|
|
214
|
-
* Depending of the role, you'll have different actions buttons
|
|
215
|
-
*/
|
|
216
|
-
const activeRole: Role[] = React.useMemo(() => ["approver"] as Role[], []);
|
|
217
|
-
|
|
218
205
|
const escrows = data ?? [];
|
|
219
206
|
|
|
220
207
|
return (
|
|
@@ -261,8 +248,8 @@ export function EscrowsBySignerTable() {
|
|
|
261
248
|
const className =
|
|
262
249
|
typeof header.column.columnDef.meta === "object" &&
|
|
263
250
|
header.column.columnDef.meta &&
|
|
264
|
-
"className" in
|
|
265
|
-
?
|
|
251
|
+
"className" in header.column.columnDef.meta
|
|
252
|
+
? header.column.columnDef.meta.className
|
|
266
253
|
: "";
|
|
267
254
|
return (
|
|
268
255
|
<TableHead
|
|
@@ -375,8 +362,8 @@ export function EscrowsBySignerTable() {
|
|
|
375
362
|
const className =
|
|
376
363
|
typeof cell.column.columnDef.meta === "object" &&
|
|
377
364
|
cell.column.columnDef.meta &&
|
|
378
|
-
"className" in
|
|
379
|
-
? (cell.column.columnDef.meta as
|
|
365
|
+
"className" in cell.column.columnDef.meta
|
|
366
|
+
? (cell.column.columnDef.meta.className as string)
|
|
380
367
|
: "";
|
|
381
368
|
return (
|
|
382
369
|
<TableCell key={cell.id} className={className}>
|
|
@@ -426,7 +413,6 @@ export function EscrowsBySignerTable() {
|
|
|
426
413
|
{/* Dialog */}
|
|
427
414
|
{dialogStates.second.isOpen ? (
|
|
428
415
|
<EscrowDetailDialog
|
|
429
|
-
activeRole={activeRole}
|
|
430
416
|
isDialogOpen={dialogStates.second.isOpen}
|
|
431
417
|
setIsDialogOpen={dialogStates.second.setIsOpen}
|
|
432
418
|
setSelectedEscrow={setSelectedEscrow}
|
|
@@ -434,6 +420,4 @@ export function EscrowsBySignerTable() {
|
|
|
434
420
|
) : null}
|
|
435
421
|
</>
|
|
436
422
|
);
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
export default React.memo(EscrowsBySignerTable);
|
|
423
|
+
};
|
|
@@ -81,7 +81,7 @@ type FiltersProps = {
|
|
|
81
81
|
setOrderDirection: (v: "asc" | "desc") => void;
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
export const Filters = ({
|
|
85
85
|
title,
|
|
86
86
|
engagementId,
|
|
87
87
|
isActive,
|
|
@@ -108,7 +108,7 @@ function Filters({
|
|
|
108
108
|
onRefresh,
|
|
109
109
|
setOrderBy,
|
|
110
110
|
setOrderDirection,
|
|
111
|
-
}: FiltersProps) {
|
|
111
|
+
}: FiltersProps) => {
|
|
112
112
|
return (
|
|
113
113
|
<div className="w-full bg-card/50 backdrop-blur-sm border border-border/50 rounded-lg p-4 shadow-sm">
|
|
114
114
|
{/* Header Section */}
|
|
@@ -384,6 +384,4 @@ function Filters({
|
|
|
384
384
|
</div>
|
|
385
385
|
</div>
|
|
386
386
|
);
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
export default React.memo(Filters);
|
|
387
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Button } from "__UI_BASE__/button";
|
|
3
|
+
import { useEscrowsMutations } from "@/components/tw-blocks/tanstack/useEscrowsMutations";
|
|
4
|
+
import { useWalletContext } from "@/components/tw-blocks/wallet-kit/WalletProvider";
|
|
5
|
+
import {
|
|
6
|
+
MultiReleaseStartDisputePayload,
|
|
7
|
+
MultiReleaseMilestone,
|
|
8
|
+
} from "@trustless-work/escrow/types";
|
|
9
|
+
import { toast } from "sonner";
|
|
10
|
+
import {
|
|
11
|
+
ErrorResponse,
|
|
12
|
+
handleError,
|
|
13
|
+
} from "@/components/tw-blocks/handle-errors/handle";
|
|
14
|
+
import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvider";
|
|
15
|
+
import { Loader2 } from "lucide-react";
|
|
16
|
+
|
|
17
|
+
type DisputeEscrowButtonProps = {
|
|
18
|
+
milestoneIndex: number | string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const DisputeEscrowButton = ({
|
|
22
|
+
milestoneIndex,
|
|
23
|
+
}: DisputeEscrowButtonProps) => {
|
|
24
|
+
const { startDispute } = useEscrowsMutations();
|
|
25
|
+
const { selectedEscrow, updateEscrow } = useEscrowContext();
|
|
26
|
+
const { walletAddress } = useWalletContext();
|
|
27
|
+
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
28
|
+
|
|
29
|
+
async function handleClick() {
|
|
30
|
+
try {
|
|
31
|
+
setIsSubmitting(true);
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Create the payload for the dispute escrow mutation
|
|
35
|
+
*
|
|
36
|
+
* @returns The payload for the dispute escrow mutation
|
|
37
|
+
*/
|
|
38
|
+
const payload: MultiReleaseStartDisputePayload = {
|
|
39
|
+
contractId: selectedEscrow?.contractId || "",
|
|
40
|
+
signer: walletAddress || "",
|
|
41
|
+
milestoneIndex: String(milestoneIndex),
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Call the dispute escrow mutation
|
|
46
|
+
*
|
|
47
|
+
* @param payload - The payload for the dispute escrow mutation
|
|
48
|
+
* @param type - The type of the escrow
|
|
49
|
+
* @param address - The address of the escrow
|
|
50
|
+
*/
|
|
51
|
+
await startDispute.mutateAsync({
|
|
52
|
+
payload,
|
|
53
|
+
type: "multi-release",
|
|
54
|
+
address: walletAddress || "",
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
toast.success("Escrow disputed successfully");
|
|
58
|
+
|
|
59
|
+
updateEscrow({
|
|
60
|
+
...selectedEscrow,
|
|
61
|
+
milestones: selectedEscrow?.milestones.map((milestone, index) => {
|
|
62
|
+
if (index === Number(milestoneIndex)) {
|
|
63
|
+
return {
|
|
64
|
+
...milestone,
|
|
65
|
+
flags: {
|
|
66
|
+
...(milestone as MultiReleaseMilestone).flags,
|
|
67
|
+
disputed: true,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
return milestone;
|
|
72
|
+
}),
|
|
73
|
+
});
|
|
74
|
+
} catch (error) {
|
|
75
|
+
toast.error(handleError(error as ErrorResponse).message);
|
|
76
|
+
} finally {
|
|
77
|
+
setIsSubmitting(false);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<Button
|
|
83
|
+
type="button"
|
|
84
|
+
disabled={isSubmitting || !selectedEscrow?.balance}
|
|
85
|
+
onClick={handleClick}
|
|
86
|
+
className="cursor-pointer w-full"
|
|
87
|
+
>
|
|
88
|
+
{isSubmitting ? (
|
|
89
|
+
<div className="flex items-center">
|
|
90
|
+
<Loader2 className="h-5 w-5 animate-spin" />
|
|
91
|
+
<span className="ml-2">Disputing...</span>
|
|
92
|
+
</div>
|
|
93
|
+
) : (
|
|
94
|
+
"Dispute Milestone"
|
|
95
|
+
)}
|
|
96
|
+
</Button>
|
|
97
|
+
);
|
|
98
|
+
};
|