@trustless-work/blocks 1.0.6 → 1.0.7
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 +1930 -1921
- package/package.json +1 -1
- package/templates/deps.json +1 -1
- package/templates/escrows/details/Actions.tsx +1 -2
- package/templates/escrows/details/Entities.tsx +23 -2
- package/templates/escrows/details/GeneralInformation.tsx +1 -13
- package/templates/escrows/details/MilestoneCard.tsx +1 -1
- package/templates/escrows/details/MilestoneDetailDialog.tsx +38 -19
- package/templates/escrows/details/SuccessReleaseDialog.tsx +84 -28
- package/templates/escrows/details/useDetailsEscrow.ts +15 -2
- package/templates/escrows/multi-release/initialize-escrow/dialog/InitializeEscrow.tsx +76 -101
- package/templates/escrows/multi-release/initialize-escrow/form/InitializeEscrow.tsx +78 -102
- package/templates/escrows/multi-release/initialize-escrow/shared/schema.ts +8 -18
- package/templates/escrows/multi-release/initialize-escrow/shared/useInitializeEscrow.ts +21 -12
- package/templates/escrows/multi-release/release-milestone/button/ReleaseMilestone.tsx +5 -1
- package/templates/escrows/multi-release/update-escrow/dialog/UpdateEscrow.tsx +112 -101
- package/templates/escrows/multi-release/update-escrow/form/UpdateEscrow.tsx +103 -101
- package/templates/escrows/multi-release/update-escrow/shared/schema.ts +8 -16
- package/templates/escrows/multi-release/update-escrow/shared/useUpdateEscrow.ts +33 -14
- package/templates/escrows/multi-release/withdraw-remaining-funds/button/WithdrawRemainingFunds.tsx +0 -1
- package/templates/escrows/multi-release/withdraw-remaining-funds/shared/useWithdrawRemainingFunds.ts +0 -1
- package/templates/escrows/single-release/initialize-escrow/dialog/InitializeEscrow.tsx +2 -25
- package/templates/escrows/single-release/initialize-escrow/form/InitializeEscrow.tsx +3 -26
- package/templates/escrows/single-release/initialize-escrow/shared/schema.ts +0 -10
- package/templates/escrows/single-release/initialize-escrow/shared/useInitializeEscrow.ts +0 -4
- package/templates/escrows/single-release/release-escrow/button/ReleaseEscrow.tsx +5 -1
- package/templates/escrows/single-release/update-escrow/dialog/UpdateEscrow.tsx +41 -27
- package/templates/escrows/single-release/update-escrow/form/UpdateEscrow.tsx +38 -3
- package/templates/escrows/single-release/update-escrow/shared/useUpdateEscrow.ts +28 -14
- package/templates/providers/EscrowAmountProvider.tsx +8 -0
- package/templates/tanstack/useEscrowsMutations.ts +1 -6
- package/templates/wallet-kit/WalletButtons.tsx +2 -2
- package/templates/wallet-kit/WalletProvider.tsx +0 -1
|
@@ -40,12 +40,6 @@ export const useUpdateEscrowSchema = () => {
|
|
|
40
40
|
.refine((value) => isValidWallet(value), {
|
|
41
41
|
message: "Dispute resolver must be a valid wallet.",
|
|
42
42
|
}),
|
|
43
|
-
receiver: z
|
|
44
|
-
.string()
|
|
45
|
-
.min(1, { message: "Receiver address is required." })
|
|
46
|
-
.refine((value) => isValidWallet(value), {
|
|
47
|
-
message: "Receiver address must be a valid wallet.",
|
|
48
|
-
}),
|
|
49
43
|
}),
|
|
50
44
|
engagementId: z.string().min(1, { message: "Engagement is required." }),
|
|
51
45
|
title: z.string().min(1, { message: "Title is required." }),
|
|
@@ -79,16 +73,6 @@ export const useUpdateEscrowSchema = () => {
|
|
|
79
73
|
},
|
|
80
74
|
{ message: "Platform fee can have a maximum of 2 decimal places." }
|
|
81
75
|
),
|
|
82
|
-
receiverMemo: z
|
|
83
|
-
.string()
|
|
84
|
-
.optional()
|
|
85
|
-
.refine((val) => !val || val.length >= 1, {
|
|
86
|
-
message: "Receiver Memo must be at least 1.",
|
|
87
|
-
})
|
|
88
|
-
.refine((val) => !val || /^[1-9][0-9]*$/.test(val), {
|
|
89
|
-
message:
|
|
90
|
-
"Receiver Memo must be a whole number greater than 0 (no decimals).",
|
|
91
|
-
}),
|
|
92
76
|
});
|
|
93
77
|
};
|
|
94
78
|
|
|
@@ -99,6 +83,14 @@ export const useUpdateEscrowSchema = () => {
|
|
|
99
83
|
milestones: z
|
|
100
84
|
.array(
|
|
101
85
|
z.object({
|
|
86
|
+
receiver: z
|
|
87
|
+
.string()
|
|
88
|
+
.min(1, {
|
|
89
|
+
message: "Receiver address is required.",
|
|
90
|
+
})
|
|
91
|
+
.refine((value) => isValidWallet(value), {
|
|
92
|
+
message: "Receiver address must be a valid wallet.",
|
|
93
|
+
}),
|
|
102
94
|
description: z.string().min(1, {
|
|
103
95
|
message: "Milestone description is required.",
|
|
104
96
|
}),
|
|
@@ -28,6 +28,11 @@ export function useUpdateEscrow() {
|
|
|
28
28
|
const { selectedEscrow, setSelectedEscrow } = useEscrowContext();
|
|
29
29
|
const { updateEscrow } = useEscrowsMutations();
|
|
30
30
|
|
|
31
|
+
const isEscrowLocked = Number(selectedEscrow?.balance || 0) > 0;
|
|
32
|
+
const initialMilestonesCountRef = React.useRef<number>(
|
|
33
|
+
((selectedEscrow?.milestones as MultiReleaseMilestone[]) || []).length
|
|
34
|
+
);
|
|
35
|
+
|
|
31
36
|
const form = useForm<z.infer<typeof formSchema>>({
|
|
32
37
|
resolver: zodResolver(formSchema),
|
|
33
38
|
defaultValues: {
|
|
@@ -38,9 +43,6 @@ export function useUpdateEscrow() {
|
|
|
38
43
|
| number
|
|
39
44
|
| string
|
|
40
45
|
| undefined,
|
|
41
|
-
receiverMemo: selectedEscrow?.receiverMemo
|
|
42
|
-
? String(selectedEscrow.receiverMemo)
|
|
43
|
-
: "",
|
|
44
46
|
trustline: {
|
|
45
47
|
address: selectedEscrow?.trustline?.address || "",
|
|
46
48
|
},
|
|
@@ -48,17 +50,19 @@ export function useUpdateEscrow() {
|
|
|
48
50
|
approver: selectedEscrow?.roles?.approver || "",
|
|
49
51
|
serviceProvider: selectedEscrow?.roles?.serviceProvider || "",
|
|
50
52
|
platformAddress: selectedEscrow?.roles?.platformAddress || "",
|
|
51
|
-
receiver: selectedEscrow?.roles?.receiver || "",
|
|
52
53
|
releaseSigner: selectedEscrow?.roles?.releaseSigner || "",
|
|
53
54
|
disputeResolver: selectedEscrow?.roles?.disputeResolver || "",
|
|
54
55
|
},
|
|
55
56
|
milestones: (
|
|
56
57
|
(selectedEscrow?.milestones as MultiReleaseMilestone[]) ?? []
|
|
57
58
|
).map((m) => ({
|
|
59
|
+
receiver:
|
|
60
|
+
(m as MultiReleaseMilestone & { receiver?: string })?.receiver || "",
|
|
58
61
|
description: m?.description || "",
|
|
59
62
|
amount: m?.amount ?? 0,
|
|
60
63
|
})) || [
|
|
61
64
|
{
|
|
65
|
+
receiver: "",
|
|
62
66
|
description: "",
|
|
63
67
|
amount: 0,
|
|
64
68
|
},
|
|
@@ -78,9 +82,6 @@ export function useUpdateEscrow() {
|
|
|
78
82
|
| number
|
|
79
83
|
| string
|
|
80
84
|
| undefined) || "",
|
|
81
|
-
receiverMemo: selectedEscrow?.receiverMemo
|
|
82
|
-
? String(selectedEscrow.receiverMemo)
|
|
83
|
-
: "",
|
|
84
85
|
trustline: {
|
|
85
86
|
address: selectedEscrow?.trustline?.address || "",
|
|
86
87
|
},
|
|
@@ -88,34 +89,51 @@ export function useUpdateEscrow() {
|
|
|
88
89
|
approver: selectedEscrow?.roles?.approver || "",
|
|
89
90
|
serviceProvider: selectedEscrow?.roles?.serviceProvider || "",
|
|
90
91
|
platformAddress: selectedEscrow?.roles?.platformAddress || "",
|
|
91
|
-
receiver: selectedEscrow?.roles?.receiver || "",
|
|
92
92
|
releaseSigner: selectedEscrow?.roles?.releaseSigner || "",
|
|
93
93
|
disputeResolver: selectedEscrow?.roles?.disputeResolver || "",
|
|
94
94
|
},
|
|
95
95
|
milestones: (
|
|
96
96
|
(selectedEscrow?.milestones as MultiReleaseMilestone[]) ?? []
|
|
97
97
|
).map((m) => ({
|
|
98
|
+
receiver:
|
|
99
|
+
(m as MultiReleaseMilestone & { receiver?: string })?.receiver || "",
|
|
98
100
|
description: m?.description || "",
|
|
99
101
|
amount: m?.amount ?? "",
|
|
100
102
|
})) || [
|
|
101
103
|
{
|
|
104
|
+
receiver: "",
|
|
102
105
|
description: "",
|
|
103
106
|
amount: "",
|
|
104
107
|
},
|
|
105
108
|
],
|
|
106
109
|
});
|
|
110
|
+
initialMilestonesCountRef.current = (
|
|
111
|
+
(selectedEscrow?.milestones as MultiReleaseMilestone[]) || []
|
|
112
|
+
).length;
|
|
107
113
|
}, [selectedEscrow, form]);
|
|
108
114
|
|
|
109
115
|
const milestones = form.watch("milestones");
|
|
110
|
-
const isAnyMilestoneEmpty = milestones.some((m) =>
|
|
116
|
+
const isAnyMilestoneEmpty = milestones.some((m, index) => {
|
|
117
|
+
const shouldValidate =
|
|
118
|
+
!isEscrowLocked || index >= initialMilestonesCountRef.current;
|
|
119
|
+
if (!shouldValidate) return false;
|
|
120
|
+
return (
|
|
121
|
+
m.description === "" ||
|
|
122
|
+
(m as { receiver?: string }).receiver === "" ||
|
|
123
|
+
m.amount === ""
|
|
124
|
+
);
|
|
125
|
+
});
|
|
111
126
|
|
|
112
127
|
const handleAddMilestone = () => {
|
|
113
128
|
const current = form.getValues("milestones");
|
|
114
|
-
const updated = [...current, { description: "", amount: "" }];
|
|
129
|
+
const updated = [...current, { receiver: "", description: "", amount: "" }];
|
|
115
130
|
form.setValue("milestones", updated);
|
|
116
131
|
};
|
|
117
132
|
|
|
118
133
|
const handleRemoveMilestone = (index: number) => {
|
|
134
|
+
if (isEscrowLocked && index < initialMilestonesCountRef.current) {
|
|
135
|
+
return; // cannot remove existing milestones when escrow has balance
|
|
136
|
+
}
|
|
119
137
|
const current = form.getValues("milestones");
|
|
120
138
|
const updated = current.filter((_, i) => i !== index);
|
|
121
139
|
form.setValue("milestones", updated);
|
|
@@ -183,19 +201,18 @@ export function useUpdateEscrow() {
|
|
|
183
201
|
typeof payload.platformFee === "string"
|
|
184
202
|
? Number(payload.platformFee)
|
|
185
203
|
: payload.platformFee,
|
|
186
|
-
receiverMemo: payload.receiverMemo
|
|
187
|
-
? Number(payload.receiverMemo)
|
|
188
|
-
: undefined,
|
|
189
204
|
trustline: {
|
|
190
205
|
address: payload.trustline.address,
|
|
191
206
|
},
|
|
192
207
|
roles: payload.roles,
|
|
193
|
-
milestones: payload.milestones.map((milestone) => ({
|
|
208
|
+
milestones: payload.milestones.map((milestone, index) => ({
|
|
194
209
|
...milestone,
|
|
195
210
|
amount:
|
|
196
211
|
typeof milestone.amount === "string"
|
|
197
212
|
? Number(milestone.amount)
|
|
198
213
|
: milestone.amount,
|
|
214
|
+
evidence: selectedEscrow?.milestones?.[index]?.evidence || "",
|
|
215
|
+
status: selectedEscrow?.milestones?.[index]?.status || "",
|
|
199
216
|
})),
|
|
200
217
|
},
|
|
201
218
|
};
|
|
@@ -246,5 +263,7 @@ export function useUpdateEscrow() {
|
|
|
246
263
|
handleRemoveMilestone,
|
|
247
264
|
handleMilestoneAmountChange,
|
|
248
265
|
handlePlatformFeeChange,
|
|
266
|
+
isEscrowLocked,
|
|
267
|
+
initialMilestonesCount: initialMilestonesCountRef.current,
|
|
249
268
|
};
|
|
250
269
|
}
|
|
@@ -320,7 +320,7 @@ export const InitializeEscrowDialog = () => {
|
|
|
320
320
|
<FormItem>
|
|
321
321
|
<FormLabel className="flex items-center justify-between">
|
|
322
322
|
<span className="flex items-center">
|
|
323
|
-
Platform
|
|
323
|
+
Platform
|
|
324
324
|
<span className="text-destructive ml-1">*</span>
|
|
325
325
|
</span>
|
|
326
326
|
</FormLabel>
|
|
@@ -364,7 +364,7 @@ export const InitializeEscrowDialog = () => {
|
|
|
364
364
|
/>
|
|
365
365
|
</div>
|
|
366
366
|
|
|
367
|
-
<div className="grid grid-cols-1 lg:grid-cols-
|
|
367
|
+
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
|
368
368
|
<FormField
|
|
369
369
|
control={form.control}
|
|
370
370
|
name="platformFee"
|
|
@@ -419,29 +419,6 @@ export const InitializeEscrowDialog = () => {
|
|
|
419
419
|
</FormItem>
|
|
420
420
|
)}
|
|
421
421
|
/>
|
|
422
|
-
|
|
423
|
-
<FormField
|
|
424
|
-
control={form.control}
|
|
425
|
-
name="receiverMemo"
|
|
426
|
-
render={({ field }) => (
|
|
427
|
-
<FormItem>
|
|
428
|
-
<FormLabel className="flex items-center">
|
|
429
|
-
Receiver Memo (opcional)
|
|
430
|
-
</FormLabel>
|
|
431
|
-
<FormControl>
|
|
432
|
-
<Input
|
|
433
|
-
type="text"
|
|
434
|
-
placeholder="Enter the escrow receiver Memo"
|
|
435
|
-
{...field}
|
|
436
|
-
onChange={(e) => {
|
|
437
|
-
field.onChange(e);
|
|
438
|
-
}}
|
|
439
|
-
/>
|
|
440
|
-
</FormControl>
|
|
441
|
-
<FormMessage />
|
|
442
|
-
</FormItem>
|
|
443
|
-
)}
|
|
444
|
-
/>
|
|
445
422
|
</div>
|
|
446
423
|
|
|
447
424
|
<FormField
|
|
@@ -78,7 +78,7 @@ export const InitializeEscrowForm = () => {
|
|
|
78
78
|
return (
|
|
79
79
|
<Form {...form}>
|
|
80
80
|
<form onSubmit={handleSubmit} className="flex flex-col space-y-6">
|
|
81
|
-
<Card className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4 p-4">
|
|
81
|
+
<Card className="flex w-full max-w-3xl flex-col sm:flex-row justify-between items-start sm:items-center gap-4 p-4">
|
|
82
82
|
<Link
|
|
83
83
|
className="flex-1"
|
|
84
84
|
href="https://docs.trustlesswork.com/trustless-work/technology-overview/escrow-types"
|
|
@@ -301,7 +301,7 @@ export const InitializeEscrowForm = () => {
|
|
|
301
301
|
<FormItem>
|
|
302
302
|
<FormLabel className="flex items-center justify-between">
|
|
303
303
|
<span className="flex items-center">
|
|
304
|
-
Platform
|
|
304
|
+
Platform
|
|
305
305
|
<span className="text-destructive ml-1">*</span>
|
|
306
306
|
</span>
|
|
307
307
|
</FormLabel>
|
|
@@ -345,7 +345,7 @@ export const InitializeEscrowForm = () => {
|
|
|
345
345
|
/>
|
|
346
346
|
</div>
|
|
347
347
|
|
|
348
|
-
<div className="grid grid-cols-1 lg:grid-cols-
|
|
348
|
+
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
|
349
349
|
<FormField
|
|
350
350
|
control={form.control}
|
|
351
351
|
name="platformFee"
|
|
@@ -399,29 +399,6 @@ export const InitializeEscrowForm = () => {
|
|
|
399
399
|
</FormItem>
|
|
400
400
|
)}
|
|
401
401
|
/>
|
|
402
|
-
|
|
403
|
-
<FormField
|
|
404
|
-
control={form.control}
|
|
405
|
-
name="receiverMemo"
|
|
406
|
-
render={({ field }) => (
|
|
407
|
-
<FormItem>
|
|
408
|
-
<FormLabel className="flex items-center">
|
|
409
|
-
Receiver Memo (opcional)
|
|
410
|
-
</FormLabel>
|
|
411
|
-
<FormControl>
|
|
412
|
-
<Input
|
|
413
|
-
type="text"
|
|
414
|
-
placeholder="Enter the escrow receiver Memo"
|
|
415
|
-
{...field}
|
|
416
|
-
onChange={(e) => {
|
|
417
|
-
field.onChange(e);
|
|
418
|
-
}}
|
|
419
|
-
/>
|
|
420
|
-
</FormControl>
|
|
421
|
-
<FormMessage />
|
|
422
|
-
</FormItem>
|
|
423
|
-
)}
|
|
424
|
-
/>
|
|
425
402
|
</div>
|
|
426
403
|
|
|
427
404
|
<FormField
|
|
@@ -104,16 +104,6 @@ export const useInitializeEscrowSchema = () => {
|
|
|
104
104
|
message: "Platform fee can have a maximum of 2 decimal places.",
|
|
105
105
|
}
|
|
106
106
|
),
|
|
107
|
-
receiverMemo: z
|
|
108
|
-
.string()
|
|
109
|
-
.optional()
|
|
110
|
-
.refine((val) => !val || val.length >= 1, {
|
|
111
|
-
message: "Receiver Memo must be at least 1.",
|
|
112
|
-
})
|
|
113
|
-
.refine((val) => !val || /^[1-9][0-9]*$/.test(val), {
|
|
114
|
-
message:
|
|
115
|
-
"Receiver Memo must be a whole number greater than 0 (no decimals).",
|
|
116
|
-
}),
|
|
117
107
|
});
|
|
118
108
|
};
|
|
119
109
|
|
|
@@ -35,7 +35,6 @@ export function useInitializeEscrow() {
|
|
|
35
35
|
description: "",
|
|
36
36
|
platformFee: undefined,
|
|
37
37
|
amount: undefined,
|
|
38
|
-
receiverMemo: "",
|
|
39
38
|
trustline: {
|
|
40
39
|
address: "",
|
|
41
40
|
},
|
|
@@ -78,7 +77,6 @@ export function useInitializeEscrow() {
|
|
|
78
77
|
description: "Landing for the new product of the company.",
|
|
79
78
|
platformFee: 5,
|
|
80
79
|
amount: 5,
|
|
81
|
-
receiverMemo: "123",
|
|
82
80
|
trustline: {
|
|
83
81
|
address: usdc?.value || "",
|
|
84
82
|
},
|
|
@@ -104,7 +102,6 @@ export function useInitializeEscrow() {
|
|
|
104
102
|
|
|
105
103
|
// Explicitly set the trustline field
|
|
106
104
|
form.setValue("trustline.address", usdc?.value || "");
|
|
107
|
-
form.setValue("trustline.decimals", 10000000);
|
|
108
105
|
};
|
|
109
106
|
|
|
110
107
|
const handleSubmit = form.handleSubmit(async (payload) => {
|
|
@@ -127,7 +124,6 @@ export function useInitializeEscrow() {
|
|
|
127
124
|
typeof payload.platformFee === "string"
|
|
128
125
|
? Number(payload.platformFee)
|
|
129
126
|
: payload.platformFee,
|
|
130
|
-
receiverMemo: Number(payload.receiverMemo) ?? 0,
|
|
131
127
|
signer: walletAddress || "",
|
|
132
128
|
milestones: payload.milestones,
|
|
133
129
|
};
|
|
@@ -17,7 +17,8 @@ export const ReleaseEscrowButton = () => {
|
|
|
17
17
|
const { releaseFunds } = useEscrowsMutations();
|
|
18
18
|
const { selectedEscrow, updateEscrow } = useEscrowContext();
|
|
19
19
|
const dialogStates = useEscrowDialogs();
|
|
20
|
-
const { setAmounts } =
|
|
20
|
+
const { setAmounts, setLastReleasedMilestoneIndex } =
|
|
21
|
+
useEscrowAmountContext();
|
|
21
22
|
const { walletAddress } = useWalletContext();
|
|
22
23
|
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
23
24
|
|
|
@@ -63,6 +64,9 @@ export const ReleaseEscrowButton = () => {
|
|
|
63
64
|
balance: (selectedEscrow?.balance || 0) - (selectedEscrow?.amount || 0),
|
|
64
65
|
});
|
|
65
66
|
|
|
67
|
+
// Clear milestone index context (single-release)
|
|
68
|
+
setLastReleasedMilestoneIndex(null);
|
|
69
|
+
|
|
66
70
|
// Open success dialog
|
|
67
71
|
dialogStates.successRelease.setIsOpen(true);
|
|
68
72
|
} catch (error) {
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
} from "__UI_BASE__/select";
|
|
20
20
|
import { Textarea } from "__UI_BASE__/textarea";
|
|
21
21
|
import { useUpdateEscrow } from "./useUpdateEscrow";
|
|
22
|
-
import { Trash2, DollarSign, Percent, Loader2 } from "lucide-react";
|
|
22
|
+
import { Trash2, DollarSign, Percent, Loader2, Lock } from "lucide-react";
|
|
23
23
|
import Link from "next/link";
|
|
24
24
|
import { trustlineOptions } from "@/components/tw-blocks/wallet-kit/trustlines";
|
|
25
25
|
import {
|
|
@@ -41,6 +41,8 @@ export const UpdateEscrowDialog = () => {
|
|
|
41
41
|
handleRemoveMilestone,
|
|
42
42
|
handleAmountChange,
|
|
43
43
|
handlePlatformFeeChange,
|
|
44
|
+
isEscrowLocked,
|
|
45
|
+
initialMilestonesCount,
|
|
44
46
|
} = useUpdateEscrow();
|
|
45
47
|
|
|
46
48
|
return (
|
|
@@ -71,6 +73,22 @@ export const UpdateEscrowDialog = () => {
|
|
|
71
73
|
<p className="text-muted-foreground mt-1">
|
|
72
74
|
Update escrow details and milestones
|
|
73
75
|
</p>
|
|
76
|
+
|
|
77
|
+
{isEscrowLocked && (
|
|
78
|
+
<div className="flex flex-col gap-2 text-sm bg-yellow-50 dark:bg-yellow-900/20 p-2 rounded-md border border-yellow-200 dark:border-yellow-800 mt-3 px-4">
|
|
79
|
+
<div className="flex items-center gap-2">
|
|
80
|
+
<Lock className="w-4 h-4 text-yellow-600 dark:text-yellow-500 font-medium" />
|
|
81
|
+
<span className="text-yellow-600 dark:text-yellow-500 font-medium">
|
|
82
|
+
Escrow is locked
|
|
83
|
+
</span>
|
|
84
|
+
</div>
|
|
85
|
+
|
|
86
|
+
<p className="text-muted-foreground font-medium">
|
|
87
|
+
When the escrow has balance, it cannot be updated in all
|
|
88
|
+
fields, just adding new milestones is allowed.
|
|
89
|
+
</p>
|
|
90
|
+
</div>
|
|
91
|
+
)}
|
|
74
92
|
</Link>
|
|
75
93
|
</Card>
|
|
76
94
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
|
|
@@ -85,6 +103,7 @@ export const UpdateEscrowDialog = () => {
|
|
|
85
103
|
<FormControl>
|
|
86
104
|
<Input
|
|
87
105
|
placeholder="Escrow title"
|
|
106
|
+
disabled={isEscrowLocked}
|
|
88
107
|
{...field}
|
|
89
108
|
onChange={(e) => {
|
|
90
109
|
field.onChange(e);
|
|
@@ -107,6 +126,7 @@ export const UpdateEscrowDialog = () => {
|
|
|
107
126
|
<FormControl>
|
|
108
127
|
<Input
|
|
109
128
|
placeholder="Enter identifier"
|
|
129
|
+
disabled={isEscrowLocked}
|
|
110
130
|
{...field}
|
|
111
131
|
onChange={(e) => {
|
|
112
132
|
field.onChange(e);
|
|
@@ -129,6 +149,7 @@ export const UpdateEscrowDialog = () => {
|
|
|
129
149
|
<FormControl>
|
|
130
150
|
<Select
|
|
131
151
|
value={field.value}
|
|
152
|
+
disabled={isEscrowLocked}
|
|
132
153
|
onValueChange={(e) => {
|
|
133
154
|
field.onChange(e);
|
|
134
155
|
}}
|
|
@@ -172,6 +193,7 @@ export const UpdateEscrowDialog = () => {
|
|
|
172
193
|
<Input
|
|
173
194
|
placeholder="Enter approver address"
|
|
174
195
|
{...field}
|
|
196
|
+
disabled={isEscrowLocked}
|
|
175
197
|
onChange={(e) => {
|
|
176
198
|
field.onChange(e);
|
|
177
199
|
}}
|
|
@@ -198,6 +220,7 @@ export const UpdateEscrowDialog = () => {
|
|
|
198
220
|
<Input
|
|
199
221
|
placeholder="Enter service provider address"
|
|
200
222
|
{...field}
|
|
223
|
+
disabled={isEscrowLocked}
|
|
201
224
|
onChange={(e) => {
|
|
202
225
|
field.onChange(e);
|
|
203
226
|
}}
|
|
@@ -226,6 +249,7 @@ export const UpdateEscrowDialog = () => {
|
|
|
226
249
|
<Input
|
|
227
250
|
placeholder="Enter release signer address"
|
|
228
251
|
{...field}
|
|
252
|
+
disabled={isEscrowLocked}
|
|
229
253
|
onChange={(e) => {
|
|
230
254
|
field.onChange(e);
|
|
231
255
|
}}
|
|
@@ -252,6 +276,7 @@ export const UpdateEscrowDialog = () => {
|
|
|
252
276
|
<Input
|
|
253
277
|
placeholder="Enter dispute resolver address"
|
|
254
278
|
{...field}
|
|
279
|
+
disabled={isEscrowLocked}
|
|
255
280
|
onChange={(e) => {
|
|
256
281
|
field.onChange(e);
|
|
257
282
|
}}
|
|
@@ -271,7 +296,7 @@ export const UpdateEscrowDialog = () => {
|
|
|
271
296
|
<FormItem>
|
|
272
297
|
<FormLabel className="flex items-center justify-between">
|
|
273
298
|
<span className="flex items-center">
|
|
274
|
-
Platform
|
|
299
|
+
Platform
|
|
275
300
|
<span className="text-destructive ml-1">*</span>
|
|
276
301
|
</span>
|
|
277
302
|
</FormLabel>
|
|
@@ -280,6 +305,7 @@ export const UpdateEscrowDialog = () => {
|
|
|
280
305
|
<Input
|
|
281
306
|
placeholder="Enter platform address"
|
|
282
307
|
{...field}
|
|
308
|
+
disabled={isEscrowLocked}
|
|
283
309
|
onChange={(e) => {
|
|
284
310
|
field.onChange(e);
|
|
285
311
|
}}
|
|
@@ -304,6 +330,7 @@ export const UpdateEscrowDialog = () => {
|
|
|
304
330
|
<Input
|
|
305
331
|
placeholder="Enter receiver address"
|
|
306
332
|
{...field}
|
|
333
|
+
disabled={isEscrowLocked}
|
|
307
334
|
onChange={(e) => {
|
|
308
335
|
field.onChange(e);
|
|
309
336
|
}}
|
|
@@ -315,7 +342,7 @@ export const UpdateEscrowDialog = () => {
|
|
|
315
342
|
/>
|
|
316
343
|
</div>
|
|
317
344
|
|
|
318
|
-
<div className="grid grid-cols-1 lg:grid-cols-
|
|
345
|
+
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
|
319
346
|
<FormField
|
|
320
347
|
control={form.control}
|
|
321
348
|
name="platformFee"
|
|
@@ -334,6 +361,7 @@ export const UpdateEscrowDialog = () => {
|
|
|
334
361
|
<Input
|
|
335
362
|
placeholder="Enter platform fee"
|
|
336
363
|
className="pl-10"
|
|
364
|
+
disabled={isEscrowLocked}
|
|
337
365
|
value={form.watch("platformFee")?.toString() || ""}
|
|
338
366
|
onChange={handlePlatformFeeChange}
|
|
339
367
|
/>
|
|
@@ -363,6 +391,7 @@ export const UpdateEscrowDialog = () => {
|
|
|
363
391
|
className="pl-10"
|
|
364
392
|
value={form.watch("amount")?.toString() || ""}
|
|
365
393
|
onChange={handleAmountChange}
|
|
394
|
+
disabled={isEscrowLocked}
|
|
366
395
|
/>
|
|
367
396
|
</div>
|
|
368
397
|
</FormControl>
|
|
@@ -370,29 +399,6 @@ export const UpdateEscrowDialog = () => {
|
|
|
370
399
|
</FormItem>
|
|
371
400
|
)}
|
|
372
401
|
/>
|
|
373
|
-
|
|
374
|
-
<FormField
|
|
375
|
-
control={form.control}
|
|
376
|
-
name="receiverMemo"
|
|
377
|
-
render={({ field }) => (
|
|
378
|
-
<FormItem>
|
|
379
|
-
<FormLabel className="flex items-center">
|
|
380
|
-
Receiver Memo (opcional)
|
|
381
|
-
</FormLabel>
|
|
382
|
-
<FormControl>
|
|
383
|
-
<Input
|
|
384
|
-
type="text"
|
|
385
|
-
placeholder="Enter the escrow receiver Memo"
|
|
386
|
-
{...field}
|
|
387
|
-
onChange={(e) => {
|
|
388
|
-
field.onChange(e);
|
|
389
|
-
}}
|
|
390
|
-
/>
|
|
391
|
-
</FormControl>
|
|
392
|
-
<FormMessage />
|
|
393
|
-
</FormItem>
|
|
394
|
-
)}
|
|
395
|
-
/>
|
|
396
402
|
</div>
|
|
397
403
|
|
|
398
404
|
<FormField
|
|
@@ -405,6 +411,7 @@ export const UpdateEscrowDialog = () => {
|
|
|
405
411
|
</FormLabel>
|
|
406
412
|
<FormControl>
|
|
407
413
|
<Textarea
|
|
414
|
+
disabled={isEscrowLocked}
|
|
408
415
|
placeholder="Escrow description"
|
|
409
416
|
{...field}
|
|
410
417
|
onChange={(e) => {
|
|
@@ -428,6 +435,9 @@ export const UpdateEscrowDialog = () => {
|
|
|
428
435
|
placeholder="Milestone Description"
|
|
429
436
|
value={milestone.description}
|
|
430
437
|
className="w-full sm:flex-1"
|
|
438
|
+
disabled={
|
|
439
|
+
isEscrowLocked && index < initialMilestonesCount
|
|
440
|
+
}
|
|
431
441
|
onChange={(e) => {
|
|
432
442
|
const updatedMilestones = [...milestones];
|
|
433
443
|
updatedMilestones[index].description = e.target.value;
|
|
@@ -438,7 +448,11 @@ export const UpdateEscrowDialog = () => {
|
|
|
438
448
|
<Button
|
|
439
449
|
onClick={() => handleRemoveMilestone(index)}
|
|
440
450
|
className="p-2 bg-transparent text-destructive rounded-md border-none shadow-none hover:bg-transparent hover:shadow-none hover:text-destructive focus:ring-0 active:ring-0 self-start sm:self-center cursor-pointer"
|
|
441
|
-
|
|
451
|
+
type="button"
|
|
452
|
+
disabled={
|
|
453
|
+
(isEscrowLocked && index < initialMilestonesCount) ||
|
|
454
|
+
milestones.length === 1
|
|
455
|
+
}
|
|
442
456
|
>
|
|
443
457
|
<Trash2 className="h-5 w-5" />
|
|
444
458
|
</Button>
|