@trustless-work/blocks 0.0.1

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.
Files changed (74) hide show
  1. package/README.md +96 -0
  2. package/bin/index.js +1123 -0
  3. package/package.json +44 -0
  4. package/templates/deps.json +29 -0
  5. package/templates/escrows/details/Actions.tsx +149 -0
  6. package/templates/escrows/details/Entities.tsx +48 -0
  7. package/templates/escrows/details/EntityCard.tsx +98 -0
  8. package/templates/escrows/details/EscrowDetailDialog.tsx +154 -0
  9. package/templates/escrows/details/GeneralInformation.tsx +329 -0
  10. package/templates/escrows/details/MilestoneCard.tsx +254 -0
  11. package/templates/escrows/details/MilestoneDetailDialog.tsx +276 -0
  12. package/templates/escrows/details/Milestones.tsx +87 -0
  13. package/templates/escrows/details/ProgressEscrow.tsx +191 -0
  14. package/templates/escrows/details/StatisticsCard.tsx +79 -0
  15. package/templates/escrows/details/SuccessReleaseDialog.tsx +101 -0
  16. package/templates/escrows/details/useDetailsEscrow.ts +126 -0
  17. package/templates/escrows/escrow-context/EscrowAmountProvider.tsx +86 -0
  18. package/templates/escrows/escrow-context/EscrowDialogsProvider.tsx +108 -0
  19. package/templates/escrows/escrow-context/EscrowProvider.tsx +124 -0
  20. package/templates/escrows/escrows-by-role/cards/EscrowsCards.tsx +503 -0
  21. package/templates/escrows/escrows-by-role/cards/Filters.tsx +421 -0
  22. package/templates/escrows/escrows-by-role/table/EscrowsTable.tsx +427 -0
  23. package/templates/escrows/escrows-by-role/table/Filters.tsx +421 -0
  24. package/templates/escrows/escrows-by-role/useEscrowsByRole.shared.ts +336 -0
  25. package/templates/escrows/escrows-by-signer/cards/EscrowsCards.tsx +502 -0
  26. package/templates/escrows/escrows-by-signer/cards/Filters.tsx +389 -0
  27. package/templates/escrows/escrows-by-signer/table/EscrowsTable.tsx +422 -0
  28. package/templates/escrows/escrows-by-signer/table/Filters.tsx +389 -0
  29. package/templates/escrows/escrows-by-signer/useEscrowsBySigner.shared.ts +320 -0
  30. package/templates/escrows/single-release/approve-milestone/button/ApproveMilestone.tsx +78 -0
  31. package/templates/escrows/single-release/approve-milestone/dialog/ApproveMilestone.tsx +102 -0
  32. package/templates/escrows/single-release/approve-milestone/form/ApproveMilestone.tsx +80 -0
  33. package/templates/escrows/single-release/approve-milestone/shared/schema.ts +9 -0
  34. package/templates/escrows/single-release/approve-milestone/shared/useApproveMilestone.ts +67 -0
  35. package/templates/escrows/single-release/change-milestone-status/button/ChangeMilestoneStatus.tsx +78 -0
  36. package/templates/escrows/single-release/change-milestone-status/dialog/ChangeMilestoneStatus.tsx +167 -0
  37. package/templates/escrows/single-release/change-milestone-status/form/ChangeMilestoneStatus.tsx +114 -0
  38. package/templates/escrows/single-release/change-milestone-status/shared/schema.ts +15 -0
  39. package/templates/escrows/single-release/change-milestone-status/shared/useChangeMilestoneStatus.ts +77 -0
  40. package/templates/escrows/single-release/dispute-escrow/button/DisputeEscrow.tsx +68 -0
  41. package/templates/escrows/single-release/fund-escrow/button/FundEscrow.tsx +84 -0
  42. package/templates/escrows/single-release/fund-escrow/dialog/FundEscrow.tsx +77 -0
  43. package/templates/escrows/single-release/fund-escrow/form/FundEscrow.tsx +54 -0
  44. package/templates/escrows/single-release/fund-escrow/shared/schema.ts +10 -0
  45. package/templates/escrows/single-release/fund-escrow/shared/useFundEscrow.ts +66 -0
  46. package/templates/escrows/single-release/initialize-escrow/dialog/InitializeEscrow.tsx +526 -0
  47. package/templates/escrows/single-release/initialize-escrow/form/InitializeEscrow.tsx +504 -0
  48. package/templates/escrows/single-release/initialize-escrow/shared/schema.ts +232 -0
  49. package/templates/escrows/single-release/initialize-escrow/shared/useInitializeEscrow.ts +115 -0
  50. package/templates/escrows/single-release/release-escrow/button/ReleaseEscrow.tsx +80 -0
  51. package/templates/escrows/single-release/resolve-dispute/button/ResolveDispute.tsx +94 -0
  52. package/templates/escrows/single-release/resolve-dispute/dialog/ResolveDispute.tsx +123 -0
  53. package/templates/escrows/single-release/resolve-dispute/form/ResolveDispute.tsx +82 -0
  54. package/templates/escrows/single-release/resolve-dispute/shared/schema.ts +82 -0
  55. package/templates/escrows/single-release/resolve-dispute/shared/useResolveDispute.ts +58 -0
  56. package/templates/escrows/single-release/update-escrow/dialog/UpdateEscrow.tsx +485 -0
  57. package/templates/escrows/single-release/update-escrow/form/UpdateEscrow.tsx +463 -0
  58. package/templates/escrows/single-release/update-escrow/shared/schema.ts +139 -0
  59. package/templates/escrows/single-release/update-escrow/shared/useUpdateEscrow.ts +211 -0
  60. package/templates/handle-errors/errors.enum.ts +6 -0
  61. package/templates/handle-errors/handle.ts +47 -0
  62. package/templates/helpers/format.helper.ts +27 -0
  63. package/templates/helpers/useCopy.ts +13 -0
  64. package/templates/providers/ReactQueryClientProvider.tsx +28 -0
  65. package/templates/providers/TrustlessWork.tsx +30 -0
  66. package/templates/tanstak/useEscrowsByRoleQuery.ts +87 -0
  67. package/templates/tanstak/useEscrowsBySignerQuery.ts +78 -0
  68. package/templates/tanstak/useEscrowsMutations.ts +411 -0
  69. package/templates/wallet-kit/WalletButtons.tsx +116 -0
  70. package/templates/wallet-kit/WalletProvider.tsx +94 -0
  71. package/templates/wallet-kit/trustlines.ts +40 -0
  72. package/templates/wallet-kit/useWallet.ts +77 -0
  73. package/templates/wallet-kit/validators.ts +12 -0
  74. package/templates/wallet-kit/wallet-kit.ts +30 -0
