notifications-form.tsx 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. import { zodResolver } from '@hookform/resolvers/zod'
  2. import { useForm } from 'react-hook-form'
  3. import { z } from 'zod'
  4. import { Button } from '@/components/custom/button'
  5. import { Checkbox } from '@/components/ui/checkbox'
  6. import {
  7. Form,
  8. FormControl,
  9. FormDescription,
  10. FormField,
  11. FormItem,
  12. FormLabel,
  13. FormMessage,
  14. } from '@/components/ui/form'
  15. import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'
  16. import { Switch } from '@/components/ui/switch'
  17. import { toast } from '@/components/ui/use-toast'
  18. import { Link } from 'react-router-dom'
  19. const notificationsFormSchema = z.object({
  20. type: z.enum(['all', 'mentions', 'none'], {
  21. required_error: 'You need to select a notification type.',
  22. }),
  23. mobile: z.boolean().default(false).optional(),
  24. communication_emails: z.boolean().default(false).optional(),
  25. social_emails: z.boolean().default(false).optional(),
  26. marketing_emails: z.boolean().default(false).optional(),
  27. security_emails: z.boolean(),
  28. })
  29. type NotificationsFormValues = z.infer<typeof notificationsFormSchema>
  30. // This can come from your database or API.
  31. const defaultValues: Partial<NotificationsFormValues> = {
  32. communication_emails: false,
  33. marketing_emails: false,
  34. social_emails: true,
  35. security_emails: true,
  36. }
  37. export function NotificationsForm() {
  38. const form = useForm<NotificationsFormValues>({
  39. resolver: zodResolver(notificationsFormSchema),
  40. defaultValues,
  41. })
  42. function onSubmit(data: NotificationsFormValues) {
  43. toast({
  44. title: 'You submitted the following values:',
  45. description: (
  46. <pre className='mt-2 w-[340px] rounded-md bg-slate-950 p-4'>
  47. <code className='text-white'>{JSON.stringify(data, null, 2)}</code>
  48. </pre>
  49. ),
  50. })
  51. }
  52. return (
  53. <Form {...form}>
  54. <form onSubmit={form.handleSubmit(onSubmit)} className='space-y-8'>
  55. <FormField
  56. control={form.control}
  57. name='type'
  58. render={({ field }) => (
  59. <FormItem className='space-y-3'>
  60. <FormLabel>Notify me about...</FormLabel>
  61. <FormControl>
  62. <RadioGroup
  63. onValueChange={field.onChange}
  64. defaultValue={field.value}
  65. className='flex flex-col space-y-1'
  66. >
  67. <FormItem className='flex items-center space-x-3 space-y-0'>
  68. <FormControl>
  69. <RadioGroupItem value='all' />
  70. </FormControl>
  71. <FormLabel className='font-normal'>
  72. All new messages
  73. </FormLabel>
  74. </FormItem>
  75. <FormItem className='flex items-center space-x-3 space-y-0'>
  76. <FormControl>
  77. <RadioGroupItem value='mentions' />
  78. </FormControl>
  79. <FormLabel className='font-normal'>
  80. Direct messages and mentions
  81. </FormLabel>
  82. </FormItem>
  83. <FormItem className='flex items-center space-x-3 space-y-0'>
  84. <FormControl>
  85. <RadioGroupItem value='none' />
  86. </FormControl>
  87. <FormLabel className='font-normal'>Nothing</FormLabel>
  88. </FormItem>
  89. </RadioGroup>
  90. </FormControl>
  91. <FormMessage />
  92. </FormItem>
  93. )}
  94. />
  95. <div>
  96. <h3 className='mb-4 text-lg font-medium'>Email Notifications</h3>
  97. <div className='space-y-4'>
  98. <FormField
  99. control={form.control}
  100. name='communication_emails'
  101. render={({ field }) => (
  102. <FormItem className='flex flex-row items-center justify-between rounded-lg border p-4'>
  103. <div className='space-y-0.5'>
  104. <FormLabel className='text-base'>
  105. Communication emails
  106. </FormLabel>
  107. <FormDescription>
  108. Receive emails about your account activity.
  109. </FormDescription>
  110. </div>
  111. <FormControl>
  112. <Switch
  113. checked={field.value}
  114. onCheckedChange={field.onChange}
  115. />
  116. </FormControl>
  117. </FormItem>
  118. )}
  119. />
  120. <FormField
  121. control={form.control}
  122. name='marketing_emails'
  123. render={({ field }) => (
  124. <FormItem className='flex flex-row items-center justify-between rounded-lg border p-4'>
  125. <div className='space-y-0.5'>
  126. <FormLabel className='text-base'>
  127. Marketing emails
  128. </FormLabel>
  129. <FormDescription>
  130. Receive emails about new products, features, and more.
  131. </FormDescription>
  132. </div>
  133. <FormControl>
  134. <Switch
  135. checked={field.value}
  136. onCheckedChange={field.onChange}
  137. />
  138. </FormControl>
  139. </FormItem>
  140. )}
  141. />
  142. <FormField
  143. control={form.control}
  144. name='social_emails'
  145. render={({ field }) => (
  146. <FormItem className='flex flex-row items-center justify-between rounded-lg border p-4'>
  147. <div className='space-y-0.5'>
  148. <FormLabel className='text-base'>Social emails</FormLabel>
  149. <FormDescription>
  150. Receive emails for friend requests, follows, and more.
  151. </FormDescription>
  152. </div>
  153. <FormControl>
  154. <Switch
  155. checked={field.value}
  156. onCheckedChange={field.onChange}
  157. />
  158. </FormControl>
  159. </FormItem>
  160. )}
  161. />
  162. <FormField
  163. control={form.control}
  164. name='security_emails'
  165. render={({ field }) => (
  166. <FormItem className='flex flex-row items-center justify-between rounded-lg border p-4'>
  167. <div className='space-y-0.5'>
  168. <FormLabel className='text-base'>Security emails</FormLabel>
  169. <FormDescription>
  170. Receive emails about your account activity and security.
  171. </FormDescription>
  172. </div>
  173. <FormControl>
  174. <Switch
  175. checked={field.value}
  176. onCheckedChange={field.onChange}
  177. disabled
  178. aria-readonly
  179. />
  180. </FormControl>
  181. </FormItem>
  182. )}
  183. />
  184. </div>
  185. </div>
  186. <FormField
  187. control={form.control}
  188. name='mobile'
  189. render={({ field }) => (
  190. <FormItem className='flex flex-row items-start space-x-3 space-y-0'>
  191. <FormControl>
  192. <Checkbox
  193. checked={field.value}
  194. onCheckedChange={field.onChange}
  195. />
  196. </FormControl>
  197. <div className='space-y-1 leading-none'>
  198. <FormLabel>
  199. Use different settings for my mobile devices
  200. </FormLabel>
  201. <FormDescription>
  202. You can manage your mobile notifications in the{' '}
  203. <Link
  204. to='/settings'
  205. className='underline decoration-dashed underline-offset-4 hover:decoration-solid'
  206. >
  207. mobile settings
  208. </Link>{' '}
  209. page.
  210. </FormDescription>
  211. </div>
  212. </FormItem>
  213. )}
  214. />
  215. <Button type='submit'>Update notifications</Button>
  216. </form>
  217. </Form>
  218. )
  219. }