rcgit

/ karakeep

Diff ec15d20abac6

Back to commit

context:
File + - Graph
A apps/web/app/dashboard/@modal/(.)preview/[bookmarkId]/page.tsx +35 -0
A apps/web/app/dashboard/@modal/[...catchAll]/page.tsx +3 -0
A apps/web/app/dashboard/@modal/default.tsx +3 -0
M apps/web/app/dashboard/layout.tsx +3 -0
M apps/web/app/dashboard/preview/[bookmarkId]/page.tsx +16 -4
M apps/web/components/dashboard/bookmarks/BookmarkActionBar.tsx +9 -17
M apps/web/components/dashboard/preview/ActionBar.tsx +3 -0
M apps/web/components/dashboard/preview/BookmarkPreview.tsx +9 -2
M packages/shared-react/hooks/bookmarks.ts +1 -0
9 file(s) changed, 82 insertions(+), 23 deletions(-)

apps/web/app/dashboard/@modal/(.)preview/[bookmarkId]/page.tsx

diff --git a/apps/web/app/dashboard/@modal/(.)preview/[bookmarkId]/page.tsx b/apps/web/app/dashboard/@modal/(.)preview/[bookmarkId]/page.tsx
new file mode 100644
index 00000000..432e7a6c
--- /dev/null
+++ b/apps/web/app/dashboard/@modal/(.)preview/[bookmarkId]/page.tsx
@@ -0,0 +1,35 @@
+"use client";
+
+import { useState } from "react";
+import { useRouter } from "next/navigation";
+import BookmarkPreview from "@/components/dashboard/preview/BookmarkPreview";
+import { Dialog, DialogContent } from "@/components/ui/dialog";
+
+export default function BookmarkPreviewPage({
+  params,
+}: {
+  params: { bookmarkId: string };
+}) {
+  const router = useRouter();
+
+  const [open, setOpen] = useState(true);
+
+  const setOpenWithRouter = (value: boolean) => {
+    setOpen(value);
+    if (!value) {
+      router.back();
+    }
+  };
+
+  return (
+    <Dialog open={open} onOpenChange={setOpenWithRouter}>
+      <DialogContent
+        className="h-[90%] max-w-[90%] overflow-hidden p-0"
+        hideCloseBtn={true}
+        onOpenAutoFocus={(e) => e.preventDefault()}
+      >
+        <BookmarkPreview bookmarkId={params.bookmarkId} />
+      </DialogContent>
+    </Dialog>
+  );
+}

apps/web/app/dashboard/@modal/[...catchAll]/page.tsx

diff --git a/apps/web/app/dashboard/@modal/[...catchAll]/page.tsx b/apps/web/app/dashboard/@modal/[...catchAll]/page.tsx
new file mode 100644
index 00000000..1fd97c20
--- /dev/null
+++ b/apps/web/app/dashboard/@modal/[...catchAll]/page.tsx
@@ -0,0 +1,3 @@
+export default function CatchAll() {
+  return null;
+}

apps/web/app/dashboard/@modal/default.tsx

diff --git a/apps/web/app/dashboard/@modal/default.tsx b/apps/web/app/dashboard/@modal/default.tsx
new file mode 100644
index 00000000..6ddf1b76
--- /dev/null
+++ b/apps/web/app/dashboard/@modal/default.tsx
@@ -0,0 +1,3 @@
+export default function Default() {
+  return null;
+}

apps/web/app/dashboard/layout.tsx

