extracted thread reply to a component because it's used again in the index, added a sort of preview of the thread when hovering

This commit is contained in:
Joonas 2023-01-16 20:03:09 +02:00
parent 76525b9200
commit d106e9c9f2
4 changed files with 123 additions and 97 deletions

View File

@ -0,0 +1,79 @@
import { Link } from "@remix-run/react";
export function ThreadReply({ post }) {
return (
<li
id={`${post.id}`}
className="m-4 w-fit rounded border p-4 shadow odd:bg-ctp-mantle even:bg-ctp-crust"
key={post.id}
>
<div className="flex flex-wrap">
<span>
Reply id: <strong>{post.id}</strong> Replied at:{" "}
<strong>{new Date(post.createdAt).toLocaleString()} </strong>
</span>
<Link
className="mx-2 text-ctp-rosewater hover:text-ctp-maroon hover:underline"
onClick={(event) => {
event.preventDefault();
document.getElementById(`bottom`).scrollIntoView(true);
setReplying(post.id);
}}
to={`/threads/${post.postId}#bottom`}
>
Reply
</Link>
<ul className="flex flex-wrap space-x-1">
{post?.replies?.map((reply) => (
<li key={reply.id}>
<Link
onClick={(event) => {
event.preventDefault();
document.getElementById(`${reply.id}`).scrollIntoView(true);
}}
className="text-ctp-teal hover:text-ctp-sky hover:underline"
to={`#${reply.id}`}
>
#{reply.id}
</Link>
</li>
))}
</ul>
</div>
{post.replyingTo ? (
<Link
onClick={(event) => {
event.preventDefault();
document.getElementById(`${post.replyingTo}`).scrollIntoView(true);
}}
className="text-sm font-semibold hover:underline"
to={`#${post.replyingTo}`}
>
Replying to id: {post.replyingTo}
</Link>
) : (
""
)}
{post.imageName !== null ? (
<div className="flex flex-col">
<img
className="max-h-96 w-60"
src={`/uploads/${post.imageName}`}
alt="post image"
/>
<Link
className=" text-xs text-ctp-surface0"
to={`/uploads/${post.imageName}`}
target="_blank"
referrerPolicy="no-referrer"
>
Click to show full image
</Link>
</div>
) : (
""
)}
<p>{post.comment}</p>
</li>
);
}

View File

@ -65,7 +65,6 @@ export default function App() {
/>
</svg>
)}
<noscript>JS is needed for the Theme Switcher</noscript>
</button>
<Outlet />
<Scripts />

View File

@ -8,6 +8,7 @@ import {
import prisma from "~/utils/db.server";
import Overlay from "~/components/Overlay";
import { useState } from "react";
import { ThreadReply } from "~/components/ThreadReply";
export async function action({ request }) {
const clonedData = request.clone();
@ -100,7 +101,11 @@ export async function loader({ request }) {
const data = await prisma.thread.findMany({
include: {
posts: true,
posts: {
include: {
replies: true,
},
},
},
});
@ -196,30 +201,48 @@ export default function Index() {
{data.map((thread) =>
thread.title.includes(search) || thread.post.includes(search) ? (
<li
className={`m-4 scale-100 rounded-xl bg-ctp-mantle p-4 shadow-xl shadow-ctp-pink outline duration-300 hover:scale-110 hover:shadow-xl`}
className={`group m-4 scale-100 rounded-xl bg-ctp-mantle p-4 shadow-xl shadow-ctp-pink outline duration-300 hover:scale-110 hover:shadow-xl`}
key={thread.id}
>
<Link
className="flex flex-col space-y-4"
className="flex items-center justify-center gap-4 space-y-4"
to={`threads/${thread.id}`}
>
<div className="flex items-center justify-center">
<img
className="max-h-96 w-48 rounded-xl "
src={`/uploads/${thread.imageName}`}
alt="thread image"
/>
</div>
<div>
<h2 className="text-center text-2xl font-semibold tracking-tighter ">
{thread.title}
</h2>
<p className=" text-center text-ctp-subtext0">
{thread.post}
</p>
<p className=" text-center text-xs text-ctp-subtext1 ">
Posts: {thread.posts.length}
</p>
<div className="flex items-center justify-center">
<img
className="max-h-96 w-48 rounded-xl "
src={`/uploads/${thread.imageName}`}
alt="thread image"
/>
</div>
<div>
<h2 className="text-center text-2xl font-semibold tracking-tighter ">
{thread.title}
</h2>
<p className=" text-center text-ctp-subtext0">
{thread.post}
</p>
<p className=" text-center text-xs text-ctp-subtext1 ">
Posts: {thread.posts.length}
</p>
</div>
</div>
<div className="hidden flex-col items-center justify-center group-hover:flex">
<h1 className="text-center text-2xl tracking-tighter">
Last {thread.posts.slice(-3).length} post(s)
</h1>
<ul className="">
{thread.posts.length > 0 ? (
thread.posts
.slice(-3)
.map((post) => (
<ThreadReply key={post.id} post={post} />
))
) : (
<li>post has no replies yet...</li>
)}
</ul>
</div>
</Link>
</li>

View File

@ -7,6 +7,7 @@ import {
import { useLoaderData, Form, useActionData, Link } from "@remix-run/react";
import { useState } from "react";
import Overlay from "~/components/Overlay";
import { ThreadReply } from "~/components/ThreadReply";
import prisma from "~/utils/db.server";
export async function action({ request, params }) {
@ -156,83 +157,7 @@ export default function Thread() {
</div>
<ul className="m-8 ">
{data.posts.map((post) => (
<li
id={`${post.id}`}
className="m-4 w-fit rounded border p-4 shadow odd:bg-ctp-mantle even:bg-ctp-crust"
key={post.id}
>
<div className="flex flex-wrap">
<span>
Reply id: <strong>{post.id}</strong> Replied at:{" "}
<strong>{new Date(post.createdAt).toLocaleString()} </strong>
</span>
<Link
className="mx-2 text-ctp-rosewater hover:text-ctp-maroon hover:underline"
onClick={(event) => {
event.preventDefault();
document.getElementById(`bottom`).scrollIntoView(true);
setReplying(post.id);
}}
to={`#bottom`}
>
Reply
</Link>
<ul className="flex flex-wrap space-x-1">
{post?.replies?.map((reply) => (
<li key={reply.id}>
<Link
onClick={(event) => {
event.preventDefault();
document
.getElementById(`${reply.id}`)
.scrollIntoView(true);
}}
className="text-ctp-teal hover:text-ctp-sky hover:underline"
to={`#${reply.id}`}
>
#{reply.id}
</Link>
</li>
))}
</ul>
</div>
{post.replyingTo ? (
<Link
onClick={(event) => {
event.preventDefault();
document
.getElementById(`${post.replyingTo}`)
.scrollIntoView(true);
}}
className="text-sm font-semibold hover:underline"
to={`#${post.replyingTo}`}
>
Replying to id: {post.replyingTo}
</Link>
) : (
""
)}
{post.imageName !== null ? (
<div className="flex flex-col">
<img
className="max-h-96 w-60"
src={`/uploads/${post.imageName}`}
alt="post image"
/>
<Link
className=" text-xs text-ctp-surface0"
to={`/uploads/${post.imageName}`}
target="_blank"
referrerPolicy="no-referrer"
>
Click to show full image
</Link>
</div>
) : (
""
)}
<p>{post.comment}</p>
</li>
<ThreadReply key={post.id} post={post} />
))}
</ul>
</div>