From b9ea061a2ed9b661df6c068b88de72da8bd18e45 Mon Sep 17 00:00:00 2001 From: mehedi-hasan Date: Wed, 1 May 2024 20:55:53 +0600 Subject: [PATCH] feat: skill, evaluation add form --- .../dashboard/evaluations/add/page.tsx | 36 ++ .../(dashboard)/dashboard/skills/add/page.tsx | 36 ++ src/components/add-skill-form.tsx | 75 ++++ src/components/evaluation-form.tsx | 324 ++++++++++++++++++ .../evaluations-table/tools-table.tsx | 2 +- src/components/skills-table/tools-table.tsx | 2 +- src/components/ui/command.tsx | 2 +- 7 files changed, 474 insertions(+), 3 deletions(-) create mode 100644 src/app/(dashboard)/dashboard/evaluations/add/page.tsx create mode 100644 src/app/(dashboard)/dashboard/skills/add/page.tsx create mode 100644 src/components/add-skill-form.tsx create mode 100644 src/components/evaluation-form.tsx diff --git a/src/app/(dashboard)/dashboard/evaluations/add/page.tsx b/src/app/(dashboard)/dashboard/evaluations/add/page.tsx new file mode 100644 index 0000000..fd7a634 --- /dev/null +++ b/src/app/(dashboard)/dashboard/evaluations/add/page.tsx @@ -0,0 +1,36 @@ +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area"; +import { Separator } from "@/components/ui/separator"; +import Breadcrumb from "@/components/breadcrumb"; +import AddEvaluationForm from "@/components/evaluation-form"; + +const breadcrumbItems = [ + { title: "Dashboard", link: "/dashboard" }, + { title: "Evaluation", link: "/dashboard/evaluations" }, + { title: "Add" }, +]; + +export default function SettingsDisplayPage() { + return ( + +
+ +
+ + + + Create Evaluation + + + + + + + + +
+ +
+
+ ); +} diff --git a/src/app/(dashboard)/dashboard/skills/add/page.tsx b/src/app/(dashboard)/dashboard/skills/add/page.tsx new file mode 100644 index 0000000..cb8ea7a --- /dev/null +++ b/src/app/(dashboard)/dashboard/skills/add/page.tsx @@ -0,0 +1,36 @@ +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area"; +import { Separator } from "@/components/ui/separator"; +import AddSkillForm from "@/components/add-skill-form"; +import Breadcrumb from "@/components/breadcrumb"; + +const breadcrumbItems = [ + { title: "Dashboard", link: "/dashboard" }, + { title: "Skills", link: "/dashboard/skills" }, + { title: "Add" }, +]; + +export default function SettingsDisplayPage() { + return ( + +
+ +
+ + + + Create Skill + + + + + + + + +
+ +
+
+ ); +} diff --git a/src/components/add-skill-form.tsx b/src/components/add-skill-form.tsx new file mode 100644 index 0000000..ceaca23 --- /dev/null +++ b/src/components/add-skill-form.tsx @@ -0,0 +1,75 @@ +"use client"; + +import { zodResolver } from "@hookform/resolvers/zod"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; + +import { Button } from "@/components/ui/button"; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { toast } from "@/components/ui/use-toast"; +import { Input } from "./ui/input"; + +const displayFormSchema = z.object({ + name: z.string().trim().min(1, "Name is required."), +}); + +type DisplayFormValues = z.infer; + +// This can come from your database or API. +const defaultValues: Partial = { + name: "", +}; + +export default function AddSkillForm() { + const form = useForm({ + resolver: zodResolver(displayFormSchema), + defaultValues, + }); + + function onSubmit(data: DisplayFormValues) { + toast({ + title: "You submitted the following values:", + description: ( +
+          {JSON.stringify(data, null, 2)}
+        
+ ), + }); + } + + return ( +
+ + ( + + Name + + + + + + )} + /> + +
+ + +
+ + + ); +} diff --git a/src/components/evaluation-form.tsx b/src/components/evaluation-form.tsx new file mode 100644 index 0000000..e4400aa --- /dev/null +++ b/src/components/evaluation-form.tsx @@ -0,0 +1,324 @@ +"use client"; + +import { zodResolver } from "@hookform/resolvers/zod"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; + +import { Button } from "@/components/ui/button"; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { toast } from "@/components/ui/use-toast"; +import { Input } from "./ui/input"; +import { Popover, PopoverContent, PopoverTrigger } from "./ui/popover"; +import { CaretSortIcon, CheckIcon } from "@radix-ui/react-icons"; +import { + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, +} from "./ui/command"; +import { cn } from "@/lib/utils"; +import { CommandList } from "cmdk"; +import { useState } from "react"; + +const statuses = [ + "uploading", + "new", + "requested", + "extraction_running", + "skills_extracted", + "evaluation_running", + "score_requested", + "course_creation", + "finished", + "deleted", + "extraction_failed", + "evaluation_failed", +] as const; + +const uploaders = ["hello@skilld.team", "johndoe@gmail.com"] as const; +const developers = ["hello@skilld.team", "johndoe@gmail.com"] as const; + +const displayFormSchema = z.object({ + status: z.string().trim().min(1, "Status is required"), + uploadTime: z.string().refine((value) => /^\d{4}-\d{2}-\d{2}$/.test(value), { + message: "Upload time should be in the format YYYY-MM-DD", + }), + uploaderAccount: z + .string() + .trim() + .email() + .min(1, "Please select a uploader account"), + developerUser: z + .string() + .trim() + .email() + .min(1, "Please select a developer user"), +}); + +type DisplayFormValues = z.infer; + +// This can come from your database or API. +const defaultValues: Partial = { + status: "", + uploadTime: "", + uploaderAccount: "", + developerUser: "", +}; + +export default function AddEvaluationForm() { + const [isStatusPopoverOpen, setIsStatusPopoverOpen] = useState(false); + const [isUploaderPopoverOpen, setIsUploaderPopoverOpen] = useState(false); + const [isDeveloperPopoverOpen, setIsDeveloperPopoverOpen] = useState(false); + + const form = useForm({ + resolver: zodResolver(displayFormSchema), + defaultValues, + }); + + function onSubmit(data: DisplayFormValues) { + toast({ + title: "You submitted the following values:", + description: ( +
+          {JSON.stringify(data, null, 2)}
+        
+ ), + }); + } + + return ( +
+ + ( + + Status + + + + + + + + + + + No status found. + + {statuses.map((status) => ( + { + form.setValue("status", status); + setIsStatusPopoverOpen(false); + }} + > + {status} + + + ))} + + + + + + + + )} + /> + + ( + + Upload Time + + + + + + )} + /> + + ( + + Uploader Account + + + + + + + + + + + No uploader found. + + {uploaders.map((uploader) => ( + { + form.setValue("uploaderAccount", uploader); + setIsUploaderPopoverOpen(false); + }} + > + {uploader} + + + ))} + + + + + + + + )} + /> + ( + + Developer User + + + + + + + + + + + No developer found. + + {developers.map((developer) => ( + { + form.setValue("developerUser", developer); + setIsDeveloperPopoverOpen(false); + }} + > + {developer} + + + ))} + + + + + + + + )} + /> + +
+ + +
+ + + ); +} diff --git a/src/components/evaluations-table/tools-table.tsx b/src/components/evaluations-table/tools-table.tsx index d911edf..82523c4 100644 --- a/src/components/evaluations-table/tools-table.tsx +++ b/src/components/evaluations-table/tools-table.tsx @@ -19,7 +19,7 @@ const ToolsTable = ({ evaluationsData }: { evaluationsData: Evaluation[] }) => { description="Manage Evaluations" /> { description="Manage Skills" />