From 7a6d9bed4d45d1984780a99b8950b547b9568cf0 Mon Sep 17 00:00:00 2001 From: Zeke Abshire Date: Fri, 22 Nov 2024 23:27:39 -0600 Subject: [PATCH] implemented 'create new list' button + dialog --- .../(home)/_components/create-new-button.tsx | 250 ++++++++++++++++++ src/app/(home)/page.tsx | 6 +- src/app/_components/ui/dialog.tsx | 11 +- src/app/_components/ui/form.tsx | 2 +- src/app/_components/ui/radio-group.tsx | 4 +- 5 files changed, 265 insertions(+), 8 deletions(-) create mode 100644 src/app/(home)/_components/create-new-button.tsx diff --git a/src/app/(home)/_components/create-new-button.tsx b/src/app/(home)/_components/create-new-button.tsx new file mode 100644 index 0000000..cf2be3f --- /dev/null +++ b/src/app/(home)/_components/create-new-button.tsx @@ -0,0 +1,250 @@ +"use client"; + +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, + useDialogControls, +} from "~/app/_components/ui/dialog"; +import { Button } from "~/app/_components/ui/button"; +import { Input } from "~/app/_components/ui/input"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "~/app/_components/ui/form"; +import { useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { api } from "~/trpc/react"; +import { toast } from "sonner"; +import { + type ListCreationSchema, + listCreationFormSchema, +} from "~/lib/schemas/list-creation-form"; +import { RadioGroup, RadioGroupItem } from "~/app/_components/ui/radio-group"; +import { VARIANTS } from "~/lib/data/list-variants"; +import { LABELS } from "~/lib/data/task-labels"; +import { Checkbox } from "~/app/_components/ui/checkbox"; +import { Separator } from "~/app/_components/ui/separator"; + +export const CreateNewButton = () => { + const [isOpen, onOpenChange] = useDialogControls(); + const handleOpenChange = (open: boolean) => { + form.reset(); + onOpenChange(open); + }; + + const utils = api.useUtils(); + const { mutate } = api.list.create.useMutation({ + onSuccess: (_, variables) => { + toast.success(`Created new list: ${variables.name}`); + onOpenChange(false); + form.reset(); + void utils.list.getAll.invalidate(); + }, + }); + + const form = useForm({ + resolver: zodResolver(listCreationFormSchema), + defaultValues: { + name: "", + variant: "", + labels: [], + id: false, + idPrefix: "", + }, + }); + + const onSubmit = (values: ListCreationSchema) => { + console.log("SUBMIT", values); + mutate(values); + }; + + return ( + + + + + +
+ + + create new list + + customize the list to your needs. + + + +
+ {/* Name */} + ( + +
+ title + + this is the name of your list. + +
+ + + + + +
+ )} + /> + + {/* Variants */} + ( + +
+ variant + + select the type of list you want to use. + +
+ + + {VARIANTS.map((v) => ( + + + + + {v} + + ))} + + + +
+ )} + /> + + + + {/* ID */} + ( + + + + +
+ enable task id + + assign an id number to each task. + +
+
+ )} + /> + + {/* ID Prefix */} + ( + +
+ id prefix + + (optional) add a prefix to your id. ex: + "ls-53" + +
+ + + + + +
+ )} + /> + + {/* Labels */} + ( + +
+ labels + + (optional) select the task labels you want to be able to + use. + +
+ {LABELS.map((label) => ( + { + return ( + + + { + return checked + ? field.onChange([...field.value, label]) + : field.onChange( + field.value?.filter( + (value) => value !== label, + ), + ); + }} + /> + + + {label} + + + ); + }} + /> + ))} + +
+ )} + /> +
+ + + + + +
+
+ ); +}; diff --git a/src/app/(home)/page.tsx b/src/app/(home)/page.tsx index 7fb8e41..2abc8ef 100644 --- a/src/app/(home)/page.tsx +++ b/src/app/(home)/page.tsx @@ -1,8 +1,8 @@ import { auth } from "~/server/auth"; -import { UserNav } from "~/app/_components/user-nav"; -import { Button } from "~/app/_components/ui/button"; +import { UserNav } from "~/app/_components/macro/user-nav"; import { api } from "~/trpc/server"; import { ListButton } from "~/app/(home)/_components/list-button"; +import { CreateNewButton } from "~/app/(home)/_components/create-new-button"; export default async function Home() { const session = await auth(); @@ -23,7 +23,7 @@ export default async function Home() {
- +
diff --git a/src/app/_components/ui/dialog.tsx b/src/app/_components/ui/dialog.tsx index ba0cc63..8ee4eb4 100644 --- a/src/app/_components/ui/dialog.tsx +++ b/src/app/_components/ui/dialog.tsx @@ -21,7 +21,7 @@ const DialogOverlay = React.forwardRef< { + const [isOpen, setIsOpen] = React.useState(false); + const onOpenChange = (open: boolean) => setIsOpen(open); + + return [isOpen, onOpenChange] as const; +}; diff --git a/src/app/_components/ui/form.tsx b/src/app/_components/ui/form.tsx index 530af54..ae165c7 100644 --- a/src/app/_components/ui/form.tsx +++ b/src/app/_components/ui/form.tsx @@ -165,7 +165,7 @@ const FormMessage = React.forwardRef< ref={ref} id={formMessageId} className={cn( - "text-gruv-red-bg dark:text-gruv-red-fg text-[0.8rem] font-medium", + "text-[0.8rem] font-medium text-gruv-red-bg dark:text-gruv-red-fg", className, )} {...props} diff --git a/src/app/_components/ui/radio-group.tsx b/src/app/_components/ui/radio-group.tsx index 6508e4d..eabcc3e 100644 --- a/src/app/_components/ui/radio-group.tsx +++ b/src/app/_components/ui/radio-group.tsx @@ -28,13 +28,13 @@ const RadioGroupItem = React.forwardRef< - + );