@trustless-work/blocks 1.1.0 → 1.1.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trustless-work/blocks",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "author": "Trustless Work",
5
5
  "keywords": [
6
6
  "react",
@@ -1,315 +1,315 @@
1
- "use client";
2
-
3
- import React from "react";
4
- import {
5
- Card,
6
- CardContent,
7
- CardDescription,
8
- CardHeader,
9
- CardTitle,
10
- } from "__UI_BASE__/card";
11
- import { Separator } from "__UI_BASE__/separator";
12
- import { useDashboard } from "./useDashboard";
13
- import { formatCurrency } from "../../helpers/format.helper";
14
- import { Activity, Layers3, PiggyBank, CloudOff } from "lucide-react";
15
- import {
16
- AreaChart,
17
- Area,
18
- XAxis,
19
- CartesianGrid,
20
- BarChart,
21
- Bar,
22
- PieChart,
23
- Pie,
24
- Cell,
25
- } from "recharts";
26
- import {
27
- ChartContainer,
28
- ChartTooltip,
29
- ChartTooltipContent,
30
- type ChartConfig,
31
- } from "__UI_BASE__/chart";
32
- import {
33
- Empty,
34
- EmptyHeader,
35
- EmptyMedia,
36
- EmptyTitle,
37
- EmptyDescription,
38
- } from "__UI_BASE__/empty";
39
-
40
- const chartConfigBar: ChartConfig = {
41
- desktop: {
42
- label: "Amount",
43
- color: "var(--chart-1)",
44
- },
45
- };
46
-
47
- const chartConfigDonut: ChartConfig = {
48
- visitors: { label: "Count" },
49
- single: { label: "Single", color: "var(--chart-1)" },
50
- multi: { label: "Multi", color: "var(--chart-2)" },
51
- };
52
-
53
- const chartConfigArea: ChartConfig = {
54
- desktop: {
55
- label: "Created",
56
- color: "var(--chart-1)",
57
- },
58
- };
59
-
60
- export const Dashboard01 = () => {
61
- const {
62
- isLoading,
63
- totalEscrows,
64
- totalAmount,
65
- totalBalance,
66
- typeSlices,
67
- amountsByDate,
68
- createdByDate,
69
- } = useDashboard();
70
-
71
- const barData = React.useMemo(
72
- () => amountsByDate.map((d) => ({ month: d.date, desktop: d.amount })),
73
- [amountsByDate]
74
- );
75
-
76
- const donutData = React.useMemo(
77
- () =>
78
- typeSlices.map((s) => ({
79
- browser: s.type === "single" ? "single" : "multi",
80
- visitors: s.value,
81
- fill:
82
- s.type === "single" ? "var(--color-single)" : "var(--color-multi)",
83
- })),
84
- [typeSlices]
85
- );
86
-
87
- const areaData = React.useMemo(
88
- () => createdByDate.map((d) => ({ month: d.date, desktop: d.count })),
89
- [createdByDate]
90
- );
91
-
92
- return (
93
- <div className="grid gap-6">
94
- {/* KPI Cards */}
95
- <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
96
- <Card className="gap-3">
97
- <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
98
- <CardTitle className="text-sm font-medium">Escrows</CardTitle>
99
- <Layers3 className="h-4 w-4 text-muted-foreground" />
100
- </CardHeader>
101
- <CardContent>
102
- <div className="text-2xl font-bold">
103
- {isLoading ? "-" : totalEscrows}
104
- </div>
105
- <p className="text-xs text-muted-foreground">
106
- Total number of escrows
107
- </p>
108
- </CardContent>
109
- </Card>
110
-
111
- <Card className="gap-3">
112
- <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
113
- <CardTitle className="text-sm font-medium">Total Amount</CardTitle>
114
- <Activity className="h-4 w-4 text-muted-foreground" />
115
- </CardHeader>
116
- <CardContent>
117
- <div className="text-2xl font-bold">
118
- {isLoading ? "-" : formatCurrency(totalAmount, "USDC")}
119
- </div>
120
- <p className="text-xs text-muted-foreground">
121
- Sum of amounts (SR + MR)
122
- </p>
123
- </CardContent>
124
- </Card>
125
-
126
- <Card className="gap-3">
127
- <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
128
- <CardTitle className="text-sm font-medium">Total Balance</CardTitle>
129
- <PiggyBank className="h-4 w-4 text-muted-foreground" />
130
- </CardHeader>
131
- <CardContent>
132
- <div className="text-2xl font-bold">
133
- {isLoading ? "-" : formatCurrency(totalBalance, "USDC")}
134
- </div>
135
- <p className="text-xs text-muted-foreground">
136
- Total balance across all escrows
137
- </p>
138
- </CardContent>
139
- </Card>
140
- </div>
141
-
142
- <Separator />
143
-
144
- {/* Charts */}
145
- <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
146
- {/* Bar chart: Amounts by date (shadcn pattern) */}
147
- <Card className="gap-3">
148
- <CardHeader>
149
- <CardTitle>Escrow Amounts</CardTitle>
150
- <CardDescription>Amounts by date</CardDescription>
151
- </CardHeader>
152
- <CardContent>
153
- <ChartContainer
154
- className="w-full h-56 sm:h-64 lg:h-72"
155
- config={chartConfigBar}
156
- >
157
- {barData.length > 0 ? (
158
- <BarChart accessibilityLayer data={barData}>
159
- <CartesianGrid vertical={false} />
160
- <XAxis
161
- dataKey="month"
162
- tickLine={false}
163
- tickMargin={10}
164
- axisLine={false}
165
- tickFormatter={(value) =>
166
- new Date(String(value)).toLocaleDateString("en-US", {
167
- month: "short",
168
- day: "numeric",
169
- })
170
- }
171
- />
172
- <ChartTooltip
173
- cursor={false}
174
- content={<ChartTooltipContent hideLabel />}
175
- />
176
- <Bar
177
- dataKey="desktop"
178
- fill="var(--color-desktop)"
179
- radius={8}
180
- />
181
- </BarChart>
182
- ) : (
183
- <Empty className="border border-dashed">
184
- <EmptyHeader>
185
- <EmptyMedia variant="icon">
186
- <CloudOff />
187
- </EmptyMedia>
188
- <EmptyTitle>No data</EmptyTitle>
189
- <EmptyDescription>No Data Available</EmptyDescription>
190
- </EmptyHeader>
191
- </Empty>
192
- )}
193
- </ChartContainer>
194
- </CardContent>
195
- </Card>
196
-
197
- {/* Donut chart: Escrow types (shadcn pattern) */}
198
- <Card className="flex flex-col">
199
- <CardHeader className="items-center pb-0">
200
- <CardTitle>Escrow Types</CardTitle>
201
- <CardDescription>Escrow types</CardDescription>
202
- </CardHeader>
203
- <CardContent className="flex-1 pb-0">
204
- <ChartContainer
205
- config={chartConfigDonut}
206
- className="w-full h-56 sm:h-64 lg:h-72"
207
- >
208
- {donutData.some((d) => Number(d.visitors) > 0) ? (
209
- <PieChart>
210
- <ChartTooltip
211
- cursor={false}
212
- content={<ChartTooltipContent hideLabel />}
213
- />
214
- <Pie
215
- data={donutData}
216
- dataKey="visitors"
217
- nameKey="browser"
218
- innerRadius={60}
219
- >
220
- {donutData.map((slice, idx) => (
221
- <Cell key={`cell-${idx}`} fill={slice.fill} />
222
- ))}
223
- </Pie>
224
- </PieChart>
225
- ) : (
226
- <Empty className="border border-dashed">
227
- <EmptyHeader>
228
- <EmptyMedia variant="icon">
229
- <CloudOff />
230
- </EmptyMedia>
231
- <EmptyTitle>No data</EmptyTitle>
232
- <EmptyDescription>No Data Available</EmptyDescription>
233
- </EmptyHeader>
234
- </Empty>
235
- )}
236
- </ChartContainer>
237
- <div className="mt-4 flex items-center justify-center gap-6">
238
- <div className="flex items-center gap-2">
239
- <span
240
- className="h-2 w-2 rounded-full"
241
- style={{ background: "var(--chart-1)" }}
242
- />
243
- <span className="text-xs text-muted-foreground">Single</span>
244
- </div>
245
- <div className="flex items-center gap-2">
246
- <span
247
- className="h-2 w-2 rounded-full"
248
- style={{ background: "var(--chart-2)" }}
249
- />
250
- <span className="text-xs text-muted-foreground">Multi</span>
251
- </div>
252
- </div>
253
- </CardContent>
254
- </Card>
255
-
256
- {/* Area chart: Created escrows (shadcn pattern) */}
257
- <Card className="lg:col-span-2">
258
- <CardHeader>
259
- <CardTitle>Escrow Created</CardTitle>
260
- <CardDescription>Created escrows by date</CardDescription>
261
- </CardHeader>
262
- <CardContent>
263
- <ChartContainer
264
- className="w-full h-56 sm:h-64 lg:h-72"
265
- config={chartConfigArea}
266
- >
267
- {areaData.length > 0 ? (
268
- <AreaChart
269
- accessibilityLayer
270
- data={areaData}
271
- margin={{ left: 12, right: 12 }}
272
- >
273
- <CartesianGrid vertical={false} />
274
- <XAxis
275
- dataKey="month"
276
- tickLine={false}
277
- axisLine={false}
278
- tickMargin={8}
279
- tickFormatter={(value) =>
280
- new Date(String(value)).toLocaleDateString("en-US", {
281
- month: "short",
282
- day: "numeric",
283
- })
284
- }
285
- />
286
- <ChartTooltip
287
- cursor={false}
288
- content={<ChartTooltipContent indicator="line" />}
289
- />
290
- <Area
291
- dataKey="desktop"
292
- type="natural"
293
- fill="var(--color-desktop)"
294
- fillOpacity={0.4}
295
- stroke="var(--color-desktop)"
296
- />
297
- </AreaChart>
298
- ) : (
299
- <Empty className="border border-dashed">
300
- <EmptyHeader>
301
- <EmptyMedia variant="icon">
302
- <CloudOff />
303
- </EmptyMedia>
304
- <EmptyTitle>No data</EmptyTitle>
305
- <EmptyDescription>No Data Available</EmptyDescription>
306
- </EmptyHeader>
307
- </Empty>
308
- )}
309
- </ChartContainer>
310
- </CardContent>
311
- </Card>
312
- </div>
313
- </div>
314
- );
315
- };
1
+ "use client";
2
+
3
+ import React from "react";
4
+ import {
5
+ Card,
6
+ CardContent,
7
+ CardDescription,
8
+ CardHeader,
9
+ CardTitle,
10
+ } from "__UI_BASE__/card";
11
+ import { Separator } from "__UI_BASE__/separator";
12
+ import { useDashboard } from "./useDashboard";
13
+ import { formatCurrency } from "../../helpers/format.helper";
14
+ import { Activity, Layers3, PiggyBank, CloudOff } from "lucide-react";
15
+ import {
16
+ AreaChart,
17
+ Area,
18
+ XAxis,
19
+ CartesianGrid,
20
+ BarChart,
21
+ Bar,
22
+ PieChart,
23
+ Pie,
24
+ Cell,
25
+ } from "recharts";
26
+ import {
27
+ ChartContainer,
28
+ ChartTooltip,
29
+ ChartTooltipContent,
30
+ type ChartConfig,
31
+ } from "__UI_BASE__/chart";
32
+ import {
33
+ Empty,
34
+ EmptyHeader,
35
+ EmptyMedia,
36
+ EmptyTitle,
37
+ EmptyDescription,
38
+ } from "__UI_BASE__/empty";
39
+
40
+ const chartConfigBar: ChartConfig = {
41
+ desktop: {
42
+ label: "Amount",
43
+ color: "var(--chart-1)",
44
+ },
45
+ };
46
+
47
+ const chartConfigDonut: ChartConfig = {
48
+ visitors: { label: "Count" },
49
+ single: { label: "Single", color: "var(--chart-1)" },
50
+ multi: { label: "Multi", color: "var(--chart-2)" },
51
+ };
52
+
53
+ const chartConfigArea: ChartConfig = {
54
+ desktop: {
55
+ label: "Created",
56
+ color: "var(--chart-1)",
57
+ },
58
+ };
59
+
60
+ export const Dashboard01 = () => {
61
+ const {
62
+ isLoading,
63
+ totalEscrows,
64
+ totalAmount,
65
+ totalBalance,
66
+ typeSlices,
67
+ amountsByDate,
68
+ createdByDate,
69
+ } = useDashboard();
70
+
71
+ const barData = React.useMemo(
72
+ () => amountsByDate.map((d) => ({ month: d.date, desktop: d.amount })),
73
+ [amountsByDate]
74
+ );
75
+
76
+ const donutData = React.useMemo(
77
+ () =>
78
+ typeSlices.map((s) => ({
79
+ browser: s.type === "single" ? "single" : "multi",
80
+ visitors: s.value,
81
+ fill:
82
+ s.type === "single" ? "var(--color-single)" : "var(--color-multi)",
83
+ })),
84
+ [typeSlices]
85
+ );
86
+
87
+ const areaData = React.useMemo(
88
+ () => createdByDate.map((d) => ({ month: d.date, desktop: d.count })),
89
+ [createdByDate]
90
+ );
91
+
92
+ return (
93
+ <div className="grid gap-6">
94
+ {/* KPI Cards */}
95
+ <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
96
+ <Card className="gap-3">
97
+ <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
98
+ <CardTitle className="text-sm font-medium">Escrows</CardTitle>
99
+ <Layers3 className="h-4 w-4 text-muted-foreground" />
100
+ </CardHeader>
101
+ <CardContent>
102
+ <div className="text-2xl font-bold">
103
+ {isLoading ? "-" : totalEscrows}
104
+ </div>
105
+ <p className="text-xs text-muted-foreground">
106
+ Total number of escrows
107
+ </p>
108
+ </CardContent>
109
+ </Card>
110
+
111
+ <Card className="gap-3">
112
+ <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
113
+ <CardTitle className="text-sm font-medium">Total Amount</CardTitle>
114
+ <Activity className="h-4 w-4 text-muted-foreground" />
115
+ </CardHeader>
116
+ <CardContent>
117
+ <div className="text-2xl font-bold">
118
+ {isLoading ? "-" : formatCurrency(totalAmount, "USDC")}
119
+ </div>
120
+ <p className="text-xs text-muted-foreground">
121
+ Sum of amounts (SR + MR)
122
+ </p>
123
+ </CardContent>
124
+ </Card>
125
+
126
+ <Card className="gap-3">
127
+ <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
128
+ <CardTitle className="text-sm font-medium">Total Balance</CardTitle>
129
+ <PiggyBank className="h-4 w-4 text-muted-foreground" />
130
+ </CardHeader>
131
+ <CardContent>
132
+ <div className="text-2xl font-bold">
133
+ {isLoading ? "-" : formatCurrency(totalBalance, "USDC")}
134
+ </div>
135
+ <p className="text-xs text-muted-foreground">
136
+ Total balance across all escrows
137
+ </p>
138
+ </CardContent>
139
+ </Card>
140
+ </div>
141
+
142
+ <Separator />
143
+
144
+ {/* Charts */}
145
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
146
+ {/* Bar chart: Amounts by date (shadcn pattern) */}
147
+ <Card className="gap-3">
148
+ <CardHeader>
149
+ <CardTitle>Escrow Amounts</CardTitle>
150
+ <CardDescription>Amounts by date</CardDescription>
151
+ </CardHeader>
152
+ <CardContent>
153
+ <ChartContainer
154
+ className="w-full h-56 sm:h-64 lg:h-72"
155
+ config={chartConfigBar}
156
+ >
157
+ {barData.length > 0 ? (
158
+ <BarChart accessibilityLayer data={barData}>
159
+ <CartesianGrid vertical={false} />
160
+ <XAxis
161
+ dataKey="month"
162
+ tickLine={false}
163
+ tickMargin={10}
164
+ axisLine={false}
165
+ tickFormatter={(value) =>
166
+ new Date(String(value)).toLocaleDateString("en-US", {
167
+ month: "short",
168
+ day: "numeric",
169
+ })
170
+ }
171
+ />
172
+ <ChartTooltip
173
+ cursor={false}
174
+ content={<ChartTooltipContent hideLabel />}
175
+ />
176
+ <Bar
177
+ dataKey="desktop"
178
+ fill="var(--color-desktop)"
179
+ radius={8}
180
+ />
181
+ </BarChart>
182
+ ) : (
183
+ <Empty className="border border-dashed">
184
+ <EmptyHeader>
185
+ <EmptyMedia variant="icon">
186
+ <CloudOff />
187
+ </EmptyMedia>
188
+ <EmptyTitle>No data</EmptyTitle>
189
+ <EmptyDescription>No Data Available</EmptyDescription>
190
+ </EmptyHeader>
191
+ </Empty>
192
+ )}
193
+ </ChartContainer>
194
+ </CardContent>
195
+ </Card>
196
+
197
+ {/* Donut chart: Escrow types (shadcn pattern) */}
198
+ <Card className="flex flex-col">
199
+ <CardHeader className="items-center pb-0">
200
+ <CardTitle>Escrow Types</CardTitle>
201
+ <CardDescription>Escrow types</CardDescription>
202
+ </CardHeader>
203
+ <CardContent className="flex-1 pb-0">
204
+ <ChartContainer
205
+ config={chartConfigDonut}
206
+ className="w-full h-56 sm:h-64 lg:h-72"
207
+ >
208
+ {donutData.some((d) => Number(d.visitors) > 0) ? (
209
+ <PieChart>
210
+ <ChartTooltip
211
+ cursor={false}
212
+ content={<ChartTooltipContent hideLabel />}
213
+ />
214
+ <Pie
215
+ data={donutData}
216
+ dataKey="visitors"
217
+ nameKey="browser"
218
+ innerRadius={60}
219
+ >
220
+ {donutData.map((slice, idx) => (
221
+ <Cell key={`cell-${idx}`} fill={slice.fill} />
222
+ ))}
223
+ </Pie>
224
+ </PieChart>
225
+ ) : (
226
+ <Empty className="border border-dashed">
227
+ <EmptyHeader>
228
+ <EmptyMedia variant="icon">
229
+ <CloudOff />
230
+ </EmptyMedia>
231
+ <EmptyTitle>No data</EmptyTitle>
232
+ <EmptyDescription>No Data Available</EmptyDescription>
233
+ </EmptyHeader>
234
+ </Empty>
235
+ )}
236
+ </ChartContainer>
237
+ <div className="mt-4 flex items-center justify-center gap-6">
238
+ <div className="flex items-center gap-2">
239
+ <span
240
+ className="h-2 w-2 rounded-full"
241
+ style={{ background: "var(--chart-1)" }}
242
+ />
243
+ <span className="text-xs text-muted-foreground">Single</span>
244
+ </div>
245
+ <div className="flex items-center gap-2">
246
+ <span
247
+ className="h-2 w-2 rounded-full"
248
+ style={{ background: "var(--chart-2)" }}
249
+ />
250
+ <span className="text-xs text-muted-foreground">Multi</span>
251
+ </div>
252
+ </div>
253
+ </CardContent>
254
+ </Card>
255
+
256
+ {/* Area chart: Created escrows (shadcn pattern) */}
257
+ <Card className="lg:col-span-2">
258
+ <CardHeader>
259
+ <CardTitle>Escrow Created</CardTitle>
260
+ <CardDescription>Created escrows by date</CardDescription>
261
+ </CardHeader>
262
+ <CardContent>
263
+ <ChartContainer
264
+ className="w-full h-56 sm:h-64 lg:h-72"
265
+ config={chartConfigArea}
266
+ >
267
+ {areaData.length > 0 ? (
268
+ <AreaChart
269
+ accessibilityLayer
270
+ data={areaData}
271
+ margin={{ left: 12, right: 12 }}
272
+ >
273
+ <CartesianGrid vertical={false} />
274
+ <XAxis
275
+ dataKey="month"
276
+ tickLine={false}
277
+ axisLine={false}
278
+ tickMargin={8}
279
+ tickFormatter={(value) =>
280
+ new Date(String(value)).toLocaleDateString("en-US", {
281
+ month: "short",
282
+ day: "numeric",
283
+ })
284
+ }
285
+ />
286
+ <ChartTooltip
287
+ cursor={false}
288
+ content={<ChartTooltipContent indicator="line" />}
289
+ />
290
+ <Area
291
+ dataKey="desktop"
292
+ type="natural"
293
+ fill="var(--color-desktop)"
294
+ fillOpacity={0.4}
295
+ stroke="var(--color-desktop)"
296
+ />
297
+ </AreaChart>
298
+ ) : (
299
+ <Empty className="border border-dashed">
300
+ <EmptyHeader>
301
+ <EmptyMedia variant="icon">
302
+ <CloudOff />
303
+ </EmptyMedia>
304
+ <EmptyTitle>No data</EmptyTitle>
305
+ <EmptyDescription>No Data Available</EmptyDescription>
306
+ </EmptyHeader>
307
+ </Empty>
308
+ )}
309
+ </ChartContainer>
310
+ </CardContent>
311
+ </Card>
312
+ </div>
313
+ </div>
314
+ );
315
+ };