From 73a5c7fae9ffbe9ada721148c8c454a643aceebe Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Sun, 20 Feb 2022 16:11:50 +0100 Subject: chore!: restructure repo I separated public files from the config/dev files. It improves repo readability. I also moved dotenv helper to public/inc directory and extract the Matomo tracker in the same directory. --- .../react-small-apps/apps/notebook/src/App.css | 40 +++++ .../react-small-apps/apps/notebook/src/App.js | 174 +++++++++++++++++++++ .../react-small-apps/apps/notebook/src/App.test.js | 8 + .../src/components/commons/Button/Button.css | 78 +++++++++ .../src/components/commons/Button/Button.js | 26 +++ .../components/commons/FormElements/Input/Input.js | 31 ++++ .../commons/FormElements/TextArea/TextArea.js | 52 ++++++ .../src/components/commons/FormElements/index.js | 4 + .../notebook/src/components/commons/List/List.css | 3 + .../notebook/src/components/commons/List/List.js | 25 +++ .../apps/notebook/src/components/commons/index.js | 5 + .../src/components/helpers/hooks/useToggle.js | 10 ++ .../src/components/layout/Footer/Footer.css | 8 + .../src/components/layout/Footer/Footer.js | 11 ++ .../src/components/layout/Header/Header.css | 7 + .../src/components/layout/Header/Header.js | 12 ++ .../notebook/src/components/layout/Main/Main.css | 3 + .../notebook/src/components/layout/Main/Main.js | 7 + .../notebook/src/components/layout/Nav/Nav.css | 65 ++++++++ .../apps/notebook/src/components/layout/Nav/Nav.js | 62 ++++++++ .../notebook/src/components/layout/Nav/NavJump.js | 28 ++++ .../notebook/src/components/layout/Page/Cover.css | 30 ++++ .../notebook/src/components/layout/Page/Page.css | 83 ++++++++++ .../notebook/src/components/layout/Page/Page.js | 107 +++++++++++++ .../src/components/layout/Page/PageToolbar.js | 27 ++++ .../apps/notebook/src/components/layout/index.js | 7 + .../apps/notebook/src/config/pages.js | 16 ++ .../apps/notebook/src/images/restore.svg | 24 +++ .../apps/notebook/src/images/trash.svg | 48 ++++++ .../react-small-apps/apps/notebook/src/index.js | 20 +++ .../react-small-apps/apps/notebook/src/logo.svg | 1 + .../apps/notebook/src/reportWebVitals.js | 13 ++ .../apps/notebook/src/setupTests.js | 5 + 33 files changed, 1040 insertions(+) create mode 100644 public/projects/react-small-apps/apps/notebook/src/App.css create mode 100644 public/projects/react-small-apps/apps/notebook/src/App.js create mode 100644 public/projects/react-small-apps/apps/notebook/src/App.test.js create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/commons/Button/Button.css create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/commons/Button/Button.js create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/commons/FormElements/Input/Input.js create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/commons/FormElements/TextArea/TextArea.js create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/commons/FormElements/index.js create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/commons/List/List.css create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/commons/List/List.js create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/commons/index.js create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/helpers/hooks/useToggle.js create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/layout/Footer/Footer.css create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/layout/Footer/Footer.js create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/layout/Header/Header.css create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/layout/Header/Header.js create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/layout/Main/Main.css create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/layout/Main/Main.js create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/layout/Nav/Nav.css create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/layout/Nav/Nav.js create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/layout/Nav/NavJump.js create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/layout/Page/Cover.css create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/layout/Page/Page.css create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/layout/Page/Page.js create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/layout/Page/PageToolbar.js create mode 100644 public/projects/react-small-apps/apps/notebook/src/components/layout/index.js create mode 100644 public/projects/react-small-apps/apps/notebook/src/config/pages.js create mode 100644 public/projects/react-small-apps/apps/notebook/src/images/restore.svg create mode 100644 public/projects/react-small-apps/apps/notebook/src/images/trash.svg create mode 100644 public/projects/react-small-apps/apps/notebook/src/index.js create mode 100644 public/projects/react-small-apps/apps/notebook/src/logo.svg create mode 100644 public/projects/react-small-apps/apps/notebook/src/reportWebVitals.js create mode 100644 public/projects/react-small-apps/apps/notebook/src/setupTests.js (limited to 'public/projects/react-small-apps/apps/notebook/src') diff --git a/public/projects/react-small-apps/apps/notebook/src/App.css b/public/projects/react-small-apps/apps/notebook/src/App.css new file mode 100644 index 0000000..76d2aec --- /dev/null +++ b/public/projects/react-small-apps/apps/notebook/src/App.css @@ -0,0 +1,40 @@ +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, + Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; + font-size: 1rem; + line-height: 1.618; +} + +.app { + display: flex; + flex-flow: column nowrap; + gap: clamp(1rem, 3vw, 2rem); + min-height: 100vh; + width: min(calc(100vw - 2rem), 1000px); + margin: auto; +} + +.notebook { + background: hsl(0, 4%, 20%); + box-shadow: 2px 2px 2px 0 hsl(0, 0%, 13%), 2px 2px 5px 3px hsl(0, 0%, 40%); + display: grid; + grid-template-columns: repeat(2, 1fr); + min-height: 550px; + margin-top: 3rem; + padding: 0.8rem 1.3rem 1.2rem 1.3rem; + position: relative; +} + +@media screen and (max-width: 1024px) { + .notebook { + padding: 0.8rem 1.3rem 1.2rem 0.1rem; + } +} + +.notebook--cover { + padding: 1rem; +} + +a { + color: hsl(212, 46%, 34%); +} diff --git a/public/projects/react-small-apps/apps/notebook/src/App.js b/public/projects/react-small-apps/apps/notebook/src/App.js new file mode 100644 index 0000000..6057342 --- /dev/null +++ b/public/projects/react-small-apps/apps/notebook/src/App.js @@ -0,0 +1,174 @@ +import { Navigate, Route, Routes, useLocation } from "react-router-dom"; +import { Footer, Header, Main, Nav, Page } from "./components/layout"; +import { useCallback, useEffect, useState } from "react"; +import { defaultPages } from "./config/pages"; +import "./App.css"; + +let pageId = 0; + +function App() { + const storedPages = JSON.parse(localStorage.getItem("notebook-pages")); + const initialPages = storedPages || defaultPages; + const [pages, setPages] = useState(initialPages); + const [currentPage, setCurrentPage] = useState({}); + const [deletedPages, setDeletedPages] = useState([]); + const location = useLocation(); + + pageId = storedPages ? storedPages.at(storedPages.length - 1).id : pageId; + + const isCover = () => currentPage && currentPage.id === 0; + const isPageExists = useCallback( + (id) => { + const pageIndex = pages.findIndex((page) => page.id === id); + return pageIndex === -1 ? false : true; + }, + [pages] + ); + + const addNewPage = useCallback(() => { + pageId++; + const newPage = { + id: pageId, + body: "", + title: `Page ${pageId}`, + url: `/page/${pageId}`, + }; + setPages((previous) => [...previous, newPage]); + }, []); + + const removePage = useCallback(() => { + const currentPageId = currentPage.id; + const pagesCopy = pages.slice(0); + const currentPageIndex = pages.findIndex( + (page) => page.id === currentPageId + ); + setDeletedPages((prev) => [...prev, currentPage]); + pagesCopy.splice(currentPageIndex, 1); + const newPages = pagesCopy.map((page) => { + if (page.id <= currentPageId) return page; + const newId = page.id - 1; + const newURL = `/page/${newId}`; + return { ...page, id: newId, url: newURL }; + }); + setCurrentPage(...newPages.filter((page) => page.id === currentPageId)); + setPages(newPages); + pageId = pageId - 1; + }, [pages, currentPage]); + + const restorePage = useCallback(() => { + const deletedPage = deletedPages.pop(); + const pagesCopy = pages.slice(0); + const restoredPageIndex = pagesCopy.findIndex( + (page) => page.id === deletedPage.id + ); + const newPages = pagesCopy.map((page) => { + if (page.id < deletedPage.id) return page; + const newId = page.id + 1; + const newURL = `/page/${newId}`; + return { ...page, id: newId, url: newURL }; + }); + newPages.splice(restoredPageIndex, 0, deletedPage); + setCurrentPage(...newPages.filter((page) => page.id === deletedPage.id)); + setPages(newPages); + }, [pages, deletedPages]); + + useEffect(() => { + !isPageExists(1) && addNewPage(); + }, [isPageExists, addNewPage]); + + useEffect(() => { + const requestedPage = pages.find((page) => page.url === location.pathname); + if (requestedPage) { + setCurrentPage(requestedPage); + } else { + setCurrentPage(() => pages.find((page) => page.url === "/404")); + } + }, [location.pathname, pages]); + + useEffect(() => { + if (currentPage) document.title = `Notebook - ${currentPage.title}`; + }, [currentPage]); + + useEffect(() => { + setPages((prevPages) => { + return prevPages.map((page) => { + if (page.id !== currentPage.id) return page; + return { ...page, body: currentPage.body }; + }); + }); + }, [currentPage.id, currentPage.body]); + + useEffect(() => { + setPages((prevPages) => { + return prevPages.map((page) => { + if (page.id !== currentPage.id) return page; + return { ...page, title: currentPage.title }; + }); + }); + }, [currentPage.id, currentPage.title]); + + useEffect(() => { + localStorage.setItem("notebook-pages", JSON.stringify(pages)); + }, [pages]); + + return ( + <> +
+
+
+
+ + + } + /> + } /> + } /> + + } + /> + + } + path="/404" + /> + } /> + +
+
+