this repo has no description
1<script lang="ts">
2 import type { AuthMethod, ServerDescription } from '../../lib/migration/types'
3 import { _ } from '../../lib/i18n'
4
5 interface Props {
6 handleInput: string
7 selectedDomain: string
8 handleAvailable: boolean | null
9 checkingHandle: boolean
10 email: string
11 password: string
12 authMethod: AuthMethod
13 inviteCode: string
14 serverInfo: ServerDescription | null
15 migratingFromLabel: string
16 migratingFromValue: string
17 loading?: boolean
18 onHandleChange: (handle: string) => void
19 onDomainChange: (domain: string) => void
20 onCheckHandle: () => void
21 onEmailChange: (email: string) => void
22 onPasswordChange: (password: string) => void
23 onAuthMethodChange: (method: AuthMethod) => void
24 onInviteCodeChange: (code: string) => void
25 onBack: () => void
26 onContinue: () => void
27 }
28
29 let {
30 handleInput,
31 selectedDomain,
32 handleAvailable,
33 checkingHandle,
34 email,
35 password,
36 authMethod,
37 inviteCode,
38 serverInfo,
39 migratingFromLabel,
40 migratingFromValue,
41 loading = false,
42 onHandleChange,
43 onDomainChange,
44 onCheckHandle,
45 onEmailChange,
46 onPasswordChange,
47 onAuthMethodChange,
48 onInviteCodeChange,
49 onBack,
50 onContinue,
51 }: Props = $props()
52
53 const canContinue = $derived(
54 handleInput.trim() &&
55 email &&
56 (authMethod === 'passkey' || password) &&
57 handleAvailable !== false
58 )
59</script>
60
61<div class="step-content">
62 <h2>{$_('migration.inbound.chooseHandle.title')}</h2>
63 <p>{$_('migration.inbound.chooseHandle.desc')}</p>
64
65 <div class="current-info">
66 <span class="label">{migratingFromLabel}:</span>
67 <span class="value">{migratingFromValue}</span>
68 </div>
69
70 <div class="field">
71 <label for="new-handle">{$_('migration.inbound.chooseHandle.newHandle')}</label>
72 <div class="handle-input-group">
73 <input
74 id="new-handle"
75 type="text"
76 placeholder="username"
77 value={handleInput}
78 oninput={(e) => onHandleChange((e.target as HTMLInputElement).value)}
79 onblur={onCheckHandle}
80 />
81 {#if serverInfo && serverInfo.availableUserDomains.length > 0 && !handleInput.includes('.')}
82 <select value={selectedDomain} onchange={(e) => onDomainChange((e.target as HTMLSelectElement).value)}>
83 {#each serverInfo.availableUserDomains as domain}
84 <option value={domain}>.{domain}</option>
85 {/each}
86 </select>
87 {/if}
88 </div>
89
90 {#if checkingHandle}
91 <p class="hint">{$_('migration.inbound.chooseHandle.checkingAvailability')}</p>
92 {:else if handleAvailable === true}
93 <p class="hint" style="color: var(--success-text)">{$_('migration.inbound.chooseHandle.handleAvailable')}</p>
94 {:else if handleAvailable === false}
95 <p class="hint error">{$_('migration.inbound.chooseHandle.handleTaken')}</p>
96 {:else}
97 <p class="hint">{$_('migration.inbound.chooseHandle.handleHint')}</p>
98 {/if}
99 </div>
100
101 <div class="field">
102 <label for="email">{$_('migration.inbound.chooseHandle.email')}</label>
103 <input
104 id="email"
105 type="email"
106 placeholder="you@example.com"
107 value={email}
108 oninput={(e) => onEmailChange((e.target as HTMLInputElement).value)}
109 required
110 />
111 </div>
112
113 <div class="field">
114 <span class="field-label">{$_('migration.inbound.chooseHandle.authMethod')}</span>
115 <div class="auth-method-options">
116 <label class="auth-option" class:selected={authMethod === 'password'}>
117 <input
118 type="radio"
119 name="auth-method"
120 value="password"
121 checked={authMethod === 'password'}
122 onchange={() => onAuthMethodChange('password')}
123 />
124 <div class="auth-option-content">
125 <strong>{$_('migration.inbound.chooseHandle.authPassword')}</strong>
126 <span>{$_('migration.inbound.chooseHandle.authPasswordDesc')}</span>
127 </div>
128 </label>
129 <label class="auth-option" class:selected={authMethod === 'passkey'}>
130 <input
131 type="radio"
132 name="auth-method"
133 value="passkey"
134 checked={authMethod === 'passkey'}
135 onchange={() => onAuthMethodChange('passkey')}
136 />
137 <div class="auth-option-content">
138 <strong>{$_('migration.inbound.chooseHandle.authPasskey')}</strong>
139 <span>{$_('migration.inbound.chooseHandle.authPasskeyDesc')}</span>
140 </div>
141 </label>
142 </div>
143 </div>
144
145 {#if authMethod === 'password'}
146 <div class="field">
147 <label for="new-password">{$_('migration.inbound.chooseHandle.password')}</label>
148 <input
149 id="new-password"
150 type="password"
151 placeholder="Password for your new account"
152 value={password}
153 oninput={(e) => onPasswordChange((e.target as HTMLInputElement).value)}
154 required
155 minlength={8}
156 />
157 <p class="hint">{$_('migration.inbound.chooseHandle.passwordHint')}</p>
158 </div>
159 {:else}
160 <div class="info-box">
161 <p>{$_('migration.inbound.chooseHandle.passkeyInfo')}</p>
162 </div>
163 {/if}
164
165 {#if serverInfo?.inviteCodeRequired}
166 <div class="field">
167 <label for="invite">{$_('migration.inbound.chooseHandle.inviteCode')}</label>
168 <input
169 id="invite"
170 type="text"
171 placeholder="Enter invite code"
172 value={inviteCode}
173 oninput={(e) => onInviteCodeChange((e.target as HTMLInputElement).value)}
174 required
175 />
176 </div>
177 {/if}
178
179 <div class="button-row">
180 <button class="ghost" onclick={onBack} disabled={loading}>{$_('migration.inbound.common.back')}</button>
181 <button disabled={!canContinue || loading} onclick={onContinue}>
182 {$_('migration.inbound.common.continue')}
183 </button>
184 </div>
185</div>