From 41cb52c4cb639b8c93c1a90448368c9ebecc804f Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Mon, 25 Nov 2024 10:11:27 -0700 Subject: [PATCH] Add ability to upload image --- .../overlay/dialog/UploadImageDialog.tsx | 75 +++++++++++++++++++ web/src/pages/FaceLibrary.tsx | 69 ++++++----------- 2 files changed, 99 insertions(+), 45 deletions(-) create mode 100644 web/src/components/overlay/dialog/UploadImageDialog.tsx diff --git a/web/src/components/overlay/dialog/UploadImageDialog.tsx b/web/src/components/overlay/dialog/UploadImageDialog.tsx new file mode 100644 index 000000000..d3d317b44 --- /dev/null +++ b/web/src/components/overlay/dialog/UploadImageDialog.tsx @@ -0,0 +1,75 @@ +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; +import { Form, FormControl, FormField, FormItem } from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; + +type UploadImageDialogProps = { + open: boolean; + title: string; + description?: string; + setOpen: (open: boolean) => void; +}; +export default function UploadImageDialog({ + open, + title, + description, + setOpen, +}: UploadImageDialogProps) { + const formSchema = z.object({ + image: z + .instanceof(File, { message: "Please select an image file." }) + .refine((file) => file.size < 1000000, "Image size is too large."), + }); + + const form = useForm>({ + resolver: zodResolver(formSchema), + mode: "onChange", + }); + + return ( + + + + {title} + {description && {description}} + +
+ + ( + + + { + // @ts-expect-error ignore + + } + + + )} + /> + + + + + + +
+
+ ); +} diff --git a/web/src/pages/FaceLibrary.tsx b/web/src/pages/FaceLibrary.tsx index fd6d50223..0f4e5998e 100644 --- a/web/src/pages/FaceLibrary.tsx +++ b/web/src/pages/FaceLibrary.tsx @@ -1,26 +1,27 @@ import { baseUrl } from "@/api/baseUrl"; import Chip from "@/components/indicators/Chip"; -import { Form, FormControl, FormField, FormItem } from "@/components/ui/form"; -import { Input } from "@/components/ui/input"; +import UploadImageDialog from "@/components/overlay/dialog/UploadImageDialog"; +import { Button } from "@/components/ui/button"; import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area"; import { Toaster } from "@/components/ui/sonner"; import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"; import useOptimisticState from "@/hooks/use-optimistic-state"; -import { zodResolver } from "@hookform/resolvers/zod"; import axios from "axios"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { isDesktop } from "react-device-detect"; -import { useForm } from "react-hook-form"; -import { LuTrash } from "react-icons/lu"; +import { LuImagePlus, LuTrash } from "react-icons/lu"; import { toast } from "sonner"; import useSWR from "swr"; -import { z } from "zod"; export default function FaceLibrary() { const [page, setPage] = useState(); const [pageToggle, setPageToggle] = useOptimisticState(page, setPage, 100); const tabsRef = useRef(null); + // upload + + const [upload, setUpload] = useState(false); + // face data const { data: faceData } = useSWR("faces"); @@ -42,29 +43,18 @@ export default function FaceLibrary() { // eslint-disable-next-line react-hooks/exhaustive-deps }, [faces]); - /** - * - */ - - const formSchema = z.object({ - image: z - .instanceof(File, { message: "Please select an image file." }) - .refine((file) => file.size < 1000000, "Image size is too large."), - }); - - const form = useForm>({ - resolver: zodResolver(formSchema), - mode: "onChange", - }); - return (
-
- + + + +
-
- - ( - - - { - // @ts-expect-error ignore - - } - - - )} - /> - -
{pageToggle && (
{faceImages.map((image: string) => ( - + ))} +
)}