Refactors, fixes and moved some of the db code to loaders instead of exporting because they weren't repeated anyways

This commit is contained in:
Joonas 2023-11-14 20:42:45 +02:00
parent cc2e299a63
commit c102d1047f
9 changed files with 184 additions and 180 deletions

View File

@ -9,7 +9,7 @@ export function Card({
}) {
return (
<div
className={`flex z-10 flex-col bg-ctp-mantle gap-5 p-8 border w-full rounded-lg ${className}`}
className={`flex z-10 flex-col bg-ctp-mantle gap-5 p-8 border w-full rounded-md ${className}`}
>
{children}
</div>

View File

@ -20,9 +20,12 @@ export function Poster({
return (
<div className={`flex break-all items-center gap-3 ${className}`}>
<img
className="rounded-full border w-12"
className="rounded-full border w-16"
src={
pfp ? `/uploads/${encodeURIComponent(pfp)}` : `/uploads/default.png`
pfp
? `
/uploads/${encodeURIComponent(pfp)}`
: `/uploads/default.png`
}
alt="pfp"
/>
@ -50,12 +53,10 @@ export function Post({
userId,
post,
liker,
following,
}: {
post: PostWithRelations;
userId?: number;
liker?: User;
following?: { id: number }[];
}) {
const fetcher = useFetcher();
const liked = post.likes.filter((like) => like.id === userId).length > 0;

View File

@ -21,55 +21,6 @@ export async function getAllPosts() {
return posts;
}
export async function getFeed(id: number) {
const following = await prisma.user.findFirst({
where: { id: id },
select: { following: { select: { id: true } } },
});
const posts = await prisma.post.findMany({
where: {
OR: [
{
userId: {
in: [...following.following.map((user) => user.id)],
},
},
{
reposts: {
some: {
id: {
in: [...following.following.map((user) => user.id), id],
},
},
},
},
],
},
include: {
author: {
select: {
username: true,
name: true,
pfp: true,
},
},
reposts: {
select: {
id: true,
},
},
likes: {
select: {
id: true,
},
},
},
});
return posts;
}
export async function getPostById(id: number) {
const post = await prisma.post.findUnique({
where: {

View File

@ -4,103 +4,11 @@ import type { User } from "@prisma/client";
import { unlink } from "node:fs";
import { redirect } from "@remix-run/node";
export async function getUserByName(
username: string,
includePw: boolean = false
) {
export async function getUserByName(username: string) {
const user = await prisma.user.findUnique({
where: {
username: username,
},
select: {
id: true,
username: true,
password: includePw,
name: true,
desc: true,
pfp: true,
createdAt: true,
followedBy: {
select: {
id: true,
},
},
following: {
select: {
id: true,
name: true,
},
},
posts: {
include: {
author: {
select: {
username: true,
name: true,
pfp: true,
},
},
reposts: {
select: {
id: true,
},
},
likes: {
select: {
id: true,
},
},
},
},
likes: {
include: {
author: {
select: {
username: true,
name: true,
pfp: true,
},
},
reposts: {
select: {
id: true,
},
},
likes: {
select: {
id: true,
},
},
},
},
reposts: {
include: {
author: {
select: {
username: true,
name: true,
pfp: true,
},
},
reposts: {
select: {
id: true,
},
},
likes: {
select: {
id: true,
},
},
},
},
_count: {
select: {
followedBy: true,
following: true,
},
},
},
});
return user;

View File

@ -86,14 +86,14 @@ export default function App() {
const data = useLoaderData<LoaderFunction>();
return (
<html className="ctp-frappe" lang="en">
<html className="ctp-mocha" lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<body className="min-h-screen bg-ctp-crust text-ctp-text">
<body className="min-h-screen bg-ctp-base text-ctp-text">
<div className="container flex flex-col gap-20 m-8 mx-auto xl:flex-row">
<div className="flex mx-auto justify-center flex-grow w-80">
<nav className="flex w-full flex-col gap-5">
@ -106,7 +106,6 @@ export default function App() {
<>
<NavItem text={`Home`} to={`home`} />
<NavItem text={`Settings`} to={`settings`} />
<NavItem text={`Logout`} to={`logout`} />
<Poster
className="justify-center"
username={data.username}
@ -144,12 +143,16 @@ function NavItem({ to, text }: { to: string; text: string }) {
return (
<NavLink
className={({ isActive, isPending }) =>
isPending ? "pending" : isActive ? "bg-ctp-surface0 rounded-lg" : ""
isPending
? "pending"
: isActive
? "bg-ctp-surface0 rounded-lg font-black"
: ""
}
to={to}
>
<div className="px-4 w-full py-2 text-center rounded-lg border bg-ctp-surface0/40 hover:bg-ctp-surface2/25">
<SubTitle>{text}</SubTitle>
<span>{text}</span>
</div>
</NavLink>
);

View File

@ -1,7 +1,4 @@
import type {
PostWithRelations,
UserWithRelations,
} from "~/utils/prisma.server";
import { prisma, type PostWithRelations } from "~/utils/prisma.server";
import type {
ActionFunction,
ActionFunctionArgs,
@ -21,11 +18,10 @@ import { FormLabel, TextArea } from "~/components/Form";
import { Post } from "~/components/Post";
import { SubTitle, Text, Title } from "~/components/Typography";
import { likePost, unLikePost } from "~/models/like.server";
import { createPost, getFeed } from "~/models/post.server";
import { createPost } from "~/models/post.server";
import { commitSession, getSession } from "~/utils/session.server";
import type { RootLoaderTypes } from "~/root";
import { repost, unRepost } from "~/models/repost.server";
import { getUserByName } from "~/models/user.server";
export async function action({ request }: ActionFunctionArgs) {
const session = await getSession(request.headers.get("Cookie"));
@ -110,17 +106,65 @@ export async function loader({ request }: LoaderFunctionArgs) {
return redirect("/");
}
return {
feed: await getFeed(session.get("userId")),
self: await getUserByName(session.get("username")),
};
const following = await prisma.user.findFirst({
where: { id: session.get("userId") },
select: { following: { select: { id: true } } },
});
const feed = await prisma.post.findMany({
where: {
OR: [
{
userId: {
in: [...following.following.map((user) => user.id)],
},
},
{
reposts: {
some: {
id: {
in: [...following.following.map((user) => user.id)],
},
},
},
},
],
},
select: {
id: true,
text: true,
createdAt: true,
author: {
select: {
username: true,
name: true,
pfp: true,
},
},
likes: {
select: {
id: true,
},
},
reposts: {
select: {
id: true,
},
},
},
orderBy: {
createdAt: "desc",
},
});
console.log(feed);
return feed;
}
export default function Index() {
const rootData = useRouteLoaderData<RootLoaderTypes>("root");
const data: { feed: PostWithRelations[]; self: UserWithRelations } =
useLoaderData<LoaderFunction>();
console.log(data.self.following);
const data: PostWithRelations[] = useLoaderData<LoaderFunction>();
const errors = useActionData<ActionFunction>();
return (
@ -148,9 +192,9 @@ export default function Index() {
)}
</Card>
<SubTitle>Feed</SubTitle>
{data.feed.length > 0 ? (
{data.length > 0 ? (
<Card className="!p-0 !gap-0 divide-y">
{data.feed.map((post) => (
{data.map((post) => (
<Post userId={rootData?.id} key={post.id} post={post} />
))}
</Card>

View File

@ -8,7 +8,7 @@ import {
redirect,
unstable_parseMultipartFormData,
} from "@remix-run/node";
import { Form, useActionData } from "@remix-run/react";
import { Form, Link, useActionData } from "@remix-run/react";
import { Button } from "~/components/Button";
import { Card } from "~/components/Card";
import { FormInput, FormLabel } from "~/components/Form";
@ -203,6 +203,9 @@ export default function Settings() {
</Form>
</Card>
</details>
<Link to={`/logout`}>
<Text type="link">Sign out</Text>
</Link>
</div>
</div>
);

View File

@ -17,7 +17,7 @@ import { Post, Poster } from "~/components/Post";
import { SubTitle, Text, Title } from "~/components/Typography";
import { followUser, getUserByName, unFollowUser } from "~/models/user.server";
import type { RootLoaderTypes } from "~/root";
import type { UserWithRelations } from "~/utils/prisma.server";
import { prisma, type UserWithRelations } from "~/utils/prisma.server";
import { getSession } from "~/utils/session.server";
export async function action({ request }: LoaderFunctionArgs) {
@ -61,7 +61,105 @@ export async function action({ request }: LoaderFunctionArgs) {
}
export async function loader({ params }: LoaderFunctionArgs) {
const data = await getUserByName(params.username);
const data = await prisma.user.findFirst({
where: {
username: params.username,
},
select: {
id: true,
username: true,
name: true,
pfp: true,
desc: true,
createdAt: true,
posts: {
select: {
id: true,
text: true,
createdAt: true,
likes: {
select: {
id: true,
},
},
reposts: {
select: {
id: true,
},
},
author: {
select: {
id: true,
username: true,
name: true,
pfp: true,
},
},
},
},
likes: {
select: {
id: true,
text: true,
createdAt: true,
likes: {
select: {
id: true,
},
},
reposts: {
select: {
id: true,
},
},
author: {
select: {
id: true,
username: true,
name: true,
pfp: true,
},
},
},
},
reposts: {
select: {
id: true,
text: true,
createdAt: true,
likes: {
select: {
id: true,
},
},
reposts: {
select: {
id: true,
},
},
author: {
select: {
id: true,
username: true,
name: true,
pfp: true,
},
},
},
},
followedBy: {
select: {
id: true,
},
},
_count: {
select: {
followedBy: true,
following: true,
},
},
},
});
if (!data) {
throw Error(`User ${params.username} not found`);

View File

@ -7,31 +7,27 @@ export type PostWithRelations = Prisma.PostGetPayload<{
}>;
export type UserWithRelations = Prisma.UserGetPayload<{
include: {
followedBy: {
select: {
id: true;
};
};
following: {
select: {
id: true;
};
};
followedBy: true;
following: true;
posts: {
include: {
author: true;
likes: true;
reposts: true;
};
};
reposts: {
include: {
author: true;
likes: true;
reposts: true;
};
};
likes: {
include: {
author: true;
likes: true;
reposts: true;
};
};
_count: {