implement edit bookmark dialog
This commit is contained in:
104
packages/web/src/app/bookmarks/-dialogs/edit-bookmark-dialog.tsx
Normal file
104
packages/web/src/app/bookmarks/-dialogs/edit-bookmark-dialog.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
import type { Bookmark, Tag } from "@markone/core"
|
||||
import { useId, useRef } from "react"
|
||||
import { useBookmarkTags, useUpdateBookmark } from "~/bookmark/api"
|
||||
import { Button } from "~/components/button"
|
||||
import { Dialog, DialogActionRow, DialogBody, DialogTitle } from "~/components/dialog"
|
||||
import { FormField } from "~/components/form-field"
|
||||
import { LoadingSpinner } from "~/components/loading-spinner"
|
||||
import { Message, MessageVariant } from "~/components/message.tsx"
|
||||
import { TagsInput, type TagsInputRef } from "~/components/tags-input"
|
||||
import { useBookmarkPageStore } from "../-store"
|
||||
|
||||
function EditBookmarkDialog({ bookmark }: { bookmark: Bookmark }) {
|
||||
const closeDialog = useBookmarkPageStore((state) => state.closeDialog)
|
||||
const { data: tags, status } = useBookmarkTags(bookmark)
|
||||
const editFormId = useId()
|
||||
|
||||
function content() {
|
||||
switch (status) {
|
||||
case "pending":
|
||||
return (
|
||||
<p>
|
||||
Loading <LoadingSpinner />
|
||||
</p>
|
||||
)
|
||||
case "success":
|
||||
return <EditForm formId={editFormId} bookmark={bookmark} tags={tags} />
|
||||
case "error":
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog>
|
||||
<DialogTitle>EDIT BOOKMARK</DialogTitle>
|
||||
<DialogBody>{content()}</DialogBody>
|
||||
<DialogActionRow>
|
||||
<Button type="submit" form={editFormId} disabled={status !== "success"}>
|
||||
<span className="underline">S</span>AVE
|
||||
</Button>
|
||||
<Button disabled={status !== "success"} onClick={closeDialog}>
|
||||
<span className="underline">C</span>ANCEL
|
||||
</Button>
|
||||
</DialogActionRow>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
|
||||
function EditForm({ formId, bookmark, tags }: { formId: string; bookmark: Bookmark; tags: Tag[] }) {
|
||||
const tagsInputRef = useRef<TagsInputRef>(null)
|
||||
const updateBookmarkMutation = useUpdateBookmark(bookmark)
|
||||
const closeDialog = useBookmarkPageStore((state) => state.closeDialog)
|
||||
|
||||
async function onSubmit(event: React.FormEvent<HTMLFormElement>) {
|
||||
if (tagsInputRef.current) {
|
||||
event.preventDefault()
|
||||
const form = new FormData(event.currentTarget)
|
||||
const title = form.get("title")
|
||||
const tags = tagsInputRef.current.tags
|
||||
if (title && typeof title === "string") {
|
||||
try {
|
||||
await updateBookmarkMutation.mutateAsync({
|
||||
title,
|
||||
tags,
|
||||
})
|
||||
closeDialog()
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function message() {
|
||||
switch (updateBookmarkMutation.status) {
|
||||
case "pending":
|
||||
return (
|
||||
<p>
|
||||
Saving changes <LoadingSpinner />
|
||||
</p>
|
||||
)
|
||||
case "error":
|
||||
return <Message variant={MessageVariant.Error}>Error updating the bookmark!</Message>
|
||||
default:
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{message()}
|
||||
<form id={formId} onSubmit={onSubmit}>
|
||||
<FormField
|
||||
type="text"
|
||||
name="title"
|
||||
label="TITLE"
|
||||
className="w-full"
|
||||
defaultValue={bookmark.title}
|
||||
labelClassName="bg-stone-300 dark:bg-stone-800"
|
||||
/>
|
||||
<TagsInput ref={tagsInputRef} initialValue={tags.map((tag) => tag.name).join(" ")} />
|
||||
</form>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export { EditBookmarkDialog }
|
Reference in New Issue
Block a user