import { useEffect, useRef, useState } from "react"; import { MdAdd, MdClose, MdContentCopy, MdDelete, MdOutlineInfo, } from "react-icons/md"; import { Tag } from "../network/models.ts"; import { network } from "../network/network.ts"; import { useNavigate } from "react-router"; import { useTranslation } from "react-i18next"; import { app } from "../app.ts"; import { ErrorAlert } from "../components/alert.tsx"; import { useAppContext } from "../components/AppContext.tsx"; import TagInput, { QuickAddTagDialog } from "../components/tag_input.tsx"; import { ImageDropArea, SelectAndUploadImageButton, UploadClipboardImageButton, } from "../components/image_selector.tsx"; export default function PublishPage() { const [title, setTitle] = useState(""); const [altTitles, setAltTitles] = useState([]); const [tags, setTags] = useState([]); const [article, setArticle] = useState(""); const [images, setImages] = useState([]); const [links, setLinks] = useState<{ label: string; url: string }[]>([]); const [error, setError] = useState(null); const [isSubmitting, setSubmitting] = useState(false); const isFirstLoad = useRef(true); useEffect(() => { if (isFirstLoad.current) { const oldData = localStorage.getItem("publish_data"); if (oldData) { try { const data = JSON.parse(oldData); setTitle(data.title || ""); setAltTitles(data.alternative_titles || []); setTags(data.tags || []); setArticle(data.article || ""); setImages(data.images || []); } catch (e) { console.error("Failed to parse publish_data from localStorage", e); } } isFirstLoad.current = false; } else { const data = { title: title, alternative_titles: altTitles, tags: tags, article: article, images: images, }; const dataString = JSON.stringify(data); localStorage.setItem("publish_data", dataString); } }, [altTitles, article, images, tags, title]); const navigate = useNavigate(); const { t } = useTranslation(); const appContext = useAppContext(); useEffect(() => { document.title = t("Publish Resource"); }, [t]); const handleSubmit = async () => { if (isSubmitting) { return; } if (!title) { setError(t("Title cannot be empty")); return; } for (let i = 0; i < altTitles.length; i++) { if (!altTitles[i]) { setError(t("Alternative title cannot be empty")); return; } } for (let i = 0; i < links.length; i++) { if (!links[i].label || !links[i].url) { setError(t("Link cannot be empty")); return; } } if (!tags || tags.length === 0) { setError(t("At least one tag required")); return; } if (!article) { setError(t("Description cannot be empty")); return; } setSubmitting(true); const res = await network.createResource({ title: title, alternative_titles: altTitles, tags: tags.map((tag) => tag.id), article: article, images: images, links: links, }); if (res.success) { localStorage.removeItem("publish_data"); setSubmitting(false); appContext.clear(); navigate("/resources/" + res.data!, { replace: true }); } else { setSubmitting(false); setError(res.message); } }; if (!app.user) { return ( ); } if (!app.canUpload()) { return ( ); } return ( { setImages((prev) => [...prev, ...images]); }} >

{t("Publish Resource")}

{t("All information can be modified after publishing")}

{t("Title")}

setTitle(e.target.value)} />

{t("Alternative Titles")}

{altTitles.map((title, index) => { return (
{ const newAltTitles = [...altTitles]; newAltTitles[index] = e.target.value; setAltTitles(newAltTitles); }} />
); })}

{t("Links")}

{links.map((link, index) => { return (
{ const newLinks = [...links]; newLinks[index].label = e.target.value; setLinks(newLinks); }} /> { const newLinks = [...links]; newLinks[index].url = e.target.value; setLinks(newLinks); }} />
); })}

{t("Tags")}

{tags.map((tag, index) => { return ( {tag.name} { const newTags = [...tags]; newTags.splice(index, 1); setTags(newTags); }} > ); })}

{ setTags((prev) => { const existingTag = prev.find((t) => t.id === tag.id); if (existingTag) { return prev; // If the tag already exists, do not add it again } return [...prev, tag]; }); }} /> { setTags((prev) => { const newTags = [...prev]; for (const tag of tags) { const existingTag = newTags.find((t) => t.id === tag.id); if (!existingTag) { newTags.push(tag); } } return newTags; }); }} />

{t("Description")}