@@ -7,7 +7,9 @@ import { GiWallet } from 'react-icons/gi'
7
7
import { MdOutlineKeyboardArrowDown } from 'react-icons/md'
8
8
import { useAppKitProvider } from '@reown/appkit/react'
9
9
import { BrowserProvider , ethers , isAddress , parseEther } from 'ethers'
10
- import { HiCurrencyDollar } from 'react-icons/hi'
10
+ import { FiPackage } from 'react-icons/fi'
11
+ import { Avatar , Dialog } from '@/components/ui'
12
+ import { apiGetDevices } from '@/services/DeviceApi'
11
13
12
14
export default function FDSToken ( ) {
13
15
const [ loading , setLoading ] = useState < boolean > ( true )
@@ -22,6 +24,12 @@ export default function FDSToken() {
22
24
const [ selectedWallet , setSelectedWallet ] = useState < string > (
23
25
walletProvider ? 'Select Wallet' : 'No Wallet Connected'
24
26
)
27
+ const [ devices , setDevices ] = useState < any [ ] > ( [ ] )
28
+ const [ isLoadingDevices , setIsLoadingDevices ] = useState ( true )
29
+ const [ selectedDevice , setSelectedDevice ] = useState < any > ( null )
30
+ const [ showDeviceDialog , setShowDeviceDialog ] = useState ( false )
31
+
32
+ const { _id : userId } = useAppSelector ( ( state ) => state . auth . user )
25
33
26
34
async function fetchData ( ) {
27
35
setLoading ( true )
@@ -40,8 +48,25 @@ export default function FDSToken() {
40
48
return accounts || [ ]
41
49
}
42
50
51
+ async function fetchDevices ( ) {
52
+ try {
53
+ setIsLoadingDevices ( true )
54
+ const deviceRes = ( await apiGetDevices ( userId || '' ) ) as any
55
+ setDevices ( deviceRes . data . data )
56
+ } catch ( error ) {
57
+ console . error ( 'Error fetching devices:' , error )
58
+ toast . push (
59
+ < Notification title = { 'Failed to load devices' } type = "danger" /> ,
60
+ { placement : 'top-center' }
61
+ )
62
+ } finally {
63
+ setIsLoadingDevices ( false )
64
+ }
65
+ }
66
+
43
67
useEffect ( ( ) => {
44
68
fetchData ( )
69
+ fetchDevices ( )
45
70
} , [ ] )
46
71
47
72
const handleSelect = ( eventKey : string , event : SyntheticEvent ) => {
@@ -132,6 +157,55 @@ export default function FDSToken() {
132
157
}
133
158
}
134
159
160
+ const DeviceSelectionDialog = ( ) => (
161
+ < Dialog
162
+ contentClassName = "max-w-[400px]"
163
+ isOpen = { showDeviceDialog }
164
+ onClose = { ( ) => setShowDeviceDialog ( false ) }
165
+ onRequestClose = { ( ) => setShowDeviceDialog ( false ) }
166
+ >
167
+ < h5 className = "mb-4" > Select Device</ h5 >
168
+ { isLoadingDevices ? (
169
+ < div className = "flex items-center justify-center h-[200px]" >
170
+ < Loading loading = { true } />
171
+ </ div >
172
+ ) : (
173
+ < div className = "grid grid-cols-1 gap-4 max-h-[400px] overflow-y-auto" >
174
+ { devices . map ( ( device ) => (
175
+ < div
176
+ key = { device . deviceEncryptedId }
177
+ onClick = { ( ) => {
178
+ setSelectedDevice ( device )
179
+ setShowDeviceDialog ( false )
180
+ } }
181
+ className = "flex items-center gap-3 p-3 border rounded-lg cursor-pointer hover:bg-gray-700"
182
+ >
183
+ < Avatar
184
+ imgClass = "!object-contain p-1"
185
+ className = { `!w-[70px] !h-[70px] overflow-hidden border-2 shadow-lg` }
186
+ style = { {
187
+ borderColor : '#1f2937' ,
188
+ } }
189
+ size = { 60 }
190
+ shape = "circle"
191
+ src = { device . image }
192
+ icon = { ! device . image && < FiPackage /> }
193
+ />
194
+ < div >
195
+ < p className = "font-medium" >
196
+ { device . deviceName }
197
+ </ p >
198
+ < p className = "text-sm text-gray-400" >
199
+ { device . deviceType }
200
+ </ p >
201
+ </ div >
202
+ </ div >
203
+ ) ) }
204
+ </ div >
205
+ ) }
206
+ </ Dialog >
207
+ )
208
+
135
209
return (
136
210
< >
137
211
{ ( loading == false && (
@@ -186,7 +260,7 @@ export default function FDSToken() {
186
260
< div className = "flex items-center gap-3" >
187
261
< p className = "text-white" > Amount:</ p >
188
262
< Input
189
- type = "text "
263
+ type = "number "
190
264
placeholder = "Amount"
191
265
prefix = { < FaCoins className = "text-[1rem]" /> }
192
266
value = { amount }
@@ -242,7 +316,6 @@ export default function FDSToken() {
242
316
onSelect = { ( eventKey , event ) =>
243
317
handleSelect ( eventKey , event )
244
318
}
245
- disabled = { isPending }
246
319
>
247
320
{ wallets . length > 0 &&
248
321
wallets . map ( ( address ) => (
@@ -260,52 +333,51 @@ export default function FDSToken() {
260
333
< p className = "text-white" > To:</ p >
261
334
< Input
262
335
type = "text"
263
- placeholder = "Destination Wallet"
336
+ placeholder = "Destination OwnerShip Wallet"
264
337
prefix = { < GiWallet className = "text-[1rem]" /> }
265
338
value = { destinationWallet }
266
339
onChange = { ( e ) =>
267
340
handleDestinationChange ( e . target . value )
268
341
}
269
- disabled = { isPending }
270
342
/>
271
343
</ div >
272
344
273
345
< div className = "flex items-center gap-3" >
274
346
< p className = "text-white" > Device NFT:</ p >
275
- < Input
276
- type = "text"
277
- placeholder = "Select Device NFT"
278
- prefix = { < FaMobile className = "text-[1rem]" /> }
279
- value = { amount }
280
- onChange = { ( e ) =>
281
- handleAmountChange ( e . target . value )
282
- }
283
- disabled = { isPending }
284
- />
285
- </ div >
286
-
287
- { transactionId && (
288
- < p className = "text-white break-all text-justify" >
289
- Transaction ID:{ ' ' }
290
- < span
291
- className = "text-green-500 hover:underline cursor-pointer"
292
- onClick = { ( ) =>
293
- window . open (
294
- `https://explorer.fidesinnova.io/tx/${ transactionId } ` ,
295
- '_blank'
296
- )
347
+ < div className = "flex-1" >
348
+ < Input
349
+ type = "text"
350
+ placeholder = "Select Device NFT"
351
+ prefix = {
352
+ < FaMobile className = "text-[1rem]" />
297
353
}
298
- >
299
- { transactionId }
300
- </ span >
301
- </ p >
302
- ) }
354
+ value = {
355
+ selectedDevice
356
+ ? selectedDevice . deviceName
357
+ : ''
358
+ }
359
+ readOnly
360
+ suffix = {
361
+ < Button
362
+ size = "xs"
363
+ variant = "twoTone"
364
+ onClick = { ( ) =>
365
+ setShowDeviceDialog ( true )
366
+ }
367
+ disabled = { isPending }
368
+ >
369
+ Select
370
+ </ Button >
371
+ }
372
+ />
373
+ </ div >
374
+ </ div >
303
375
304
376
< Button
305
377
variant = "solid"
306
378
size = "sm"
307
379
onClick = { handleTransfer }
308
- loading = { isPending }
380
+ className = "mt-auto"
309
381
>
310
382
{ isPending ? 'Processing...' : 'Transfer' }
311
383
</ Button >
@@ -316,6 +388,7 @@ export default function FDSToken() {
316
388
< Loading loading = { true } />
317
389
</ section >
318
390
) }
391
+ < DeviceSelectionDialog />
319
392
</ >
320
393
)
321
394
}
0 commit comments