@trustless-work/blocks 0.0.5 → 0.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/README.md +39 -13
- package/bin/index.js +1128 -1137
- package/package.json +44 -44
- package/templates/escrows/details/EscrowDetailDialog.tsx +3 -3
- package/templates/escrows/details/GeneralInformation.tsx +2 -2
- package/templates/escrows/details/SuccessReleaseDialog.tsx +2 -3
- package/templates/escrows/details/useDetailsEscrow.ts +2 -2
- package/templates/escrows/escrows-by-role/cards/EscrowsCards.tsx +42 -16
- package/templates/escrows/escrows-by-role/table/EscrowsTable.tsx +45 -18
- package/templates/escrows/escrows-by-role/useEscrowsByRole.shared.ts +39 -25
- package/templates/escrows/escrows-by-signer/cards/EscrowsCards.tsx +33 -16
- package/templates/escrows/escrows-by-signer/table/EscrowsTable.tsx +34 -17
- package/templates/escrows/escrows-by-signer/useEscrowsBySigner.shared.ts +38 -25
- package/templates/escrows/single-release/approve-milestone/button/ApproveMilestone.tsx +14 -1
- package/templates/escrows/single-release/approve-milestone/dialog/ApproveMilestone.tsx +1 -1
- package/templates/escrows/single-release/approve-milestone/form/ApproveMilestone.tsx +1 -1
- package/templates/escrows/single-release/approve-milestone/shared/useApproveMilestone.ts +14 -1
- package/templates/escrows/single-release/change-milestone-status/button/ChangeMilestoneStatus.tsx +16 -1
- package/templates/escrows/single-release/change-milestone-status/dialog/ChangeMilestoneStatus.tsx +1 -1
- package/templates/escrows/single-release/change-milestone-status/form/ChangeMilestoneStatus.tsx +1 -1
- package/templates/escrows/single-release/change-milestone-status/shared/useChangeMilestoneStatus.ts +14 -1
- package/templates/escrows/single-release/dispute-escrow/button/DisputeEscrow.tsx +13 -1
- package/templates/escrows/single-release/fund-escrow/button/FundEscrow.tsx +13 -1
- package/templates/escrows/single-release/fund-escrow/shared/useFundEscrow.ts +14 -1
- package/templates/escrows/single-release/initialize-escrow/shared/useInitializeEscrow.ts +17 -1
- package/templates/escrows/single-release/release-escrow/button/ReleaseEscrow.tsx +15 -3
- package/templates/escrows/single-release/resolve-dispute/button/ResolveDispute.tsx +13 -1
- package/templates/escrows/single-release/resolve-dispute/dialog/ResolveDispute.tsx +1 -1
- package/templates/escrows/single-release/resolve-dispute/shared/useResolveDispute.ts +14 -1
- package/templates/escrows/single-release/update-escrow/shared/useUpdateEscrow.ts +224 -211
- package/templates/handle-errors/handle.ts +16 -0
- package/templates/helpers/format.helper.ts +31 -0
- package/templates/helpers/useCopy.ts +5 -0
- package/templates/{escrows/escrow-context → providers}/EscrowAmountProvider.tsx +3 -0
- package/templates/providers/EscrowDialogsProvider.tsx +61 -0
- package/templates/{escrows/escrow-context → providers}/EscrowProvider.tsx +30 -0
- package/templates/providers/ReactQueryClientProvider.tsx +17 -1
- package/templates/tanstack/useEscrowsByRoleQuery.ts +14 -0
- package/templates/tanstack/useEscrowsBySignerQuery.ts +13 -0
- package/templates/tanstack/useEscrowsMutations.ts +36 -0
- package/templates/wallet-kit/trustlines.ts +7 -0
- package/templates/wallet-kit/validators.ts +6 -0
- package/templates/wallet-kit/wallet-kit.ts +13 -0
- package/templates/escrows/escrow-context/EscrowDialogsProvider.tsx +0 -108
package/package.json
CHANGED
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@trustless-work/blocks",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"author": "Trustless Work",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"react",
|
|
7
|
-
"hooks",
|
|
8
|
-
"trustless work",
|
|
9
|
-
"escrow",
|
|
10
|
-
"api",
|
|
11
|
-
"blocks",
|
|
12
|
-
"ui",
|
|
13
|
-
"components",
|
|
14
|
-
"helpers",
|
|
15
|
-
"templates",
|
|
16
|
-
"blockchain"
|
|
17
|
-
],
|
|
18
|
-
"bin": {
|
|
19
|
-
"trustless-work": "bin/index.js"
|
|
20
|
-
},
|
|
21
|
-
"scripts": {
|
|
22
|
-
"test": "echo \"Error: no test specified\" && exit 1",
|
|
23
|
-
"build": "node -e \"console.log('Skipping build: no src to bundle')\"",
|
|
24
|
-
"prepublishOnly": "npm run build"
|
|
25
|
-
},
|
|
26
|
-
"description": "",
|
|
27
|
-
"type": "module",
|
|
28
|
-
"publishConfig": {
|
|
29
|
-
"access": "public"
|
|
30
|
-
},
|
|
31
|
-
"repository": {
|
|
32
|
-
"type": "git",
|
|
33
|
-
"url": "https://github.com/Trustless-Work/react-library-trustless-work-blocks.git"
|
|
34
|
-
},
|
|
35
|
-
"files": [
|
|
36
|
-
"bin",
|
|
37
|
-
"templates",
|
|
38
|
-
"README.md"
|
|
39
|
-
],
|
|
40
|
-
"license": "MIT",
|
|
41
|
-
"engines": {
|
|
42
|
-
"node": ">=18.17"
|
|
43
|
-
}
|
|
44
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@trustless-work/blocks",
|
|
3
|
+
"version": "0.0.7",
|
|
4
|
+
"author": "Trustless Work",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"react",
|
|
7
|
+
"hooks",
|
|
8
|
+
"trustless work",
|
|
9
|
+
"escrow",
|
|
10
|
+
"api",
|
|
11
|
+
"blocks",
|
|
12
|
+
"ui",
|
|
13
|
+
"components",
|
|
14
|
+
"helpers",
|
|
15
|
+
"templates",
|
|
16
|
+
"blockchain"
|
|
17
|
+
],
|
|
18
|
+
"bin": {
|
|
19
|
+
"trustless-work": "bin/index.js"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
23
|
+
"build": "node -e \"console.log('Skipping build: no src to bundle')\"",
|
|
24
|
+
"prepublishOnly": "npm run build"
|
|
25
|
+
},
|
|
26
|
+
"description": "",
|
|
27
|
+
"type": "module",
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/Trustless-Work/react-library-trustless-work-blocks.git"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"bin",
|
|
37
|
+
"templates",
|
|
38
|
+
"README.md"
|
|
39
|
+
],
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=18.17"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -12,7 +12,7 @@ import useEscrowDetailDialog from "./useDetailsEscrow";
|
|
|
12
12
|
import Link from "next/link";
|
|
13
13
|
import { Card } from "__UI_BASE__/card";
|
|
14
14
|
import { Info, Users, ListChecks } from "lucide-react";
|
|
15
|
-
import { useEscrowDialogs } from "
|
|
15
|
+
import { useEscrowDialogs } from "@/components/tw-blocks/providers/EscrowDialogsProvider";
|
|
16
16
|
import type {
|
|
17
17
|
GetEscrowsFromIndexerResponse as Escrow,
|
|
18
18
|
Role,
|
|
@@ -21,7 +21,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "__UI_BASE__/tabs";
|
|
|
21
21
|
import { Milestones } from "./Milestones";
|
|
22
22
|
import { Entities } from "./Entities";
|
|
23
23
|
import { GeneralInformation } from "./GeneralInformation";
|
|
24
|
-
import { useEscrowContext } from "
|
|
24
|
+
import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvider";
|
|
25
25
|
import SuccessReleaseDialog from "./SuccessReleaseDialog";
|
|
26
26
|
|
|
27
27
|
interface EscrowDetailDialogProps {
|
|
@@ -151,4 +151,4 @@ const EscrowDetailDialog = ({
|
|
|
151
151
|
);
|
|
152
152
|
};
|
|
153
153
|
|
|
154
|
-
export default EscrowDetailDialog;
|
|
154
|
+
export default React.memo(EscrowDetailDialog);
|
|
@@ -19,12 +19,12 @@ import { Actions, roleActions } from "./Actions";
|
|
|
19
19
|
import type {
|
|
20
20
|
DialogStates,
|
|
21
21
|
StatusStates,
|
|
22
|
-
} from "
|
|
22
|
+
} from "@/components/tw-blocks/providers/EscrowDialogsProvider";
|
|
23
23
|
import {
|
|
24
24
|
GetEscrowsFromIndexerResponse,
|
|
25
25
|
Role,
|
|
26
26
|
} from "@trustless-work/escrow/types";
|
|
27
|
-
import { useEscrowAmountContext } from "
|
|
27
|
+
import { useEscrowAmountContext } from "@/components/tw-blocks/providers/EscrowAmountProvider";
|
|
28
28
|
import { StatisticsCard } from "./StatisticsCard";
|
|
29
29
|
import {
|
|
30
30
|
formatAddress,
|
|
@@ -8,10 +8,9 @@ import {
|
|
|
8
8
|
DialogHeader,
|
|
9
9
|
DialogTitle,
|
|
10
10
|
} from "__UI_BASE__/dialog";
|
|
11
|
-
import { Card } from "__UI_BASE__/card";
|
|
12
11
|
import EntityCard from "./EntityCard";
|
|
13
|
-
import { useEscrowContext } from "
|
|
14
|
-
import { useEscrowAmountContext } from "
|
|
12
|
+
import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvider";
|
|
13
|
+
import { useEscrowAmountContext } from "@/components/tw-blocks/providers/EscrowAmountProvider";
|
|
15
14
|
import { CircleCheckBig } from "lucide-react";
|
|
16
15
|
|
|
17
16
|
interface SuccessReleaseDialogProps {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
2
|
import { GetEscrowsFromIndexerResponse as Escrow } from "@trustless-work/escrow/types";
|
|
3
3
|
import { useWalletContext } from "@/components/tw-blocks/wallet-kit/WalletProvider";
|
|
4
|
-
import { useEscrowContext } from "
|
|
5
|
-
import { useEscrowAmountContext } from "
|
|
4
|
+
import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvider";
|
|
5
|
+
import { useEscrowAmountContext } from "@/components/tw-blocks/providers/EscrowAmountProvider";
|
|
6
6
|
|
|
7
7
|
interface EscrowDetailDialogProps {
|
|
8
8
|
setIsDialogOpen: (value: boolean) => void;
|
|
@@ -22,8 +22,8 @@ import {
|
|
|
22
22
|
import { useEscrowsByRole } from "../useEscrowsByRole.shared";
|
|
23
23
|
import Filters from "./Filters";
|
|
24
24
|
import EscrowDetailDialog from "../details/EscrowDetailDialog";
|
|
25
|
-
import { useEscrowContext } from "
|
|
26
|
-
import { useEscrowDialogs } from "
|
|
25
|
+
import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvider";
|
|
26
|
+
import { useEscrowDialogs } from "@/components/tw-blocks/providers/EscrowDialogsProvider";
|
|
27
27
|
import {
|
|
28
28
|
formatCurrency,
|
|
29
29
|
formatTimestamp,
|
|
@@ -75,6 +75,17 @@ export function EscrowsByRoleCards() {
|
|
|
75
75
|
|
|
76
76
|
const dialogStates = useEscrowDialogs();
|
|
77
77
|
|
|
78
|
+
const handleRefresh = React.useCallback(() => {
|
|
79
|
+
void refetch();
|
|
80
|
+
}, [refetch]);
|
|
81
|
+
|
|
82
|
+
const setRoleStable = React.useCallback(
|
|
83
|
+
(v: Role | undefined) => {
|
|
84
|
+
if (v) setRole(v);
|
|
85
|
+
},
|
|
86
|
+
[setRole]
|
|
87
|
+
);
|
|
88
|
+
|
|
78
89
|
function allMilestonesReleasedOrResolved(
|
|
79
90
|
milestones: MultiReleaseMilestone[]
|
|
80
91
|
) {
|
|
@@ -119,7 +130,20 @@ export function EscrowsByRoleCards() {
|
|
|
119
130
|
dialogStates.second.setIsOpen(true);
|
|
120
131
|
};
|
|
121
132
|
|
|
122
|
-
|
|
133
|
+
/**
|
|
134
|
+
* Based on the provided roles -> https://docs.trustlesswork.com/trustless-work/technology-overview/roles-in-trustless-work
|
|
135
|
+
*
|
|
136
|
+
* You must pass one or more roles according to requirements. Acctually it's coming from the select filter.
|
|
137
|
+
*
|
|
138
|
+
* For example:
|
|
139
|
+
* - If the user is a freelancer, you must pass the "serviceProvider" and "receiver" role
|
|
140
|
+
*
|
|
141
|
+
* Depending of the role, you'll have different actions buttons
|
|
142
|
+
*/
|
|
143
|
+
const activeRole: Role[] = React.useMemo(
|
|
144
|
+
() => role.split(",") as Role[],
|
|
145
|
+
[role]
|
|
146
|
+
);
|
|
123
147
|
|
|
124
148
|
return (
|
|
125
149
|
<>
|
|
@@ -140,19 +164,19 @@ export function EscrowsByRoleCards() {
|
|
|
140
164
|
setEngagementId={setEngagementId}
|
|
141
165
|
setIsActive={setIsActive}
|
|
142
166
|
setValidateOnChain={setValidateOnChain}
|
|
143
|
-
setType={
|
|
144
|
-
setStatus={
|
|
167
|
+
setType={setType}
|
|
168
|
+
setStatus={setStatus}
|
|
145
169
|
setMinAmount={setMinAmount}
|
|
146
170
|
setMaxAmount={setMaxAmount}
|
|
147
171
|
setDateRange={setDateRange}
|
|
148
|
-
setRole={
|
|
172
|
+
setRole={setRoleStable}
|
|
149
173
|
onClearFilters={onClearFilters}
|
|
150
|
-
onRefresh={
|
|
174
|
+
onRefresh={handleRefresh}
|
|
151
175
|
isRefreshing={isFetching}
|
|
152
176
|
orderBy={orderBy}
|
|
153
177
|
orderDirection={orderDirection}
|
|
154
|
-
setOrderBy={
|
|
155
|
-
setOrderDirection={
|
|
178
|
+
setOrderBy={setOrderBy}
|
|
179
|
+
setOrderDirection={setOrderDirection}
|
|
156
180
|
/>
|
|
157
181
|
|
|
158
182
|
<div className="w-full py-2 sm:py-4">
|
|
@@ -492,14 +516,16 @@ export function EscrowsByRoleCards() {
|
|
|
492
516
|
</div>
|
|
493
517
|
|
|
494
518
|
{/* Dialog */}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
519
|
+
{dialogStates.second.isOpen ? (
|
|
520
|
+
<EscrowDetailDialog
|
|
521
|
+
activeRole={activeRole}
|
|
522
|
+
isDialogOpen={dialogStates.second.isOpen}
|
|
523
|
+
setIsDialogOpen={dialogStates.second.setIsOpen}
|
|
524
|
+
setSelectedEscrow={setSelectedEscrow}
|
|
525
|
+
/>
|
|
526
|
+
) : null}
|
|
501
527
|
</>
|
|
502
528
|
);
|
|
503
529
|
}
|
|
504
530
|
|
|
505
|
-
export default EscrowsByRoleCards;
|
|
531
|
+
export default React.memo(EscrowsByRoleCards);
|
|
@@ -25,8 +25,8 @@ import {
|
|
|
25
25
|
import { FileX, Loader2, Wallet, RefreshCw, AlertTriangle } from "lucide-react";
|
|
26
26
|
import Filters from "./Filters";
|
|
27
27
|
import EscrowDetailDialog from "../details/EscrowDetailDialog";
|
|
28
|
-
import { useEscrowDialogs } from "
|
|
29
|
-
import { useEscrowContext } from "
|
|
28
|
+
import { useEscrowDialogs } from "@/components/tw-blocks/providers/EscrowDialogsProvider";
|
|
29
|
+
import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvider";
|
|
30
30
|
import { useEscrowsByRole } from "../useEscrowsByRole.shared";
|
|
31
31
|
import { formatTimestamp } from "../../../helpers/format.helper";
|
|
32
32
|
|
|
@@ -75,6 +75,17 @@ export function EscrowsByRoleTable() {
|
|
|
75
75
|
const dialogStates = useEscrowDialogs();
|
|
76
76
|
const { setSelectedEscrow } = useEscrowContext();
|
|
77
77
|
|
|
78
|
+
const handleRefresh = React.useCallback(() => {
|
|
79
|
+
void refetch();
|
|
80
|
+
}, [refetch]);
|
|
81
|
+
|
|
82
|
+
const setRoleStable = React.useCallback(
|
|
83
|
+
(v: Role | undefined) => {
|
|
84
|
+
if (v) setRole(v);
|
|
85
|
+
},
|
|
86
|
+
[setRole]
|
|
87
|
+
);
|
|
88
|
+
|
|
78
89
|
const columns = React.useMemo<ColumnDef<Escrow>[]>(
|
|
79
90
|
() => [
|
|
80
91
|
{
|
|
@@ -187,7 +198,7 @@ export function EscrowsByRoleTable() {
|
|
|
187
198
|
),
|
|
188
199
|
},
|
|
189
200
|
],
|
|
190
|
-
[]
|
|
201
|
+
[dialogStates.second.setIsOpen, setSelectedEscrow]
|
|
191
202
|
);
|
|
192
203
|
|
|
193
204
|
const table = useReactTable({
|
|
@@ -202,7 +213,21 @@ export function EscrowsByRoleTable() {
|
|
|
202
213
|
enableSortingRemoval: true,
|
|
203
214
|
});
|
|
204
215
|
|
|
205
|
-
|
|
216
|
+
/**
|
|
217
|
+
* Based on the provided roles -> https://docs.trustlesswork.com/trustless-work/technology-overview/roles-in-trustless-work
|
|
218
|
+
*
|
|
219
|
+
* You must pass one or more roles according to requirements. Acctually it's coming from the select filter.
|
|
220
|
+
*
|
|
221
|
+
* For example:
|
|
222
|
+
* - If the user is a freelancer, you must pass the "serviceProvider" and "receiver" role
|
|
223
|
+
*
|
|
224
|
+
* Depending of the role, you'll have different actions buttons
|
|
225
|
+
*/
|
|
226
|
+
const activeRole: Role[] = React.useMemo(
|
|
227
|
+
() => role.split(",") as Role[],
|
|
228
|
+
[role]
|
|
229
|
+
);
|
|
230
|
+
|
|
206
231
|
const escrows = data ?? [];
|
|
207
232
|
|
|
208
233
|
return (
|
|
@@ -224,19 +249,19 @@ export function EscrowsByRoleTable() {
|
|
|
224
249
|
setEngagementId={setEngagementId}
|
|
225
250
|
setIsActive={setIsActive}
|
|
226
251
|
setValidateOnChain={setValidateOnChain}
|
|
227
|
-
setType={
|
|
228
|
-
setStatus={
|
|
252
|
+
setType={setType}
|
|
253
|
+
setStatus={setStatus}
|
|
229
254
|
setMinAmount={setMinAmount}
|
|
230
255
|
setMaxAmount={setMaxAmount}
|
|
231
256
|
setDateRange={setDateRange}
|
|
232
|
-
setRole={
|
|
257
|
+
setRole={setRoleStable}
|
|
233
258
|
onClearFilters={onClearFilters}
|
|
234
|
-
onRefresh={
|
|
259
|
+
onRefresh={handleRefresh}
|
|
235
260
|
isRefreshing={isFetching}
|
|
236
261
|
orderBy={orderBy}
|
|
237
262
|
orderDirection={orderDirection}
|
|
238
|
-
setOrderBy={
|
|
239
|
-
setOrderDirection={
|
|
263
|
+
setOrderBy={setOrderBy}
|
|
264
|
+
setOrderDirection={setOrderDirection}
|
|
240
265
|
/>
|
|
241
266
|
|
|
242
267
|
<Card className="w-full py-2 sm:py-4">
|
|
@@ -335,7 +360,7 @@ export function EscrowsByRoleTable() {
|
|
|
335
360
|
<Button
|
|
336
361
|
variant="outline"
|
|
337
362
|
size="sm"
|
|
338
|
-
onClick={
|
|
363
|
+
onClick={handleRefresh}
|
|
339
364
|
>
|
|
340
365
|
<RefreshCw className="h-4 w-4 mr-2" />
|
|
341
366
|
Retry
|
|
@@ -414,14 +439,16 @@ export function EscrowsByRoleTable() {
|
|
|
414
439
|
</div>
|
|
415
440
|
|
|
416
441
|
{/* Dialog */}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
442
|
+
{dialogStates.second.isOpen ? (
|
|
443
|
+
<EscrowDetailDialog
|
|
444
|
+
activeRole={activeRole}
|
|
445
|
+
isDialogOpen={dialogStates.second.isOpen}
|
|
446
|
+
setIsDialogOpen={dialogStates.second.setIsOpen}
|
|
447
|
+
setSelectedEscrow={setSelectedEscrow}
|
|
448
|
+
/>
|
|
449
|
+
) : null}
|
|
423
450
|
</>
|
|
424
451
|
);
|
|
425
452
|
}
|
|
426
453
|
|
|
427
|
-
export default EscrowsByRoleTable;
|
|
454
|
+
export default React.memo(EscrowsByRoleTable);
|
|
@@ -108,8 +108,8 @@ export function useEscrowsByRole() {
|
|
|
108
108
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
109
109
|
}, []);
|
|
110
110
|
|
|
111
|
-
const
|
|
112
|
-
{
|
|
111
|
+
const stableSearchParams = React.useMemo(
|
|
112
|
+
() => ({
|
|
113
113
|
page,
|
|
114
114
|
orderBy,
|
|
115
115
|
orderDirection,
|
|
@@ -126,10 +126,29 @@ export function useEscrowsByRole() {
|
|
|
126
126
|
: undefined,
|
|
127
127
|
endDate: dateRange.to ? endOfDay(dateRange.to).toISOString() : undefined,
|
|
128
128
|
role,
|
|
129
|
-
},
|
|
130
|
-
|
|
129
|
+
}),
|
|
130
|
+
[
|
|
131
|
+
page,
|
|
132
|
+
orderBy,
|
|
133
|
+
orderDirection,
|
|
134
|
+
debouncedTitle,
|
|
135
|
+
debouncedEngagementId,
|
|
136
|
+
isActive,
|
|
137
|
+
validateOnChain,
|
|
138
|
+
type,
|
|
139
|
+
status,
|
|
140
|
+
debouncedMinAmount,
|
|
141
|
+
debouncedMaxAmount,
|
|
142
|
+
dateRange.from,
|
|
143
|
+
dateRange.to,
|
|
144
|
+
role,
|
|
145
|
+
]
|
|
131
146
|
);
|
|
132
147
|
|
|
148
|
+
const debouncedSearchParams = useDebouncedValue(stableSearchParams, 200);
|
|
149
|
+
|
|
150
|
+
const lastQueryStringRef = React.useRef("");
|
|
151
|
+
|
|
133
152
|
React.useEffect(() => {
|
|
134
153
|
if (!pathname) return;
|
|
135
154
|
const qp = new URLSearchParams();
|
|
@@ -145,8 +164,10 @@ export function useEscrowsByRole() {
|
|
|
145
164
|
qp.set("engagementId", debouncedSearchParams.engagementId);
|
|
146
165
|
qp.set("isActive", String(debouncedSearchParams.isActive));
|
|
147
166
|
qp.set("validateOnChain", String(debouncedSearchParams.validateOnChain));
|
|
148
|
-
if (type && type !== "all")
|
|
149
|
-
|
|
167
|
+
if (debouncedSearchParams.type && debouncedSearchParams.type !== "all")
|
|
168
|
+
qp.set("type", debouncedSearchParams.type);
|
|
169
|
+
if (debouncedSearchParams.status && debouncedSearchParams.status !== "all")
|
|
170
|
+
qp.set("status", debouncedSearchParams.status);
|
|
150
171
|
if (debouncedSearchParams.minAmount)
|
|
151
172
|
qp.set("minAmount", String(debouncedSearchParams.minAmount));
|
|
152
173
|
if (debouncedSearchParams.maxAmount)
|
|
@@ -158,25 +179,12 @@ export function useEscrowsByRole() {
|
|
|
158
179
|
if (debouncedSearchParams.role)
|
|
159
180
|
qp.set("role", String(debouncedSearchParams.role));
|
|
160
181
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
debouncedSearchParams.orderDirection,
|
|
168
|
-
debouncedSearchParams.title,
|
|
169
|
-
debouncedSearchParams.engagementId,
|
|
170
|
-
debouncedSearchParams.isActive,
|
|
171
|
-
debouncedSearchParams.validateOnChain,
|
|
172
|
-
type,
|
|
173
|
-
status,
|
|
174
|
-
debouncedSearchParams.minAmount,
|
|
175
|
-
debouncedSearchParams.maxAmount,
|
|
176
|
-
debouncedSearchParams.startDate,
|
|
177
|
-
debouncedSearchParams.endDate,
|
|
178
|
-
debouncedSearchParams.role,
|
|
179
|
-
]);
|
|
182
|
+
const newQs = qp.toString();
|
|
183
|
+
if (lastQueryStringRef.current !== newQs) {
|
|
184
|
+
lastQueryStringRef.current = newQs;
|
|
185
|
+
router.replace(`${pathname}?${newQs}`);
|
|
186
|
+
}
|
|
187
|
+
}, [pathname, router, debouncedSearchParams]);
|
|
180
188
|
|
|
181
189
|
const formattedRangeLabel = React.useMemo(() => {
|
|
182
190
|
if (!dateRange?.from && !dateRange?.to) return "Date range";
|
|
@@ -234,6 +242,12 @@ export function useEscrowsByRole() {
|
|
|
234
242
|
dateRange,
|
|
235
243
|
]);
|
|
236
244
|
|
|
245
|
+
/**
|
|
246
|
+
* Call the query to get the escrows from the Trustless Work Indexer
|
|
247
|
+
*
|
|
248
|
+
* @param params - The parameters for the query
|
|
249
|
+
* @returns The query result
|
|
250
|
+
*/
|
|
237
251
|
const query = useEscrowsByRoleQuery(params);
|
|
238
252
|
const nextPageQuery = useEscrowsByRoleQuery({ ...params, page: page + 1 });
|
|
239
253
|
|
|
@@ -21,8 +21,8 @@ import {
|
|
|
21
21
|
RefreshCw,
|
|
22
22
|
FileX,
|
|
23
23
|
} from "lucide-react";
|
|
24
|
-
import { useEscrowContext } from "
|
|
25
|
-
import { useEscrowDialogs } from "
|
|
24
|
+
import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvider";
|
|
25
|
+
import { useEscrowDialogs } from "@/components/tw-blocks/providers/EscrowDialogsProvider";
|
|
26
26
|
import EscrowDetailDialog from "../../escrows-by-role/details/EscrowDetailDialog";
|
|
27
27
|
import { formatTimestamp } from "../../../helpers/format.helper";
|
|
28
28
|
|
|
@@ -70,6 +70,10 @@ export function EscrowsBySignerCards() {
|
|
|
70
70
|
|
|
71
71
|
const dialogStates = useEscrowDialogs();
|
|
72
72
|
|
|
73
|
+
const handleRefresh = React.useCallback(() => {
|
|
74
|
+
void refetch();
|
|
75
|
+
}, [refetch]);
|
|
76
|
+
|
|
73
77
|
const formatCurrency = (value: number, currency: string) => {
|
|
74
78
|
return `${currency} ${value.toFixed(2)}`;
|
|
75
79
|
};
|
|
@@ -116,7 +120,18 @@ export function EscrowsBySignerCards() {
|
|
|
116
120
|
dialogStates.second.setIsOpen(true);
|
|
117
121
|
};
|
|
118
122
|
|
|
119
|
-
|
|
123
|
+
/**
|
|
124
|
+
* Based on the provided roles -> https://docs.trustlesswork.com/trustless-work/technology-overview/roles-in-trustless-work
|
|
125
|
+
*
|
|
126
|
+
* You must pass one or more roles according to requirements
|
|
127
|
+
*
|
|
128
|
+
* For example:
|
|
129
|
+
* - If the user is a freelancer, you must pass the "serviceProvider" and "receiver" role
|
|
130
|
+
*
|
|
131
|
+
* Depending of the role, you'll have different actions buttons
|
|
132
|
+
*/
|
|
133
|
+
const activeRole: Role[] = React.useMemo(() => ["approver"] as Role[], []);
|
|
134
|
+
|
|
120
135
|
const escrows: Escrow[] = data ?? [];
|
|
121
136
|
|
|
122
137
|
return (
|
|
@@ -137,18 +152,18 @@ export function EscrowsBySignerCards() {
|
|
|
137
152
|
setEngagementId={setEngagementId}
|
|
138
153
|
setIsActive={setIsActive}
|
|
139
154
|
setValidateOnChain={setValidateOnChain}
|
|
140
|
-
setType={
|
|
141
|
-
setStatus={
|
|
155
|
+
setType={setType}
|
|
156
|
+
setStatus={setStatus}
|
|
142
157
|
setMinAmount={setMinAmount}
|
|
143
158
|
setMaxAmount={setMaxAmount}
|
|
144
159
|
setDateRange={setDateRange}
|
|
145
160
|
onClearFilters={onClearFilters}
|
|
146
|
-
onRefresh={
|
|
161
|
+
onRefresh={handleRefresh}
|
|
147
162
|
isRefreshing={isFetching}
|
|
148
163
|
orderBy={orderBy}
|
|
149
164
|
orderDirection={orderDirection}
|
|
150
|
-
setOrderBy={
|
|
151
|
-
setOrderDirection={
|
|
165
|
+
setOrderBy={setOrderBy}
|
|
166
|
+
setOrderDirection={setOrderDirection}
|
|
152
167
|
/>
|
|
153
168
|
|
|
154
169
|
<div className="w-full py-2 sm:py-4">
|
|
@@ -224,7 +239,7 @@ export function EscrowsBySignerCards() {
|
|
|
224
239
|
An error occurred while loading the information. Please try
|
|
225
240
|
again.
|
|
226
241
|
</p>
|
|
227
|
-
<Button variant="outline" size="sm" onClick={
|
|
242
|
+
<Button variant="outline" size="sm" onClick={handleRefresh}>
|
|
228
243
|
<RefreshCw className="h-4 w-4 mr-2" />
|
|
229
244
|
Retry
|
|
230
245
|
</Button>
|
|
@@ -491,14 +506,16 @@ export function EscrowsBySignerCards() {
|
|
|
491
506
|
</div>
|
|
492
507
|
|
|
493
508
|
{/* Dialog */}
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
509
|
+
{dialogStates.second.isOpen ? (
|
|
510
|
+
<EscrowDetailDialog
|
|
511
|
+
activeRole={activeRole}
|
|
512
|
+
isDialogOpen={dialogStates.second.isOpen}
|
|
513
|
+
setIsDialogOpen={dialogStates.second.setIsOpen}
|
|
514
|
+
setSelectedEscrow={setSelectedEscrow}
|
|
515
|
+
/>
|
|
516
|
+
) : null}
|
|
500
517
|
</>
|
|
501
518
|
);
|
|
502
519
|
}
|
|
503
520
|
|
|
504
|
-
export default EscrowsBySignerCards;
|
|
521
|
+
export default React.memo(EscrowsBySignerCards);
|