From 7eeadbe065644146263f7b2914949d33cf9df3a1 Mon Sep 17 00:00:00 2001 From: Max Leiter Date: Sun, 4 Dec 2022 01:55:20 -0800 Subject: [PATCH] Add basic /author/{id} page --- client/app/(posts)/new/components/new.tsx | 2 +- .../[id]/components/header/title/index.tsx | 28 ++++++++------ client/app/(posts)/post/[id]/page.tsx | 6 ++- client/app/author/[username]/page.tsx | 38 +++++++++++++++++++ client/app/components/post-list/index.tsx | 8 ++-- client/lib/server/prisma.ts | 10 +++-- client/pages/api/post/search.ts | 20 ++++++++-- 7 files changed, 86 insertions(+), 26 deletions(-) create mode 100644 client/app/author/[username]/page.tsx diff --git a/client/app/(posts)/new/components/new.tsx b/client/app/(posts)/new/components/new.tsx index d00f70b8..689d5d2a 100644 --- a/client/app/(posts)/new/components/new.tsx +++ b/client/app/(posts)/new/components/new.tsx @@ -37,7 +37,7 @@ const Post = ({ initialPost?: string newPostParent?: string }) => { - const parsedPost = JSON.parse(stringifiedInitialPost || "{}") + const parsedPost = JSON.parse(stringifiedInitialPost || "{}") const initialPost = parsedPost?.id ? parsedPost : null const { setToast } = useToasts() const router = useRouter() diff --git a/client/app/(posts)/post/[id]/components/header/title/index.tsx b/client/app/(posts)/post/[id]/components/header/title/index.tsx index 4269f6cd..f2babd47 100644 --- a/client/app/(posts)/post/[id]/components/header/title/index.tsx +++ b/client/app/(posts)/post/[id]/components/header/title/index.tsx @@ -1,8 +1,9 @@ -import CreatedAgoBadge from '@components/badges/created-ago-badge' -import ExpirationBadge from '@components/badges/expiration-badge' -import VisibilityBadge from '@components/badges/visibility-badge' -import Skeleton from '@components/skeleton' -import styles from './title.module.css' +import CreatedAgoBadge from "@components/badges/created-ago-badge" +import ExpirationBadge from "@components/badges/expiration-badge" +import VisibilityBadge from "@components/badges/visibility-badge" +import Link from "@components/link" +import Skeleton from "@components/skeleton" +import styles from "./title.module.css" type TitleProps = { title: string @@ -11,22 +12,25 @@ type TitleProps = { visibility?: string createdAt?: Date expiresAt?: Date + authorId?: string } export const PostTitle = ({ - title, - displayName, - visibility, - createdAt, - expiresAt, - loading + title, + displayName, + visibility, + createdAt, + expiresAt, + loading, + authorId }: TitleProps) => { return (

{title}{" "} - by {displayName || "anonymous"} + by{" "} + {displayName || "anonymous"}

{!loading && ( diff --git a/client/app/(posts)/post/[id]/page.tsx b/client/app/(posts)/post/[id]/page.tsx index 9bc5b3c6..273d9ae1 100644 --- a/client/app/(posts)/post/[id]/page.tsx +++ b/client/app/(posts)/post/[id]/page.tsx @@ -65,9 +65,10 @@ const getPost = async (id: string) => { title: "", createdAt: new Date("1970-01-01"), author: { - displayName: "" + displayName: "", }, - description: "" + description: "", + authorId: "", }, isProtected: true, isAuthor: isAuthorOrAdmin @@ -110,6 +111,7 @@ const PostView = async ({ createdAt={post.createdAt} displayName={post.author?.displayName || ""} visibility={post.visibility} + authorId={post.authorId} /> {post.description && ( diff --git a/client/app/author/[username]/page.tsx b/client/app/author/[username]/page.tsx new file mode 100644 index 00000000..6ec95ecf --- /dev/null +++ b/client/app/author/[username]/page.tsx @@ -0,0 +1,38 @@ +import PostList from "@components/post-list" +import { getPostsByUser, getUserById } from "@lib/server/prisma" +import { Suspense } from "react" + +async function PostListWrapper({ + posts, + userId, +}: { + posts: ReturnType + userId: string +}) { + const data = (await posts).filter((post) => post.visibility === "public") + return +} + +export default async function UserPage({ + params +}: { + params: { + username: string + } +}) { + // TODO: the route should be user.name, not id + const id = params.username + const user = await getUserById(id) + + const posts = getPostsByUser(id, true) + + return ( + <> +

{user?.displayName}'s public posts

+ }> + {/* @ts-ignore because TS async JSX support is iffy */} + + + + ) +} diff --git a/client/app/components/post-list/index.tsx b/client/app/components/post-list/index.tsx index f519c5c3..60e6b1f8 100644 --- a/client/app/components/post-list/index.tsx +++ b/client/app/components/post-list/index.tsx @@ -1,7 +1,6 @@ "use client" import styles from "./post-list.module.css" -import { ListItemSkeleton } from "./list-item-skeleton" import ListItem from "./list-item" import { ChangeEvent, useCallback, useEffect, useState } from "react" import useDebounce from "@lib/hooks/use-debounce" @@ -10,10 +9,11 @@ import type { PostWithFiles } from "@lib/server/prisma" import Input from "@components/input" import Button from "@components/button" import { useToasts } from "@components/toasts" +import { ListItemSkeleton } from "./list-item-skeleton" type Props = { initialPosts: string | PostWithFiles[] - morePosts: boolean + morePosts?: boolean userId?: string } @@ -120,12 +120,12 @@ const PostList = ({ /> {!posts &&

Failed to load.

} - {/* {!posts?.length && ( + {!posts?.length && (
- )} */} + )} {posts?.length === 0 && posts && (

No posts found. Create one{" "} diff --git a/client/lib/server/prisma.ts b/client/lib/server/prisma.ts index 3122fa6f..7fc8574f 100644 --- a/client/lib/server/prisma.ts +++ b/client/lib/server/prisma.ts @@ -218,10 +218,12 @@ export const searchPosts = async ( query: string, { withFiles = false, - userId + userId, + publicOnly }: { withFiles?: boolean userId?: User["id"] + publicOnly?: boolean } = {} ): Promise => { const posts = await prisma.post.findMany({ @@ -231,7 +233,8 @@ export const searchPosts = async ( title: { search: query }, - authorId: userId + authorId: userId, + visibility: publicOnly ? "public" : undefined }, { files: { @@ -241,7 +244,8 @@ export const searchPosts = async ( }, userId: userId } - } + }, + visibility: publicOnly ? "public" : undefined } ] }, diff --git a/client/pages/api/post/search.ts b/client/pages/api/post/search.ts index 12d43386..5b6229e8 100644 --- a/client/pages/api/post/search.ts +++ b/client/pages/api/post/search.ts @@ -1,11 +1,14 @@ import { withMethods } from "@lib/api-middleware/with-methods" import { parseQueryParam } from "@lib/server/parse-query-param" -import { searchPosts } from "@lib/server/prisma" +import { PostWithFiles, searchPosts } from "@lib/server/prisma" import { NextApiRequest, NextApiResponse } from "next" +import { getSession } from "next-auth/react" const handler = async (req: NextApiRequest, res: NextApiResponse) => { const { q, userId } = req.query + const session = await getSession() + const query = parseQueryParam(q) if (!query) { res.status(400).json({ error: "Invalid query" }) @@ -13,9 +16,18 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { } try { - const posts = await searchPosts(query, { - userId: parseQueryParam(userId), - }) + let posts: PostWithFiles[] + if (session?.user.id === userId || session?.user.role === "admin") { + posts = await searchPosts(query, { + userId: parseQueryParam(userId), + publicOnly: true + }) + } else { + posts = await searchPosts(query, { + userId: parseQueryParam(userId), + publicOnly: true + }) + } res.status(200).json(posts) } catch (err) {