From 0144bfc9cc6c616a00a8171f3950a75ec948427e Mon Sep 17 00:00:00 2001 From: jackyzha0 Date: Sun, 11 Apr 2021 10:27:27 -0700 Subject: base next refactor --- frontend/src/pages/[hash].js | 65 +++++++++++++++++ frontend/src/pages/_app.js | 23 ++++++ frontend/src/pages/_document.js | 30 ++++++++ frontend/src/pages/index.js | 150 ++++++++++++++++++++++++++++++++++++++++ frontend/src/pages/raw/index.js | 14 ++++ 5 files changed, 282 insertions(+) create mode 100644 frontend/src/pages/[hash].js create mode 100644 frontend/src/pages/_app.js create mode 100644 frontend/src/pages/_document.js create mode 100644 frontend/src/pages/index.js create mode 100644 frontend/src/pages/raw/index.js (limited to 'frontend/src/pages') diff --git a/frontend/src/pages/[hash].js b/frontend/src/pages/[hash].js new file mode 100644 index 0000000..27f808b --- /dev/null +++ b/frontend/src/pages/[hash].js @@ -0,0 +1,65 @@ +import React, { useEffect, useState, useRef } from 'react'; +import Error from '../components/Err'; +import { Text } from '../components/Inputs'; +import CodeRenderer from '../components/renderers/Code' +import PasteInfo from '../components/PasteInfo'; +import PasswordModal from '../components/modals/PasswordModal' +import RenderDispatch from '../components/renderers/RenderDispatch' +import useFetchPaste from "../http/useFetchPaste"; + +const ViewPaste = (props) => { + const { err, requiresAuth, validPass, getWithPassword, result } = useFetchPaste(props.hash) + const {content, language, expiry, title} = result ?? {} + const [theme, setTheme] = useState('atom'); + const [isRenderMode, setIsRenderMode] = useState(false); + const [enteredPass, setEnteredPass] = useState(''); + const ErrorLabelRef = useRef(null); + + if (err) { + ErrorLabelRef.current.showMessage(err, -1) + } + + useEffect(() => { + setIsRenderMode(language === 'latex' || language === 'markdown') + }, [language]) + + function getDisplay() { + return isRenderMode ? : + } + + return ( +
+ setEnteredPass(e.target.value)} + validateCallback={getWithPassword} /> + + {getDisplay()} + setIsRenderMode(!isRenderMode)} + isRenderMode={isRenderMode} + onChange={(e) => setTheme(e.target.value)} + err={} + /> +
+ ); +} + +export default ViewPaste \ No newline at end of file diff --git a/frontend/src/pages/_app.js b/frontend/src/pages/_app.js new file mode 100644 index 0000000..7e99f01 --- /dev/null +++ b/frontend/src/pages/_app.js @@ -0,0 +1,23 @@ +import React from 'react' +import ThemeProvider from "../theme/ThemeProvider"; +import GlobalStyle from "../theme/GlobalStyle"; +import '../theme/style.css'; +import {Watermark} from "../components/Watermark"; +import styled from "styled-components"; + +const Main = styled.div` + margin-top: 10vh; + padding: 0 20vw 30px 20vw; +` + +const App = ({ Component, pageProps }) => ( + + + +
+ +
+
+) + +export default App \ No newline at end of file diff --git a/frontend/src/pages/_document.js b/frontend/src/pages/_document.js new file mode 100644 index 0000000..0cbd6a3 --- /dev/null +++ b/frontend/src/pages/_document.js @@ -0,0 +1,30 @@ +import Document from 'next/document' +import { ServerStyleSheet } from 'styled-components' + +export default class StyledDocument extends Document { + static async getInitialProps(ctx) { + const sheet = new ServerStyleSheet() + const originalRenderPage = ctx.renderPage + + try { + ctx.renderPage = () => + originalRenderPage({ + enhanceApp: (App) => (props) => + sheet.collectStyles(), + }) + + const initialProps = await Document.getInitialProps(ctx) + return { + ...initialProps, + styles: ( + <> + {initialProps.styles} + {sheet.getStyleElement()} + + ), + } + } finally { + sheet.seal() + } + } +} \ No newline at end of file diff --git a/frontend/src/pages/index.js b/frontend/src/pages/index.js new file mode 100644 index 0000000..141ebac --- /dev/null +++ b/frontend/src/pages/index.js @@ -0,0 +1,150 @@ +import React, { useEffect, useState, useRef } from 'react'; +import { Text, Code } from '../components/Inputs' +import OptionsContainer from '../components/Options' +import Error from '../components/Err' +import PasteModal from '../components/modals/PasteModal' +import styled from 'styled-components' +import CodeRenderer from '../components/renderers/Code' +import Latex from '../components/renderers/Latex' +import Markdown from '../components/renderers/Markdown' +import {Button, SubmitButton} from "../components/Common/Button"; +import {newPaste} from "../http/shared"; + +const Flex = styled.div` + display: flex; + flex-direction: row; +` + +const FlexLeft = styled.div` + flex: 0 0 calc(50% - 1em - 2px); +` + +const FlexRight = styled.div` + flex: 0 0 50%; + max-width: calc(50% - 1em + 2px); + margin-left: 2em; +` + +const PreviewWrapper = styled.div` + margin: 2em; +` + +const NewPaste = () => { + const [title, setTitle] = useState(''); + const [content, setContent] = useState(''); + const [pass, setPass] = useState(''); + const [language, setLanguage] = useState('detect'); + const [expiry, setExpiry] = useState(''); + const [hash, setHash] = useState(''); + const [isPreview, setIsPreview] = useState(false); + const ErrorLabel = useRef(null); + + useEffect(() => { + document.title = title === "" ? `ctrl-v` : `ctrl-v | ${title}`; + }, [title]) + + function handleSubmit(e) { + e.preventDefault(); + + // prevent resubmission + if (!hash) { + newPaste({title, content, language, pass, expiry}) + .then(resp => {setHash(resp.data.hash)}) + .catch((error) => { + const resp = error.response + + // some weird err (e.g. network) + if (!resp) { + ErrorLabel.current.showMessage(error) + return + } + + // some weird err + const errTxt = `${resp.status}: ${resp.data}` + ErrorLabel.current.showMessage(errTxt) + }); + } + } + + function renderPreview() { + const pasteInput = + + if (isPreview) { + var preview + switch (language) { + case 'latex': + preview = + + + + break + case 'markdown': + preview = + + + + break + default: + preview = + + } + + return ( + + + {pasteInput} + + + {preview} + + + ); + } else { + return ( + pasteInput + ); + } + } + + return ( +
+ + {setTitle(e.target.value)}} + value={title} + autoFocus + maxLength="100" + id="titleInput" /> + {renderPreview()} + { setPass(e.target.value) }} + onLangChange={(e) => { setLanguage(e.target.value) }} + onExpiryChange={(e) => { setExpiry(e.target.value) }} /> +
+ + {language !== 'detect' && } +
+
+ + + ); +} + +export default NewPaste \ No newline at end of file diff --git a/frontend/src/pages/raw/index.js b/frontend/src/pages/raw/index.js new file mode 100644 index 0000000..86db3d4 --- /dev/null +++ b/frontend/src/pages/raw/index.js @@ -0,0 +1,14 @@ +import React from 'react'; +import useFetchPaste from "../../http/useFetchPaste"; +import { useRouter } from 'next/router' + + +export default (req, res) => { + const router = useRouter() + const { hash } = router.query + const { err, result } = useFetchPaste(hash) + res.statusCode = 200 + res.json({ + text: 'Hello World! This is the Next.js starter kit :D', + }) +} \ No newline at end of file -- cgit v1.2.3