diff --git a/apps/cms/src/app/(protected)/content/article/[documentId]/page.tsx b/apps/cms/src/app/(protected)/content/article/[documentId]/page.tsx index 644074c9..c6ee817d 100644 --- a/apps/cms/src/app/(protected)/content/article/[documentId]/page.tsx +++ b/apps/cms/src/app/(protected)/content/article/[documentId]/page.tsx @@ -1,6 +1,17 @@ "use client"; import {UserNotification} from "@tanam/domain-frontend"; -import {Button, Input, Loader, Notification, PageHeader, TiptapEditor} from "@tanam/ui-components"; +import { + Badge, + Button, + Input, + Loader, + Modal, + MultipleText, + Notification, + PageHeader, + TextArea, + TiptapEditor, +} from "@tanam/ui-components"; import {useParams, useRouter} from "next/navigation"; import {Suspense, useEffect, useState} from "react"; import {useCrudTanamDocument, useTanamDocument} from "../../../../../hooks/useTanamDocuments"; @@ -12,8 +23,11 @@ export default function DocumentDetailsPage() { const {update, error: writeError} = useCrudTanamDocument(); const [title, setTitle] = useState(""); + const [description, setDescription] = useState(""); + const [tags, setTags] = useState([]); + const [showModalMetadata, setShowMetadataModal] = useState(false); const [readonlyMode] = useState(false); - const [updateTitleShown, setUpdateTitleShown] = useState(false); + const [loading, setLoading] = useState(false); const [notification, setNotification] = useState(null); useEffect(() => { @@ -26,27 +40,33 @@ export default function DocumentDetailsPage() { setNotification(documentError || writeError); }, [documentError, writeError]); - useEffect(() => { - if (updateTitleShown) return; - - onDocumentTitleChange(title); - }, [updateTitleShown]); - useEffect(() => { if (document) { setTitle(document.data.title as string); + setDescription(document.data.blurb as string); + setTags(document.data.tags as string[]); } - return () => setTitle(""); - }, [document]); + return () => { + pruneState(); + }; + }, [document, showModalMetadata]); + + function pruneState() { + setTitle(""); + setDescription(""); + setTags((document?.data.tags as string[]) ?? []); + } - async function onDocumentTitleChange(title: string) { - console.log("[onDocumentTitleChange]", title); + async function fetchDocumentUpdate(title: string, blurb: string, tags: string[]) { + console.log("[fetchDocumentUpdate]", title); if (!document) { return; } document.data.title = title; + document.data.blurb = blurb; + document.data.tags = tags; await update(document); } @@ -60,6 +80,61 @@ export default function DocumentDetailsPage() { await update(document); } + function onCloseMetadataModal() { + setShowMetadataModal(false); + } + + async function onSaveMetadataModal() { + setLoading(true); + + setNotification(null); + + try { + await fetchDocumentUpdate(title, description, tags); + + setNotification(new UserNotification("success", "Update Metadata", "Success to update metadata")); + } catch (error) { + console.error(error); + setNotification(new UserNotification("error", "Update Metadata", "Failed to update metadata")); + } finally { + setLoading(false); + onCloseMetadataModal(); + } + } + + function onOpenMetadata() { + setShowMetadataModal(true); + } + + /** + * Modal actions for saving or canceling metadata changes. + * @constant + * @type {JSX.Element} + */ + const modalActionMetadata = ( +
+ {/* Start button to close the metadata modal */} +
+ ); + return ( <> {notification && ( @@ -69,27 +144,26 @@ export default function DocumentDetailsPage() { }> {document ? ( <> -
- {!updateTitleShown && } - - {updateTitleShown && ( - setTitle(e.target.value)} - /> - )} - - +
+
+ +
+ +
+ +
+ +
+

{document.data.blurb as string}

+
+ +
+ {tags.length > 0 && tags.map((tag, index) => )} +
+ +
{document?.data.content && ( @@ -100,6 +174,49 @@ export default function DocumentDetailsPage() { onChange={onDocumentContentChange} /> )} + + {/* Start modal metadata */} + +
+
+ setTitle(e.target.value)} + /> +
+ +
+