aboutsummaryrefslogtreecommitdiffstats
path: root/apps/web/components/dashboard/bookmarks
diff options
context:
space:
mode:
Diffstat (limited to 'apps/web/components/dashboard/bookmarks')
-rw-r--r--apps/web/components/dashboard/bookmarks/BookmarkLayoutAdaptingCard.tsx11
-rw-r--r--apps/web/components/dashboard/bookmarks/BookmarkMarkdownComponent.tsx2
-rw-r--r--apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx53
-rw-r--r--apps/web/components/dashboard/bookmarks/DeleteBookmarkConfirmationDialog.tsx63
4 files changed, 100 insertions, 29 deletions
diff --git a/apps/web/components/dashboard/bookmarks/BookmarkLayoutAdaptingCard.tsx b/apps/web/components/dashboard/bookmarks/BookmarkLayoutAdaptingCard.tsx
index 1df0c197..a2323987 100644
--- a/apps/web/components/dashboard/bookmarks/BookmarkLayoutAdaptingCard.tsx
+++ b/apps/web/components/dashboard/bookmarks/BookmarkLayoutAdaptingCard.tsx
@@ -30,6 +30,13 @@ interface Props {
wrapTags: boolean;
}
+function BookmarkFormattedCreatedAt({ bookmark }: { bookmark: ZBookmark }) {
+ const createdAt = dayjs(bookmark.createdAt);
+ const oneYearAgo = dayjs().subtract(1, "year");
+ const formatString = createdAt.isAfter(oneYearAgo) ? "MMM D" : "MMM D, YYYY";
+ return createdAt.format(formatString);
+}
+
function BottomRow({
footer,
bookmark,
@@ -45,7 +52,7 @@ function BottomRow({
href={`/dashboard/preview/${bookmark.id}`}
suppressHydrationWarning
>
- {dayjs(bookmark.createdAt).format("MMM DD")}
+ <BookmarkFormattedCreatedAt bookmark={bookmark} />
</Link>
</div>
<BookmarkActionBar bookmark={bookmark} />
@@ -232,7 +239,7 @@ function CompactView({ bookmark, title, footer, className }: Props) {
suppressHydrationWarning
className="shrink-0 gap-2 text-gray-500"
>
- {dayjs(bookmark.createdAt).format("MMM DD")}
+ <BookmarkFormattedCreatedAt bookmark={bookmark} />
</Link>
</div>
<BookmarkActionBar bookmark={bookmark} />
diff --git a/apps/web/components/dashboard/bookmarks/BookmarkMarkdownComponent.tsx b/apps/web/components/dashboard/bookmarks/BookmarkMarkdownComponent.tsx
index 74eb0868..60a6d634 100644
--- a/apps/web/components/dashboard/bookmarks/BookmarkMarkdownComponent.tsx
+++ b/apps/web/components/dashboard/bookmarks/BookmarkMarkdownComponent.tsx
@@ -30,7 +30,7 @@ export function BookmarkMarkdownComponent({
});
};
return (
- <div className="h-full overflow-hidden">
+ <div className="h-full">
{readOnly ? (
<MarkdownReadonly>{bookmark.content.text}</MarkdownReadonly>
) : (
diff --git a/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx b/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx
index 8dfb96fd..c37c6417 100644
--- a/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx
+++ b/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx
@@ -28,15 +28,16 @@ import type {
ZBookmarkedLink,
} from "@hoarder/shared/types/bookmarks";
import {
- useDeleteBookmark,
useRecrawlBookmark,
useUpdateBookmark,
} from "@hoarder/shared-react/hooks//bookmarks";
import { useRemoveBookmarkFromList } from "@hoarder/shared-react/hooks//lists";
import { useBookmarkGridContext } from "@hoarder/shared-react/hooks/bookmark-grid-context";
+import { useBookmarkListContext } from "@hoarder/shared-react/hooks/bookmark-list-context";
import { BookmarkTypes } from "@hoarder/shared/types/bookmarks";
import { BookmarkedTextEditor } from "./BookmarkedTextEditor";
+import DeleteBookmarkConfirmationDialog from "./DeleteBookmarkConfirmationDialog";
import { ArchivedActionIcon, FavouritedActionIcon } from "./icons";
import { useManageListsModal } from "./ManageListsModal";
import { useTagModel } from "./TagModal";
@@ -53,9 +54,12 @@ export default function BookmarkOptions({ bookmark }: { bookmark: ZBookmark }) {
const { setOpen: setManageListsModalOpen, content: manageListsModal } =
useManageListsModal(bookmark.id);
+ const [deleteBookmarkDialogOpen, setDeleteBookmarkDialogOpen] =
+ useState(false);
const [isTextEditorOpen, setTextEditorOpen] = useState(false);
const { listId } = useBookmarkGridContext() ?? {};
+ const withinListContext = useBookmarkListContext();
const onError = () => {
toast({
@@ -63,14 +67,6 @@ export default function BookmarkOptions({ bookmark }: { bookmark: ZBookmark }) {
title: t("common.something_went_wrong"),
});
};
- const deleteBookmarkMutator = useDeleteBookmark({
- onSuccess: () => {
- toast({
- description: t("toasts.bookmarks.deleted"),
- });
- },
- onError,
- });
const updateBookmarkMutator = useUpdateBookmark({
onSuccess: () => {
@@ -112,6 +108,11 @@ export default function BookmarkOptions({ bookmark }: { bookmark: ZBookmark }) {
<>
{tagModal}
{manageListsModal}
+ <DeleteBookmarkConfirmationDialog
+ bookmark={bookmark}
+ open={deleteBookmarkDialogOpen}
+ setOpen={setDeleteBookmarkDialogOpen}
+ />
<BookmarkedTextEditor
bookmark={bookmark}
open={isTextEditorOpen}
@@ -211,20 +212,22 @@ export default function BookmarkOptions({ bookmark }: { bookmark: ZBookmark }) {
<span>{t("actions.manage_lists")}</span>
</DropdownMenuItem>
- {listId && (
- <DropdownMenuItem
- disabled={demoMode}
- onClick={() =>
- removeFromListMutator.mutate({
- listId,
- bookmarkId: bookmark.id,
- })
- }
- >
- <ListX className="mr-2 size-4" />
- <span>{t("actions.remove_from_list")}</span>
- </DropdownMenuItem>
- )}
+ {listId &&
+ withinListContext &&
+ withinListContext.type === "manual" && (
+ <DropdownMenuItem
+ disabled={demoMode}
+ onClick={() =>
+ removeFromListMutator.mutate({
+ listId,
+ bookmarkId: bookmark.id,
+ })
+ }
+ >
+ <ListX className="mr-2 size-4" />
+ <span>{t("actions.remove_from_list")}</span>
+ </DropdownMenuItem>
+ )}
{bookmark.content.type === BookmarkTypes.LINK && (
<DropdownMenuItem
@@ -240,9 +243,7 @@ export default function BookmarkOptions({ bookmark }: { bookmark: ZBookmark }) {
<DropdownMenuItem
disabled={demoMode}
className="text-destructive"
- onClick={() =>
- deleteBookmarkMutator.mutate({ bookmarkId: bookmark.id })
- }
+ onClick={() => setDeleteBookmarkDialogOpen(true)}
>
<Trash2 className="mr-2 size-4" />
<span>{t("actions.delete")}</span>
diff --git a/apps/web/components/dashboard/bookmarks/DeleteBookmarkConfirmationDialog.tsx b/apps/web/components/dashboard/bookmarks/DeleteBookmarkConfirmationDialog.tsx
new file mode 100644
index 00000000..4a69e3d0
--- /dev/null
+++ b/apps/web/components/dashboard/bookmarks/DeleteBookmarkConfirmationDialog.tsx
@@ -0,0 +1,63 @@
+import { usePathname, useRouter } from "next/navigation";
+import { ActionButton } from "@/components/ui/action-button";
+import ActionConfirmingDialog from "@/components/ui/action-confirming-dialog";
+import { toast } from "@/components/ui/use-toast";
+import { useTranslation } from "@/lib/i18n/client";
+
+import { useDeleteBookmark } from "@hoarder/shared-react/hooks//bookmarks";
+import { ZBookmark } from "@hoarder/shared/types/bookmarks";
+
+export default function DeleteBookmarkConfirmationDialog({
+ bookmark,
+ children,
+ open,
+ setOpen,
+}: {
+ bookmark: ZBookmark;
+ children?: React.ReactNode;
+ open: boolean;
+ setOpen: (v: boolean) => void;
+}) {
+ const { t } = useTranslation();
+ const currentPath = usePathname();
+ const router = useRouter();
+
+ const { mutate: deleteBoomark, isPending } = useDeleteBookmark({
+ onSuccess: () => {
+ toast({
+ description: t("toasts.bookmarks.deleted"),
+ });
+ setOpen(false);
+ if (currentPath.includes(bookmark.id)) {
+ router.push("/dashboard/bookmarks");
+ }
+ },
+ onError: () => {
+ toast({
+ variant: "destructive",
+ description: `Something went wrong`,
+ });
+ },
+ });
+
+ return (
+ <ActionConfirmingDialog
+ open={open}
+ setOpen={setOpen}
+ title={t("dialogs.bookmarks.delete_confirmation_title")}
+ description={t("dialogs.bookmarks.delete_confirmation_description")}
+ actionButton={() => (
+ <ActionButton
+ type="button"
+ variant="destructive"
+ loading={isPending}
+ onClick={() => deleteBoomark({ bookmarkId: bookmark.id })}
+ >
+ Delete
+ </ActionButton>
+ )}
+ >
+ {children}
+ </ActionConfirmingDialog>
+ );
+}