From 6afc4c915e75783a93d9929e215a3b2fba980c24 Mon Sep 17 00:00:00 2001 From: Max Leiter Date: Tue, 29 Mar 2022 00:11:02 -0700 Subject: [PATCH] client/server: search cleanup, admin work --- client/components/admin/admin.module.css | 11 ++++ client/components/admin/index.tsx | 37 +++++++++--- client/components/admin/post-modal-link.tsx | 51 +++++++++++++++++ client/components/header/header.tsx | 1 + .../new-post/drag-and-drop/index.tsx | 4 +- client/components/post-list/index.tsx | 2 +- docker-compose.yml | 4 +- drift.sqlite | Bin 45056 -> 5603328 bytes server/src/routes/admin.ts | 54 +++++++++++++++++- server/src/routes/auth.ts | 2 +- server/src/routes/posts.ts | 43 +++++++++++--- 11 files changed, 186 insertions(+), 23 deletions(-) create mode 100644 client/components/admin/post-modal-link.tsx diff --git a/client/components/admin/admin.module.css b/client/components/admin/admin.module.css index 57d378dc..9c4cb99d 100644 --- a/client/components/admin/admin.module.css +++ b/client/components/admin/admin.module.css @@ -12,3 +12,14 @@ color: var(--gray-dark); font-weight: bold; } + +.postModal details { + border-radius: var(--radius); + padding: var(--gap); + border-radius: var(--radius); +} + +.postModal summary { + cursor: pointer; + outline: none; +} diff --git a/client/components/admin/index.tsx b/client/components/admin/index.tsx index ffff89e4..28338a61 100644 --- a/client/components/admin/index.tsx +++ b/client/components/admin/index.tsx @@ -1,10 +1,12 @@ import { Text, Fieldset, Spacer, Link } from '@geist-ui/core' -import getPostPath from '@lib/get-post-path' import { Post, User } from '@lib/types' import Cookies from 'js-cookie' +import { useEffect, useState } from 'react' import useSWR from 'swr' import styles from './admin.module.css' -const fetcher = (url: string) => fetch(url, { +import PostModal from './post-modal-link' + +export const adminFetcher = (url: string) => fetch(url, { method: "GET", headers: { "Content-Type": "application/json", @@ -13,9 +15,21 @@ const fetcher = (url: string) => fetch(url, { }).then(res => res.json()) const Admin = () => { - const { data: posts, error } = useSWR('/server-api/admin/posts', fetcher) - const { data: users, error: errorUsers } = useSWR('/server-api/admin/users', fetcher) - console.log(posts, error) + const { data: posts, error: postsError } = useSWR('/server-api/admin/posts', adminFetcher) + const { data: users, error: usersError } = useSWR('/server-api/admin/users', adminFetcher) + const [postSizes, setPostSizes] = useState<{ [key: string]: number }>({}) + const byteToMB = (bytes: number) => Math.round(bytes / 1024 / 1024 * 100) / 100 + useEffect(() => { + if (posts) { + // sum the sizes of each file per post + const sizes = posts.reduce((acc, post) => { + const size = post.files.reduce((acc, file) => acc + file.html.length, 0) + return { ...acc, [post.id]: byteToMB(size) } + }, {}) + setPostSizes(sizes) + } + }, [posts]) + return (
Administration @@ -23,6 +37,7 @@ const Admin = () => { Users {users && {users.length} users} {!users && Loading...} + {usersError && An error occured} {users && @@ -50,6 +65,7 @@ const Admin = () => { Posts {posts && {posts.length} posts} {!posts && Loading...} + {postsError && An error occured} {posts &&
@@ -57,19 +73,24 @@ const Admin = () => { + - {posts?.map(post => ( + {posts?.map((post, i) => ( - + - + + ))}
Visibility Created AuthorSize
{post.title} {post.visibility} {new Date(post.createdAt).toLocaleDateString()} {new Date(post.createdAt).toLocaleTimeString()}{post.users ? post.users[0].username : ''}{post.users?.length ? post.users[0].username : Deleted}{postSizes[post.id] ? `${postSizes[post.id]} MB` : ''}
} + {Object.keys(postSizes).length &&
+ Total size: {Object.values(postSizes).reduce((prev, curr) => prev + curr)} MB +
}
diff --git a/client/components/admin/post-modal-link.tsx b/client/components/admin/post-modal-link.tsx new file mode 100644 index 00000000..e1d3a5b0 --- /dev/null +++ b/client/components/admin/post-modal-link.tsx @@ -0,0 +1,51 @@ +import { Link, Modal, useModal } from "@geist-ui/core"; +import { Post } from "@lib/types"; +import Cookies from "js-cookie"; +import useSWR from "swr"; +import { adminFetcher } from "."; +import styles from './admin.module.css' + +const PostModal = ({ id }: { + id: string, +}) => { + const { visible, setVisible, bindings } = useModal() + const { data: post, error } = useSWR(`/server-api/admin/post/${id}`, adminFetcher) + if (error) return failed to load + if (!post) return loading... + + const deletePost = async () => { + await fetch(`/server-api/admin/post/${id}`, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${Cookies.get("drift-token")}`, + } + }) + setVisible(false) + } + + return ( + <> + setVisible(true)}>{post.title} + + {post.title} + Click an item to expand + {post.files.map((file) => ( +
+ +
+ {file.title} +
+
+
+
+
+ ) + )} + Delete + setVisible(false)}>Close +
+ ) +} + +export default PostModal \ No newline at end of file diff --git a/client/components/header/header.tsx b/client/components/header/header.tsx index a0d35949..2a6ffa10 100644 --- a/client/components/header/header.tsx +++ b/client/components/header/header.tsx @@ -40,6 +40,7 @@ const Header = () => { const userData = useUserData(); const [pages, setPages] = useState([]) const { setTheme, theme } = useTheme() + useEffect(() => { setBodyHidden(expanded) }, [expanded, setBodyHidden]) diff --git a/client/components/new-post/drag-and-drop/index.tsx b/client/components/new-post/drag-and-drop/index.tsx index dfc0f465..6c65b4a4 100644 --- a/client/components/new-post/drag-and-drop/index.tsx +++ b/client/components/new-post/drag-and-drop/index.tsx @@ -33,12 +33,14 @@ function FileDropzone({ setDocs }: { setDocs: ((docs: Document[]) => void) }) { } const validator = (file: File) => { + const byteToMB = (bytes: number) => Math.round(bytes / 1024 / 1024 * 100) / 100 + // TODO: make this configurable const maxFileSize = 50000000; if (file.size > maxFileSize) { return { code: 'file-too-big', - message: 'File is too big. Maximum file size is ' + (maxFileSize).toFixed(2) + ' MB.', + message: 'File is too big. Maximum file size is ' + byteToMB(maxFileSize) + ' MB.', } } diff --git a/client/components/post-list/index.tsx b/client/components/post-list/index.tsx index ce0b1157..6918580b 100644 --- a/client/components/post-list/index.tsx +++ b/client/components/post-list/index.tsx @@ -117,7 +117,7 @@ const PostList = ({ morePosts, initialPosts, error }: Props) => { } - {posts?.length === 0 && !error && No posts found.Create one here.} + {posts?.length === 0 && !error && No posts found. Create one here.} { posts?.length > 0 &&