{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "phone-auth-form",
  "type": "registry:block",
  "title": "Phone Auth Form",
  "description": "A form allowing users to authenticate using their phone number with SMS verification.",
  "dependencies": [
    "@invertase/firebaseui-react"
  ],
  "registryDependencies": [
    "form",
    "input",
    "button",
    "https://fir-ui-shadcn-registry.web.app/r/country-selector.json",
    "https://fir-ui-shadcn-registry.web.app/r/policies.json"
  ],
  "files": [
    {
      "path": "src/components/phone-auth-form.tsx",
      "content": "\"use client\";\n\nimport {\n  type PhoneAuthFormProps,\n  usePhoneAuthNumberFormSchema,\n  usePhoneAuthVerifyFormSchema,\n  usePhoneNumberFormAction,\n  useRecaptchaVerifier,\n  useUI,\n  useVerifyPhoneNumberFormAction,\n} from \"@invertase/firebaseui-react\";\nimport { useState } from \"react\";\nimport type { UserCredential } from \"firebase/auth\";\nimport { useRef } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { standardSchemaResolver } from \"@hookform/resolvers/standard-schema\";\nimport {\n  FirebaseUIError,\n  formatPhoneNumber,\n  getTranslation,\n  type PhoneAuthNumberFormSchema,\n  type PhoneAuthVerifyFormSchema,\n} from \"@invertase/firebaseui-core\";\n\nimport { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from \"@/components/ui/form\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { Policies } from \"@/components/policies\";\nimport { CountrySelector, type CountrySelectorRef } from \"@/components/country-selector\";\nimport { InputOTP, InputOTPGroup, InputOTPSlot } from \"@/components/ui/input-otp\";\n\ntype VerifyPhoneNumberFormProps = {\n  verificationId: string;\n  onSuccess: (credential: UserCredential) => void;\n};\n\nfunction VerifyPhoneNumberForm(props: VerifyPhoneNumberFormProps) {\n  const ui = useUI();\n  const schema = usePhoneAuthVerifyFormSchema();\n  const action = useVerifyPhoneNumberFormAction();\n\n  const form = useForm<PhoneAuthVerifyFormSchema>({\n    resolver: standardSchemaResolver(schema),\n    defaultValues: {\n      verificationId: props.verificationId,\n      verificationCode: \"\",\n    },\n  });\n\n  async function onSubmit(values: PhoneAuthVerifyFormSchema) {\n    try {\n      const credential = await action(values);\n      props.onSuccess(credential);\n    } catch (error) {\n      const message = error instanceof FirebaseUIError ? error.message : String(error);\n      form.setError(\"root\", { message });\n    }\n  }\n\n  return (\n    <Form {...form}>\n      <form onSubmit={form.handleSubmit(onSubmit)} className=\"flex flex-col gap-4\">\n        <FormField\n          control={form.control}\n          name=\"verificationCode\"\n          render={({ field }) => (\n            <FormItem>\n              <FormLabel>{getTranslation(ui, \"labels\", \"verificationCode\")}</FormLabel>\n              <FormDescription>{getTranslation(ui, \"prompts\", \"smsVerificationPrompt\")}</FormDescription>\n              <FormControl>\n                <InputOTP maxLength={6} {...field}>\n                  <InputOTPGroup>\n                    <InputOTPSlot index={0} />\n                    <InputOTPSlot index={1} />\n                    <InputOTPSlot index={2} />\n                    <InputOTPSlot index={3} />\n                    <InputOTPSlot index={4} />\n                    <InputOTPSlot index={5} />\n                  </InputOTPGroup>\n                </InputOTP>\n              </FormControl>\n              <FormMessage />\n            </FormItem>\n          )}\n        />\n        <Button type=\"submit\" disabled={ui.state !== \"idle\"}>\n          {getTranslation(ui, \"labels\", \"verifyCode\")}\n        </Button>\n        {form.formState.errors.root && <FormMessage>{form.formState.errors.root.message}</FormMessage>}\n      </form>\n    </Form>\n  );\n}\n\ntype PhoneNumberFormProps = {\n  onSubmit: (verificationId: string) => void;\n};\n\nfunction PhoneNumberForm(props: PhoneNumberFormProps) {\n  const ui = useUI();\n  const recaptchaContainerRef = useRef<HTMLDivElement>(null);\n  const recaptchaVerifier = useRecaptchaVerifier(recaptchaContainerRef);\n  const countrySelector = useRef<CountrySelectorRef>(null);\n  const action = usePhoneNumberFormAction();\n  const schema = usePhoneAuthNumberFormSchema();\n\n  const form = useForm<PhoneAuthNumberFormSchema>({\n    resolver: standardSchemaResolver(schema),\n    defaultValues: {\n      phoneNumber: \"\",\n    },\n  });\n\n  async function onSubmit(values: PhoneAuthNumberFormSchema) {\n    try {\n      const formatted = formatPhoneNumber(values.phoneNumber, countrySelector.current!.getCountry());\n      const verificationId = await action({ phoneNumber: formatted, recaptchaVerifier: recaptchaVerifier! });\n      props.onSubmit(verificationId);\n    } catch (error) {\n      const message = error instanceof FirebaseUIError ? error.message : String(error);\n      form.setError(\"root\", { message });\n    }\n  }\n\n  return (\n    <Form {...form}>\n      <form onSubmit={form.handleSubmit(onSubmit)} className=\"flex flex-col gap-4\">\n        <FormField\n          control={form.control}\n          name=\"phoneNumber\"\n          render={({ field }) => (\n            <FormItem>\n              <FormLabel>{getTranslation(ui, \"labels\", \"phoneNumber\")}</FormLabel>\n              <FormControl>\n                <div className=\"flex items-center gap-2\">\n                  <CountrySelector ref={countrySelector} />\n                  <Input {...field} type=\"tel\" />\n                </div>\n              </FormControl>\n              <FormMessage />\n            </FormItem>\n          )}\n        />\n        <div ref={recaptchaContainerRef} />\n        <Policies />\n        <Button type=\"submit\" disabled={ui.state !== \"idle\"}>\n          {getTranslation(ui, \"labels\", \"sendCode\")}\n        </Button>\n        {form.formState.errors.root && <FormMessage>{form.formState.errors.root.message}</FormMessage>}\n      </form>\n    </Form>\n  );\n}\n\nexport type { PhoneAuthFormProps };\n\nexport function PhoneAuthForm(props: PhoneAuthFormProps) {\n  const [verificationId, setVerificationId] = useState<string | null>(null);\n\n  if (!verificationId) {\n    return <PhoneNumberForm onSubmit={setVerificationId} />;\n  }\n\n  return (\n    <VerifyPhoneNumberForm\n      verificationId={verificationId}\n      onSuccess={(credential) => {\n        props.onSignIn?.(credential);\n      }}\n    />\n  );\n}\n",
      "type": "registry:component"
    }
  ],
  "meta": {
    "version": "0.0.2"
  }
}