busybar-ui / src / components / auth / register-form.tsx
register-form.tsx
Raw
import { zodResolver } from '@hookform/resolvers/zod'
import React from 'react'
import type { SubmitHandler } from 'react-hook-form'
import { useForm } from 'react-hook-form'
import { KeyboardAvoidingView } from 'react-native-keyboard-controller'
import * as z from 'zod'

import { Button, ControlledInput, Text, View, Modal, useModal } from '@/ui'

const schema = z.object({
  email: z
    .string({
      required_error: 'Email is required',
    })
    .email('Invalid email format'),
  firstName: z
    .string({
      required_error: 'First name is required',
    })
    .min(2, 'First name must be at least 2 characters'),
  lastName: z
    .string({
      required_error: 'Last name is required',
    })
    .min(2, 'Last name must be at least 2 characters'),
  degreeProgram: z.string({
    required_error: 'Degree program is required',
  }),
  school: z.string({
    required_error: 'School is required',
  }),
  gender: z.enum(['Male', 'Female'], {
    required_error: 'Gender is required',
  }),
})

export type FormType = z.infer<typeof schema>

export type SignupFormProps = {
  onSubmit?: SubmitHandler<FormType>
}

export const SignupForm = ({ onSubmit = () => {} }: SignupFormProps) => {
  const { handleSubmit, control, setValue } = useForm<FormType>({
    resolver: zodResolver(schema),
  })
  const genderModal = useModal()

  const handleGenderSelect = (gender: 'Male' | 'Female') => {
    setValue('gender', gender)
    genderModal.dismiss()
  }

  return (
    <KeyboardAvoidingView style={{ flex: 1 }} behavior="padding" keyboardVerticalOffset={10}>
      <View className="flex-1 justify-center p-4">
        <Text testID="form-title" className="pb-6 text-center text-2xl">
          Student Registration
        </Text>

        <ControlledInput
          testID="firstName-input"
          control={control}
          name="firstName"
          label="First Name"
        />
        <ControlledInput
          testID="lastName-input"
          control={control}
          name="lastName"
          label="Last Name"
        />

        <ControlledInput testID="email-input" control={control} name="email" label="Email" />

        <ControlledInput
          testID="degreeProgram-input"
          control={control}
          name="degreeProgram"
          label="Degree Program"
        />
        <ControlledInput testID="school-input" control={control} name="school" label="School" />
        <ControlledInput
          testID="gender-input"
          control={control}
          name="gender"
          label="Gender"
          onPressIn={genderModal.present}
          editable={false}
        />

        <Button
          testID="signup-button"
          label="Register"
          onPress={handleSubmit((data) => onSubmit({ ...data }))}
        />

        <Modal ref={genderModal.ref} snapPoints={['25%']} title="Select Gender">
          <View className="p-4">
            <Button label="Male" onPress={() => handleGenderSelect('Male')} className="mb-2" />
            <Button label="Female" onPress={() => handleGenderSelect('Female')} />
          </View>
        </Modal>
      </View>
    </KeyboardAvoidingView>
  )
}