1
1
import dayjs from "dayjs" ;
2
- import { ArrowDownIcon , ArrowUpIcon , Drum } from "lucide-react" ;
2
+ import {
3
+ ArrowDownIcon ,
4
+ ArrowUpIcon ,
5
+ ChevronDown ,
6
+ ChevronUp ,
7
+ CopyIcon ,
8
+ Drum ,
9
+ } from "lucide-react" ;
10
+ import React from "react" ;
3
11
import EmptyState from "src/components/EmptyState" ;
4
-
5
12
import Loading from "src/components/Loading" ;
13
+ import {
14
+ Credenza ,
15
+ CredenzaBody ,
16
+ CredenzaContent ,
17
+ CredenzaFooter ,
18
+ CredenzaHeader ,
19
+ CredenzaTitle ,
20
+ CredenzaTrigger ,
21
+ } from "src/components/ui/credenza" ;
22
+ import { toast } from "src/components/ui/use-toast" ;
6
23
import { useTransactions } from "src/hooks/useTransactions" ;
24
+ import { copyToClipboard } from "src/lib/clipboard" ;
7
25
8
26
function TransactionsList ( ) {
9
27
const { data : transactions , isLoading } = useTransactions ( ) ;
28
+ const [ showDetails , setShowDetails ] = React . useState ( false ) ;
10
29
11
30
if ( isLoading ) {
12
31
return < Loading /> ;
13
32
}
14
33
34
+ const copy = ( text : string ) => {
35
+ copyToClipboard ( text ) ;
36
+ toast ( { title : "Copied to clipboard." } ) ;
37
+ } ;
38
+
15
39
return (
16
40
< div >
17
41
{ ! transactions ?. length ? (
@@ -28,79 +52,182 @@ function TransactionsList() {
28
52
const type = tx . type ;
29
53
30
54
return (
31
- < div
55
+ < Credenza
32
56
key = { `tx-${ i } ` }
33
- className = "p-3 mb-4 rounded-md"
34
- // TODO: Add modal onclick to show payment details
57
+ onOpenChange = { ( open ) => {
58
+ if ( ! open ) {
59
+ setShowDetails ( false ) ;
60
+ }
61
+ } }
35
62
>
36
- < div className = "flex gap-3" >
37
- < div className = "flex items-center" >
38
- { type == "outgoing" ? (
39
- < div
40
- className = {
41
- "flex justify-center items-center bg-orange-100 dark:bg-orange-950 rounded-full w-10 h-10 md:w-14 md:h-14"
42
- }
43
- >
44
- < ArrowUpIcon
45
- strokeWidth = { 3 }
46
- className = "w-6 h-6 md:w-8 md:h-8 text-orange-400 dark:text-amber-600 stroke-orange-400 dark:stroke-amber-600"
47
- />
48
- </ div >
49
- ) : (
50
- < div className = "flex justify-center items-center bg-green-100 dark:bg-emerald-950 rounded-full w-10 h-10 md:w-14 md:h-14" >
51
- < ArrowDownIcon
52
- strokeWidth = { 3 }
53
- className = "w-6 h-6 md:w-8 md:h-8 text-green-500 dark:text-emerald-500 stroke-green-400 dark:stroke-emerald-500"
54
- />
63
+ < CredenzaTrigger
64
+ asChild
65
+ className = "p-3 mb-4 hover:bg-gray-100 dark:hover:bg-surface-02dp cursor-pointer rounded-md slashed-zero"
66
+ >
67
+ < div className = "flex gap-3" >
68
+ < div className = "flex items-center" >
69
+ { type == "outgoing" ? (
70
+ < div
71
+ className = {
72
+ "flex justify-center items-center bg-orange-100 dark:bg-orange-950 rounded-full w-10 h-10 md:w-14 md:h-14"
73
+ }
74
+ >
75
+ < ArrowUpIcon
76
+ strokeWidth = { 3 }
77
+ className = "w-6 h-6 md:w-8 md:h-8 text-orange-400 dark:text-amber-600 stroke-orange-400 dark:stroke-amber-600"
78
+ />
79
+ </ div >
80
+ ) : (
81
+ < div className = "flex justify-center items-center bg-green-100 dark:bg-emerald-950 rounded-full w-10 h-10 md:w-14 md:h-14" >
82
+ < ArrowDownIcon
83
+ strokeWidth = { 3 }
84
+ className = "w-6 h-6 md:w-8 md:h-8 text-green-500 dark:text-emerald-500 stroke-green-400 dark:stroke-emerald-500"
85
+ />
86
+ </ div >
87
+ ) }
88
+ </ div >
89
+ < div className = "overflow-hidden mr-3" >
90
+ < div className = "flex items-center gap-2 truncate dark:text-white" >
91
+ < p className = "text-lg md:text-xl font-semibold" >
92
+ { type == "incoming" ? "Received" : "Sent" }
93
+ </ p >
94
+ < p className = "text-sm md:text-base truncate text-muted-foreground" >
95
+ { dayjs ( tx . settled_at * 1000 ) . fromNow ( ) }
96
+ </ p >
55
97
</ div >
56
- ) }
57
- </ div >
58
- < div className = "overflow-hidden mr-3" >
59
- < div className = "flex items-center gap-2 truncate dark:text-white" >
60
- < p className = "text-lg md:text-xl font-semibold" >
61
- { type == "incoming" ? "Received" : "Sent" }
62
- </ p >
63
- < p className = "text-sm md:text-base truncate text-muted-foreground" >
64
- { dayjs ( tx . settled_at * 1000 ) . fromNow ( ) }
98
+ < p className = "text-sm md:text-base text-muted-foreground" >
99
+ { tx . description || "Lightning invoice" }
65
100
</ p >
66
101
</ div >
67
- < p className = "text-sm md:text-base text-muted-foreground" >
68
- { tx . description || "Lightning invoice" }
69
- </ p >
70
- </ div >
71
- < div className = "flex ml-auto text-right space-x-3 shrink-0 dark:text-white" >
72
- < div className = "flex items-center gap-2 text-xl" >
73
- < p
74
- className = { `font-semibold ${
75
- type == "incoming" &&
76
- "text-green-600 dark:color-green-400"
77
- } `}
78
- >
79
- { type == "outgoing" ? "-" : "+" } { " " }
80
- { Math . floor ( tx . amount / 1000 ) }
81
- </ p >
82
- < p className = "text-muted-foreground" > sats</ p >
102
+ < div className = "flex ml-auto text-right space-x-3 shrink-0 dark:text-white" >
103
+ < div className = "flex items-center gap-2 text-xl" >
104
+ < p
105
+ className = { `font-semibold ${
106
+ type == "incoming" &&
107
+ "text-green-600 dark:color-green-400"
108
+ } `}
109
+ >
110
+ { type == "outgoing" ? "-" : "+" } { " " }
111
+ { Math . floor ( tx . amount / 1000 ) }
112
+ </ p >
113
+ < p className = "text-muted-foreground" > sats</ p >
83
114
84
- { /* {!!tx.totalAmountFiat && (
115
+ { /* {!!tx.totalAmountFiat && (
85
116
<p className="text-xs text-gray-400 dark:text-neutral-600">
86
117
~{tx.totalAmountFiat}
87
118
</p>
88
119
)} */ }
120
+ </ div >
89
121
</ div >
90
122
</ div >
91
- </ div >
92
- </ div >
123
+ </ CredenzaTrigger >
124
+ < CredenzaContent className = "slashed-zero" >
125
+ < CredenzaHeader >
126
+ < CredenzaTitle >
127
+ { type == "outgoing" ? "Sent Bitcoin" : "Received Bitcoin" }
128
+ </ CredenzaTitle >
129
+ </ CredenzaHeader >
130
+ < CredenzaBody >
131
+ < div className = "flex items-center mt-6" >
132
+ { type == "outgoing" ? (
133
+ < div
134
+ className = {
135
+ "flex justify-center items-center bg-orange-100 dark:bg-orange-950 rounded-full w-10 h-10 md:w-14 md:h-14"
136
+ }
137
+ >
138
+ < ArrowUpIcon
139
+ strokeWidth = { 3 }
140
+ className = "w-6 h-6 md:w-8 md:h-8 text-orange-400 dark:text-amber-600 stroke-orange-400 dark:stroke-amber-600"
141
+ />
142
+ </ div >
143
+ ) : (
144
+ < div className = "flex justify-center items-center bg-green-100 dark:bg-emerald-950 rounded-full w-10 h-10 md:w-14 md:h-14" >
145
+ < ArrowDownIcon
146
+ strokeWidth = { 3 }
147
+ className = "w-6 h-6 md:w-8 md:h-8 text-green-500 dark:text-emerald-500 stroke-green-400 dark:stroke-emerald-500"
148
+ />
149
+ </ div >
150
+ ) }
151
+ < div className = "ml-4" >
152
+ < p className = "text-xl md:text-2xl font-semibold" >
153
+ { Math . floor ( tx . amount / 1000 ) } { " " }
154
+ { Math . floor ( tx . amount / 1000 ) == 1 ? "sat" : "sats" }
155
+ </ p >
156
+ { /* <p className="text-sm md:text-base text-gray-500">
157
+ Fiat Amount
158
+ </p> */ }
159
+ </ div >
160
+ </ div >
161
+ < div className = "mt-8" >
162
+ < p className = "dark:text-white" > Date & Time </ p >
163
+ < p className = "text-muted-foreground" >
164
+ { dayjs ( tx . settled_at ) . toString ( ) }
165
+ </ p >
166
+ </ div >
167
+ < div className = "mt-6" >
168
+ < p className = "dark:text-white" > Fee</ p >
169
+ < p className = "text-muted-foreground" >
170
+ { tx . fees_paid } { tx . fees_paid == 1 ? "sat" : "sats" }
171
+ </ p >
172
+ </ div >
173
+ { tx . description && (
174
+ < div className = "mt-6" >
175
+ < p className = "dark:text-white" > Description</ p >
176
+ < p className = "text-muted-foreground" >
177
+ { tx . description }
178
+ </ p >
179
+ </ div >
180
+ ) }
181
+ </ CredenzaBody >
182
+ < CredenzaFooter className = "!justify-start mt-4 !flex-col" >
183
+ < div
184
+ className = "flex items-center gap-2 cursor-pointer"
185
+ onClick = { ( ) => setShowDetails ( ! showDetails ) }
186
+ >
187
+ Details
188
+ { showDetails ? (
189
+ < ChevronUp className = "w-4 h-4" />
190
+ ) : (
191
+ < ChevronDown className = "w-4 h-4" />
192
+ ) }
193
+ </ div >
194
+ { showDetails && (
195
+ < >
196
+ < div className = "mt-6 !ml-0" >
197
+ < p className = "dark:text-white" > Preimage</ p >
198
+ < div className = "flex items-center gap-4" >
199
+ < p className = "text-muted-foreground break-all" >
200
+ { tx . preimage }
201
+ </ p >
202
+ < CopyIcon
203
+ className = "cursor-pointer text-muted-foreground w-6 h-6"
204
+ onClick = { ( ) => {
205
+ copy ( tx . preimage ) ;
206
+ } }
207
+ />
208
+ </ div >
209
+ </ div >
210
+ < div className = "mt-6 !ml-0" >
211
+ < p className = "dark:text-white" > Hash</ p >
212
+ < div className = "flex items-center gap-4" >
213
+ < p className = "text-muted-foreground break-all" >
214
+ { tx . payment_hash }
215
+ </ p >
216
+ < CopyIcon
217
+ className = "cursor-pointer text-muted-foreground w-6 h-6"
218
+ onClick = { ( ) => {
219
+ copy ( tx . payment_hash ) ;
220
+ } }
221
+ />
222
+ </ div >
223
+ </ div >
224
+ </ >
225
+ ) }
226
+ </ CredenzaFooter >
227
+ </ CredenzaContent >
228
+ </ Credenza >
93
229
) ;
94
230
} ) }
95
- { /* {transaction && (
96
- <TransactionModal
97
- transaction={transaction}
98
- isOpen={modalOpen}
99
- onClose={() => {
100
- setModalOpen(false);
101
- }}
102
- />
103
- )} */ }
104
231
</ >
105
232
) }
106
233
</ div >
0 commit comments