import { redirect } from "@remix-run/node"; import { unstable_createFileUploadHandler, unstable_parseMultipartFormData, json, } from "@remix-run/node"; import { useLoaderData, Form, useActionData, Link } from "@remix-run/react"; import { useState } from "react"; import Overlay from "~/components/Overlay"; import prisma from "~/utils/db.server"; export async function action({ request, params }) { const threadId = params.threadId; if (!parseInt(threadId)) throw new Error("Bad route parameter"); const clonedData = request.clone(); const formData = await clonedData.formData(); const post = formData.get("post"); const replying = formData.get("replying"); const fileUploadHandler = unstable_createFileUploadHandler({ directory: "./public/uploads/", maxPartSize: 500000, file: ({ filename }) => { if (formData.get("anonymize")) return `${require("crypto").randomBytes(16).toString("hex")}.${ filename.split(".").slice(-1)[0] }`; return filename; }, filter: (data) => { const fileTypes = ["jpeg", "jpg", "png", "gif"]; // if sent file is not an image, don't handle it if (!fileTypes.includes(data.contentType.split("/")[1])) return false; return true; }, }); const errors = {}; let imageName; let multiPartformdata; try { multiPartformdata = await unstable_parseMultipartFormData( request, fileUploadHandler ); multiPartformdata.get("image") !== null ? (imageName = multiPartformdata.get("image").name) : (imageName = null); } catch (err) { errors.image = "Image size too big"; } if (typeof post !== "string" || post.length > 50 || post.length < 3) { errors.post = "Post too long or short"; } if (replying !== "") { let currentThreadreplyids = []; const currentThread = await prisma.thread.findUnique({ where: { id: parseInt(threadId), }, include: { posts: true, }, }); currentThread.posts.map((post) => currentThreadreplyids.push(post.id)); if ( typeof replying !== "string" || !parseInt(replying) || !currentThreadreplyids.includes(parseInt(replying)) ) { errors.replying = "bad reply id"; } } if (Object.keys(errors).length) { return json(errors, { status: 422 }); } const createPost = await prisma.post.create({ data: { comment: post, imageName: imageName, replyingTo: replying ? parseInt(replying) : null, postId: parseInt(threadId), }, }); return redirect(`/threads/${threadId}`); } export async function loader({ params }) { const threadId = params.threadId; if (!parseInt(threadId)) throw new Error("Bad route parameter"); const thread = await prisma.thread.findUnique({ where: { id: parseInt(threadId), }, include: { posts: { include: { replies: true, }, }, }, }); if (!thread) { throw new Error("Thread not found"); } return thread; } export default function Thread() { const data = useLoaderData(); const actionData = useActionData(); const [replying, setReplying] = useState(); return (
{data.title} Post id: {data.id}{" "} Created at:{" "} {new Date(data.createdAt).toLocaleString()} Reply count: {data.posts.length}
post image Click to show full image

{data.post}