2
2
3
3
import { MouseEventHandler , useState } from 'react'
4
4
import { useRouter } from 'next/navigation'
5
- import { ChevronLeftIcon , ChevronRightIcon } from '@heroicons/react/20/solid'
5
+ import { ArrowPathIcon , ChevronLeftIcon , ChevronRightIcon } from '@heroicons/react/20/solid'
6
6
import { H1 , H2 } from '@/components/Text'
7
7
import { useMigrations } from '@/components/MigrationsProvider'
8
8
import { DIDKey , useW3 } from '@w3ui/react'
9
- import * as NFTStorageMigrator from '@/lib/migrations/nft-storage'
10
- import * as Web3StorageMigrator from '@/lib/migrations/web3-storage'
11
9
import { DidIcon } from '@/components/DidIcon'
12
- import { MigrationConfiguration , MigrationSource } from '@/lib/migrations/api'
10
+ import { MigrationConfiguration , DataSourceID } from '@/lib/migrations/api'
11
+ import { dataSources } from '@/app/migration/data-sources'
13
12
14
13
interface WizardProps {
15
14
config : Partial < MigrationConfiguration >
@@ -46,7 +45,7 @@ export default function CreateMigrationPage (): JSX.Element {
46
45
}
47
46
48
47
function ChooseSource ( { config, onNext } : WizardProps ) {
49
- const [ source , setSource ] = useState < MigrationSource | undefined > ( config . source )
48
+ const [ source , setSource ] = useState < DataSourceID | undefined > ( config . source )
50
49
const handleNextClick : MouseEventHandler = e => {
51
50
e . preventDefault ( )
52
51
if ( ! source ) return
@@ -58,16 +57,14 @@ function ChooseSource ({ config, onNext }: WizardProps) {
58
57
< H1 > Create a new migration</ H1 >
59
58
< div className = 'bg-white my-4 p-5 rounded-2xl border border-hot-red font-epilogue' >
60
59
< p className = 'mb-8' > This tool allows data to be migrated from a previous provider to one of your spaces.</ p >
61
-
62
60
< H2 > Where from?</ H2 >
63
61
< p className = 'mb-4' > Pick a storage service you want to migrate data from.</ p >
64
- < div className = 'mb-4' >
65
- < button className = { `bg-white/60 rounded-lg shadow-md p-8 hover:outline mr-4 ${ source === 'classic.nft.storage' ? 'outline' : '' } ` } type = 'button' onClick = { ( ) => setSource ( 'classic.nft.storage' ) } title = 'Migrate from NFT.Storage (Classic)' >
66
- < img src = '/nftstorage-logo.png' width = '350' />
67
- </ button >
68
- < button className = { `bg-white/60 opacity-60 rounded-lg shadow-md p-8 ${ source === 'old.web3.storage' ? 'outline' : '' } ` } type = 'button' onClick = { ( ) => setSource ( 'old.web3.storage' ) } title = 'COMING SOON! Migrate from Web3.Storage (Old)' disabled = { true } >
69
- < img src = '/web3storage-logo.png' width = '350' />
70
- </ button >
62
+ < div className = 'mb-4 text-center' >
63
+ { dataSources . map ( ( { name, logo, source : { id } } ) => (
64
+ < button key = { id } className = { `bg-white/60 rounded-lg shadow-md p-8 border border-black hover:outline ml-4 first:ml-0 mb-4 ${ source === id ? 'outline' : '' } ` } type = 'button' onClick = { ( ) => setSource ( id ) } title = { `Migrate from ${ name } ` } >
65
+ { logo }
66
+ </ button >
67
+ ) ) }
71
68
</ div >
72
69
< button onClick = { handleNextClick } className = { `inline-block bg-hot-red border border-hot-red font-epilogue text-white uppercase text-sm px-6 py-2 rounded-full whitespace-nowrap ${ source ? 'hover:bg-white hover:text-hot-red' : 'opacity-10' } ` } disabled = { ! source } >
73
70
Next < ChevronRightIcon className = 'h-5 w-5 inline-block ml-1 align-middle' style = { { marginTop : - 4 } } />
@@ -79,32 +76,33 @@ function ChooseSource ({ config, onNext }: WizardProps) {
79
76
80
77
function AddSourceToken ( { config, onNext, onPrev } : WizardProps ) {
81
78
const [ token , setToken ] = useState < string | undefined > ( config . token )
79
+ const [ checking , setChecking ] = useState ( false )
82
80
const [ error , setError ] = useState ( '' )
83
81
82
+ const ds = dataSources . find ( ( { source } ) => source . id === config . source )
83
+ if ( ! ds ) return
84
+
84
85
const handleNextClick : MouseEventHandler = async e => {
85
86
e . preventDefault ( )
86
- if ( ! token ) return
87
+ if ( ! token || checking ) return
87
88
setError ( '' )
89
+ setChecking ( true )
88
90
89
91
try {
90
- if ( config . source === 'classic.nft.storage' ) {
91
- await NFTStorageMigrator . checkToken ( token )
92
- } else if ( config . source === 'old.web3.storage' ) {
93
- await Web3StorageMigrator . checkToken ( token )
94
- } else {
95
- throw new Error ( `unknown data source: ${ config . source } ` )
96
- }
92
+ await ds . source . checkToken ( token )
97
93
} catch ( err : any ) {
98
94
console . error ( err )
99
95
return setError ( `Error using token: ${ err . message } ` )
96
+ } finally {
97
+ setChecking ( false )
100
98
}
101
99
onNext ( { ...config , token } )
102
100
}
103
101
return (
104
102
< div className = 'max-w-4xl' >
105
103
< H1 > Add data source token</ H1 >
106
104
< div className = 'bg-white my-4 p-5 rounded-2xl border border-hot-red font-epilogue' >
107
- < p className = 'mb-8' > Add your < strong > { config . source } </ strong > API token . Note: the key never leaves this device, it is for local use only by the migration tool.</ p >
105
+ < p className = 'mb-8' > Add your API token for < strong > { ds . name } </ strong > . Note: the key never leaves this device, it is for local use only by the migration tool.</ p >
108
106
< H2 > API Token</ H2 >
109
107
< div className = 'max-w-xl mb-4' >
110
108
< input
@@ -120,8 +118,10 @@ function AddSourceToken ({ config, onNext, onPrev }: WizardProps) {
120
118
< button onClick = { e => { e . preventDefault ( ) ; onPrev ( ) } } className = { `inline-block bg-hot-red border border-hot-red font-epilogue text-white uppercase text-sm mr-2 px-6 py-2 rounded-full whitespace-nowrap hover:bg-white hover:text-hot-red` } >
121
119
< ChevronLeftIcon className = 'h-5 w-5 inline-block mr-1 align-middle' style = { { marginTop : - 4 } } /> Previous
122
120
</ button >
123
- < button onClick = { handleNextClick } className = { `inline-block bg-hot-red border border-hot-red font-epilogue text-white uppercase text-sm px-6 py-2 rounded-full whitespace-nowrap ${ token ? 'hover:bg-white hover:text-hot-red' : 'opacity-10' } ` } disabled = { ! token } >
124
- Next < ChevronRightIcon className = 'h-5 w-5 inline-block ml-1 align-middle' style = { { marginTop : - 4 } } />
121
+ < button onClick = { handleNextClick } className = { `inline-block bg-hot-red border border-hot-red font-epilogue text-white uppercase text-sm px-6 py-2 rounded-full whitespace-nowrap ${ token ? 'hover:bg-white hover:text-hot-red' : 'opacity-10' } ` } disabled = { ! token || checking } >
122
+ { checking
123
+ ? < > < ArrowPathIcon className = { `h-5 w-5 animate-spin inline-block mr-1 align-middle` } /> Checking...</ >
124
+ : < > Next < ChevronRightIcon className = 'h-5 w-5 inline-block ml-1 align-middle' style = { { marginTop : - 4 } } /> </ > }
125
125
</ button >
126
126
</ div >
127
127
</ div >
@@ -176,6 +176,9 @@ function Confirmation ({ config, onNext, onPrev }: WizardProps) {
176
176
const space = spaces . find ( s => s . did ( ) === config . space )
177
177
if ( ! space ) return
178
178
179
+ const ds = dataSources . find ( ( { source } ) => source . id === config . source )
180
+ if ( ! ds ) return
181
+
179
182
const handleNextClick : MouseEventHandler = async e => {
180
183
e . preventDefault ( )
181
184
onNext ( config )
@@ -186,8 +189,8 @@ function Confirmation ({ config, onNext, onPrev }: WizardProps) {
186
189
< div className = 'bg-white my-4 p-5 rounded-2xl border border-hot-red font-epilogue' >
187
190
< p className = 'mb-8' > Make sure these details are correct before starting the migration.</ p >
188
191
< H2 > Source</ H2 >
189
- < div className = { `bg-white/60 rounded-lg shadow-md p-8 mb-4 inline-block` } title = 'Web3.Storage (Old)' >
190
- < img src = { config . source === 'old.web3.storage' ? '/web3storage- logo.png' : '/nftstorage-logo.png' } width = '360' />
192
+ < div className = { `bg-white/60 rounded-lg shadow-md p-8 mb-4 inline-block border border-black ` } title = { ds . name } >
193
+ { ds . logo }
191
194
</ div >
192
195
< H2 > Target</ H2 >
193
196
< div className = 'max-w-lg border rounded-2xl border-hot-red bg-white mb-4' >
0 commit comments