diff --git a/apps/web/app/dashboard/layout.tsx b/apps/web/app/dashboard/layout.tsx
index 3b6908f8..23c379cb 100644
--- a/apps/web/app/dashboard/layout.tsx
+++ b/apps/web/app/dashboard/layout.tsx
@@ -7,8 +7,10 @@ import serverConfig from "@hoarder/shared/config";
 
 export default async function Dashboard({
   children,
+  modal,
 }: Readonly<{
   children: React.ReactNode;
+  modal: React.ReactNode;
 }>) {
   return (
     <div className="flex min-h-screen w-screen flex-col sm:h-screen sm:flex-row">
@@ -21,6 +23,7 @@ export default async function Dashboard({
           <MobileSidebar />
           <Separator />
         </div>
+        {modal}
         <div className="container min-h-screen p-4">{children}</div>
       </main>
     </div>

apps/web/app/dashboard/preview/[bookmarkId]/page.tsx

diff --git a/apps/web/app/dashboard/preview/[bookmarkId]/page.tsx b/apps/web/app/dashboard/preview/[bookmarkId]/page.tsx
index 6cac7377..236f5447 100644
--- a/apps/web/app/dashboard/preview/[bookmarkId]/page.tsx
+++ b/apps/web/app/dashboard/preview/[bookmarkId]/page.tsx
@@ -1,18 +1,30 @@
+import { notFound } from "next/navigation";
 import BookmarkPreview from "@/components/dashboard/preview/BookmarkPreview";
 import { api } from "@/server/api/client";
+import { TRPCError } from "@trpc/server";
 
 export default async function BookmarkPreviewPage({
   params,
 }: {
   params: { bookmarkId: string };
 }) {
-  const bookmark = await api.bookmarks.getBookmark({
-    bookmarkId: params.bookmarkId,
-  });
+  let bookmark;
+  try {
+    bookmark = await api.bookmarks.getBookmark({
+      bookmarkId: params.bookmarkId,
+    });
+  } catch (e) {
+    if (e instanceof TRPCError) {
+      if (e.code === "NOT_FOUND") {
+        notFound();
+      }
+    }
+    throw e;
+  }
 
   return (
     <div className="max-h-screen">
-      <BookmarkPreview initialData={bookmark} />
+      <BookmarkPreview bookmarkId={bookmark.id} initialData={bookmark} />
     </div>
   );
 }

apps/web/components/dashboard/bookmarks/BookmarkActionBar.tsx

diff --git a/apps/web/components/dashboard/bookmarks/BookmarkActionBar.tsx b/apps/web/components/dashboard/bookmarks/BookmarkActionBar.tsx
index d4e8dfca..6cc8e44e 100644
--- a/apps/web/components/dashboard/bookmarks/BookmarkActionBar.tsx
+++ b/apps/web/components/dashboard/bookmarks/BookmarkActionBar.tsx
@@ -1,6 +1,6 @@
-import BookmarkPreview from "@/components/dashboard/preview/BookmarkPreview";
-import { Button } from "@/components/ui/button";
-import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog";
+import Link from "next/link";
+import { buttonVariants } from "@/components/ui/button";
+import { cn } from "@/lib/utils";
 import { Maximize2 } from "lucide-react";
 
 import type { ZBookmark } from "@hoarder/shared/types/bookmarks";
@@ -18,20 +18,12 @@ export default function BookmarkActionBar({
       {bookmark.favourited && (
         <FavouritedActionIcon className="m-1 size-8 rounded p-1" favourited />
       )}
-      <Dialog>
-        <DialogTrigger asChild>
-          <Button variant="ghost" className="my-auto block px-2">
-            <Maximize2 size="20" />
-          </Button>
-        </DialogTrigger>
-        <DialogContent
-          className="h-[90%] max-w-[90%] overflow-hidden p-0"
-          hideCloseBtn={true}
-          onOpenAutoFocus={(e) => e.preventDefault()}
-        >
-          <BookmarkPreview initialData={bookmark} />
-        </DialogContent>
-      </Dialog>
+      <Link
+        href={`/dashboard/preview/${bookmark.id}`}
+        className={cn(buttonVariants({ variant: "ghost" }), "px-2")}
+      >
+        <Maximize2 size="20" />
+      </Link>
       <BookmarkOptions bookmark={bookmark} />
     </div>
   );

apps/web/components/dashboard/preview/ActionBar.tsx

diff --git a/apps/web/components/dashboard/preview/ActionBar.tsx b/apps/web/components/dashboard/preview/ActionBar.tsx
index ec659e35..3505d0a5 100644
--- a/apps/web/components/dashboard/preview/ActionBar.tsx
+++ b/apps/web/components/dashboard/preview/ActionBar.tsx
@@ -1,3 +1,4 @@
+import { useRouter } from "next/navigation";
 import { ActionButton } from "@/components/ui/action-button";
 import {
   Tooltip,
@@ -16,6 +17,7 @@ import {
 import { ArchivedActionIcon, FavouritedActionIcon } from "../bookmarks/icons";
 
 export default function ActionBar({ bookmark }: { bookmark: ZBookmark }) {
+  const router = useRouter();
   const onError = () => {
     toast({
       variant: "destructive",
@@ -46,6 +48,7 @@ export default function ActionBar({ bookmark }: { bookmark: ZBookmark }) {
         toast({
           description: "The bookmark has been deleted!",
         });
+        router.back();
       },
       onError,
     });

apps/web/components/dashboard/preview/BookmarkPreview.tsx

diff --git a/apps/web/components/dashboard/preview/BookmarkPreview.tsx b/apps/web/components/dashboard/preview/BookmarkPreview.tsx
index 581ec4bd..3d98dd19 100644
--- a/apps/web/components/dashboard/preview/BookmarkPreview.tsx
+++ b/apps/web/components/dashboard/preview/BookmarkPreview.tsx
@@ -3,6 +3,7 @@
 import { useEffect, useState } from "react";
 import Link from "next/link";
 import { TagsEditor } from "@/components/dashboard/bookmarks/TagsEditor";
+import { FullPageSpinner } from "@/components/ui/full-page-spinner";
 import { Separator } from "@/components/ui/separator";
 import { Skeleton } from "@/components/ui/skeleton";
 import {
@@ -65,13 +66,15 @@ function CreationTime({ createdAt }: { createdAt: Date }) {
 }
 
 export default function BookmarkPreview({
+  bookmarkId,
   initialData,
 }: {
-  initialData: ZBookmark;
+  bookmarkId: string;
+  initialData?: ZBookmark;
 }) {
   const { data: bookmark } = api.bookmarks.getBookmark.useQuery(
     {
-      bookmarkId: initialData.id,
+      bookmarkId,
     },
     {
       initialData,
@@ -89,6 +92,10 @@ export default function BookmarkPreview({
     },
   );
 
+  if (!bookmark) {
+    return <FullPageSpinner />;
+  }
+
   let content;
   switch (bookmark.content.type) {
     case "link": {

packages/shared-react/hooks/bookmarks.ts

diff --git a/packages/shared-react/hooks/bookmarks.ts b/packages/shared-react/hooks/bookmarks.ts
index ceaed3a9..402bfae4 100644
--- a/packages/shared-react/hooks/bookmarks.ts
+++ b/packages/shared-react/hooks/bookmarks.ts
@@ -46,6 +46,7 @@ export function useDeleteBookmark(
     onSuccess: (res, req, meta) => {
       apiUtils.bookmarks.getBookmarks.invalidate();
       apiUtils.bookmarks.searchBookmarks.invalidate();
+      apiUtils.bookmarks.getBookmark.invalidate({ bookmarkId: req.bookmarkId });
       return opts[0]?.onSuccess?.(res, req, meta);
     },
   });