diff options
Diffstat (limited to 'apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx')
| -rw-r--r-- | apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx b/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx new file mode 100644 index 00000000..4f08ebee --- /dev/null +++ b/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx @@ -0,0 +1,185 @@ +"use client"; + +import { useToast } from "@/components/ui/use-toast"; +import { api } from "@/lib/trpc"; +import { ZBookmark, ZBookmarkedLink } from "@hoarder/trpc/types/bookmarks"; +import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { + Archive, + Link, + List, + MoreHorizontal, + Pencil, + RotateCw, + Star, + Tags, + Trash2, +} from "lucide-react"; +import { useTagModel } from "./TagModal"; +import { useState } from "react"; +import { BookmarkedTextEditor } from "./BookmarkedTextEditor"; +import { useAddToListModal } from "./AddToListModal"; + +export default function BookmarkOptions({ bookmark }: { bookmark: ZBookmark }) { + const { toast } = useToast(); + const linkId = bookmark.id; + + const { setOpen: setTagModalIsOpen, content: tagModal } = + useTagModel(bookmark); + const { setOpen: setAddToListModalOpen, content: addToListModal } = + useAddToListModal(bookmark.id); + + const [isTextEditorOpen, setTextEditorOpen] = useState(false); + + const invalidateAllBookmarksCache = + api.useUtils().bookmarks.getBookmarks.invalidate; + + const invalidateBookmarkCache = + api.useUtils().bookmarks.getBookmark.invalidate; + + const onError = () => { + toast({ + variant: "destructive", + title: "Something went wrong", + description: "There was a problem with your request.", + }); + }; + const deleteBookmarkMutator = api.bookmarks.deleteBookmark.useMutation({ + onSuccess: () => { + toast({ + description: "The bookmark has been deleted!", + }); + }, + onError, + onSettled: () => { + invalidateAllBookmarksCache(); + }, + }); + + const updateBookmarkMutator = api.bookmarks.updateBookmark.useMutation({ + onSuccess: () => { + toast({ + description: "The bookmark has been updated!", + }); + }, + onError, + onSettled: () => { + invalidateBookmarkCache({ bookmarkId: bookmark.id }); + invalidateAllBookmarksCache(); + }, + }); + + const crawlBookmarkMutator = api.bookmarks.recrawlBookmark.useMutation({ + onSuccess: () => { + toast({ + description: "Re-fetch has been enqueued!", + }); + }, + onError, + onSettled: () => { + invalidateBookmarkCache({ bookmarkId: bookmark.id }); + }, + }); + + return ( + <> + {tagModal} + {addToListModal} + <BookmarkedTextEditor + bookmark={bookmark} + open={isTextEditorOpen} + setOpen={setTextEditorOpen} + /> + <DropdownMenu> + <DropdownMenuTrigger asChild> + <Button + variant="ghost" + className="px-1 focus-visible:ring-0 focus-visible:ring-offset-0" + > + <MoreHorizontal /> + </Button> + </DropdownMenuTrigger> + <DropdownMenuContent className="w-fit"> + {bookmark.content.type === "text" && ( + <DropdownMenuItem onClick={() => setTextEditorOpen(true)}> + <Pencil className="mr-2 size-4" /> + <span>Edit</span> + </DropdownMenuItem> + )} + <DropdownMenuItem + onClick={() => + updateBookmarkMutator.mutate({ + bookmarkId: linkId, + favourited: !bookmark.favourited, + }) + } + > + <Star className="mr-2 size-4" /> + <span>{bookmark.favourited ? "Un-favourite" : "Favourite"}</span> + </DropdownMenuItem> + <DropdownMenuItem + onClick={() => + updateBookmarkMutator.mutate({ + bookmarkId: linkId, + archived: !bookmark.archived, + }) + } + > + <Archive className="mr-2 size-4" /> + <span>{bookmark.archived ? "Un-archive" : "Archive"}</span> + </DropdownMenuItem> + {bookmark.content.type === "link" && ( + <DropdownMenuItem + onClick={() => { + navigator.clipboard.writeText( + (bookmark.content as ZBookmarkedLink).url, + ); + toast({ + description: "Link was added to your clipboard!", + }); + }} + > + <Link className="mr-2 size-4" /> + <span>Copy Link</span> + </DropdownMenuItem> + )} + <DropdownMenuItem onClick={() => setTagModalIsOpen(true)}> + <Tags className="mr-2 size-4" /> + <span>Edit Tags</span> + </DropdownMenuItem> + + <DropdownMenuItem onClick={() => setAddToListModalOpen(true)}> + <List className="mr-2 size-4" /> + <span>Add to List</span> + </DropdownMenuItem> + + {bookmark.content.type === "link" && ( + <DropdownMenuItem + onClick={() => + crawlBookmarkMutator.mutate({ bookmarkId: bookmark.id }) + } + > + <RotateCw className="mr-2 size-4" /> + <span>Refresh</span> + </DropdownMenuItem> + )} + <DropdownMenuItem + className="text-destructive" + onClick={() => + deleteBookmarkMutator.mutate({ bookmarkId: bookmark.id }) + } + > + <Trash2 className="mr-2 size-4" /> + <span>Delete</span> + </DropdownMenuItem> + </DropdownMenuContent> + </DropdownMenu> + </> + ); +} |
