import Compressor from "compressorjs"; import { X } from "lucide-react"; import { nanoid } from "nanoid"; import * as React from "react"; import { useTranslation } from "react-i18next"; import type { MetaFunction } from "react-router"; import { Form, useFetcher, useLoaderData } from "react-router"; import { Alert } from "~/components/Alert"; import { SendouButton } from "~/components/elements/Button"; import { SendouSwitch } from "~/components/elements/Switch"; import { UserSearch } from "~/components/elements/UserSearch"; import { FormMessage } from "~/components/FormMessage"; import { Label } from "~/components/Label"; import { Main } from "~/components/Main"; import { useHasRole } from "~/modules/permissions/hooks"; import invariant from "~/utils/invariant"; import { logger } from "~/utils/logger"; import type { SendouRouteHandle } from "~/utils/remix.server"; import { artPage, navIconUrl } from "~/utils/urls"; import { metaTitle } from "../../../utils/remix"; import { action } from "../actions/art.new.server"; import { ART } from "../art-constants"; import { previewUrl } from "../art-utils"; import { TagSelect } from "../components/TagSelect"; import { loader } from "../loaders/art.new.server"; export { action, loader }; export const handle: SendouRouteHandle = { i18n: ["art"], breadcrumb: () => ({ imgPath: navIconUrl("art"), href: artPage(), type: "IMAGE", }), }; export const meta: MetaFunction = () => { return metaTitle({ title: "New art", }); }; export default function NewArtPage() { const data = useLoaderData(); const [img, setImg] = React.useState(null); const [smallImg, setSmallImg] = React.useState(null); const { t } = useTranslation(["common", "art"]); const ref = React.useRef(null); const fetcher = useFetcher(); const isArtist = useHasRole("ARTIST"); const handleSubmit = () => { const formData = new FormData(ref.current!); if (img) formData.append("img", img, img.name); if (smallImg) formData.append("smallImg", smallImg, smallImg.name); fetcher.submit(formData, { encType: "multipart/form-data", method: "post", }); }; const submitButtonDisabled = () => { if (fetcher.state !== "idle") return true; return !img && !data.art; }; if (!isArtist) { return (
{t("art:gainPerms")}
); } return (
{t("art:forms.caveats")} {data.art ? : null}
{t("common:actions.save")}
); } function ImageUpload({ img, setImg, setSmallImg, }: { img: File | null; setImg: (file: File | null) => void; setSmallImg: (file: File | null) => void; }) { const data = useLoaderData(); const { t } = useTranslation(["common"]); const id = React.useId(); if (data.art) { return ; } return (
{ const uploadedFile = e.target.files?.[0]; if (!uploadedFile) { setImg(null); return; } new Compressor(uploadedFile, { success(result) { invariant(result instanceof Blob); const file = new File([result], uploadedFile.name); setImg(file); }, error(err) { logger.error(err.message); }, }); new Compressor(uploadedFile, { maxWidth: ART.THUMBNAIL_WIDTH, success(result) { invariant(result instanceof Blob); const file = new File([result], uploadedFile.name); setSmallImg(file); }, error(err) { logger.error(err.message); }, }); }} /> {img && }
); } function Description() { const { t } = useTranslation(["art"]); const data = useLoaderData(); const [value, setValue] = React.useState(data.art?.description ?? ""); const id = React.useId(); return (