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:
parent
76525b9200
commit
d106e9c9f2
|
@ -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>
|
||||
);
|
||||
}
|
|
@ -65,7 +65,6 @@ export default function App() {
|
|||
/>
|
||||
</svg>
|
||||
)}
|
||||
<noscript>JS is needed for the Theme Switcher</noscript>
|
||||
</button>
|
||||
<Outlet />
|
||||
<Scripts />
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue