Post permissions

This commit is contained in:
Max Leiter 2022-03-06 22:16:08 -08:00
parent 171946a38e
commit ecd89fdf0e
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS.
GPG key ID: A3512F2F2F17EBDA
6 changed files with 76 additions and 43 deletions

View file

@ -10,9 +10,10 @@ type Props = {
content?: string content?: string
setTitle?: (title: string) => void setTitle?: (title: string) => void
setContent?: (content: string) => void setContent?: (content: string) => void
initialTab?: "edit" | "preview"
} }
const Document = ({ remove, editable, title, content, setTitle, setContent }: Props) => { const Document = ({ remove, editable, title, content, setTitle, setContent, initialTab = 'edit' }: Props) => {
const codeEditorRef = useRef<HTMLTextAreaElement>(null) const codeEditorRef = useRef<HTMLTextAreaElement>(null)
const removeFile = (remove?: () => void) => { const removeFile = (remove?: () => void) => {
@ -45,7 +46,7 @@ const Document = ({ remove, editable, title, content, setTitle, setContent }: Pr
{remove && editable && <Button type="error" ghost icon={<Trash />} auto height={'36px'} width={'36px'} onClick={() => removeFile(remove)} />} {remove && editable && <Button type="error" ghost icon={<Trash />} auto height={'36px'} width={'36px'} onClick={() => removeFile(remove)} />}
</div> </div>
<div className={styles.descriptionContainer}> <div className={styles.descriptionContainer}>
<Tabs initialValue="edit" hideDivider width={"100%"} > <Tabs initialValue={initialTab} hideDivider width={"100%"} >
<Tabs.Item label={editable ? "Edit" : "Raw"} value="edit"> <Tabs.Item label={editable ? "Edit" : "Raw"} value="edit">
{/* <textarea className={styles.lineCounter} wrap='off' readOnly ref={lineNumberRef}>1.</textarea> */} {/* <textarea className={styles.lineCounter} wrap='off' readOnly ref={lineNumberRef}>1.</textarea> */}
<Textarea <Textarea

View file

@ -1,13 +0,0 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from 'next'
type Data = {
name: string
}
export default function handler(
req: NextApiRequest,
res: NextApiResponse<Data>
) {
res.status(200).json({ name: 'John Doe' })
}

View file

@ -1,18 +1,48 @@
import { Badge, Page, Text } from "@geist-ui/core"; import { Loading, Page, Text } from "@geist-ui/core";
import { GetServerSidePropsContext } from "next" import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import Document from '../../components/document' import Document from '../../components/document'
import Header from "../../components/header"; import Header from "../../components/header";
import VisibilityBadge from "../../components/visibility-badge"; import VisibilityBadge from "../../components/visibility-badge";
import { ThemeProps } from "../_app"; import { ThemeProps } from "../_app";
type Props = ThemeProps & { const Post = ({ theme, changeTheme }: ThemeProps) => {
post: any const [post, setPost] = useState<any>()
} const [isLoading, setIsLoading] = useState(true)
const [error, setError] = useState<string>()
const router = useRouter();
const Post = ({ post, theme, changeTheme }: Props) => { useEffect(() => {
if (!post.files) { async function fetchPost() {
return <div>No files</div> setIsLoading(true);
} if (router.query.id) {
const post = await fetch(`/api/posts/${router.query.id}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${localStorage.getItem("drift-token")}`
}
})
if (post.ok) {
const res = await post.json()
if (res)
setPost(res)
else
setError("Post not found")
} else {
if (post.status.toString().startsWith("4")) {
router.push("/signin")
} else {
setError(post.statusText)
}
}
setIsLoading(false)
}
}
fetchPost()
}, [router, router.query.id])
console.log(post, isLoading, error)
return ( return (
<Page> <Page>
@ -20,16 +50,19 @@ const Post = ({ post, theme, changeTheme }: Props) => {
<Header theme={theme} changeTheme={changeTheme} /> <Header theme={theme} changeTheme={changeTheme} />
</Page.Header> </Page.Header>
<Page.Content width={"var(--main-content-width)"} margin="auto"> <Page.Content width={"var(--main-content-width)"} margin="auto">
<Text h2>{post.title} <VisibilityBadge visibility={post.visibility} /></Text> {error && <Text type="error">{error}</Text>}
{ {!error && (isLoading || !post?.files) && <Loading />}
post.files.map(({ id, content, title }: { id: any, content: string, title: string }) => ( {!isLoading && post && <><Text h2>{post.title} <VisibilityBadge visibility={post.visibility} /></Text>
{post.files.map(({ id, content, title }: { id: any, content: string, title: string }) => (
<Document <Document
key={id} key={id}
content={content} content={content}
title={title} title={title}
editable={false} editable={false}
initialTab={'preview'}
/> />
)) ))}
))</>
} }
</Page.Content> </Page.Content>
@ -38,14 +71,3 @@ const Post = ({ post, theme, changeTheme }: Props) => {
} }
export default Post export default Post
export async function getServerSideProps(context: GetServerSidePropsContext) {
const { id } = context.query;
const response = await fetch(`http://localhost:3000/posts/${id}`);
const json = await response.json();
return {
props: {
post: json
},
}
}

View file

@ -8,10 +8,19 @@
width: var(--main-content-width); width: var(--main-content-width);
} }
.container {
width: 100% !important;
}
@media screen and (max-width: 768px) { @media screen and (max-width: 768px) {
.container { .container {
width: 100%; width: 100%;
margin: 0 !important; margin: 0 auto !important;
padding: 0;
}
.container h1 {
font-size: 2rem;
} }
.main { .main {

View file

@ -7,6 +7,12 @@
--font-size: 16px; --font-size: 16px;
} }
@media screen and (max-width: 768px) {
:root {
--main-content-width: 100%;
}
}
html, html,
body { body {
padding: 0; padding: 0;

View file

@ -2,7 +2,7 @@ import { Router } from 'express'
// import { Movie } from '../models/Post' // import { Movie } from '../models/Post'
import { File } from '../../lib/models/File' import { File } from '../../lib/models/File'
import { Post } from '../../lib/models/Post'; import { Post } from '../../lib/models/Post';
import jwt from '../../lib/middleware/jwt'; import jwt, { UserJwtRequest } from '../../lib/middleware/jwt';
import * as crypto from "crypto"; import * as crypto from "crypto";
import { User } from '../../lib/models/User'; import { User } from '../../lib/models/User';
@ -61,7 +61,7 @@ posts.post('/create', jwt, async (req, res, next) => {
} }
}); });
posts.get("/:id", async (req, res, next) => { posts.get("/:id", async (req: UserJwtRequest, res, next) => {
try { try {
const post = await Post.findOne({ const post = await Post.findOne({
where: { where: {
@ -80,7 +80,15 @@ posts.get("/:id", async (req, res, next) => {
}, },
] ]
}) })
res.json(post);
console.log(post)
if (post?.visibility === 'public' || post?.visibility === 'unlisted') {
res.json(post);
} else {
jwt(req, res, () => {
res.json(post);
});
}
} }
catch (e) { catch (e) {
next(e); next(e);