105 lines
2.9 KiB
TypeScript
105 lines
2.9 KiB
TypeScript
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 }
|