@trustless-work/blocks 0.0.6 → 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/README.md +39 -13
- package/bin/index.js +1596 -1137
- package/package.json +44 -44
- 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 +18 -18
- package/templates/escrows/details/GeneralInformation.tsx +20 -23
- 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 +6 -9
- package/templates/escrows/details/useDetailsEscrow.ts +2 -2
- package/templates/escrows/escrows-by-role/cards/EscrowsCards.tsx +111 -60
- package/templates/escrows/escrows-by-role/cards/Filters.tsx +3 -5
- package/templates/escrows/escrows-by-role/table/EscrowsTable.tsx +36 -38
- package/templates/escrows/escrows-by-role/table/Filters.tsx +3 -5
- package/templates/escrows/escrows-by-role/useEscrowsByRole.shared.ts +33 -25
- package/templates/escrows/escrows-by-signer/cards/EscrowsCards.tsx +107 -67
- package/templates/escrows/escrows-by-signer/cards/Filters.tsx +3 -5
- package/templates/escrows/escrows-by-signer/table/EscrowsTable.tsx +28 -38
- package/templates/escrows/escrows-by-signer/table/Filters.tsx +3 -5
- package/templates/escrows/escrows-by-signer/useEscrowsBySigner.shared.ts +32 -25
- 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 +21 -8
- package/templates/escrows/{single-release → single-multi-release}/approve-milestone/dialog/ApproveMilestone.tsx +4 -4
- package/templates/escrows/{single-release → single-multi-release}/approve-milestone/form/ApproveMilestone.tsx +4 -4
- package/templates/escrows/{single-release/approve-milestone/shared → single-multi-release/approve-milestone}/useApproveMilestone.ts +17 -17
- package/templates/escrows/{single-release → single-multi-release}/change-milestone-status/button/ChangeMilestoneStatus.tsx +5 -5
- package/templates/escrows/{single-release → single-multi-release}/change-milestone-status/dialog/ChangeMilestoneStatus.tsx +5 -5
- package/templates/escrows/{single-release → single-multi-release}/change-milestone-status/form/ChangeMilestoneStatus.tsx +4 -4
- package/templates/escrows/{single-release/change-milestone-status/shared → single-multi-release/change-milestone-status}/useChangeMilestoneStatus.ts +2 -2
- package/templates/escrows/{single-release → single-multi-release}/fund-escrow/button/FundEscrow.tsx +4 -4
- 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 +2 -2
- package/templates/escrows/single-release/dispute-escrow/button/DisputeEscrow.tsx +3 -3
- 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 +43 -2
- package/templates/escrows/single-release/release-escrow/button/ReleaseEscrow.tsx +5 -5
- package/templates/escrows/single-release/resolve-dispute/button/ResolveDispute.tsx +4 -4
- package/templates/escrows/single-release/resolve-dispute/dialog/ResolveDispute.tsx +4 -7
- package/templates/escrows/single-release/resolve-dispute/form/ResolveDispute.tsx +2 -2
- package/templates/escrows/single-release/resolve-dispute/shared/useResolveDispute.ts +15 -2
- 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 +229 -224
- package/templates/{escrows/escrow-context → providers}/EscrowDialogsProvider.tsx +1 -3
- package/templates/{escrows/escrow-context → providers}/EscrowProvider.tsx +27 -4
- package/templates/providers/ReactQueryClientProvider.tsx +3 -1
- 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
- /package/templates/{escrows/escrow-context → providers}/EscrowAmountProvider.tsx +0 -0
|
@@ -23,14 +23,14 @@ import {
|
|
|
23
23
|
TableRow,
|
|
24
24
|
} from "__UI_BASE__/table";
|
|
25
25
|
import { FileX, Loader2, Wallet, RefreshCw, AlertTriangle } from "lucide-react";
|
|
26
|
-
import Filters from "./Filters";
|
|
27
|
-
import EscrowDetailDialog from "../details/EscrowDetailDialog";
|
|
28
|
-
import { useEscrowDialogs } from "
|
|
29
|
-
import { useEscrowContext } from "
|
|
26
|
+
import { Filters } from "./Filters";
|
|
27
|
+
import { EscrowDetailDialog } from "../details/EscrowDetailDialog";
|
|
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
|
|
|
33
|
-
export
|
|
33
|
+
export const EscrowsByRoleTable = () => {
|
|
34
34
|
const {
|
|
35
35
|
walletAddress,
|
|
36
36
|
data,
|
|
@@ -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,18 +213,6 @@ export function EscrowsByRoleTable() {
|
|
|
202
213
|
enableSortingRemoval: true,
|
|
203
214
|
});
|
|
204
215
|
|
|
205
|
-
/**
|
|
206
|
-
* Based on the provided roles -> https://docs.trustlesswork.com/trustless-work/technology-overview/roles-in-trustless-work
|
|
207
|
-
*
|
|
208
|
-
* You must pass one or more roles according to requirements. Acctually it's coming from the select filter.
|
|
209
|
-
*
|
|
210
|
-
* For example:
|
|
211
|
-
* - If the user is a freelancer, you must pass the "serviceProvider" and "receiver" role
|
|
212
|
-
*
|
|
213
|
-
* Depending of the role, you'll have different actions buttons
|
|
214
|
-
*/
|
|
215
|
-
const activeRole: Role[] = role.split(",") as Role[];
|
|
216
|
-
|
|
217
216
|
const escrows = data ?? [];
|
|
218
217
|
|
|
219
218
|
return (
|
|
@@ -235,19 +234,19 @@ export function EscrowsByRoleTable() {
|
|
|
235
234
|
setEngagementId={setEngagementId}
|
|
236
235
|
setIsActive={setIsActive}
|
|
237
236
|
setValidateOnChain={setValidateOnChain}
|
|
238
|
-
setType={
|
|
239
|
-
setStatus={
|
|
237
|
+
setType={setType}
|
|
238
|
+
setStatus={setStatus}
|
|
240
239
|
setMinAmount={setMinAmount}
|
|
241
240
|
setMaxAmount={setMaxAmount}
|
|
242
241
|
setDateRange={setDateRange}
|
|
243
|
-
setRole={
|
|
242
|
+
setRole={setRoleStable}
|
|
244
243
|
onClearFilters={onClearFilters}
|
|
245
|
-
onRefresh={
|
|
244
|
+
onRefresh={handleRefresh}
|
|
246
245
|
isRefreshing={isFetching}
|
|
247
246
|
orderBy={orderBy}
|
|
248
247
|
orderDirection={orderDirection}
|
|
249
|
-
setOrderBy={
|
|
250
|
-
setOrderDirection={
|
|
248
|
+
setOrderBy={setOrderBy}
|
|
249
|
+
setOrderDirection={setOrderDirection}
|
|
251
250
|
/>
|
|
252
251
|
|
|
253
252
|
<Card className="w-full py-2 sm:py-4">
|
|
@@ -262,8 +261,8 @@ export function EscrowsByRoleTable() {
|
|
|
262
261
|
const className =
|
|
263
262
|
typeof header.column.columnDef.meta === "object" &&
|
|
264
263
|
header.column.columnDef.meta &&
|
|
265
|
-
"className" in
|
|
266
|
-
?
|
|
264
|
+
"className" in header.column.columnDef.meta
|
|
265
|
+
? header.column.columnDef.meta.className
|
|
267
266
|
: "";
|
|
268
267
|
return (
|
|
269
268
|
<TableHead
|
|
@@ -346,7 +345,7 @@ export function EscrowsByRoleTable() {
|
|
|
346
345
|
<Button
|
|
347
346
|
variant="outline"
|
|
348
347
|
size="sm"
|
|
349
|
-
onClick={
|
|
348
|
+
onClick={handleRefresh}
|
|
350
349
|
>
|
|
351
350
|
<RefreshCw className="h-4 w-4 mr-2" />
|
|
352
351
|
Retry
|
|
@@ -376,8 +375,8 @@ export function EscrowsByRoleTable() {
|
|
|
376
375
|
const className =
|
|
377
376
|
typeof cell.column.columnDef.meta === "object" &&
|
|
378
377
|
cell.column.columnDef.meta &&
|
|
379
|
-
"className" in
|
|
380
|
-
? (cell.column.columnDef.meta as
|
|
378
|
+
"className" in cell.column.columnDef.meta
|
|
379
|
+
? (cell.column.columnDef.meta.className as string)
|
|
381
380
|
: "";
|
|
382
381
|
return (
|
|
383
382
|
<TableCell key={cell.id} className={className}>
|
|
@@ -425,14 +424,13 @@ export function EscrowsByRoleTable() {
|
|
|
425
424
|
</div>
|
|
426
425
|
|
|
427
426
|
{/* Dialog */}
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
427
|
+
{dialogStates.second.isOpen ? (
|
|
428
|
+
<EscrowDetailDialog
|
|
429
|
+
isDialogOpen={dialogStates.second.isOpen}
|
|
430
|
+
setIsDialogOpen={dialogStates.second.setIsOpen}
|
|
431
|
+
setSelectedEscrow={setSelectedEscrow}
|
|
432
|
+
/>
|
|
433
|
+
) : null}
|
|
434
434
|
</>
|
|
435
435
|
);
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
export default EscrowsByRoleTable;
|
|
436
|
+
};
|
|
@@ -84,7 +84,7 @@ type FiltersProps = {
|
|
|
84
84
|
setOrderDirection: (v: "asc" | "desc") => void;
|
|
85
85
|
};
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
export const Filters = ({
|
|
88
88
|
title,
|
|
89
89
|
engagementId,
|
|
90
90
|
isActive,
|
|
@@ -113,7 +113,7 @@ function Filters({
|
|
|
113
113
|
onRefresh,
|
|
114
114
|
setOrderBy,
|
|
115
115
|
setOrderDirection,
|
|
116
|
-
}: FiltersProps) {
|
|
116
|
+
}: FiltersProps) => {
|
|
117
117
|
return (
|
|
118
118
|
<div className="w-full bg-card/50 backdrop-blur-sm border border-border/50 rounded-lg p-4 shadow-sm">
|
|
119
119
|
{/* Header Section */}
|
|
@@ -416,6 +416,4 @@ function Filters({
|
|
|
416
416
|
</div>
|
|
417
417
|
</div>
|
|
418
418
|
);
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
export default React.memo(Filters);
|
|
419
|
+
};
|
|
@@ -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";
|
|
@@ -5,14 +5,14 @@ import { Button } from "__UI_BASE__/button";
|
|
|
5
5
|
import type {
|
|
6
6
|
GetEscrowsFromIndexerResponse as Escrow,
|
|
7
7
|
MultiReleaseMilestone,
|
|
8
|
-
Role,
|
|
9
8
|
SingleReleaseMilestone,
|
|
10
9
|
} from "@trustless-work/escrow/types";
|
|
11
|
-
import Filters from "./Filters";
|
|
10
|
+
import { Filters } from "./Filters";
|
|
12
11
|
import { useEscrowsBySigner } from "../useEscrowsBySigner.shared";
|
|
13
12
|
import { Card, CardContent, CardHeader, CardTitle } from "__UI_BASE__/card";
|
|
14
13
|
import { Badge } from "__UI_BASE__/badge";
|
|
15
14
|
import { Separator } from "__UI_BASE__/separator";
|
|
15
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from "__UI_BASE__/tooltip";
|
|
16
16
|
import {
|
|
17
17
|
Goal,
|
|
18
18
|
Wallet,
|
|
@@ -21,12 +21,15 @@ import {
|
|
|
21
21
|
RefreshCw,
|
|
22
22
|
FileX,
|
|
23
23
|
} from "lucide-react";
|
|
24
|
-
import { useEscrowContext } from "
|
|
25
|
-
import { useEscrowDialogs } from "
|
|
26
|
-
import EscrowDetailDialog from "
|
|
27
|
-
import {
|
|
24
|
+
import { useEscrowContext } from "@/components/tw-blocks/providers/EscrowProvider";
|
|
25
|
+
import { useEscrowDialogs } from "@/components/tw-blocks/providers/EscrowDialogsProvider";
|
|
26
|
+
import { EscrowDetailDialog } from "../details/EscrowDetailDialog";
|
|
27
|
+
import {
|
|
28
|
+
formatCurrency,
|
|
29
|
+
formatTimestamp,
|
|
30
|
+
} from "../../../helpers/format.helper";
|
|
28
31
|
|
|
29
|
-
export
|
|
32
|
+
export const EscrowsBySignerCards = () => {
|
|
30
33
|
const {
|
|
31
34
|
walletAddress,
|
|
32
35
|
data,
|
|
@@ -70,9 +73,9 @@ export function EscrowsBySignerCards() {
|
|
|
70
73
|
|
|
71
74
|
const dialogStates = useEscrowDialogs();
|
|
72
75
|
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
};
|
|
76
|
+
const handleRefresh = React.useCallback(() => {
|
|
77
|
+
void refetch();
|
|
78
|
+
}, [refetch]);
|
|
76
79
|
|
|
77
80
|
function allMilestonesReleasedOrResolved(
|
|
78
81
|
milestones: MultiReleaseMilestone[]
|
|
@@ -116,18 +119,6 @@ export function EscrowsBySignerCards() {
|
|
|
116
119
|
dialogStates.second.setIsOpen(true);
|
|
117
120
|
};
|
|
118
121
|
|
|
119
|
-
/**
|
|
120
|
-
* Based on the provided roles -> https://docs.trustlesswork.com/trustless-work/technology-overview/roles-in-trustless-work
|
|
121
|
-
*
|
|
122
|
-
* You must pass one or more roles according to requirements
|
|
123
|
-
*
|
|
124
|
-
* For example:
|
|
125
|
-
* - If the user is a freelancer, you must pass the "serviceProvider" and "receiver" role
|
|
126
|
-
*
|
|
127
|
-
* Depending of the role, you'll have different actions buttons
|
|
128
|
-
*/
|
|
129
|
-
const activeRole: Role[] = ["approver"];
|
|
130
|
-
|
|
131
122
|
const escrows: Escrow[] = data ?? [];
|
|
132
123
|
|
|
133
124
|
return (
|
|
@@ -148,18 +139,18 @@ export function EscrowsBySignerCards() {
|
|
|
148
139
|
setEngagementId={setEngagementId}
|
|
149
140
|
setIsActive={setIsActive}
|
|
150
141
|
setValidateOnChain={setValidateOnChain}
|
|
151
|
-
setType={
|
|
152
|
-
setStatus={
|
|
142
|
+
setType={setType}
|
|
143
|
+
setStatus={setStatus}
|
|
153
144
|
setMinAmount={setMinAmount}
|
|
154
145
|
setMaxAmount={setMaxAmount}
|
|
155
146
|
setDateRange={setDateRange}
|
|
156
147
|
onClearFilters={onClearFilters}
|
|
157
|
-
onRefresh={
|
|
148
|
+
onRefresh={handleRefresh}
|
|
158
149
|
isRefreshing={isFetching}
|
|
159
150
|
orderBy={orderBy}
|
|
160
151
|
orderDirection={orderDirection}
|
|
161
|
-
setOrderBy={
|
|
162
|
-
setOrderDirection={
|
|
152
|
+
setOrderBy={setOrderBy}
|
|
153
|
+
setOrderDirection={setOrderDirection}
|
|
163
154
|
/>
|
|
164
155
|
|
|
165
156
|
<div className="w-full py-2 sm:py-4">
|
|
@@ -235,7 +226,7 @@ export function EscrowsBySignerCards() {
|
|
|
235
226
|
An error occurred while loading the information. Please try
|
|
236
227
|
again.
|
|
237
228
|
</p>
|
|
238
|
-
<Button variant="outline" size="sm" onClick={
|
|
229
|
+
<Button variant="outline" size="sm" onClick={handleRefresh}>
|
|
239
230
|
<RefreshCw className="h-4 w-4 mr-2" />
|
|
240
231
|
Retry
|
|
241
232
|
</Button>
|
|
@@ -258,7 +249,7 @@ export function EscrowsBySignerCards() {
|
|
|
258
249
|
{escrows.map((escrow) => (
|
|
259
250
|
<React.Fragment key={escrow.contractId}>
|
|
260
251
|
<Card
|
|
261
|
-
className="w-full max-w-md mx-auto hover:shadow-lg transition-shadow duration-200"
|
|
252
|
+
className="w-full max-w-md mx-auto hover:shadow-lg transition-shadow duration-200 cursor-pointer"
|
|
262
253
|
onClick={(e) => {
|
|
263
254
|
e.stopPropagation();
|
|
264
255
|
onCardClick(escrow);
|
|
@@ -343,9 +334,9 @@ export function EscrowsBySignerCards() {
|
|
|
343
334
|
<ul className="list-disc list-inside flex flex-col gap-1">
|
|
344
335
|
{escrow.milestones
|
|
345
336
|
.slice(0, 3)
|
|
346
|
-
.map((milestone) => (
|
|
337
|
+
.map((milestone, index) => (
|
|
347
338
|
<li
|
|
348
|
-
key={milestone.description.
|
|
339
|
+
key={`milestone-${milestone.description}-${milestone.status}-${index}`}
|
|
349
340
|
className="text-xs flex justify-between"
|
|
350
341
|
>
|
|
351
342
|
{milestone.description}
|
|
@@ -361,33 +352,83 @@ export function EscrowsBySignerCards() {
|
|
|
361
352
|
)}
|
|
362
353
|
</span>
|
|
363
354
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
355
|
+
{milestone.flags?.disputed && (
|
|
356
|
+
<Tooltip>
|
|
357
|
+
<TooltipTrigger>
|
|
358
|
+
<span
|
|
359
|
+
className={`bg-red-800 rounded-full h-2 w-2 ml-1 ${
|
|
360
|
+
milestone.flags?.disputed
|
|
361
|
+
? "block"
|
|
362
|
+
: "hidden"
|
|
363
|
+
}`}
|
|
364
|
+
/>
|
|
365
|
+
</TooltipTrigger>
|
|
366
|
+
<TooltipContent>
|
|
367
|
+
Disputed
|
|
368
|
+
</TooltipContent>
|
|
369
|
+
</Tooltip>
|
|
370
|
+
)}
|
|
371
|
+
|
|
372
|
+
{milestone.flags?.resolved && (
|
|
373
|
+
<Tooltip>
|
|
374
|
+
<TooltipTrigger>
|
|
375
|
+
<span
|
|
376
|
+
className={`bg-green-800 rounded-full h-2 w-2 ml-1 ${
|
|
377
|
+
milestone.flags?.resolved
|
|
378
|
+
? "block"
|
|
379
|
+
: "hidden"
|
|
380
|
+
}`}
|
|
381
|
+
/>
|
|
382
|
+
</TooltipTrigger>
|
|
383
|
+
<TooltipContent>
|
|
384
|
+
Resolved
|
|
385
|
+
</TooltipContent>
|
|
386
|
+
</Tooltip>
|
|
387
|
+
)}
|
|
388
|
+
|
|
389
|
+
{milestone.flags?.released && (
|
|
390
|
+
<Tooltip>
|
|
391
|
+
<TooltipTrigger>
|
|
392
|
+
<span
|
|
393
|
+
className={`bg-green-800 rounded-full h-2 w-2 ml-1 ${
|
|
394
|
+
milestone.flags?.released
|
|
395
|
+
? "block"
|
|
396
|
+
: "hidden"
|
|
397
|
+
}`}
|
|
398
|
+
/>
|
|
399
|
+
</TooltipTrigger>
|
|
400
|
+
<TooltipContent>
|
|
401
|
+
Released
|
|
402
|
+
</TooltipContent>
|
|
403
|
+
</Tooltip>
|
|
404
|
+
)}
|
|
405
|
+
|
|
406
|
+
{milestone.flags?.approved &&
|
|
407
|
+
!milestone.flags?.disputed &&
|
|
408
|
+
!milestone.flags?.resolved &&
|
|
409
|
+
!milestone.flags?.released && (
|
|
410
|
+
<Tooltip>
|
|
411
|
+
<TooltipTrigger>
|
|
412
|
+
<span
|
|
413
|
+
className={`bg-yellow-600 rounded-full h-2 w-2 ml-1 ${
|
|
414
|
+
milestone.flags
|
|
415
|
+
?.approved &&
|
|
416
|
+
!milestone.flags
|
|
417
|
+
?.disputed &&
|
|
418
|
+
!milestone.flags
|
|
419
|
+
?.resolved &&
|
|
420
|
+
!milestone.flags
|
|
421
|
+
?.released
|
|
422
|
+
? "block"
|
|
423
|
+
: "hidden"
|
|
424
|
+
}`}
|
|
425
|
+
/>
|
|
426
|
+
</TooltipTrigger>
|
|
427
|
+
<TooltipContent>
|
|
428
|
+
Pending Release
|
|
429
|
+
</TooltipContent>
|
|
430
|
+
</Tooltip>
|
|
431
|
+
)}
|
|
391
432
|
</div>
|
|
392
433
|
</>
|
|
393
434
|
)}
|
|
@@ -502,14 +543,13 @@ export function EscrowsBySignerCards() {
|
|
|
502
543
|
</div>
|
|
503
544
|
|
|
504
545
|
{/* Dialog */}
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
546
|
+
{dialogStates.second.isOpen ? (
|
|
547
|
+
<EscrowDetailDialog
|
|
548
|
+
isDialogOpen={dialogStates.second.isOpen}
|
|
549
|
+
setIsDialogOpen={dialogStates.second.setIsOpen}
|
|
550
|
+
setSelectedEscrow={setSelectedEscrow}
|
|
551
|
+
/>
|
|
552
|
+
) : null}
|
|
511
553
|
</>
|
|
512
554
|
);
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
export default EscrowsBySignerCards;
|
|
555
|
+
};
|
|
@@ -81,7 +81,7 @@ type FiltersProps = {
|
|
|
81
81
|
setOrderDirection: (v: "asc" | "desc") => void;
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
export const Filters = ({
|
|
85
85
|
title,
|
|
86
86
|
engagementId,
|
|
87
87
|
isActive,
|
|
@@ -108,7 +108,7 @@ function Filters({
|
|
|
108
108
|
onRefresh,
|
|
109
109
|
setOrderBy,
|
|
110
110
|
setOrderDirection,
|
|
111
|
-
}: FiltersProps) {
|
|
111
|
+
}: FiltersProps) => {
|
|
112
112
|
return (
|
|
113
113
|
<div className="w-full bg-card/50 backdrop-blur-sm border border-border/50 rounded-lg p-4 shadow-sm">
|
|
114
114
|
{/* Header Section */}
|
|
@@ -384,6 +384,4 @@ function Filters({
|
|
|
384
384
|
</div>
|
|
385
385
|
</div>
|
|
386
386
|
);
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
export default React.memo(Filters);
|
|
387
|
+
};
|