All files / pages Signup.page.tsx

92.85% Statements 13/14
66.66% Branches 4/6
100% Functions 3/3
100% Lines 12/12

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63                    4x 4x 4x                 4x     1x       1x   1x         1x         1x       1x       4x       1x                    
/**
 * Signup page - Route-level container
 * Handles hooks, crypto, and API calls, delegates rendering to SignupForm
 */
 
import { useState } from 'react';
import { generateKeyPair, useSignup } from '@/features/identity';
import { SignupForm } from '@/features/identity/components';
import { useCryptoRequired } from '@/providers/CryptoProvider';
 
export function SignupPage() {
  const crypto = useCryptoRequired();
  const signup = useSignup();
 
  const [username, setUsername] = useState('');
  const [isGeneratingKeys, setIsGeneratingKeys] = useState(false);
  const [createdAccount, setCreatedAccount] = useState<{
    account_id: string;
    root_kid: string;
  } | null>(null);
 
  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
 
    if (!username.trim()) {
      return;
    }
 
    setIsGeneratingKeys(true);
 
    try {
      // Generate key pair (uses WASM for KID derivation)
      const keyPair = generateKeyPair(crypto);
 
      // Call signup API
      const response = await signup.mutateAsync({
        username: username.trim(),
        root_pubkey: crypto.encode_base64url(keyPair.publicKey),
      });
 
      setCreatedAccount(response);
    } catch {
      // Error is handled by TanStack Query mutation state
    } finally {
      setIsGeneratingKeys(false);
    }
  };
 
  return (
    <SignupForm
      username={username}
      onUsernameChange={setUsername}
      onSubmit={(e) => {
        void handleSubmit(e);
      }}
      isLoading={signup.isPending || isGeneratingKeys}
      loadingText={isGeneratingKeys ? 'Generating keys...' : undefined}
      error={signup.isError ? signup.error.message : null}
      successData={createdAccount}
    />
  );
}