An easy-to-host PDS on the ATProtocol, MacOS. Grandma-approved.

feat(identity-wallet): add ClaimCodeScreen component

authored by malpercio.dev and committed by

Tangled 764515e5 4f802b57

+110
+110
apps/identity-wallet/src/lib/components/onboarding/ClaimCodeScreen.svelte
··· 1 + <script lang="ts"> 2 + let { 3 + value = $bindable(''), 4 + onnext, 5 + error = undefined, 6 + }: { 7 + value: string; 8 + onnext: () => void; 9 + error?: string; 10 + } = $props(); 11 + 12 + let isValid = $derived(value.length === 6); 13 + 14 + function handleInput(e: Event) { 15 + const raw = (e.currentTarget as HTMLInputElement).value; 16 + value = raw.toUpperCase().replace(/[^A-Z0-9]/g, '').slice(0, 6); 17 + } 18 + </script> 19 + 20 + <div class="screen"> 21 + <h2>Enter Your Claim Code</h2> 22 + <p class="hint">You'll receive a 6-character code from your administrator.</p> 23 + 24 + <input 25 + type="text" 26 + class="code-input" 27 + class:error={!!error} 28 + maxlength="6" 29 + placeholder="ABC123" 30 + autocomplete="off" 31 + autocorrect="off" 32 + autocapitalize="characters" 33 + spellcheck={false} 34 + {value} 35 + oninput={handleInput} 36 + /> 37 + 38 + {#if error} 39 + <p class="error-text">{error}</p> 40 + {/if} 41 + 42 + <button disabled={!isValid} onclick={onnext}>Next</button> 43 + </div> 44 + 45 + <style> 46 + .screen { 47 + display: flex; 48 + flex-direction: column; 49 + align-items: center; 50 + padding: 2rem; 51 + gap: 1rem; 52 + height: 100%; 53 + justify-content: center; 54 + } 55 + 56 + h2 { 57 + font-size: 1.5rem; 58 + font-weight: 700; 59 + margin: 0; 60 + } 61 + 62 + .hint { 63 + font-size: 0.9rem; 64 + color: #6b7280; 65 + text-align: center; 66 + margin: 0; 67 + } 68 + 69 + .code-input { 70 + width: 100%; 71 + max-width: 320px; 72 + padding: 1rem; 73 + font-size: 1.5rem; 74 + font-family: monospace; 75 + letter-spacing: 0.5rem; 76 + text-align: center; 77 + border: 2px solid #d1d5db; 78 + border-radius: 12px; 79 + text-transform: uppercase; 80 + } 81 + 82 + .code-input.error { 83 + border-color: #ef4444; 84 + } 85 + 86 + .error-text { 87 + color: #ef4444; 88 + font-size: 0.875rem; 89 + margin: 0; 90 + text-align: center; 91 + } 92 + 93 + button { 94 + width: 100%; 95 + max-width: 320px; 96 + padding: 1rem; 97 + background: #007aff; 98 + color: #fff; 99 + border: none; 100 + border-radius: 12px; 101 + font-size: 1rem; 102 + font-weight: 600; 103 + cursor: pointer; 104 + } 105 + 106 + button:disabled { 107 + background: #9ca3af; 108 + cursor: not-allowed; 109 + } 110 + </style>