Added simple admin page
continuous-integration/drone/push Build is passing Details

main
Guus van Meerveld 2 years ago
parent fd47f81e38
commit 6340d248fd
Signed by: Guusvanmeerveld
GPG Key ID: 2BA7D7912771966E

@ -17,7 +17,7 @@ const Post: FC<{
<div className="columns mt-2"> <div className="columns mt-2">
<div <div
className={multipleClassNames( className={multipleClassNames(
"column col-4 col-md-6 col-ml-auto bg-gray", "column col-4 col-md-12 col-ml-auto bg-gray",
styles.body styles.body
)} )}
> >
@ -39,7 +39,7 @@ const Post: FC<{
</div> </div>
<div <div
className={multipleClassNames( className={multipleClassNames(
"column col-4 col-md-6 col-mr-auto bg-gray", "column col-4 col-md-12 col-mr-auto bg-gray",
styles.body, styles.body,
styles.info styles.info
)} )}

@ -35,7 +35,8 @@ const handle: NextApiHandler = async (req, res) => {
create: { create: {
...data, ...data,
published: data.published !== undefined, published: data.published !== undefined,
tags: data.tags.trim().split(" ") tags: data.tags.trim().split(" "),
content: data.content.trim()
} }
} }
} }

@ -24,6 +24,7 @@ const PostPage: NextPage<{
<div className="column col-2" /> <div className="column col-2" />
<div className="column col-6 col-md-12"> <div className="column col-6 col-md-12">
<h1>{post.title}</h1> <h1>{post.title}</h1>
<div className="divider" />
<h4> <h4>
by {post.author.name} on{" "} by {post.author.name} on{" "}
{new Date(post.createdAt).toLocaleDateString()} {new Date(post.createdAt).toLocaleDateString()}

@ -0,0 +1,3 @@
.body {
padding: 10rem 0;
}

@ -8,14 +8,79 @@ import Layout from "@components/Layout";
import { withSessionSsr } from "@utils/session"; import { withSessionSsr } from "@utils/session";
import prisma from "@utils/prisma"; import prisma from "@utils/prisma";
const AdminPage: NextPage<{ user: User; posts: Post & { author: User } }> = ({ import styles from "./admin.module.scss";
user,
posts const AdminPage: NextPage<{
}) => { user: User;
users: User[];
posts: (Post & { author: User })[];
}> = ({ user, users, posts }) => {
return ( return (
<Layout> <Layout>
<NextSeo title="Admin" /> <NextSeo title="Admin" />
Welcome {user.name} <div className={styles.body}>
<div className="container">
<div className="columns">
<div className="col col-8 col-mx-auto">
<h3>Welcome {user.name}</h3>
</div>
<div className="col col-8 col-mx-auto py-2">
<h4>Users</h4>
<table className="table table-striped table-hover mb-2">
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>email</th>
<th>admin</th>
<th>postCount</th>
</tr>
</thead>
<tbody>
{users.map((user, i) => (
<tr key={user.id} className={i % 2 === 0 ? "active" : ""}>
<td>{user.id}</td>
<td>{user.name}</td>
<td>{user.email}</td>
<td>{user.admin ? "true" : "false"}</td>
<td>0</td>
</tr>
))}
</tbody>
</table>
</div>
<div className="col col-8 col-mx-auto">
<h4>Posts</h4>
<table className="table table-striped table-hover">
<thead>
<tr>
<th>id</th>
<th>title</th>
<th>content</th>
<th>published</th>
<th>createdAt</th>
<th>tags</th>
<th>author</th>
</tr>
</thead>
<tbody>
{posts.map((post, i) => (
<tr key={post.id} className={i % 2 === 0 ? "active" : ""}>
<td>{post.id}</td>
<td>{post.title}</td>
<td>{post.content}</td>
<td>{post.published ? "true" : "false"}</td>
<td>{new Date(post.createdAt).toLocaleString()}</td>
<td>{post.tags}</td>
<td>{post.author.name}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</div>
</Layout> </Layout>
); );
}; };
@ -31,7 +96,23 @@ export const getServerSideProps = withSessionSsr(async ({ req }) => {
include: { author: true } include: { author: true }
}); });
return { props: { user, posts } }; const users = await prisma.user.findMany({
orderBy: { id: "desc" },
take: 5
});
return {
props: {
user,
users,
posts: posts.map((post) => ({
...post,
createdAt: post.createdAt.getTime(),
tags: post.tags.join(", "),
content: post.content?.slice(0, 100).concat("...")
}))
}
};
}); });
export default AdminPage; export default AdminPage;

@ -1,4 +1,10 @@
.body { .body {
padding: 10rem 1rem; padding: 10rem 1rem;
@media (max-width: 840px) {
padding: 2rem 1rem;
}
min-height: 100vh; min-height: 100vh;
} }

@ -67,7 +67,7 @@ export const getStaticProps: GetStaticProps = async (
posts: posts.map((post) => ({ posts: posts.map((post) => ({
...post, ...post,
createdAt: post.createdAt.toString(), createdAt: post.createdAt.toString(),
content: post.content?.split("\n")[0] content: post.content?.trim().split("\n")[0]
})) }))
}, },
revalidate: 60 * 1 revalidate: 60 * 1

@ -43,6 +43,19 @@
border-color: $bg-dark-secondary; border-color: $bg-dark-secondary;
} }
.table {
td,
th {
border-color: lighten($bg-dark-secondary, 10%);
}
}
.table tbody tr.active,
.table.table-striped tbody tr.active {
background: $bg-dark-secondary
}
a:hover { a:hover {
color: $primary-color-dark; color: $primary-color-dark;
} }

@ -3,4 +3,8 @@
@import "variables"; @import "variables";
@import "dark"; @import "dark";
p {
line-height: 1.25rem;
}
Loading…
Cancel
Save