@@ -0,0 +1,485 @@
1
+ import * as React from "react";
2
+ import {
3
+ Form,
4
+ FormField,
5
+ FormItem,
6
+ FormLabel,
7
+ FormControl,
8
+ FormMessage,
9
+ } from "__UI_BASE__/form";
10
+ import { Input } from "__UI_BASE__/input";
11
+ import { Button } from "__UI_BASE__/button";
12
+ import { Card } from "__UI_BASE__/card";
13
+ import {
14
+ Select,
15
+ SelectTrigger,
16
+ SelectValue,
17
+ SelectContent,
18
+ SelectItem,
19
+ } from "__UI_BASE__/select";
20
+ import { Textarea } from "__UI_BASE__/textarea";
21
+ import { useUpdateEscrow } from "./useUpdateEscrow";
22
+ import { Trash2, DollarSign, Percent, Loader2 } from "lucide-react";
23
+ import Link from "next/link";
24
+ import { trustlineOptions } from "@/components/tw-blocks/wallet-kit/trustlines";
25
+ import {
26
+ Dialog,
27
+ DialogContent,
28
+ DialogHeader,
29
+ DialogTitle,
30
+ DialogTrigger,
31
+ } from "__UI_BASE__/dialog";
32
+
33
+ export default function UpdateEscrowDialog() {
34
+ const {
35
+ form,
36
+ isSubmitting,
37
+ milestones,
38
+ isAnyMilestoneEmpty,
39
+ handleSubmit,
40
+ handleAddMilestone,
41
+ handleRemoveMilestone,
42
+ handleAmountChange,
43
+ handlePlatformFeeChange,
44
+ } = useUpdateEscrow();
45
+
46
+ return (
47
+ <Dialog>
48
+ <DialogTrigger asChild>
49
+ <Button type="button" className="cursor-pointer w-full">
50
+ Update
51
+ </Button>
52
+ </DialogTrigger>
53
+ <DialogContent className="!w-full sm:!max-w-4xl max-h-[95vh] overflow-y-auto">
54
+ <DialogHeader>
55
+ <DialogTitle>Update Escrow</DialogTitle>
56
+ </DialogHeader>
57
+ <Form {...form}>
58
+ <form onSubmit={handleSubmit} className="flex flex-col space-y-6">
59
+ <Card className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4 p-4">
60
+ <Link
61
+ className="flex-1"
62
+ href="https://docs.trustlesswork.com/trustless-work/technology-overview/escrow-types"
63
+ target="_blank"
64
+ >
65
+ <div className="flex items-center gap-2">
66
+ <div className="h-2 w-2 rounded-full bg-primary" />
67
+ <h2 className="text-xl font-semibold">
68
+ Single Release Escrow
69
+ </h2>
70
+ </div>
71
+ <p className="text-muted-foreground mt-1">
72
+ Update escrow details and milestones
73
+ </p>
74
+ </Link>
75
+ </Card>
76
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
77
+ <FormField
78
+ control={form.control}
79
+ name="title"
80
+ render={({ field }) => (
81
+ <FormItem>
82
+ <FormLabel className="flex items-center">
83
+ Title<span className="text-destructive ml-1">*</span>
84
+ </FormLabel>
85
+ <FormControl>
86
+ <Input
87
+ placeholder="Escrow title"
88
+ {...field}
89
+ onChange={(e) => {
90
+ field.onChange(e);
91
+ }}
92
+ />
93
+ </FormControl>
94
+ <FormMessage />
95
+ </FormItem>
96
+ )}
97
+ />
98
+
99
+ <FormField
100
+ control={form.control}
101
+ name="engagementId"
102
+ render={({ field }) => (
103
+ <FormItem>
104
+ <FormLabel className="flex items-center">
105
+ Engagement<span className="text-destructive ml-1">*</span>
106
+ </FormLabel>
107
+ <FormControl>
108
+ <Input
109
+ placeholder="Enter identifier"
110
+ {...field}
111
+ onChange={(e) => {
112
+ field.onChange(e);
113
+ }}
114
+ />
115
+ </FormControl>
116
+ <FormMessage />
117
+ </FormItem>
118
+ )}
119
+ />
120
+
121
+ <FormField
122
+ control={form.control}
123
+ name="trustline.address"
124
+ render={({ field }) => (
125
+ <FormItem>
126
+ <FormLabel className="flex items-center">
127
+ Trustline<span className="text-destructive ml-1">*</span>
128
+ </FormLabel>
129
+ <FormControl>
130
+ <Select
131
+ value={field.value}
132
+ onValueChange={(e) => {
133
+ field.onChange(e);
134
+ }}
135
+ >
136
+ <SelectTrigger className="w-full">
137
+ <SelectValue placeholder="Select trustline" />
138
+ </SelectTrigger>
139
+ <SelectContent>
140
+ {trustlineOptions
141
+ .filter((option) => option.value)
142
+ .map((option, index) => (
143
+ <SelectItem
144
+ key={`${option.value}-${index}`}
145
+ value={option.value}
146
+ >
147
+ {option.label}
148
+ </SelectItem>
149
+ ))}
150
+ </SelectContent>
151
+ </Select>
152
+ </FormControl>
153
+ <FormMessage />
154
+ </FormItem>
155
+ )}
156
+ />
157
+ </div>
158
+
159
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
160
+ <FormField
161
+ control={form.control}
162
+ name="roles.approver"
163
+ render={({ field }) => (
164
+ <FormItem>
165
+ <FormLabel className="flex items-center justify-between">
166
+ <span className="flex items-center">
167
+ Approver<span className="text-destructive ml-1">*</span>
168
+ </span>
169
+ </FormLabel>
170
+
171
+ <FormControl>
172
+ <Input
173
+ placeholder="Enter approver address"
174
+ {...field}
175
+ onChange={(e) => {
176
+ field.onChange(e);
177
+ }}
178
+ />
179
+ </FormControl>
180
+ <FormMessage />
181
+ </FormItem>
182
+ )}
183
+ />
184
+
185
+ <FormField
186
+ control={form.control}
187
+ name="roles.serviceProvider"
188
+ render={({ field }) => (
189
+ <FormItem>
190
+ <FormLabel className="flex items-center justify-between">
191
+ <span className="flex items-center">
192
+ Service Provider
193
+ <span className="text-destructive ml-1">*</span>
194
+ </span>
195
+ </FormLabel>
196
+
197
+ <FormControl>
198
+ <Input
199
+ placeholder="Enter service provider address"
200
+ {...field}
201
+ onChange={(e) => {
202
+ field.onChange(e);
203
+ }}
204
+ />
205
+ </FormControl>
206
+ <FormMessage />
207
+ </FormItem>
208
+ )}
209
+ />
210
+ </div>
211
+
212
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
213
+ <FormField
214
+ control={form.control}
215
+ name="roles.releaseSigner"
216
+ render={({ field }) => (
217
+ <FormItem>
218
+ <FormLabel className="flex items-center justify-between">
219
+ <span className="flex items-center">
220
+ Release Signer
221
+ <span className="text-destructive ml-1">*</span>
222
+ </span>
223
+ </FormLabel>
224
+
225
+ <FormControl>
226
+ <Input
227
+ placeholder="Enter release signer address"
228
+ {...field}
229
+ onChange={(e) => {
230
+ field.onChange(e);
231
+ }}
232
+ />
233
+ </FormControl>
234
+ <FormMessage />
235
+ </FormItem>
236
+ )}
237
+ />
238
+
239
+ <FormField
240
+ control={form.control}
241
+ name="roles.disputeResolver"
242
+ render={({ field }) => (
243
+ <FormItem>
244
+ <FormLabel className="flex items-center justify-between">
245
+ <span className="flex items-center">
246
+ Dispute Resolver
247
+ <span className="text-destructive ml-1">*</span>
248
+ </span>
249
+ </FormLabel>
250
+
251
+ <FormControl>
252
+ <Input
253
+ placeholder="Enter dispute resolver address"
254
+ {...field}
255
+ onChange={(e) => {
256
+ field.onChange(e);
257
+ }}
258
+ />
259
+ </FormControl>
260
+ <FormMessage />
261
+ </FormItem>
262
+ )}
263
+ />
264
+ </div>
265
+
266
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
267
+ <FormField
268
+ control={form.control}
269
+ name="roles.platformAddress"
270
+ render={({ field }) => (
271
+ <FormItem>
272
+ <FormLabel className="flex items-center justify-between">
273
+ <span className="flex items-center">
274
+ Platform Address
275
+ <span className="text-destructive ml-1">*</span>
276
+ </span>
277
+ </FormLabel>
278
+
279
+ <FormControl>
280
+ <Input
281
+ placeholder="Enter platform address"
282
+ {...field}
283
+ onChange={(e) => {
284
+ field.onChange(e);
285
+ }}
286
+ />
287
+ </FormControl>
288
+ <FormMessage />
289
+ </FormItem>
290
+ )}
291
+ />
292
+ <FormField
293
+ control={form.control}
294
+ name="roles.receiver"
295
+ render={({ field }) => (
296
+ <FormItem>
297
+ <FormLabel className="flex items-center justify-between">
298
+ <span className="flex items-center">
299
+ Receiver<span className="text-destructive ml-1">*</span>
300
+ </span>
301
+ </FormLabel>
302
+
303
+ <FormControl>
304
+ <Input
305
+ placeholder="Enter receiver address"
306
+ {...field}
307
+ onChange={(e) => {
308
+ field.onChange(e);
309
+ }}
310
+ />
311
+ </FormControl>
312
+ <FormMessage />
313
+ </FormItem>
314
+ )}
315
+ />
316
+ </div>
317
+
318
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
319
+ <FormField
320
+ control={form.control}
321
+ name="platformFee"
322
+ render={() => (
323
+ <FormItem>
324
+ <FormLabel className="flex items-center">
325
+ Platform Fee
326
+ <span className="text-destructive ml-1">*</span>
327
+ </FormLabel>
328
+ <FormControl>
329
+ <div className="relative">
330
+ <Percent
331
+ className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-500"
332
+ size={18}
333
+ />
334
+ <Input
335
+ placeholder="Enter platform fee"
336
+ className="pl-10"
337
+ value={form.watch("platformFee")?.toString() || ""}
338
+ onChange={handlePlatformFeeChange}
339
+ />
340
+ </div>
341
+ </FormControl>
342
+ <FormMessage />
343
+ </FormItem>
344
+ )}
345
+ />
346
+
347
+ <FormField
348
+ control={form.control}
349
+ name="amount"
350
+ render={() => (
351
+ <FormItem>
352
+ <FormLabel className="flex items-center">
353
+ Amount<span className="text-destructive ml-1">*</span>
354
+ </FormLabel>
355
+ <FormControl>
356
+ <div className="relative">
357
+ <DollarSign
358
+ className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-500"
359
+ size={18}
360
+ />
361
+ <Input
362
+ placeholder="Enter amount"
363
+ className="pl-10"
364
+ value={form.watch("amount")?.toString() || ""}
365
+ onChange={handleAmountChange}
366
+ />
367
+ </div>
368
+ </FormControl>
369
+ <FormMessage />
370
+ </FormItem>
371
+ )}
372
+ />
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
+ </div>
397
+
398
+ <FormField
399
+ control={form.control}
400
+ name="description"
401
+ render={({ field }) => (
402
+ <FormItem>
403
+ <FormLabel className="flex items-center">
404
+ Description<span className="text-destructive ml-1">*</span>
405
+ </FormLabel>
406
+ <FormControl>
407
+ <Textarea
408
+ placeholder="Escrow description"
409
+ {...field}
410
+ onChange={(e) => {
411
+ field.onChange(e);
412
+ }}
413
+ />
414
+ </FormControl>
415
+ <FormMessage />
416
+ </FormItem>
417
+ )}
418
+ />
419
+
420
+ <div className="space-y-4">
421
+ <FormLabel className="flex items-center">
422
+ Milestones<span className="text-destructive ml-1">*</span>
423
+ </FormLabel>
424
+ {milestones.map((milestone, index) => (
425
+ <div key={index}>
426
+ <div className="flex flex-col sm:flex-row items-start sm:items-center space-y-2 sm:space-y-0 sm:space-x-4">
427
+ <Input
428
+ placeholder="Milestone Description"
429
+ value={milestone.description}
430
+ className="w-full sm:flex-1"
431
+ onChange={(e) => {
432
+ const updatedMilestones = [...milestones];
433
+ updatedMilestones[index].description = e.target.value;
434
+ form.setValue("milestones", updatedMilestones);
435
+ }}
436
+ />
437
+
438
+ <Button
439
+ onClick={() => handleRemoveMilestone(index)}
440
+ 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
+ disabled={milestones.length === 1}
442
+ >
443
+ <Trash2 className="h-5 w-5" />
444
+ </Button>
445
+ </div>
446
+
447
+ {index === milestones.length - 1 && (
448
+ <div className="flex justify-end mt-4">
449
+ <Button
450
+ disabled={isAnyMilestoneEmpty}
451
+ className="w-full md:w-1/4 cursor-pointer"
452
+ variant="outline"
453
+ onClick={handleAddMilestone}
454
+ type="button"
455
+ >
456
+ Add Item
457
+ </Button>
458
+ </div>
459
+ )}
460
+ </div>
461
+ ))}
462
+ </div>
463
+
464
+ <div className="flex justify-start">
465
+ <Button
466
+ className="w-full md:w-1/4 cursor-pointer"
467
+ type="submit"
468
+ disabled={isAnyMilestoneEmpty || isSubmitting}
469
+ >
470
+ {isSubmitting ? (
471
+ <div className="flex items-center">
472
+ <Loader2 className="h-5 w-5 animate-spin" />
473
+ <span className="ml-2">Updating...</span>
474
+ </div>
475
+ ) : (
476
+ "Update"
477
+ )}
478
+ </Button>
479
+ </div>
480
+ </form>
481
+ </Form>
482
+ </DialogContent>
483
+ </Dialog>
484
+ );
485
+ }