tasks-mutate-drawer.tsx 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. import { z } from 'zod'
  2. import { useForm } from 'react-hook-form'
  3. import { zodResolver } from '@hookform/resolvers/zod'
  4. import { showSubmittedData } from '@/lib/show-submitted-data'
  5. import { Button } from '@/components/ui/button'
  6. import {
  7. Form,
  8. FormControl,
  9. FormField,
  10. FormItem,
  11. FormLabel,
  12. FormMessage,
  13. } from '@/components/ui/form'
  14. import { Input } from '@/components/ui/input'
  15. import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'
  16. import {
  17. Sheet,
  18. SheetClose,
  19. SheetContent,
  20. SheetDescription,
  21. SheetFooter,
  22. SheetHeader,
  23. SheetTitle,
  24. } from '@/components/ui/sheet'
  25. import { SelectDropdown } from '@/components/select-dropdown'
  26. import { type Task } from '../data/schema'
  27. type TaskMutateDrawerProps = {
  28. open: boolean
  29. onOpenChange: (open: boolean) => void
  30. currentRow?: Task
  31. }
  32. const formSchema = z.object({
  33. title: z.string().min(1, 'Title is required.'),
  34. status: z.string().min(1, 'Please select a status.'),
  35. label: z.string().min(1, 'Please select a label.'),
  36. priority: z.string().min(1, 'Please choose a priority.'),
  37. })
  38. type TaskForm = z.infer<typeof formSchema>
  39. export function TasksMutateDrawer({
  40. open,
  41. onOpenChange,
  42. currentRow,
  43. }: TaskMutateDrawerProps) {
  44. const isUpdate = !!currentRow
  45. const form = useForm<TaskForm>({
  46. resolver: zodResolver(formSchema),
  47. defaultValues: currentRow ?? {
  48. title: '',
  49. status: '',
  50. label: '',
  51. priority: '',
  52. },
  53. })
  54. const onSubmit = (data: TaskForm) => {
  55. // do something with the form data
  56. onOpenChange(false)
  57. form.reset()
  58. showSubmittedData(data)
  59. }
  60. return (
  61. <Sheet
  62. open={open}
  63. onOpenChange={(v) => {
  64. onOpenChange(v)
  65. form.reset()
  66. }}
  67. >
  68. <SheetContent className='flex flex-col'>
  69. <SheetHeader className='text-start'>
  70. <SheetTitle>{isUpdate ? 'Update' : 'Create'} Task</SheetTitle>
  71. <SheetDescription>
  72. {isUpdate
  73. ? 'Update the task by providing necessary info.'
  74. : 'Add a new task by providing necessary info.'}
  75. Click save when you&apos;re done.
  76. </SheetDescription>
  77. </SheetHeader>
  78. <Form {...form}>
  79. <form
  80. id='tasks-form'
  81. onSubmit={form.handleSubmit(onSubmit)}
  82. className='flex-1 space-y-6 overflow-y-auto px-4'
  83. >
  84. <FormField
  85. control={form.control}
  86. name='title'
  87. render={({ field }) => (
  88. <FormItem>
  89. <FormLabel>Title</FormLabel>
  90. <FormControl>
  91. <Input {...field} placeholder='Enter a title' />
  92. </FormControl>
  93. <FormMessage />
  94. </FormItem>
  95. )}
  96. />
  97. <FormField
  98. control={form.control}
  99. name='status'
  100. render={({ field }) => (
  101. <FormItem>
  102. <FormLabel>Status</FormLabel>
  103. <SelectDropdown
  104. defaultValue={field.value}
  105. onValueChange={field.onChange}
  106. placeholder='Select dropdown'
  107. items={[
  108. { label: 'In Progress', value: 'in progress' },
  109. { label: 'Backlog', value: 'backlog' },
  110. { label: 'Todo', value: 'todo' },
  111. { label: 'Canceled', value: 'canceled' },
  112. { label: 'Done', value: 'done' },
  113. ]}
  114. />
  115. <FormMessage />
  116. </FormItem>
  117. )}
  118. />
  119. <FormField
  120. control={form.control}
  121. name='label'
  122. render={({ field }) => (
  123. <FormItem className='relative'>
  124. <FormLabel>Label</FormLabel>
  125. <FormControl>
  126. <RadioGroup
  127. onValueChange={field.onChange}
  128. defaultValue={field.value}
  129. className='flex flex-col space-y-1'
  130. >
  131. <FormItem className='flex items-center'>
  132. <FormControl>
  133. <RadioGroupItem value='documentation' />
  134. </FormControl>
  135. <FormLabel className='font-normal'>
  136. Documentation
  137. </FormLabel>
  138. </FormItem>
  139. <FormItem className='flex items-center'>
  140. <FormControl>
  141. <RadioGroupItem value='feature' />
  142. </FormControl>
  143. <FormLabel className='font-normal'>Feature</FormLabel>
  144. </FormItem>
  145. <FormItem className='flex items-center'>
  146. <FormControl>
  147. <RadioGroupItem value='bug' />
  148. </FormControl>
  149. <FormLabel className='font-normal'>Bug</FormLabel>
  150. </FormItem>
  151. </RadioGroup>
  152. </FormControl>
  153. <FormMessage />
  154. </FormItem>
  155. )}
  156. />
  157. <FormField
  158. control={form.control}
  159. name='priority'
  160. render={({ field }) => (
  161. <FormItem className='relative'>
  162. <FormLabel>Priority</FormLabel>
  163. <FormControl>
  164. <RadioGroup
  165. onValueChange={field.onChange}
  166. defaultValue={field.value}
  167. className='flex flex-col space-y-1'
  168. >
  169. <FormItem className='flex items-center'>
  170. <FormControl>
  171. <RadioGroupItem value='high' />
  172. </FormControl>
  173. <FormLabel className='font-normal'>High</FormLabel>
  174. </FormItem>
  175. <FormItem className='flex items-center'>
  176. <FormControl>
  177. <RadioGroupItem value='medium' />
  178. </FormControl>
  179. <FormLabel className='font-normal'>Medium</FormLabel>
  180. </FormItem>
  181. <FormItem className='flex items-center'>
  182. <FormControl>
  183. <RadioGroupItem value='low' />
  184. </FormControl>
  185. <FormLabel className='font-normal'>Low</FormLabel>
  186. </FormItem>
  187. </RadioGroup>
  188. </FormControl>
  189. <FormMessage />
  190. </FormItem>
  191. )}
  192. />
  193. </form>
  194. </Form>
  195. <SheetFooter className='gap-2'>
  196. <SheetClose asChild>
  197. <Button variant='outline'>Close</Button>
  198. </SheetClose>
  199. <Button form='tasks-form' type='submit'>
  200. Save changes
  201. </Button>
  202. </SheetFooter>
  203. </SheetContent>
  204. </Sheet>
  205. )
  206. }