All files / src/hooks/useRegistration useRegistration.ts

100% Statements 13/13
75% Branches 6/8
100% Functions 2/2
100% Lines 13/13

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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81                                                    1x 22x   22x         11x 11x     11x                         11x 1x               10x 4x 4x           1x         10x              
/**
 * useRegistration Hook
 * Story 1.2.3: Implement Account Creation Flow - Task 10 (GREEN Phase)
 * Handles user registration via AWS Cognito SignUp
 */
 
import { useMutation } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import { authService } from '@/services/auth/authService';
import { subscribe as subscribeToNewsletter } from '@/services/newsletterService';
 
export interface RegistrationFormData {
  firstName: string;
  lastName: string;
  email: string;
  password: string;
  confirmPassword: string;
  agreedToTerms: boolean;
  newsletterOptIn: boolean;
}
 
export interface RegistrationResult {
  email: string;
  requiresConfirmation: boolean;
}
 
export const useRegistration = () => {
  const { i18n } = useTranslation();
 
  return useMutation({
    mutationFn: async (data: RegistrationFormData): Promise<RegistrationResult> => {
      // Story 12.6a: names are captured in two clean fields — no more fragile
      // fullName.split(/\s+/) heuristic that mis-split multi-word given names
      // ("Anna Maria") and compound surnames ("von der Berg").
      const firstName = data.firstName.trim();
      const lastName = data.lastName.trim();
 
      // Call existing authService.signUp method (using existing SignUpData interface)
      const result = await authService.signUp({
        email: data.email,
        password: data.password,
        confirmPassword: data.password, // Already validated in form
        firstName,
        lastName,
        role: 'attendee', // FR22: All self-registered users are ATTENDEE (lowercase per UserRole type)
        companyId: '', // Not needed for self-registration
        acceptTerms: data.agreedToTerms,
        language: i18n.language, // User's selected language
        newsletterOptIn: data.newsletterOptIn,
      });
 
      if (!result.success) {
        throw new Error(result.error?.code || 'SIGNUP_FAILED');
      }
 
      // Story 12.11 (Scope Revision #4): the newsletter checkbox used to be packed into
      // custom:preferences and silently dropped (nothing consumed it). Newsletter consent
      // lives in EMS `newsletter_subscribers` (Story 10.7), so subscribe via the existing
      // public endpoint — same approach as NewsletterSubscribeWidget. Best-effort: a
      // subscribe failure (or 409 already-subscribed) must never fail the registration.
      if (data.newsletterOptIn) {
        try {
          await subscribeToNewsletter({
            email: data.email,
            firstName,
            language: i18n.language?.startsWith('de') ? 'de' : 'en',
          });
        } catch (error) {
          console.warn('[useRegistration] Newsletter subscribe failed (non-blocking)', error);
        }
      }
 
      // PostConfirmation Lambda (Story 1.2.5) creates database record automatically
      return {
        email: data.email,
        requiresConfirmation: result.requiresConfirmation,
      };
    },
  });
};