diff options
| author | MohamedBassem <me@mbassem.com> | 2024-03-20 21:22:21 +0000 |
|---|---|---|
| committer | MohamedBassem <me@mbassem.com> | 2024-03-20 21:35:18 +0000 |
| commit | 957fd12ff5211099619eb9ddec5a7a4bc8ae48a0 (patch) | |
| tree | 26e7c671d6abd79a1d2e7f7ebc70be7206ed3bf9 /apps/web | |
| parent | 03faa429f9342b4b5aa15d870b4e86ee5bf41650 (diff) | |
| download | karakeep-957fd12ff5211099619eb9ddec5a7a4bc8ae48a0.tar.zst | |
ui(web): Show an overlay when dragging is active
Diffstat (limited to 'apps/web')
| -rw-r--r-- | apps/web/app/dashboard/bookmarks/layout.tsx | 15 | ||||
| -rw-r--r-- | apps/web/app/dashboard/layout.tsx | 3 | ||||
| -rw-r--r-- | apps/web/components/dashboard/UploadDropzone.tsx | 42 |
3 files changed, 41 insertions, 19 deletions
diff --git a/apps/web/app/dashboard/bookmarks/layout.tsx b/apps/web/app/dashboard/bookmarks/layout.tsx index ca99a87b..bfc3b155 100644 --- a/apps/web/app/dashboard/bookmarks/layout.tsx +++ b/apps/web/app/dashboard/bookmarks/layout.tsx @@ -1,6 +1,7 @@ import type { Metadata } from "next"; import React from "react"; import TopNav from "@/components/dashboard/bookmarks/TopNav"; +import UploadDropzone from "@/components/dashboard/UploadDropzone"; export const metadata: Metadata = { title: "Hoarder - Bookmarks", @@ -12,12 +13,14 @@ export default function BookmarksLayout({ children: React.ReactNode; }>) { return ( - <div className="flex h-full flex-col"> - <div> - <TopNav /> + <UploadDropzone> + <div className="flex h-full flex-col"> + <div> + <TopNav /> + </div> + <hr /> + <div className="my-4 flex-1 pb-4">{children}</div> </div> - <hr /> - <div className="my-4 flex-1 pb-4">{children}</div> - </div> + </UploadDropzone> ); } diff --git a/apps/web/app/dashboard/layout.tsx b/apps/web/app/dashboard/layout.tsx index 50c7cc60..b2d3806b 100644 --- a/apps/web/app/dashboard/layout.tsx +++ b/apps/web/app/dashboard/layout.tsx @@ -1,6 +1,5 @@ import MobileSidebar from "@/components/dashboard/sidebar/ModileSidebar"; import Sidebar from "@/components/dashboard/sidebar/Sidebar"; -import UploadDropzone from "@/components/dashboard/UploadDropzone"; import DemoModeBanner from "@/components/DemoModeBanner"; import { Separator } from "@/components/ui/separator"; @@ -22,7 +21,7 @@ export default async function Dashboard({ <MobileSidebar /> <Separator /> </div> - <UploadDropzone>{children}</UploadDropzone> + {children} </main> </div> ); diff --git a/apps/web/components/dashboard/UploadDropzone.tsx b/apps/web/components/dashboard/UploadDropzone.tsx index 61db8dc5..d1a423ce 100644 --- a/apps/web/components/dashboard/UploadDropzone.tsx +++ b/apps/web/components/dashboard/UploadDropzone.tsx @@ -2,6 +2,7 @@ import React, { useState } from "react"; import { api } from "@/lib/trpc"; +import { cn } from "@/lib/utils"; import { useMutation } from "@tanstack/react-query"; import DropZone from "react-dropzone"; @@ -10,6 +11,7 @@ import { zUploadResponseSchema, } from "@hoarder/trpc/types/uploads"; +import LoadingSpinner from "../ui/spinner"; import { toast } from "../ui/use-toast"; export default function UploadDropzone({ @@ -20,17 +22,18 @@ export default function UploadDropzone({ const invalidateAllBookmarks = api.useUtils().bookmarks.getBookmarks.invalidate; - const { mutate: createBookmark } = api.bookmarks.createBookmark.useMutation({ - onSuccess: () => { - toast({ description: "Bookmark uploaded" }); - invalidateAllBookmarks(); - }, - onError: () => { - toast({ description: "Something went wrong", variant: "destructive" }); - }, - }); + const { mutate: createBookmark, isPending: isCreating } = + api.bookmarks.createBookmark.useMutation({ + onSuccess: () => { + toast({ description: "Bookmark uploaded" }); + invalidateAllBookmarks(); + }, + onError: () => { + toast({ description: "Something went wrong", variant: "destructive" }); + }, + }); - const { mutate: uploadAsset } = useMutation({ + const { mutate: uploadAsset, isPending: isUploading } = useMutation({ mutationFn: async (file: File) => { const formData = new FormData(); formData.append("image", file); @@ -53,7 +56,7 @@ export default function UploadDropzone({ }, }); - const [_isDragging, setDragging] = useState(false); + const [isDragging, setDragging] = useState(false); const onDrop = (acceptedFiles: File[]) => { const file = acceptedFiles[0]; setDragging(false); @@ -71,6 +74,23 @@ export default function UploadDropzone({ {({ getRootProps, getInputProps }) => ( <div {...getRootProps()}> <input {...getInputProps()} hidden /> + <div + className={cn( + "fixed inset-0 flex h-full w-full items-center justify-center bg-gray-200 opacity-90", + isDragging || isUploading || isCreating ? undefined : "hidden", + )} + > + {isUploading || isCreating ? ( + <div className="flex items-center justify-center gap-2"> + <p className="text-2xl font-bold text-gray-700">Uploading</p> + <LoadingSpinner /> + </div> + ) : ( + <p className="text-2xl font-bold text-gray-700"> + Drop Your Image + </p> + )} + </div> {children} </div> )} |
