added validation for route params and replyingid

This commit is contained in:
Joonas 2023-01-14 19:20:29 +02:00
parent 9aaf065654
commit 901a569900
3 changed files with 32 additions and 20 deletions

View File

@ -7,7 +7,7 @@ export default function Header() {
</div>
<div className="">
<h1 className="text-4xl font-bold text-ctp-lavender">Lauta</h1>
<h1 className="text-4xl font-bold">Lauta</h1>
</div>
<nav className="flex-1 flex justify-end">
<Link className="text-ctp-blue hover:underline hover:text-ctp-teal" to={'/'}>threads</Link>

View File

@ -1,10 +1,7 @@
import { useLoaderData, useActionData, Form } from "@remix-run/react";
import { unstable_createFileUploadHandler, unstable_parseMultipartFormData } from "@remix-run/node";
import { useLoaderData, useActionData, Form, Link } from "@remix-run/react";
import { unstable_createFileUploadHandler, unstable_parseMultipartFormData, json, redirect } from "@remix-run/node";
import prisma from "~/utils/db.server";
import { redirect } from "@remix-run/node";
import { Link } from "@remix-run/react";
import Overlay from "~/components/Overlay";
import { json } from "@remix-run/node";
export async function action({ request }) {
const clonedData = request.clone();
@ -94,10 +91,10 @@ export default function Index() {
{data.length > 0 ?
<ul className="flex flex-wrap justify-around items-center p-8">
{data.map(thread =>
<li className="bg-ctp-mantle shadow-xl outline shadow-ctp-pink rounded-xl p-4 m-4 hover:shadow-xl scale-100 hover:scale-110 duration-500" key={thread.id}>
<li className="bg-ctp-mantle shadow-xl outline shadow-ctp-pink rounded-xl p-4 m-4 hover:shadow-xl scale-100 hover:scale-110 duration-300" key={thread.id}>
<Link className="space-y-4 flex flex-col" to={`threads/${thread.id}`}>
<div className="flex items-center justify-center">
<img className="w-48 max-h-96 rounded-xl " src={`/uploads/${thread.imageName}`} alt="" />
<img className="w-48 max-h-96 rounded-xl " src={`/uploads/${thread.imageName}`} alt="thread image" />
</div>
<div>
<h2 className="text-2xl font-semibold text-center tracking-tighter ">{thread.title}</h2>

View File

@ -1,17 +1,18 @@
import { redirect, unstable_createFileUploadHandler, unstable_parseMultipartFormData, json } from "@remix-run/node";
import { useLocation } from "@remix-run/react";
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 { useEffect, useState } from "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");
let replying = formData.get("replying");
const fileUploadHandler = unstable_createFileUploadHandler({
directory: './public/uploads/',
@ -27,6 +28,7 @@ export async function action({ request, params }) {
});
const errors = {};
let imageName;
let multiPartformdata;
try {
@ -34,15 +36,26 @@ export async function action({ request, params }) {
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";
};
const currentThread = await prisma.thread.findUnique({
where: {
id: parseInt(threadId),
},
include: {
posts: true
},
});
if (typeof replying !== "string" || !parseInt(replying) || parseInt(replying) > currentThread.posts.length ) {
replying = ""
};
if (Object.keys(errors).length) {
return json(errors, { status: 422 });
}
};
const createPost = await prisma.post.create({
data: {
@ -53,11 +66,13 @@ export async function action({ request, params }) {
},
});
return createPost;
return redirect(`/threads/${threadId}#${createPost.id}`);
};
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),
@ -72,7 +87,7 @@ export async function loader({ params }) {
});
if (!thread) {
return redirect('/')
throw new Error('Thread not found')
}
return thread;
@ -144,14 +159,14 @@ export default function Thread() {
</label>
<details class="flex items-center justify-center duration-300">
<summary className="text-center text-ctp-subtext0 font-semibold cursor-pointer">Manual replying (needed when JS is disabled)</summary>
<div class="flex items-center justify-center">
<div class="flex flex-col items-center justify-center">
<input className="bg-ctp-surface0 m-1 p-1 rounded shadow shadow-ctp-overlay0" placeholder="Enter a Reply ID" type="number" name="replying" value={replying} />
</div>
</details>
{actionData?.replying}
<button className="bg-white px-4 py-2 shadow rounded-full" type="submit">Submit</button>
</Form>
</Overlay>
);
}
};