aboutsummaryrefslogtreecommitdiffstats
path: root/apps/web
diff options
context:
space:
mode:
authorMohamedBassem <me@mbassem.com>2024-03-20 21:22:21 +0000
committerMohamedBassem <me@mbassem.com>2024-03-20 21:35:18 +0000
commit957fd12ff5211099619eb9ddec5a7a4bc8ae48a0 (patch)
tree26e7c671d6abd79a1d2e7f7ebc70be7206ed3bf9 /apps/web
parent03faa429f9342b4b5aa15d870b4e86ee5bf41650 (diff)
downloadkarakeep-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.tsx15
-rw-r--r--apps/web/app/dashboard/layout.tsx3
-rw-r--r--apps/web/components/dashboard/UploadDropzone.tsx42
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>
)}