import * as React from "react"; import { ActionButton } from "@/components/ui/action-button"; import { Button } from "@/components/ui/button"; import { Calendar } from "@/components/ui/calendar"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; import { Textarea } from "@/components/ui/textarea"; import { toast } from "@/components/ui/use-toast"; import { useTranslation } from "@/lib/i18n/client"; import { cn } from "@/lib/utils"; import { zodResolver } from "@hookform/resolvers/zod"; import { format } from "date-fns"; import { CalendarIcon } from "lucide-react"; import { useForm } from "react-hook-form"; import { useUpdateBookmark } from "@hoarder/shared-react/hooks/bookmarks"; import { BookmarkTypes, ZBookmark, ZUpdateBookmarksRequest, zUpdateBookmarksRequestSchema, } from "@hoarder/shared/types/bookmarks"; import { BookmarkTagsEditor } from "./BookmarkTagsEditor"; const formSchema = zUpdateBookmarksRequestSchema; export function EditBookmarkDialog({ open, setOpen, bookmark, children, }: { bookmark: ZBookmark; children?: React.ReactNode; open: boolean; setOpen: (v: boolean) => void; }) { const { t } = useTranslation(); const bookmarkToDefault = (bookmark: ZBookmark) => ({ bookmarkId: bookmark.id, summary: bookmark.summary, title: bookmark.title ? bookmark.title : bookmark.content.type === BookmarkTypes.LINK ? bookmark.content.title : undefined, createdAt: bookmark.createdAt ?? new Date(), // Link specific defaults (only if bookmark is a link) url: bookmark.content.type === BookmarkTypes.LINK ? bookmark.content.url : undefined, description: bookmark.content.type === BookmarkTypes.LINK ? (bookmark.content.description ?? "") : undefined, author: bookmark.content.type === BookmarkTypes.LINK ? (bookmark.content.author ?? "") : undefined, publisher: bookmark.content.type === BookmarkTypes.LINK ? (bookmark.content.publisher ?? "") : undefined, datePublished: bookmark.content.type === BookmarkTypes.LINK ? bookmark.content.datePublished : undefined, }); const form = useForm({ resolver: zodResolver(formSchema), defaultValues: bookmarkToDefault(bookmark), }); const { mutate: updateBookmarkMutate, isPending: isUpdatingBookmark } = useUpdateBookmark({ onSuccess: (updatedBookmark) => { toast({ description: "Bookmark details updated successfully!" }); // Close the dialog after successful detail update setOpen(false); // Reset form with potentially updated data form.reset(bookmarkToDefault(updatedBookmark)); }, onError: (error) => { toast({ variant: "destructive", title: "Failed to update bookmark", description: error.message, }); }, }); function onSubmit(values: ZUpdateBookmarksRequest) { // Ensure optional fields that are empty strings are sent as null/undefined if appropriate const payload = { ...values, title: values.title ?? null, }; updateBookmarkMutate(payload); } // Reset form when bookmark data changes externally or dialog reopens React.useEffect(() => { if (open) { form.reset(bookmarkToDefault(bookmark)); } }, [bookmark, form, open]); const isLink = bookmark.content.type === BookmarkTypes.LINK; return ( {children && {children}} {t("bookmark_editor.title")} {t("bookmark_editor.subtitle")}
( {t("common.title")} )} /> {isLink && ( ( {t("common.url")} )} /> )} {isLink && ( ( {t("common.description")}