@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
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { useForm } from "react-hook-form";
|
|
3
|
+
import { zodResolver } from "@hookform/resolvers/zod";
|
|
4
|
+
import { useUpdateEscrowSchema } from "./schema";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import {
|
|
7
|
+
UpdateMultiReleaseEscrowPayload,
|
|
8
|
+
UpdateMultiReleaseEscrowResponse,
|
|
9
|
+
MultiReleaseMilestone,
|
|
10
|
+
} from "@trustless-work/escrow/types";
|
|
11
|
+
import { toast } from "sonner";
|
|
12
|
+
import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvider";
|
|
13
|
+
import { useWalletContext } from "@/components/tw-blocks/wallet-kit/WalletProvider";
|
|
14
|
+
import { useEscrowsMutations } from "@/components/tw-blocks/tanstack/useEscrowsMutations";
|
|
15
|
+
import {
|
|
16
|
+
ErrorResponse,
|
|
17
|
+
handleError,
|
|
18
|
+
} from "@/components/tw-blocks/handle-errors/handle";
|
|
19
|
+
import { GetEscrowsFromIndexerResponse } from "@trustless-work/escrow/types";
|
|
20
|
+
|
|
21
|
+
export function useUpdateEscrow() {
|
|
22
|
+
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
23
|
+
|
|
24
|
+
const { getMultiReleaseFormSchema } = useUpdateEscrowSchema();
|
|
25
|
+
const formSchema = getMultiReleaseFormSchema();
|
|
26
|
+
|
|
27
|
+
const { walletAddress } = useWalletContext();
|
|
28
|
+
const { selectedEscrow, setSelectedEscrow } = useEscrowContext();
|
|
29
|
+
const { updateEscrow } = useEscrowsMutations();
|
|
30
|
+
|
|
31
|
+
const form = useForm<z.infer<typeof formSchema>>({
|
|
32
|
+
resolver: zodResolver(formSchema),
|
|
33
|
+
defaultValues: {
|
|
34
|
+
engagementId: selectedEscrow?.engagementId || "",
|
|
35
|
+
title: selectedEscrow?.title || "",
|
|
36
|
+
description: selectedEscrow?.description || "",
|
|
37
|
+
platformFee: selectedEscrow?.platformFee as unknown as
|
|
38
|
+
| number
|
|
39
|
+
| string
|
|
40
|
+
| undefined,
|
|
41
|
+
receiverMemo: selectedEscrow?.receiverMemo
|
|
42
|
+
? String(selectedEscrow.receiverMemo)
|
|
43
|
+
: "",
|
|
44
|
+
trustline: {
|
|
45
|
+
address: selectedEscrow?.trustline?.address || "",
|
|
46
|
+
decimals: 10000000,
|
|
47
|
+
},
|
|
48
|
+
roles: {
|
|
49
|
+
approver: selectedEscrow?.roles?.approver || "",
|
|
50
|
+
serviceProvider: selectedEscrow?.roles?.serviceProvider || "",
|
|
51
|
+
platformAddress: selectedEscrow?.roles?.platformAddress || "",
|
|
52
|
+
receiver: selectedEscrow?.roles?.receiver || "",
|
|
53
|
+
releaseSigner: selectedEscrow?.roles?.releaseSigner || "",
|
|
54
|
+
disputeResolver: selectedEscrow?.roles?.disputeResolver || "",
|
|
55
|
+
},
|
|
56
|
+
milestones: (
|
|
57
|
+
(selectedEscrow?.milestones as MultiReleaseMilestone[]) ?? []
|
|
58
|
+
).map((m) => ({
|
|
59
|
+
description: m?.description || "",
|
|
60
|
+
amount: m?.amount ?? 0,
|
|
61
|
+
})) || [
|
|
62
|
+
{
|
|
63
|
+
description: "",
|
|
64
|
+
amount: 0,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
mode: "onChange",
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
React.useEffect(() => {
|
|
72
|
+
if (!selectedEscrow) return;
|
|
73
|
+
form.reset({
|
|
74
|
+
engagementId: selectedEscrow?.engagementId || "",
|
|
75
|
+
title: selectedEscrow?.title || "",
|
|
76
|
+
description: selectedEscrow?.description || "",
|
|
77
|
+
platformFee:
|
|
78
|
+
(selectedEscrow?.platformFee as unknown as
|
|
79
|
+
| number
|
|
80
|
+
| string
|
|
81
|
+
| undefined) || "",
|
|
82
|
+
receiverMemo: selectedEscrow?.receiverMemo
|
|
83
|
+
? String(selectedEscrow.receiverMemo)
|
|
84
|
+
: "",
|
|
85
|
+
trustline: {
|
|
86
|
+
address: selectedEscrow?.trustline?.address || "",
|
|
87
|
+
decimals: 10000000,
|
|
88
|
+
},
|
|
89
|
+
roles: {
|
|
90
|
+
approver: selectedEscrow?.roles?.approver || "",
|
|
91
|
+
serviceProvider: selectedEscrow?.roles?.serviceProvider || "",
|
|
92
|
+
platformAddress: selectedEscrow?.roles?.platformAddress || "",
|
|
93
|
+
receiver: selectedEscrow?.roles?.receiver || "",
|
|
94
|
+
releaseSigner: selectedEscrow?.roles?.releaseSigner || "",
|
|
95
|
+
disputeResolver: selectedEscrow?.roles?.disputeResolver || "",
|
|
96
|
+
},
|
|
97
|
+
milestones: (
|
|
98
|
+
(selectedEscrow?.milestones as MultiReleaseMilestone[]) ?? []
|
|
99
|
+
).map((m) => ({
|
|
100
|
+
description: m?.description || "",
|
|
101
|
+
amount: m?.amount ?? "",
|
|
102
|
+
})) || [
|
|
103
|
+
{
|
|
104
|
+
description: "",
|
|
105
|
+
amount: "",
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
});
|
|
109
|
+
}, [selectedEscrow, form]);
|
|
110
|
+
|
|
111
|
+
const milestones = form.watch("milestones");
|
|
112
|
+
const isAnyMilestoneEmpty = milestones.some((m) => m.description === "");
|
|
113
|
+
|
|
114
|
+
const handleAddMilestone = () => {
|
|
115
|
+
const current = form.getValues("milestones");
|
|
116
|
+
const updated = [...current, { description: "", amount: "" }];
|
|
117
|
+
form.setValue("milestones", updated);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const handleRemoveMilestone = (index: number) => {
|
|
121
|
+
const current = form.getValues("milestones");
|
|
122
|
+
const updated = current.filter((_, i) => i !== index);
|
|
123
|
+
form.setValue("milestones", updated);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const handleMilestoneAmountChange = (
|
|
127
|
+
index: number,
|
|
128
|
+
e: React.ChangeEvent<HTMLInputElement>
|
|
129
|
+
) => {
|
|
130
|
+
let rawValue = e.target.value;
|
|
131
|
+
rawValue = rawValue.replace(/[^0-9.]/g, "");
|
|
132
|
+
|
|
133
|
+
if (rawValue.split(".").length > 2) {
|
|
134
|
+
rawValue = rawValue.slice(0, -1);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Limit to 2 decimal places
|
|
138
|
+
if (rawValue.includes(".")) {
|
|
139
|
+
const parts = rawValue.split(".");
|
|
140
|
+
if (parts[1] && parts[1].length > 2) {
|
|
141
|
+
rawValue = parts[0] + "." + parts[1].slice(0, 2);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Always keep as string to allow partial input like "0." or "0.5"
|
|
146
|
+
const updatedMilestones = [...milestones];
|
|
147
|
+
updatedMilestones[index] = {
|
|
148
|
+
...updatedMilestones[index],
|
|
149
|
+
amount: rawValue,
|
|
150
|
+
};
|
|
151
|
+
form.setValue("milestones", updatedMilestones);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const handlePlatformFeeChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
155
|
+
let rawValue = e.target.value;
|
|
156
|
+
rawValue = rawValue.replace(/[^0-9.]/g, "");
|
|
157
|
+
if (rawValue.split(".").length > 2) rawValue = rawValue.slice(0, -1);
|
|
158
|
+
if (rawValue.includes(".")) {
|
|
159
|
+
const parts = rawValue.split(".");
|
|
160
|
+
if (parts[1] && parts[1].length > 2) {
|
|
161
|
+
rawValue = parts[0] + "." + parts[1].slice(0, 2);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
form.setValue("platformFee", rawValue);
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const handleSubmit = form.handleSubmit(async (payload) => {
|
|
168
|
+
try {
|
|
169
|
+
setIsSubmitting(true);
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Create the final payload for the update escrow mutation
|
|
173
|
+
*
|
|
174
|
+
* @param payload - The payload from the form
|
|
175
|
+
* @returns The final payload for the update escrow mutation
|
|
176
|
+
*/
|
|
177
|
+
const finalPayload: UpdateMultiReleaseEscrowPayload = {
|
|
178
|
+
contractId: selectedEscrow?.contractId || "",
|
|
179
|
+
signer: walletAddress || "",
|
|
180
|
+
escrow: {
|
|
181
|
+
engagementId: payload.engagementId,
|
|
182
|
+
title: payload.title,
|
|
183
|
+
description: payload.description,
|
|
184
|
+
platformFee:
|
|
185
|
+
typeof payload.platformFee === "string"
|
|
186
|
+
? Number(payload.platformFee)
|
|
187
|
+
: payload.platformFee,
|
|
188
|
+
receiverMemo: payload.receiverMemo
|
|
189
|
+
? Number(payload.receiverMemo)
|
|
190
|
+
: undefined,
|
|
191
|
+
trustline: {
|
|
192
|
+
address: payload.trustline.address,
|
|
193
|
+
decimals: 10000000,
|
|
194
|
+
},
|
|
195
|
+
roles: payload.roles,
|
|
196
|
+
milestones: payload.milestones.map((milestone) => ({
|
|
197
|
+
...milestone,
|
|
198
|
+
amount:
|
|
199
|
+
typeof milestone.amount === "string"
|
|
200
|
+
? Number(milestone.amount)
|
|
201
|
+
: milestone.amount,
|
|
202
|
+
})),
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Call the update escrow mutation
|
|
208
|
+
*
|
|
209
|
+
* @param payload - The final payload for the update escrow mutation
|
|
210
|
+
* @param type - The type of the escrow
|
|
211
|
+
* @param address - The address of the escrow
|
|
212
|
+
*/
|
|
213
|
+
(await updateEscrow.mutateAsync({
|
|
214
|
+
payload: finalPayload,
|
|
215
|
+
type: "multi-release",
|
|
216
|
+
address: walletAddress || "",
|
|
217
|
+
})) as UpdateMultiReleaseEscrowResponse;
|
|
218
|
+
|
|
219
|
+
if (!selectedEscrow) return;
|
|
220
|
+
|
|
221
|
+
const nextSelectedEscrow: GetEscrowsFromIndexerResponse = {
|
|
222
|
+
...selectedEscrow,
|
|
223
|
+
...finalPayload.escrow,
|
|
224
|
+
trustline: {
|
|
225
|
+
name:
|
|
226
|
+
selectedEscrow.trustline?.name ||
|
|
227
|
+
(selectedEscrow.trustline?.address as string) ||
|
|
228
|
+
"",
|
|
229
|
+
address: finalPayload.escrow.trustline.address,
|
|
230
|
+
decimals: finalPayload.escrow.trustline.decimals,
|
|
231
|
+
},
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
setSelectedEscrow(nextSelectedEscrow);
|
|
235
|
+
toast.success("Escrow updated successfully");
|
|
236
|
+
} catch (error) {
|
|
237
|
+
toast.error(handleError(error as ErrorResponse).message);
|
|
238
|
+
} finally {
|
|
239
|
+
setIsSubmitting(false);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
return {
|
|
244
|
+
form,
|
|
245
|
+
isSubmitting,
|
|
246
|
+
milestones,
|
|
247
|
+
isAnyMilestoneEmpty,
|
|
248
|
+
handleSubmit,
|
|
249
|
+
handleAddMilestone,
|
|
250
|
+
handleRemoveMilestone,
|
|
251
|
+
handleMilestoneAmountChange,
|
|
252
|
+
handlePlatformFeeChange,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
@@ -2,7 +2,10 @@ import * as React from "react";
|
|
|
2
2
|
import { Button } from "__UI_BASE__/button";
|
|
3
3
|
import { useEscrowsMutations } from "@/components/tw-blocks/tanstack/useEscrowsMutations";
|
|
4
4
|
import { useWalletContext } from "@/components/tw-blocks/wallet-kit/WalletProvider";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
ApproveMilestonePayload,
|
|
7
|
+
MultiReleaseMilestone,
|
|
8
|
+
} from "@trustless-work/escrow/types";
|
|
6
9
|
import { toast } from "sonner";
|
|
7
10
|
import {
|
|
8
11
|
ErrorResponse,
|
|
@@ -15,9 +18,9 @@ type ApproveMilestoneButtonProps = {
|
|
|
15
18
|
milestoneIndex: number | string;
|
|
16
19
|
};
|
|
17
20
|
|
|
18
|
-
export
|
|
21
|
+
export const ApproveMilestoneButton = ({
|
|
19
22
|
milestoneIndex,
|
|
20
|
-
}: ApproveMilestoneButtonProps) {
|
|
23
|
+
}: ApproveMilestoneButtonProps) => {
|
|
21
24
|
const { approveMilestone } = useEscrowsMutations();
|
|
22
25
|
const { selectedEscrow, updateEscrow } = useEscrowContext();
|
|
23
26
|
const { walletAddress } = useWalletContext();
|
|
@@ -49,7 +52,7 @@ export default function ApproveMilestoneButton({
|
|
|
49
52
|
*/
|
|
50
53
|
await approveMilestone.mutateAsync({
|
|
51
54
|
payload,
|
|
52
|
-
type: "
|
|
55
|
+
type: selectedEscrow?.type || "multi-release",
|
|
53
56
|
address: walletAddress || "",
|
|
54
57
|
});
|
|
55
58
|
|
|
@@ -58,8 +61,18 @@ export default function ApproveMilestoneButton({
|
|
|
58
61
|
updateEscrow({
|
|
59
62
|
...selectedEscrow,
|
|
60
63
|
milestones: selectedEscrow?.milestones.map((milestone, index) => {
|
|
61
|
-
if (index === Number(milestoneIndex)) {
|
|
62
|
-
|
|
64
|
+
if (index === Number(payload.milestoneIndex)) {
|
|
65
|
+
if (selectedEscrow?.type === "single-release") {
|
|
66
|
+
return { ...milestone, approved: true };
|
|
67
|
+
} else {
|
|
68
|
+
return {
|
|
69
|
+
...milestone,
|
|
70
|
+
flags: {
|
|
71
|
+
...(milestone as MultiReleaseMilestone).flags,
|
|
72
|
+
approved: true,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
63
76
|
}
|
|
64
77
|
return milestone;
|
|
65
78
|
}),
|
|
@@ -88,4 +101,4 @@ export default function ApproveMilestoneButton({
|
|
|
88
101
|
)}
|
|
89
102
|
</Button>
|
|
90
103
|
);
|
|
91
|
-
}
|
|
104
|
+
};
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
DialogTrigger,
|
|
17
17
|
} from "__UI_BASE__/dialog";
|
|
18
18
|
import { Loader2 } from "lucide-react";
|
|
19
|
-
import { useApproveMilestone } from "
|
|
19
|
+
import { useApproveMilestone } from "../useApproveMilestone";
|
|
20
20
|
import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvider";
|
|
21
21
|
import {
|
|
22
22
|
Select,
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
SelectValue,
|
|
27
27
|
} from "__UI_BASE__/select";
|
|
28
28
|
|
|
29
|
-
export
|
|
29
|
+
export const ApproveMilestoneDialog = () => {
|
|
30
30
|
const { form, handleSubmit, isSubmitting } = useApproveMilestone();
|
|
31
31
|
const { selectedEscrow } = useEscrowContext();
|
|
32
32
|
|
|
@@ -99,4 +99,4 @@ export default function ApproveMilestoneDialog() {
|
|
|
99
99
|
</DialogContent>
|
|
100
100
|
</Dialog>
|
|
101
101
|
);
|
|
102
|
-
}
|
|
102
|
+
};
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
FormMessage,
|
|
9
9
|
} from "__UI_BASE__/form";
|
|
10
10
|
import { Button } from "__UI_BASE__/button";
|
|
11
|
-
import { useApproveMilestone } from "
|
|
11
|
+
import { useApproveMilestone } from "../useApproveMilestone";
|
|
12
12
|
import { Loader2 } from "lucide-react";
|
|
13
13
|
import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvider";
|
|
14
14
|
import {
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
SelectValue,
|
|
20
20
|
} from "__UI_BASE__/select";
|
|
21
21
|
|
|
22
|
-
export
|
|
22
|
+
export const ApproveMilestoneForm = () => {
|
|
23
23
|
const { form, handleSubmit, isSubmitting } = useApproveMilestone();
|
|
24
24
|
const { selectedEscrow } = useEscrowContext();
|
|
25
25
|
|
|
@@ -77,4 +77,4 @@ export default function ApproveMilestoneForm() {
|
|
|
77
77
|
</form>
|
|
78
78
|
</Form>
|
|
79
79
|
);
|
|
80
|
-
}
|
|
80
|
+
};
|
|
@@ -3,7 +3,10 @@ import { useForm } from "react-hook-form";
|
|
|
3
3
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
4
4
|
import { approveMilestoneSchema, type ApproveMilestoneValues } from "./schema";
|
|
5
5
|
import { toast } from "sonner";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
ApproveMilestonePayload,
|
|
8
|
+
MultiReleaseMilestone,
|
|
9
|
+
} from "@trustless-work/escrow";
|
|
7
10
|
import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvider";
|
|
8
11
|
import { useEscrowsMutations } from "@/components/tw-blocks/tanstack/useEscrowsMutations";
|
|
9
12
|
import {
|
|
@@ -31,12 +34,6 @@ export function useApproveMilestone() {
|
|
|
31
34
|
try {
|
|
32
35
|
setIsSubmitting(true);
|
|
33
36
|
|
|
34
|
-
/**
|
|
35
|
-
* Create the final payload for the approve milestone mutation
|
|
36
|
-
*
|
|
37
|
-
* @param payload - The payload from the form
|
|
38
|
-
* @returns The final payload for the approve milestone mutation
|
|
39
|
-
*/
|
|
40
37
|
const finalPayload: ApproveMilestonePayload = {
|
|
41
38
|
contractId: selectedEscrow?.contractId || "",
|
|
42
39
|
milestoneIndex: payload.milestoneIndex,
|
|
@@ -44,16 +41,9 @@ export function useApproveMilestone() {
|
|
|
44
41
|
newFlag: true,
|
|
45
42
|
};
|
|
46
43
|
|
|
47
|
-
/**
|
|
48
|
-
* Call the approve milestone mutation
|
|
49
|
-
*
|
|
50
|
-
* @param payload - The final payload for the approve milestone mutation
|
|
51
|
-
* @param type - The type of the escrow
|
|
52
|
-
* @param address - The address of the escrow
|
|
53
|
-
*/
|
|
54
44
|
await approveMilestone.mutateAsync({
|
|
55
45
|
payload: finalPayload,
|
|
56
|
-
type: "
|
|
46
|
+
type: selectedEscrow?.type || "multi-release",
|
|
57
47
|
address: walletAddress || "",
|
|
58
48
|
});
|
|
59
49
|
|
|
@@ -63,7 +53,17 @@ export function useApproveMilestone() {
|
|
|
63
53
|
...selectedEscrow,
|
|
64
54
|
milestones: selectedEscrow?.milestones.map((milestone, index) => {
|
|
65
55
|
if (index === Number(payload.milestoneIndex)) {
|
|
66
|
-
|
|
56
|
+
if (selectedEscrow?.type === "single-release") {
|
|
57
|
+
return { ...milestone, approved: true };
|
|
58
|
+
} else {
|
|
59
|
+
return {
|
|
60
|
+
...milestone,
|
|
61
|
+
flags: {
|
|
62
|
+
...(milestone as MultiReleaseMilestone).flags,
|
|
63
|
+
approved: true,
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
67
|
}
|
|
68
68
|
return milestone;
|
|
69
69
|
}),
|
|
@@ -17,11 +17,11 @@ type ChangeMilestoneStatusButtonProps = {
|
|
|
17
17
|
milestoneIndex: number | string;
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
export
|
|
20
|
+
export const ChangeMilestoneStatusButton = ({
|
|
21
21
|
status,
|
|
22
22
|
evidence,
|
|
23
23
|
milestoneIndex,
|
|
24
|
-
}: ChangeMilestoneStatusButtonProps) {
|
|
24
|
+
}: ChangeMilestoneStatusButtonProps) => {
|
|
25
25
|
const { changeMilestoneStatus } = useEscrowsMutations();
|
|
26
26
|
const { selectedEscrow } = useEscrowContext();
|
|
27
27
|
const { walletAddress } = useWalletContext();
|
|
@@ -61,7 +61,7 @@ export default function ChangeMilestoneStatusButton({
|
|
|
61
61
|
*/
|
|
62
62
|
await changeMilestoneStatus.mutateAsync({
|
|
63
63
|
payload,
|
|
64
|
-
type: "
|
|
64
|
+
type: selectedEscrow?.type || "multi-release",
|
|
65
65
|
address: walletAddress || "",
|
|
66
66
|
});
|
|
67
67
|
|
|
@@ -90,4 +90,4 @@ export default function ChangeMilestoneStatusButton({
|
|
|
90
90
|
)}
|
|
91
91
|
</Button>
|
|
92
92
|
);
|
|
93
|
-
}
|
|
93
|
+
};
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
DialogTrigger,
|
|
19
19
|
} from "__UI_BASE__/dialog";
|
|
20
20
|
import { Loader2 } from "lucide-react";
|
|
21
|
-
import { useChangeMilestoneStatus } from "
|
|
21
|
+
import { useChangeMilestoneStatus } from "../useChangeMilestoneStatus";
|
|
22
22
|
import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvider";
|
|
23
23
|
import {
|
|
24
24
|
Select,
|
|
@@ -28,13 +28,13 @@ import {
|
|
|
28
28
|
SelectValue,
|
|
29
29
|
} from "__UI_BASE__/select";
|
|
30
30
|
|
|
31
|
-
export
|
|
31
|
+
export const ChangeMilestoneStatusDialog = ({
|
|
32
32
|
showSelectMilestone = false,
|
|
33
33
|
milestoneIndex,
|
|
34
34
|
}: {
|
|
35
35
|
showSelectMilestone?: boolean;
|
|
36
36
|
milestoneIndex?: number | string;
|
|
37
|
-
}) {
|
|
37
|
+
}) => {
|
|
38
38
|
const { form, handleSubmit, isSubmitting } = useChangeMilestoneStatus();
|
|
39
39
|
const { selectedEscrow } = useEscrowContext();
|
|
40
40
|
|
|
@@ -164,4 +164,4 @@ export default function ChangeMilestoneStatusDialog({
|
|
|
164
164
|
</DialogContent>
|
|
165
165
|
</Dialog>
|
|
166
166
|
);
|
|
167
|
-
}
|
|
167
|
+
};
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import { Input } from "__UI_BASE__/input";
|
|
11
11
|
import { Textarea } from "__UI_BASE__/textarea";
|
|
12
12
|
import { Button } from "__UI_BASE__/button";
|
|
13
|
-
import { useChangeMilestoneStatus } from "
|
|
13
|
+
import { useChangeMilestoneStatus } from "../useChangeMilestoneStatus";
|
|
14
14
|
import { Loader2 } from "lucide-react";
|
|
15
15
|
import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvider";
|
|
16
16
|
import {
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
SelectValue,
|
|
22
22
|
} from "__UI_BASE__/select";
|
|
23
23
|
|
|
24
|
-
export
|
|
24
|
+
export const ChangeMilestoneStatusForm = () => {
|
|
25
25
|
const { form, handleSubmit, isSubmitting } = useChangeMilestoneStatus();
|
|
26
26
|
const { selectedEscrow } = useEscrowContext();
|
|
27
27
|
|
|
@@ -111,4 +111,4 @@ export default function ChangeMilestoneStatusForm() {
|
|
|
111
111
|
</form>
|
|
112
112
|
</Form>
|
|
113
113
|
);
|
|
114
|
-
}
|
|
114
|
+
};
|
package/templates/escrows/{single-release → single-multi-release}/fund-escrow/button/FundEscrow.tsx
RENAMED
|
@@ -15,7 +15,7 @@ type FundEscrowButtonProps = {
|
|
|
15
15
|
amount: number;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
export
|
|
18
|
+
export const FundEscrowButton = ({ amount }: FundEscrowButtonProps) => {
|
|
19
19
|
const { fundEscrow } = useEscrowsMutations();
|
|
20
20
|
const { selectedEscrow, updateEscrow } = useEscrowContext();
|
|
21
21
|
const { walletAddress } = useWalletContext();
|
|
@@ -55,7 +55,7 @@ export default function FundEscrowButton({ amount }: FundEscrowButtonProps) {
|
|
|
55
55
|
*/
|
|
56
56
|
await fundEscrow.mutateAsync({
|
|
57
57
|
payload,
|
|
58
|
-
type: "
|
|
58
|
+
type: selectedEscrow?.type || "multi-release",
|
|
59
59
|
address: walletAddress || "",
|
|
60
60
|
});
|
|
61
61
|
|
|
@@ -88,4 +88,4 @@ export default function FundEscrowButton({ amount }: FundEscrowButtonProps) {
|
|
|
88
88
|
)}
|
|
89
89
|
</Button>
|
|
90
90
|
);
|
|
91
|
-
}
|
|
91
|
+
};
|
package/templates/escrows/{single-release → single-multi-release}/fund-escrow/dialog/FundEscrow.tsx
RENAMED
|
@@ -17,9 +17,9 @@ import {
|
|
|
17
17
|
DialogTrigger,
|
|
18
18
|
} from "__UI_BASE__/dialog";
|
|
19
19
|
import { Loader2 } from "lucide-react";
|
|
20
|
-
import { useFundEscrow } from "
|
|
20
|
+
import { useFundEscrow } from "../useFundEscrow";
|
|
21
21
|
|
|
22
|
-
export
|
|
22
|
+
export const FundEscrowDialog = () => {
|
|
23
23
|
const { form, handleSubmit, isSubmitting } = useFundEscrow();
|
|
24
24
|
|
|
25
25
|
return (
|
|
@@ -74,4 +74,4 @@ export default function FundEscrowDialog() {
|
|
|
74
74
|
</DialogContent>
|
|
75
75
|
</Dialog>
|
|
76
76
|
);
|
|
77
|
-
}
|
|
77
|
+
};
|
package/templates/escrows/{single-release → single-multi-release}/fund-escrow/form/FundEscrow.tsx
RENAMED
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
} from "__UI_BASE__/form";
|
|
10
10
|
import { Input } from "__UI_BASE__/input";
|
|
11
11
|
import { Button } from "__UI_BASE__/button";
|
|
12
|
-
import { useFundEscrow } from "
|
|
12
|
+
import { useFundEscrow } from "../useFundEscrow";
|
|
13
13
|
import { Loader2 } from "lucide-react";
|
|
14
14
|
|
|
15
|
-
export
|
|
15
|
+
export const FundEscrowForm = () => {
|
|
16
16
|
const { form, handleSubmit, isSubmitting } = useFundEscrow();
|
|
17
17
|
|
|
18
18
|
return (
|
|
@@ -51,4 +51,4 @@ export default function FundEscrowForm() {
|
|
|
51
51
|
</form>
|
|
52
52
|
</Form>
|
|
53
53
|
);
|
|
54
|
-
}
|
|
54
|
+
};
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvider";
|
|
12
12
|
import { Loader2 } from "lucide-react";
|
|
13
13
|
|
|
14
|
-
export
|
|
14
|
+
export const DisputeEscrowButton = () => {
|
|
15
15
|
const { startDispute } = useEscrowsMutations();
|
|
16
16
|
const { selectedEscrow, updateEscrow } = useEscrowContext();
|
|
17
17
|
const { walletAddress } = useWalletContext();
|
|
@@ -77,4 +77,4 @@ export default function DisputeEscrowButton() {
|
|
|
77
77
|
)}
|
|
78
78
|
</Button>
|
|
79
79
|
);
|
|
80
|
-
}
|
|
80
|
+
};
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
DialogTrigger,
|
|
31
31
|
} from "__UI_BASE__/dialog";
|
|
32
32
|
|
|
33
|
-
export
|
|
33
|
+
export const InitializeEscrowDialog = () => {
|
|
34
34
|
const {
|
|
35
35
|
form,
|
|
36
36
|
isSubmitting,
|
|
@@ -39,6 +39,7 @@ export function InitializeEscrowDialog() {
|
|
|
39
39
|
handleSubmit,
|
|
40
40
|
handleAddMilestone,
|
|
41
41
|
handleRemoveMilestone,
|
|
42
|
+
fillTemplateForm,
|
|
42
43
|
} = useInitializeEscrow();
|
|
43
44
|
|
|
44
45
|
const handleAmountChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
@@ -107,10 +108,19 @@ export function InitializeEscrowDialog() {
|
|
|
107
108
|
</h2>
|
|
108
109
|
</div>
|
|
109
110
|
<p className="text-muted-foreground mt-1">
|
|
110
|
-
|
|
111
|
-
milestones
|
|
111
|
+
Fill out the form to initialize a single release escrow
|
|
112
112
|
</p>
|
|
113
113
|
</Link>
|
|
114
|
+
{process.env.NODE_ENV !== "production" && (
|
|
115
|
+
<Button
|
|
116
|
+
type="button"
|
|
117
|
+
variant="outline"
|
|
118
|
+
onClick={fillTemplateForm}
|
|
119
|
+
className="cursor-pointer"
|
|
120
|
+
>
|
|
121
|
+
Autofill
|
|
122
|
+
</Button>
|
|
123
|
+
)}
|
|
114
124
|
</Card>
|
|
115
125
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
|
|
116
126
|
<FormField
|
|
@@ -521,6 +531,4 @@ export function InitializeEscrowDialog() {
|
|
|
521
531
|
</DialogContent>
|
|
522
532
|
</Dialog>
|
|
523
533
|
);
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
export default InitializeEscrowDialog;
|
|
534
|
+
};
|