this repo has no description
1<script lang="ts">
2 import { api, ApiError } from '../api'
3 import { resendVerification } from '../auth.svelte'
4 import type { RegistrationFlow } from './flow.svelte'
5
6 interface Props {
7 flow: RegistrationFlow
8 }
9
10 let { flow }: Props = $props()
11
12 let verificationCode = $state('')
13 let resending = $state(false)
14 let resendMessage = $state<string | null>(null)
15
16 function channelLabel(ch: string): string {
17 switch (ch) {
18 case 'email': return 'email'
19 case 'discord': return 'Discord'
20 case 'telegram': return 'Telegram'
21 case 'signal': return 'Signal'
22 default: return ch
23 }
24 }
25
26 async function handleSubmit(e: Event) {
27 e.preventDefault()
28 if (!verificationCode.trim()) return
29 resendMessage = null
30 await flow.verifyAccount(verificationCode)
31 }
32
33 async function handleResend() {
34 if (resending || !flow.account) return
35 resending = true
36 resendMessage = null
37 flow.clearError()
38
39 try {
40 await resendVerification(flow.account.did)
41 resendMessage = 'Verification code resent!'
42 } catch (err) {
43 if (err instanceof ApiError) {
44 flow.setError(err.message || 'Failed to resend code')
45 } else if (err instanceof Error) {
46 flow.setError(err.message || 'Failed to resend code')
47 } else {
48 flow.setError('Failed to resend code')
49 }
50 } finally {
51 resending = false
52 }
53 }
54</script>
55
56<div class="verification-step">
57 <p class="info-text">
58 We've sent a verification code to your {channelLabel(flow.info.verificationChannel)}.
59 Enter it below to continue.
60 </p>
61
62 {#if resendMessage}
63 <div class="message success">{resendMessage}</div>
64 {/if}
65
66 <form onsubmit={handleSubmit}>
67 <div class="field">
68 <label for="verification-code">Verification Code</label>
69 <input
70 id="verification-code"
71 type="text"
72 bind:value={verificationCode}
73 placeholder="XXXX-XXXX-XXXX-XXXX"
74 disabled={flow.state.submitting}
75 required
76 autocomplete="one-time-code"
77 class="code-input"
78 />
79 <span class="hint">Copy the entire code from your message, including dashes.</span>
80 </div>
81
82 <button type="submit" disabled={flow.state.submitting || !verificationCode.trim()}>
83 {flow.state.submitting ? 'Verifying...' : 'Verify'}
84 </button>
85
86 <button type="button" class="secondary" onclick={handleResend} disabled={resending}>
87 {resending ? 'Resending...' : 'Resend Code'}
88 </button>
89 </form>
90</div>
91
92<style>
93 .verification-step {
94 display: flex;
95 flex-direction: column;
96 gap: var(--space-4);
97 }
98
99 .info-text {
100 color: var(--text-secondary);
101 margin: 0;
102 }
103
104 .code-input {
105 font-family: var(--font-mono, monospace);
106 font-size: var(--text-base);
107 letter-spacing: 0.05em;
108 }
109
110 .hint {
111 display: block;
112 color: var(--text-secondary);
113 font-size: var(--text-sm);
114 margin-top: var(--space-1);
115 }
116</style>