@trustless-work/blocks 1.0.5 → 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 -1920
- package/package.json +1 -1
- package/templates/dashboard/dashboard-01/Dashboard.tsx +118 -71
- 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
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
DialogTitle,
|
|
30
30
|
DialogTrigger,
|
|
31
31
|
} from "__UI_BASE__/dialog";
|
|
32
|
+
import { Separator } from "__UI_BASE__/separator";
|
|
32
33
|
|
|
33
34
|
export const InitializeEscrowDialog = () => {
|
|
34
35
|
const {
|
|
@@ -130,7 +131,7 @@ export const InitializeEscrowDialog = () => {
|
|
|
130
131
|
</Button>
|
|
131
132
|
)}
|
|
132
133
|
</Card>
|
|
133
|
-
<div className="grid grid-cols-1 lg:grid-cols-
|
|
134
|
+
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
|
134
135
|
<FormField
|
|
135
136
|
control={form.control}
|
|
136
137
|
name="title"
|
|
@@ -174,7 +175,9 @@ export const InitializeEscrowDialog = () => {
|
|
|
174
175
|
</FormItem>
|
|
175
176
|
)}
|
|
176
177
|
/>
|
|
178
|
+
</div>
|
|
177
179
|
|
|
180
|
+
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
|
178
181
|
<FormField
|
|
179
182
|
control={form.control}
|
|
180
183
|
name="trustline.address"
|
|
@@ -211,6 +214,34 @@ export const InitializeEscrowDialog = () => {
|
|
|
211
214
|
</FormItem>
|
|
212
215
|
)}
|
|
213
216
|
/>
|
|
217
|
+
|
|
218
|
+
<FormField
|
|
219
|
+
control={form.control}
|
|
220
|
+
name="platformFee"
|
|
221
|
+
render={() => (
|
|
222
|
+
<FormItem>
|
|
223
|
+
<FormLabel className="flex items-center">
|
|
224
|
+
Platform Fee
|
|
225
|
+
<span className="text-destructive ml-1">*</span>
|
|
226
|
+
</FormLabel>
|
|
227
|
+
<FormControl>
|
|
228
|
+
<div className="relative">
|
|
229
|
+
<Percent
|
|
230
|
+
className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-500"
|
|
231
|
+
size={18}
|
|
232
|
+
/>
|
|
233
|
+
<Input
|
|
234
|
+
placeholder="Enter platform fee"
|
|
235
|
+
className="pl-10"
|
|
236
|
+
value={form.watch("platformFee")?.toString() || ""}
|
|
237
|
+
onChange={handlePlatformFeeChange}
|
|
238
|
+
/>
|
|
239
|
+
</div>
|
|
240
|
+
</FormControl>
|
|
241
|
+
<FormMessage />
|
|
242
|
+
</FormItem>
|
|
243
|
+
)}
|
|
244
|
+
/>
|
|
214
245
|
</div>
|
|
215
246
|
|
|
216
247
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
|
@@ -320,7 +351,7 @@ export const InitializeEscrowDialog = () => {
|
|
|
320
351
|
/>
|
|
321
352
|
</div>
|
|
322
353
|
|
|
323
|
-
<div className="grid grid-cols-1
|
|
354
|
+
<div className="grid grid-cols-1 gap-4">
|
|
324
355
|
<FormField
|
|
325
356
|
control={form.control}
|
|
326
357
|
name="roles.platformAddress"
|
|
@@ -328,7 +359,7 @@ export const InitializeEscrowDialog = () => {
|
|
|
328
359
|
<FormItem>
|
|
329
360
|
<FormLabel className="flex items-center justify-between">
|
|
330
361
|
<span className="flex items-center">
|
|
331
|
-
Platform
|
|
362
|
+
Platform
|
|
332
363
|
<span className="text-destructive ml-1">*</span>
|
|
333
364
|
</span>
|
|
334
365
|
</FormLabel>
|
|
@@ -346,83 +377,6 @@ export const InitializeEscrowDialog = () => {
|
|
|
346
377
|
</FormItem>
|
|
347
378
|
)}
|
|
348
379
|
/>
|
|
349
|
-
<FormField
|
|
350
|
-
control={form.control}
|
|
351
|
-
name="roles.receiver"
|
|
352
|
-
render={({ field }) => (
|
|
353
|
-
<FormItem>
|
|
354
|
-
<FormLabel className="flex items-center justify-between">
|
|
355
|
-
<span className="flex items-center">
|
|
356
|
-
Receiver<span className="text-destructive ml-1">*</span>
|
|
357
|
-
</span>
|
|
358
|
-
</FormLabel>
|
|
359
|
-
|
|
360
|
-
<FormControl>
|
|
361
|
-
<Input
|
|
362
|
-
placeholder="Enter receiver address"
|
|
363
|
-
{...field}
|
|
364
|
-
onChange={(e) => {
|
|
365
|
-
field.onChange(e);
|
|
366
|
-
}}
|
|
367
|
-
/>
|
|
368
|
-
</FormControl>
|
|
369
|
-
<FormMessage />
|
|
370
|
-
</FormItem>
|
|
371
|
-
)}
|
|
372
|
-
/>
|
|
373
|
-
</div>
|
|
374
|
-
|
|
375
|
-
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
|
376
|
-
<FormField
|
|
377
|
-
control={form.control}
|
|
378
|
-
name="platformFee"
|
|
379
|
-
render={() => (
|
|
380
|
-
<FormItem>
|
|
381
|
-
<FormLabel className="flex items-center">
|
|
382
|
-
Platform Fee
|
|
383
|
-
<span className="text-destructive ml-1">*</span>
|
|
384
|
-
</FormLabel>
|
|
385
|
-
<FormControl>
|
|
386
|
-
<div className="relative">
|
|
387
|
-
<Percent
|
|
388
|
-
className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-500"
|
|
389
|
-
size={18}
|
|
390
|
-
/>
|
|
391
|
-
<Input
|
|
392
|
-
placeholder="Enter platform fee"
|
|
393
|
-
className="pl-10"
|
|
394
|
-
value={form.watch("platformFee")?.toString() || ""}
|
|
395
|
-
onChange={handlePlatformFeeChange}
|
|
396
|
-
/>
|
|
397
|
-
</div>
|
|
398
|
-
</FormControl>
|
|
399
|
-
<FormMessage />
|
|
400
|
-
</FormItem>
|
|
401
|
-
)}
|
|
402
|
-
/>
|
|
403
|
-
|
|
404
|
-
<FormField
|
|
405
|
-
control={form.control}
|
|
406
|
-
name="receiverMemo"
|
|
407
|
-
render={({ field }) => (
|
|
408
|
-
<FormItem>
|
|
409
|
-
<FormLabel className="flex items-center">
|
|
410
|
-
Receiver Memo (opcional)
|
|
411
|
-
</FormLabel>
|
|
412
|
-
<FormControl>
|
|
413
|
-
<Input
|
|
414
|
-
type="text"
|
|
415
|
-
placeholder="Enter the escrow receiver Memo"
|
|
416
|
-
{...field}
|
|
417
|
-
onChange={(e) => {
|
|
418
|
-
field.onChange(e);
|
|
419
|
-
}}
|
|
420
|
-
/>
|
|
421
|
-
</FormControl>
|
|
422
|
-
<FormMessage />
|
|
423
|
-
</FormItem>
|
|
424
|
-
)}
|
|
425
|
-
/>
|
|
426
380
|
</div>
|
|
427
381
|
|
|
428
382
|
<FormField
|
|
@@ -453,19 +407,32 @@ export const InitializeEscrowDialog = () => {
|
|
|
453
407
|
</FormLabel>
|
|
454
408
|
{milestones.map((milestone, index) => (
|
|
455
409
|
<div key={index} className="space-y-4">
|
|
456
|
-
<div className="
|
|
457
|
-
<
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
410
|
+
<div className="grid grid-cols-1 md:grid-cols-12 gap-4 items-center">
|
|
411
|
+
<div className="md:col-span-4">
|
|
412
|
+
<Input
|
|
413
|
+
placeholder="Enter receiver address"
|
|
414
|
+
value={milestone.receiver}
|
|
415
|
+
onChange={(e) => {
|
|
416
|
+
const updatedMilestones = [...milestones];
|
|
417
|
+
updatedMilestones[index].receiver = e.target.value;
|
|
418
|
+
form.setValue("milestones", updatedMilestones);
|
|
419
|
+
}}
|
|
420
|
+
/>
|
|
421
|
+
</div>
|
|
422
|
+
|
|
423
|
+
<div className="md:col-span-4">
|
|
424
|
+
<Input
|
|
425
|
+
placeholder="Milestone description"
|
|
426
|
+
value={milestone.description}
|
|
427
|
+
onChange={(e) => {
|
|
428
|
+
const updatedMilestones = [...milestones];
|
|
429
|
+
updatedMilestones[index].description = e.target.value;
|
|
430
|
+
form.setValue("milestones", updatedMilestones);
|
|
431
|
+
}}
|
|
432
|
+
/>
|
|
433
|
+
</div>
|
|
467
434
|
|
|
468
|
-
<div className="
|
|
435
|
+
<div className="md:col-span-3 relative">
|
|
469
436
|
<DollarSign
|
|
470
437
|
className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-500"
|
|
471
438
|
size={18}
|
|
@@ -478,21 +445,29 @@ export const InitializeEscrowDialog = () => {
|
|
|
478
445
|
/>
|
|
479
446
|
</div>
|
|
480
447
|
|
|
481
|
-
<
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
448
|
+
<div className="md:col-span-1 flex justify-end">
|
|
449
|
+
<Button
|
|
450
|
+
onClick={() => handleRemoveMilestone(index)}
|
|
451
|
+
className="p-2 bg-transparent text-red-500 hover:text-red-600"
|
|
452
|
+
disabled={milestones.length === 1}
|
|
453
|
+
type="button"
|
|
454
|
+
>
|
|
455
|
+
<Trash2 className="h-5 w-5" />
|
|
456
|
+
</Button>
|
|
457
|
+
</div>
|
|
489
458
|
</div>
|
|
490
459
|
|
|
460
|
+
{/* Separator */}
|
|
461
|
+
{index < milestones.length - 1 && (
|
|
462
|
+
<Separator className="w-full" />
|
|
463
|
+
)}
|
|
464
|
+
|
|
465
|
+
{/* Add button */}
|
|
491
466
|
{index === milestones.length - 1 && (
|
|
492
467
|
<div className="flex justify-end mt-4">
|
|
493
468
|
<Button
|
|
494
469
|
disabled={isAnyMilestoneEmpty}
|
|
495
|
-
className="w-full md:w-
|
|
470
|
+
className="w-full md:w-fit md:min-w-40 cursor-pointer"
|
|
496
471
|
variant="outline"
|
|
497
472
|
onClick={handleAddMilestone}
|
|
498
473
|
type="button"
|
|
@@ -22,6 +22,7 @@ import { useInitializeEscrow } from "./useInitializeEscrow";
|
|
|
22
22
|
import { Trash2, DollarSign, Percent, Loader2 } from "lucide-react";
|
|
23
23
|
import Link from "next/link";
|
|
24
24
|
import { trustlineOptions } from "@/components/tw-blocks/wallet-kit/trustlines";
|
|
25
|
+
import { Separator } from "__UI_BASE__/separator";
|
|
25
26
|
|
|
26
27
|
export const InitializeEscrowForm = () => {
|
|
27
28
|
const {
|
|
@@ -86,7 +87,7 @@ export const InitializeEscrowForm = () => {
|
|
|
86
87
|
return (
|
|
87
88
|
<Form {...form}>
|
|
88
89
|
<form onSubmit={handleSubmit} className="flex flex-col space-y-6">
|
|
89
|
-
<Card className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4 p-4">
|
|
90
|
+
<Card className="flex w-full max-w-3xl flex-col sm:flex-row justify-between items-start sm:items-center gap-4 p-4">
|
|
90
91
|
<Link
|
|
91
92
|
className="flex-1"
|
|
92
93
|
href="https://docs.trustlesswork.com/trustless-work/technology-overview/escrow-types"
|
|
@@ -111,7 +112,7 @@ export const InitializeEscrowForm = () => {
|
|
|
111
112
|
</Button>
|
|
112
113
|
)}
|
|
113
114
|
</Card>
|
|
114
|
-
<div className="grid grid-cols-1 lg:grid-cols-
|
|
115
|
+
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
|
115
116
|
<FormField
|
|
116
117
|
control={form.control}
|
|
117
118
|
name="title"
|
|
@@ -155,7 +156,9 @@ export const InitializeEscrowForm = () => {
|
|
|
155
156
|
</FormItem>
|
|
156
157
|
)}
|
|
157
158
|
/>
|
|
159
|
+
</div>
|
|
158
160
|
|
|
161
|
+
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
|
159
162
|
<FormField
|
|
160
163
|
control={form.control}
|
|
161
164
|
name="trustline.address"
|
|
@@ -192,6 +195,34 @@ export const InitializeEscrowForm = () => {
|
|
|
192
195
|
</FormItem>
|
|
193
196
|
)}
|
|
194
197
|
/>
|
|
198
|
+
|
|
199
|
+
<FormField
|
|
200
|
+
control={form.control}
|
|
201
|
+
name="platformFee"
|
|
202
|
+
render={() => (
|
|
203
|
+
<FormItem>
|
|
204
|
+
<FormLabel className="flex items-center">
|
|
205
|
+
Platform Fee
|
|
206
|
+
<span className="text-destructive ml-1">*</span>
|
|
207
|
+
</FormLabel>
|
|
208
|
+
<FormControl>
|
|
209
|
+
<div className="relative">
|
|
210
|
+
<Percent
|
|
211
|
+
className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-500"
|
|
212
|
+
size={18}
|
|
213
|
+
/>
|
|
214
|
+
<Input
|
|
215
|
+
placeholder="Enter platform fee"
|
|
216
|
+
className="pl-10"
|
|
217
|
+
value={form.watch("platformFee")?.toString() || ""}
|
|
218
|
+
onChange={handlePlatformFeeChange}
|
|
219
|
+
/>
|
|
220
|
+
</div>
|
|
221
|
+
</FormControl>
|
|
222
|
+
<FormMessage />
|
|
223
|
+
</FormItem>
|
|
224
|
+
)}
|
|
225
|
+
/>
|
|
195
226
|
</div>
|
|
196
227
|
|
|
197
228
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
|
@@ -301,7 +332,7 @@ export const InitializeEscrowForm = () => {
|
|
|
301
332
|
/>
|
|
302
333
|
</div>
|
|
303
334
|
|
|
304
|
-
<div className="grid grid-cols-1
|
|
335
|
+
<div className="grid grid-cols-1 gap-4">
|
|
305
336
|
<FormField
|
|
306
337
|
control={form.control}
|
|
307
338
|
name="roles.platformAddress"
|
|
@@ -309,7 +340,7 @@ export const InitializeEscrowForm = () => {
|
|
|
309
340
|
<FormItem>
|
|
310
341
|
<FormLabel className="flex items-center justify-between">
|
|
311
342
|
<span className="flex items-center">
|
|
312
|
-
Platform
|
|
343
|
+
Platform
|
|
313
344
|
<span className="text-destructive ml-1">*</span>
|
|
314
345
|
</span>
|
|
315
346
|
</FormLabel>
|
|
@@ -327,82 +358,6 @@ export const InitializeEscrowForm = () => {
|
|
|
327
358
|
</FormItem>
|
|
328
359
|
)}
|
|
329
360
|
/>
|
|
330
|
-
<FormField
|
|
331
|
-
control={form.control}
|
|
332
|
-
name="roles.receiver"
|
|
333
|
-
render={({ field }) => (
|
|
334
|
-
<FormItem>
|
|
335
|
-
<FormLabel className="flex items-center justify-between">
|
|
336
|
-
<span className="flex items-center">
|
|
337
|
-
Receiver<span className="text-destructive ml-1">*</span>
|
|
338
|
-
</span>
|
|
339
|
-
</FormLabel>
|
|
340
|
-
|
|
341
|
-
<FormControl>
|
|
342
|
-
<Input
|
|
343
|
-
placeholder="Enter receiver address"
|
|
344
|
-
{...field}
|
|
345
|
-
onChange={(e) => {
|
|
346
|
-
field.onChange(e);
|
|
347
|
-
}}
|
|
348
|
-
/>
|
|
349
|
-
</FormControl>
|
|
350
|
-
<FormMessage />
|
|
351
|
-
</FormItem>
|
|
352
|
-
)}
|
|
353
|
-
/>
|
|
354
|
-
</div>
|
|
355
|
-
|
|
356
|
-
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
|
357
|
-
<FormField
|
|
358
|
-
control={form.control}
|
|
359
|
-
name="platformFee"
|
|
360
|
-
render={() => (
|
|
361
|
-
<FormItem>
|
|
362
|
-
<FormLabel className="flex items-center">
|
|
363
|
-
Platform Fee<span className="text-destructive ml-1">*</span>
|
|
364
|
-
</FormLabel>
|
|
365
|
-
<FormControl>
|
|
366
|
-
<div className="relative">
|
|
367
|
-
<Percent
|
|
368
|
-
className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-500"
|
|
369
|
-
size={18}
|
|
370
|
-
/>
|
|
371
|
-
<Input
|
|
372
|
-
placeholder="Enter platform fee"
|
|
373
|
-
className="pl-10"
|
|
374
|
-
value={form.watch("platformFee")?.toString() || ""}
|
|
375
|
-
onChange={handlePlatformFeeChange}
|
|
376
|
-
/>
|
|
377
|
-
</div>
|
|
378
|
-
</FormControl>
|
|
379
|
-
<FormMessage />
|
|
380
|
-
</FormItem>
|
|
381
|
-
)}
|
|
382
|
-
/>
|
|
383
|
-
|
|
384
|
-
<FormField
|
|
385
|
-
control={form.control}
|
|
386
|
-
name="receiverMemo"
|
|
387
|
-
render={({ field }) => (
|
|
388
|
-
<FormItem>
|
|
389
|
-
<FormLabel className="flex items-center">
|
|
390
|
-
Receiver Memo (opcional)
|
|
391
|
-
</FormLabel>
|
|
392
|
-
<FormControl>
|
|
393
|
-
<Input
|
|
394
|
-
type="text"
|
|
395
|
-
placeholder="Enter the escrow receiver Memo"
|
|
396
|
-
{...field}
|
|
397
|
-
onChange={(e) => {
|
|
398
|
-
field.onChange(e);
|
|
399
|
-
}}
|
|
400
|
-
/>
|
|
401
|
-
</FormControl>
|
|
402
|
-
<FormMessage />
|
|
403
|
-
</FormItem>
|
|
404
|
-
)}
|
|
405
|
-
/>
|
|
406
361
|
</div>
|
|
407
362
|
|
|
408
363
|
<FormField
|
|
@@ -432,20 +387,33 @@ export const InitializeEscrowForm = () => {
|
|
|
432
387
|
Milestones<span className="text-destructive ml-1">*</span>
|
|
433
388
|
</FormLabel>
|
|
434
389
|
{milestones.map((milestone, index) => (
|
|
435
|
-
<div key={index} className="space-y-4">
|
|
436
|
-
<div className="
|
|
437
|
-
<
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
390
|
+
<div key={index} className="space-y-4 max-w-3xl">
|
|
391
|
+
<div className="grid grid-cols-1 md:grid-cols-12 gap-4 items-center">
|
|
392
|
+
<div className="md:col-span-4">
|
|
393
|
+
<Input
|
|
394
|
+
placeholder="Enter receiver address"
|
|
395
|
+
value={milestone.receiver}
|
|
396
|
+
onChange={(e) => {
|
|
397
|
+
const updatedMilestones = [...milestones];
|
|
398
|
+
updatedMilestones[index].receiver = e.target.value;
|
|
399
|
+
form.setValue("milestones", updatedMilestones);
|
|
400
|
+
}}
|
|
401
|
+
/>
|
|
402
|
+
</div>
|
|
403
|
+
|
|
404
|
+
<div className="md:col-span-4">
|
|
405
|
+
<Input
|
|
406
|
+
placeholder="Milestone description"
|
|
407
|
+
value={milestone.description}
|
|
408
|
+
onChange={(e) => {
|
|
409
|
+
const updatedMilestones = [...milestones];
|
|
410
|
+
updatedMilestones[index].description = e.target.value;
|
|
411
|
+
form.setValue("milestones", updatedMilestones);
|
|
412
|
+
}}
|
|
413
|
+
/>
|
|
414
|
+
</div>
|
|
447
415
|
|
|
448
|
-
<div className="
|
|
416
|
+
<div className="md:col-span-3 relative">
|
|
449
417
|
<DollarSign
|
|
450
418
|
className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-500"
|
|
451
419
|
size={18}
|
|
@@ -458,21 +426,29 @@ export const InitializeEscrowForm = () => {
|
|
|
458
426
|
/>
|
|
459
427
|
</div>
|
|
460
428
|
|
|
461
|
-
<
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
429
|
+
<div className="md:col-span-1 flex justify-end">
|
|
430
|
+
<Button
|
|
431
|
+
onClick={() => handleRemoveMilestone(index)}
|
|
432
|
+
className="p-2 bg-transparent text-red-500 hover:text-red-600"
|
|
433
|
+
disabled={milestones.length === 1}
|
|
434
|
+
type="button"
|
|
435
|
+
>
|
|
436
|
+
<Trash2 className="h-5 w-5" />
|
|
437
|
+
</Button>
|
|
438
|
+
</div>
|
|
469
439
|
</div>
|
|
470
440
|
|
|
441
|
+
{/* Separator */}
|
|
442
|
+
{index < milestones.length - 1 && (
|
|
443
|
+
<Separator className="w-full" />
|
|
444
|
+
)}
|
|
445
|
+
|
|
446
|
+
{/* Add button */}
|
|
471
447
|
{index === milestones.length - 1 && (
|
|
472
448
|
<div className="flex justify-end mt-4">
|
|
473
449
|
<Button
|
|
474
450
|
disabled={isAnyMilestoneEmpty}
|
|
475
|
-
className="w-full md:w-
|
|
451
|
+
className="w-full md:w-fit md:min-w-40 cursor-pointer"
|
|
476
452
|
variant="outline"
|
|
477
453
|
onClick={handleAddMilestone}
|
|
478
454
|
type="button"
|
|
@@ -50,14 +50,6 @@ export const useInitializeEscrowSchema = () => {
|
|
|
50
50
|
.refine((value) => isValidWallet(value), {
|
|
51
51
|
message: "Dispute resolver must be a valid wallet.",
|
|
52
52
|
}),
|
|
53
|
-
receiver: z
|
|
54
|
-
.string()
|
|
55
|
-
.min(1, {
|
|
56
|
-
message: "Receiver address is required.",
|
|
57
|
-
})
|
|
58
|
-
.refine((value) => isValidWallet(value), {
|
|
59
|
-
message: "Receiver address must be a valid wallet.",
|
|
60
|
-
}),
|
|
61
53
|
}),
|
|
62
54
|
engagementId: z.string().min(1, {
|
|
63
55
|
message: "Engagement is required.",
|
|
@@ -104,16 +96,6 @@ export const useInitializeEscrowSchema = () => {
|
|
|
104
96
|
message: "Platform fee can have a maximum of 2 decimal places.",
|
|
105
97
|
}
|
|
106
98
|
),
|
|
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
99
|
});
|
|
118
100
|
};
|
|
119
101
|
|
|
@@ -124,6 +106,14 @@ export const useInitializeEscrowSchema = () => {
|
|
|
124
106
|
milestones: z
|
|
125
107
|
.array(
|
|
126
108
|
z.object({
|
|
109
|
+
receiver: z
|
|
110
|
+
.string()
|
|
111
|
+
.min(1, {
|
|
112
|
+
message: "Receiver address is required.",
|
|
113
|
+
})
|
|
114
|
+
.refine((value) => isValidWallet(value), {
|
|
115
|
+
message: "Receiver address must be a valid wallet.",
|
|
116
|
+
}),
|
|
127
117
|
description: z.string().min(1, {
|
|
128
118
|
message: "Milestone description is required.",
|
|
129
119
|
}),
|
|
@@ -34,7 +34,6 @@ export function useInitializeEscrow() {
|
|
|
34
34
|
title: "",
|
|
35
35
|
description: "",
|
|
36
36
|
platformFee: undefined,
|
|
37
|
-
receiverMemo: "",
|
|
38
37
|
trustline: {
|
|
39
38
|
address: "",
|
|
40
39
|
},
|
|
@@ -42,25 +41,27 @@ export function useInitializeEscrow() {
|
|
|
42
41
|
approver: "",
|
|
43
42
|
serviceProvider: "",
|
|
44
43
|
platformAddress: "",
|
|
45
|
-
receiver: "",
|
|
46
44
|
releaseSigner: "",
|
|
47
45
|
disputeResolver: "",
|
|
48
46
|
},
|
|
49
|
-
milestones: [{ description: "", amount: "" }],
|
|
47
|
+
milestones: [{ receiver: "", description: "", amount: "" }],
|
|
50
48
|
},
|
|
51
49
|
mode: "onChange",
|
|
52
50
|
});
|
|
53
51
|
|
|
54
52
|
const milestones = form.watch("milestones");
|
|
55
53
|
const isAnyMilestoneEmpty = milestones.some(
|
|
56
|
-
(milestone) =>
|
|
54
|
+
(milestone) =>
|
|
55
|
+
milestone.description === "" ||
|
|
56
|
+
milestone.receiver === "" ||
|
|
57
|
+
milestone.amount === ""
|
|
57
58
|
);
|
|
58
59
|
|
|
59
60
|
const handleAddMilestone = () => {
|
|
60
61
|
const currentMilestones = form.getValues("milestones");
|
|
61
62
|
const updatedMilestones = [
|
|
62
63
|
...currentMilestones,
|
|
63
|
-
{ description: "", amount: "" },
|
|
64
|
+
{ receiver: "", description: "", amount: "" },
|
|
64
65
|
];
|
|
65
66
|
form.setValue("milestones", updatedMilestones);
|
|
66
67
|
};
|
|
@@ -79,7 +80,6 @@ export function useInitializeEscrow() {
|
|
|
79
80
|
title: "Design Landing Page",
|
|
80
81
|
description: "Landing for the new product of the company.",
|
|
81
82
|
platformFee: 5,
|
|
82
|
-
receiverMemo: "123",
|
|
83
83
|
trustline: {
|
|
84
84
|
address: usdc?.value || "",
|
|
85
85
|
},
|
|
@@ -87,14 +87,25 @@ export function useInitializeEscrow() {
|
|
|
87
87
|
approver: walletAddress || "",
|
|
88
88
|
serviceProvider: walletAddress || "",
|
|
89
89
|
platformAddress: walletAddress || "",
|
|
90
|
-
receiver: walletAddress || "",
|
|
91
90
|
releaseSigner: walletAddress || "",
|
|
92
91
|
disputeResolver: walletAddress || "",
|
|
93
92
|
},
|
|
94
93
|
milestones: [
|
|
95
|
-
{
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
{
|
|
95
|
+
receiver: walletAddress || "",
|
|
96
|
+
description: "Design the wireframe",
|
|
97
|
+
amount: 2,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
receiver: walletAddress || "",
|
|
101
|
+
description: "Develop the wireframe",
|
|
102
|
+
amount: 2,
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
receiver: walletAddress || "",
|
|
106
|
+
description: "Deploy the wireframe",
|
|
107
|
+
amount: 2,
|
|
108
|
+
},
|
|
98
109
|
],
|
|
99
110
|
};
|
|
100
111
|
|
|
@@ -105,7 +116,6 @@ export function useInitializeEscrow() {
|
|
|
105
116
|
|
|
106
117
|
// Explicitly set the trustline field
|
|
107
118
|
form.setValue("trustline.address", usdc?.value || "");
|
|
108
|
-
form.setValue("trustline.decimals", 10000000);
|
|
109
119
|
};
|
|
110
120
|
|
|
111
121
|
const handleSubmit = form.handleSubmit(async (payload) => {
|
|
@@ -124,7 +134,6 @@ export function useInitializeEscrow() {
|
|
|
124
134
|
typeof payload.platformFee === "string"
|
|
125
135
|
? Number(payload.platformFee)
|
|
126
136
|
: payload.platformFee,
|
|
127
|
-
receiverMemo: Number(payload.receiverMemo) ?? 0,
|
|
128
137
|
signer: walletAddress || "",
|
|
129
138
|
milestones: payload.milestones.map((milestone) => ({
|
|
130
139
|
...milestone,
|
|
@@ -26,7 +26,8 @@ export const ReleaseMilestoneButton = ({
|
|
|
26
26
|
const { releaseFunds } = useEscrowsMutations();
|
|
27
27
|
const { selectedEscrow, updateEscrow } = useEscrowContext();
|
|
28
28
|
const dialogStates = useEscrowDialogs();
|
|
29
|
-
const { setAmounts } =
|
|
29
|
+
const { setAmounts, setLastReleasedMilestoneIndex } =
|
|
30
|
+
useEscrowAmountContext();
|
|
30
31
|
const { walletAddress } = useWalletContext();
|
|
31
32
|
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
32
33
|
|
|
@@ -87,6 +88,9 @@ export const ReleaseMilestoneButton = ({
|
|
|
87
88
|
balance: (selectedEscrow?.balance || 0) - (selectedEscrow?.amount || 0),
|
|
88
89
|
});
|
|
89
90
|
|
|
91
|
+
// Remember which milestone was released for the success dialog
|
|
92
|
+
setLastReleasedMilestoneIndex(Number(milestoneIndex));
|
|
93
|
+
|
|
90
94
|
// Open success dialog
|
|
91
95
|
dialogStates.successRelease.setIsOpen(true);
|
|
92
96
|
} catch (error) {
|