From 81e0b2849d837649da9adbc5d077b8c819fe7bee Mon Sep 17 00:00:00 2001 From: MohamedBassem Date: Mon, 15 Apr 2024 18:39:59 +0100 Subject: feature: Add title to bookmarks and allow editing them. Fixes #27 --- .../components/dashboard/preview/EditableTitle.tsx | 165 +++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 apps/web/components/dashboard/preview/EditableTitle.tsx (limited to 'apps/web/components/dashboard/preview/EditableTitle.tsx') diff --git a/apps/web/components/dashboard/preview/EditableTitle.tsx b/apps/web/components/dashboard/preview/EditableTitle.tsx new file mode 100644 index 00000000..1500212d --- /dev/null +++ b/apps/web/components/dashboard/preview/EditableTitle.tsx @@ -0,0 +1,165 @@ +import { useEffect, useRef, useState } from "react"; +import { ActionButtonWithTooltip } from "@/components/ui/action-button"; +import { ButtonWithTooltip } from "@/components/ui/button"; +import { + Tooltip, + TooltipContent, + TooltipPortal, + TooltipTrigger, +} from "@/components/ui/tooltip"; +import { toast } from "@/components/ui/use-toast"; +import { Check, Pencil, X } from "lucide-react"; + +import { useUpdateBookmark } from "@hoarder/shared-react/hooks/bookmarks"; +import { ZBookmark } from "@hoarder/trpc/types/bookmarks"; + +interface Props { + bookmarkId: string; + originalTitle: string | null; + setEditable: (editable: boolean) => void; +} + +function EditMode({ bookmarkId, originalTitle, setEditable }: Props) { + const ref = useRef(null); + + const { mutate: updateBookmark, isPending } = useUpdateBookmark({ + onSuccess: () => { + toast({ + description: "Title updated!", + }); + }, + }); + + useEffect(() => { + if (ref.current) { + ref.current.focus(); + ref.current.textContent = originalTitle; + } + }, [ref]); + + const onSave = () => { + let toSave: string | null = ref.current?.textContent ?? null; + if (originalTitle == toSave) { + // Nothing to do here + return; + } + if (toSave == "") { + toSave = null; + } + updateBookmark({ + bookmarkId, + title: toSave, + }); + setEditable(false); + }; + + return ( +
+
{ + if (e.key === "Enter") { + e.preventDefault(); + } + }} + /> + onSave()} + > + + + { + setEditable(false); + }} + > + + +
+ ); +} + +function ViewMode({ originalTitle, setEditable }: Props) { + return ( + +
+ + {originalTitle ? ( +

{originalTitle}

+ ) : ( +

Untitled

+ )} +
+ { + setEditable(true); + }} + > + + +
+ + {originalTitle && ( + + {originalTitle} + + )} + +
+ ); +} + +export function EditableTitle({ bookmark }: { bookmark: ZBookmark }) { + const [editable, setEditable] = useState(false); + + let title: string | null = null; + switch (bookmark.content.type) { + case "link": + title = bookmark.content.title ?? bookmark.content.url; + break; + case "text": + title = null; + break; + case "asset": + title = bookmark.content.fileName ?? null; + break; + } + + title = bookmark.title ?? title; + if (title == "") { + title = null; + } + + return editable ? ( + + ) : ( + + ); +} -- cgit v1.2.3-70-g09d2