SSODomains.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import { Plus, Trash } from 'lucide-react'
  2. import { useFieldArray, useForm } from 'react-hook-form'
  3. import { Button, FormControl, FormField, FormItem, FormMessage, Input } from 'ui'
  4. import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
  5. import { SSOConfigFormSchema } from './SSOConfig'
  6. export const SSODomains = ({ form }: { form: ReturnType<typeof useForm<SSOConfigFormSchema>> }) => {
  7. const { fields, append, remove } = useFieldArray({
  8. control: form.control,
  9. name: 'domains',
  10. })
  11. const domainsError = form.formState.errors.domains
  12. // Handle different error structures - could be root error or direct error
  13. const arrayLevelError =
  14. domainsError &&
  15. typeof domainsError === 'object' &&
  16. 'message' in domainsError &&
  17. typeof domainsError.message === 'string'
  18. ? domainsError.message
  19. : domainsError &&
  20. typeof domainsError === 'object' &&
  21. 'root' in domainsError &&
  22. domainsError.root &&
  23. typeof domainsError.root === 'object' &&
  24. 'message' in domainsError.root
  25. ? String(domainsError.root.message)
  26. : null
  27. return (
  28. <>
  29. <FormItemLayout
  30. label="Email Domains"
  31. layout="flex-row-reverse"
  32. description="Users with these email domains will be redirected to your identity provider when logging in from Briven."
  33. >
  34. <div className="grid gap-2 w-full">
  35. {fields.map((field, idx) => (
  36. <div key={field.id} className="flex gap-2 items-top">
  37. <FormField
  38. name={`domains.${idx}.value`}
  39. render={({ field }) => (
  40. <FormItem className="flex-1">
  41. <FormControl>
  42. <Input {...field} autoComplete="off" placeholder="example.com" />
  43. </FormControl>
  44. <FormMessage />
  45. </FormItem>
  46. )}
  47. />
  48. <Button
  49. type="default"
  50. icon={<Trash size={12} />}
  51. className="h-[34px] w-[34px]"
  52. onClick={() => remove(idx)}
  53. />
  54. </div>
  55. ))}
  56. <div>
  57. <Button
  58. type="default"
  59. icon={<Plus className="w-4 h-4" />}
  60. size="tiny"
  61. onClick={() => append({ value: '' })}
  62. >
  63. Add another
  64. </Button>
  65. </div>
  66. {arrayLevelError && (
  67. <p className="text-sm font-medium text-destructive">{arrayLevelError}</p>
  68. )}
  69. </div>
  70. </FormItemLayout>
  71. </>
  72. )
  73. }