From fd67ff21147de87fbe8eac9b30a9a348ccbea843 Mon Sep 17 00:00:00 2001 From: developomp Date: Fri, 17 Dec 2021 13:31:10 +0900 Subject: [PATCH] split page to smaller components --- source/src/pages/Page/Meta.tsx | 42 ++++ source/src/pages/Page/NextPrevButtons.tsx | 69 +++++++ source/src/pages/Page/Toc.tsx | 65 ++++++ source/src/pages/{Page.tsx => Page/index.tsx} | 188 ++---------------- 4 files changed, 192 insertions(+), 172 deletions(-) create mode 100644 source/src/pages/Page/Meta.tsx create mode 100644 source/src/pages/Page/NextPrevButtons.tsx create mode 100644 source/src/pages/Page/Toc.tsx rename source/src/pages/{Page.tsx => Page/index.tsx} (50%) diff --git a/source/src/pages/Page/Meta.tsx b/source/src/pages/Page/Meta.tsx new file mode 100644 index 0000000..c751ceb --- /dev/null +++ b/source/src/pages/Page/Meta.tsx @@ -0,0 +1,42 @@ +import styled from "styled-components" +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" +import { + faBook, + faCalendar, + faHourglass, +} from "@fortawesome/free-solid-svg-icons" + +import { FetchedPage } from "../../types/typings" +import theming from "../../styles/theming" + +const StyledMetaContainer = styled.div` + color: ${(props) => + theming.theme(props.theme.currentTheme, { + light: "#555", + dark: "#CCC", + })}; +` + +const Meta = (props: { fetchedPage: FetchedPage }) => { + return ( + + +     + {props.fetchedPage.date || "Unknown date"} +      + +     + {props.fetchedPage.readTime + ? props.fetchedPage.readTime + " read" + : "unknown length"} +      + +     + {props.fetchedPage.wordCount + ? props.fetchedPage.wordCount + " words" + : "unknown words"} + + ) +} + +export default Meta diff --git a/source/src/pages/Page/NextPrevButtons.tsx b/source/src/pages/Page/NextPrevButtons.tsx new file mode 100644 index 0000000..2687bc2 --- /dev/null +++ b/source/src/pages/Page/NextPrevButtons.tsx @@ -0,0 +1,69 @@ +import styled from "styled-components" +import { Link } from "react-router-dom" + +import theming from "../../styles/theming" + +const StyledNextPrevContainer = styled.div` + display: flex; + justify-content: space-between; + size: 100%; +` + +const StyledLink = styled(Link)` + ${theming.styles.navbarButtonStyle} + + background-color: ${(props) => + theming.theme(props.theme.currentTheme, { + light: "#EEEEEE", + dark: "#202225", + })}; + + height: 1rem; + width: 2rem; + margin-top: 2rem; + + line-height: 1rem; + text-align: center; +` + +const StyledDisabledLink = styled.div` + font-size: 1rem; + border-radius: 0.5rem; + float: left; + padding: 14px 16px; + text-decoration: none; + transition: transform 0.1s linear; + color: grey; + background-color: ${(props) => + theming.theme(props.theme.currentTheme, { + light: "#EEEEEE", + dark: "#202225", + })}; + + height: 1rem; + width: 2rem; + margin-top: 2rem; + + line-height: 1rem; + text-align: center; + user-select: none; +` + +const NextPrevButtons = (props: { prevURL?: string; nextURL?: string }) => { + return ( + + {props.prevURL ? ( + prev + ) : ( + prev + )} + {props.nextURL ? ( + next + ) : ( + next + )} + + ) +} + +export default NextPrevButtons diff --git a/source/src/pages/Page/Toc.tsx b/source/src/pages/Page/Toc.tsx new file mode 100644 index 0000000..06fb96c --- /dev/null +++ b/source/src/pages/Page/Toc.tsx @@ -0,0 +1,65 @@ +import { useEffect, useState } from "react" +import { Collapse } from "react-collapse" +import storage from "local-storage-fallback" + +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" +import { faCaretDown, faCaretUp } from "@fortawesome/free-solid-svg-icons" +import styled from "styled-components" + +import theming from "../../styles/theming" + +import { FetchedPage } from "../../types/typings" + +const StyledTocToggleButton = styled.button` + border: none; + text-align: left; + background-color: rgba(0, 0, 0, 0); + width: 100%; + padding: 0.5rem; + color: ${(props) => + theming.theme(props.theme.currentTheme, { + light: "black", + dark: "white", + })}; +` + +const StyledCollapseContainer = styled.div` + * { + transition: height 200ms ease-out; + } +` + +const Toc = (props: { fetchedPage: FetchedPage }) => { + const [isTocOpened, setIsTocOpened] = useState( + storage.getItem("isTocOpened") == "true" + ) + + useEffect(() => { + storage.setItem("isTocOpened", isTocOpened.toString()) + }, [isTocOpened]) + + return ( + <> + { + setIsTocOpened((prev) => !prev) + }} + > + Table of Content + {isTocOpened ? ( + + ) : ( + + )} + + + +
{props.fetchedPage.toc}
+
+
+
+ + ) +} + +export default Toc diff --git a/source/src/pages/Page.tsx b/source/src/pages/Page/index.tsx similarity index 50% rename from source/src/pages/Page.tsx rename to source/src/pages/Page/index.tsx index 521fba7..2460bd1 100644 --- a/source/src/pages/Page.tsx +++ b/source/src/pages/Page/index.tsx @@ -1,31 +1,22 @@ import { useState } from "react" import { Helmet } from "react-helmet-async" -import { Link, useLocation } from "react-router-dom" +import { useLocation } from "react-router-dom" import styled from "styled-components" import { HashLink } from "react-router-hash-link" -import { Collapse } from "react-collapse" -import storage from "local-storage-fallback" -import { TocElement, FetchedPage, Map } from "../types/typings" +import { TocElement, FetchedPage, Map } from "../../types/typings" -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" -import { - faBook, - faCalendar, - faCaretDown, - faCaretUp, - faHourglass, -} from "@fortawesome/free-solid-svg-icons" +import MainContent from "../../components/MainContent" +import Loading from "../../components/Loading" +import TagList from "../../components/TagList" +import Tag from "../../components/Tag" +import NotFound from "../NotFound" -import MainContent from "../components/MainContent" -import Loading from "../components/Loading" -import TagList from "../components/TagList" -import Tag from "../components/Tag" -import NotFound from "./NotFound" +import NextPrevButtons from "./NextPrevButtons" +import Meta from "./Meta" +import Toc from "./Toc" -import theming from "../styles/theming" - -import _map from "../data/map.json" +import _map from "../../data/map.json" import { useEffect } from "react" const map: Map = _map @@ -38,79 +29,6 @@ const StyledTitle = styled.h1` margin-bottom: 1rem; ` -const StyledNextPrevContainer = styled.div` - display: flex; - justify-content: space-between; - size: 100%; -` - -const StyledLink = styled(Link)` - ${theming.styles.navbarButtonStyle} - - background-color: ${(props) => - theming.theme(props.theme.currentTheme, { - light: "#EEEEEE", - dark: "#202225", - })}; - - height: 1rem; - width: 2rem; - margin-top: 2rem; - - line-height: 1rem; - text-align: center; -` - -const StyledDisabledLink = styled.div` - font-size: 1rem; - border-radius: 0.5rem; - float: left; - padding: 14px 16px; - text-decoration: none; - transition: transform 0.1s linear; - color: grey; - background-color: ${(props) => - theming.theme(props.theme.currentTheme, { - light: "#EEEEEE", - dark: "#202225", - })}; - - height: 1rem; - width: 2rem; - margin-top: 2rem; - - line-height: 1rem; - text-align: center; - user-select: none; -` - -const StyledTocToggleButton = styled.button` - border: none; - text-align: left; - background-color: rgba(0, 0, 0, 0); - width: 100%; - padding: 0.5rem; - color: ${(props) => - theming.theme(props.theme.currentTheme, { - light: "black", - dark: "white", - })}; -` - -const StyledCollapseContainer = styled.div` - * { - transition: height 200ms ease-out; - } -` - -const StyledMetaContainer = styled.div` - color: ${(props) => - theming.theme(props.theme.currentTheme, { - light: "#555", - dark: "#CCC", - })}; -` - function parseToc(tocData: TocElement[]) { return (
    @@ -126,78 +44,6 @@ function parseToc(tocData: TocElement[]) { ) } -const NextPrevButton = (props: { prevURL?: string; nextURL?: string }) => { - return ( - - {props.prevURL ? ( - prev - ) : ( - prev - )} - {props.nextURL ? ( - next - ) : ( - next - )} - - ) -} - -const PostMeta = (props: { fetchedPage: FetchedPage }) => { - return ( - - -     - {props.fetchedPage.date || "Unknown date"} -      - -     - {props.fetchedPage.readTime - ? props.fetchedPage.readTime + " read" - : "unknown length"} -      - -     - {props.fetchedPage.wordCount - ? props.fetchedPage.wordCount + " words" - : "unknown words"} - - ) -} - -const PageTOC = (props: { fetchedPage: FetchedPage }) => { - const [isTocOpened, setIsTocOpened] = useState( - storage.getItem("isTocOpened") == "true" - ) - - useEffect(() => { - storage.setItem("isTocOpened", isTocOpened.toString()) - }, [isTocOpened]) - - return ( - <> - { - setIsTocOpened((prev) => !prev) - }} - > - Table of Content - {isTocOpened ? ( - - ) : ( - - )} - - - -
    {props.fetchedPage.toc}
    -
    -
    -
    - - ) -} - interface SeriesData { seriesHome: string prev?: string @@ -221,8 +67,8 @@ const Page = () => { url: string ) => { return isContentUnsearchable - ? await import(`../data/content/unsearchable${url}.json`) - : await import(`../data/content${url}.json`) + ? await import(`../../data/content/unsearchable${url}.json`) + : await import(`../../data/content${url}.json`) } useEffect(() => { @@ -315,7 +161,7 @@ const Page = () => { {isSeries ? ( - @@ -341,16 +187,14 @@ const Page = () => {
    {/* Post metadata */} - {!isPageUnsearchable && ( - - )} + {!isPageUnsearchable && }
    {/* add table of contents if it exists */} {!!fetchedPage.toc?.props.children.length && ( - + )} {/* page content */}