From 45f5455f942548fa8139e51825a97114a3a7f3f5 Mon Sep 17 00:00:00 2001 From: Sonny Date: Thu, 20 Apr 2023 18:18:03 +0200 Subject: [PATCH] =?UTF-8?q?feat/fix/chore:=20refactor=20project=20structur?= =?UTF-8?q?e=20+=20add=20favicon=20-=20Changement=20de=20structure=20de=20?= =?UTF-8?q?fichier=20-=20Ajout=20des=20favicons=20des=20sites=20-=20Suppre?= =?UTF-8?q?ssion=20et=20mise=20=C3=A0=20jour=20de=20d=C3=A9pendances=20-?= =?UTF-8?q?=20Ajout=20React-Icons=20pour=20g=C3=A9rer=20les=20icons=20-=20?= =?UTF-8?q?Am=C3=A9lioration=20du=20l'UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .prettierrc | 4 +- components/BlockWrapper/BlockWrapper.tsx | 16 + .../BlockWrapper/block-wrapper.module.scss | 47 ++ components/Categories/Favorites.tsx | 36 -- components/Categories/SideMenu.tsx | 47 -- components/Categories/UserCard.tsx | 24 - components/FormLayout.tsx | 12 +- components/Links/LinkFavicon.tsx | 58 ++ components/Links/LinkItem.tsx | 81 +++ components/Links/Links.tsx | 63 +-- components/Links/links.module.scss | 174 ++++++ components/MessageManager.tsx | 14 - components/MessageManager/MessageManager.tsx | 20 + .../message-manager.module.scss | 0 components/SideMenu/Categories/Categories.tsx | 31 ++ .../Categories/CategoryItem.tsx} | 41 +- .../Categories/categories.module.scss | 90 ++++ .../SideMenu/Favorites/FavoriteItem.tsx | 19 + components/SideMenu/Favorites/Favorites.tsx | 19 + .../SideMenu/Favorites/favorites.module.scss | 55 ++ components/SideMenu/SideMenu.tsx | 62 +++ components/SideMenu/UserCard/UserCard.tsx | 28 + .../SideMenu/UserCard/user-card.module.scss | 33 ++ components/SideMenu/sidemenu.module.scss | 19 + example.env | 2 - next.config.js | 19 +- package-lock.json | 510 ++---------------- package.json | 5 +- pages/404.tsx | 11 +- pages/500.tsx | 11 +- pages/_app.tsx | 68 +-- pages/_document.tsx | 6 +- pages/api/favicon.ts | 163 ++++++ pages/category/create.tsx | 28 +- pages/category/edit/[cid].tsx | 52 +- pages/category/remove/[cid].tsx | 52 +- pages/index.tsx | 99 ++-- pages/link/create.tsx | 50 +- pages/link/remove/[lid].tsx | 55 +- pages/signin.tsx | 9 +- styles/globals.scss | 10 +- styles/home/categories.module.scss | 225 -------- styles/home/links.module.scss | 139 ----- test.js | 60 +++ tsconfig.json | 47 +- utils/client.ts | 7 + utils/link.ts | 3 + 47 files changed, 1274 insertions(+), 1350 deletions(-) create mode 100644 components/BlockWrapper/BlockWrapper.tsx create mode 100644 components/BlockWrapper/block-wrapper.module.scss delete mode 100644 components/Categories/Favorites.tsx delete mode 100644 components/Categories/SideMenu.tsx delete mode 100644 components/Categories/UserCard.tsx create mode 100644 components/Links/LinkFavicon.tsx create mode 100644 components/Links/LinkItem.tsx create mode 100644 components/Links/links.module.scss delete mode 100644 components/MessageManager.tsx create mode 100644 components/MessageManager/MessageManager.tsx rename {styles/components => components/MessageManager}/message-manager.module.scss (100%) create mode 100644 components/SideMenu/Categories/Categories.tsx rename components/{Categories/Categories.tsx => SideMenu/Categories/CategoryItem.tsx} (53%) create mode 100644 components/SideMenu/Categories/categories.module.scss create mode 100644 components/SideMenu/Favorites/FavoriteItem.tsx create mode 100644 components/SideMenu/Favorites/Favorites.tsx create mode 100644 components/SideMenu/Favorites/favorites.module.scss create mode 100644 components/SideMenu/SideMenu.tsx create mode 100644 components/SideMenu/UserCard/UserCard.tsx create mode 100644 components/SideMenu/UserCard/user-card.module.scss create mode 100644 components/SideMenu/sidemenu.module.scss create mode 100644 pages/api/favicon.ts delete mode 100644 styles/home/categories.module.scss delete mode 100644 styles/home/links.module.scss create mode 100644 test.js create mode 100644 utils/client.ts create mode 100644 utils/link.ts diff --git a/.prettierrc b/.prettierrc index 2c9427b..7a28161 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,4 +1,4 @@ { - "tabWidth": 4, - "useTabs": true + "tabWidth": 2, + "useTabs": false } \ No newline at end of file diff --git a/components/BlockWrapper/BlockWrapper.tsx b/components/BlockWrapper/BlockWrapper.tsx new file mode 100644 index 0000000..375c7f9 --- /dev/null +++ b/components/BlockWrapper/BlockWrapper.tsx @@ -0,0 +1,16 @@ +import { CSSProperties, ReactNode } from "react"; + +import styles from "./block-wrapper.module.scss"; + +interface BlockWrapperProps { + children: ReactNode; + style?: CSSProperties; +} + +export default function BlockWrapper({ children, style }: BlockWrapperProps) { + return ( +
+ {children} +
+ ); +} diff --git a/components/BlockWrapper/block-wrapper.module.scss b/components/BlockWrapper/block-wrapper.module.scss new file mode 100644 index 0000000..3c70f2d --- /dev/null +++ b/components/BlockWrapper/block-wrapper.module.scss @@ -0,0 +1,47 @@ +.block-wrapper { + height: auto; + width: 100%; + + & h4 { + user-select: none; + text-transform: uppercase; + font-size: 0.85em; + font-weight: 500; + color: #bbb; + margin-bottom: 5px; + } + + & ul { + animation: fadein 0.3s both; + } + + & ul li { + position: relative; + user-select: none; + cursor: pointer; + height: fit-content; + width: 100%; + background-color: #fff; + padding: 7px 12px; + border: 1px solid #dadce0; + border-bottom: 2px solid #dadce0; + border-radius: 3px; + transition: 0.15s; + + &:not(:last-child) { + margin-bottom: 5px; + } + } +} + +@keyframes fadein { + 0% { + transform: translateX(-15px); + opacity: 0; + } + + 100% { + transform: translateX(0); + opacity: 1; + } +} diff --git a/components/Categories/Favorites.tsx b/components/Categories/Favorites.tsx deleted file mode 100644 index 50d247d..0000000 --- a/components/Categories/Favorites.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import LinkTag from "next/link"; - -import { Link } from "../../types"; - -import styles from "../../styles/home/categories.module.scss"; - -export default function Favorites({ favorites }: { favorites: Link[] }) { - return ( -
-

Favoris

- -
- ); -} - -function NoFavLink(): JSX.Element { - return
  • Aucun favoris
  • ; -} - -function LinkFavorite({ link }: { link: Link }): JSX.Element { - const { name, url, category } = link; - return ( -
  • - - {name} - - {category.name} - -
  • - ); -} diff --git a/components/Categories/SideMenu.tsx b/components/Categories/SideMenu.tsx deleted file mode 100644 index 26326f0..0000000 --- a/components/Categories/SideMenu.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { Session } from "next-auth"; -import LinkTag from "next/link"; - -import Categories from "./Categories"; -import Favorites from "./Favorites"; -import UserCard from "./UserCard"; - -import { Category, Link } from "../../types"; - -import styles from "../../styles/home/categories.module.scss"; - -interface SideMenuProps { - categories: Category[]; - favorites: Link[]; - handleSelectCategory: (category: Category) => void; - categoryActive: Category; - session: Session; -} -export default function SideMenu({ - categories, - favorites, - handleSelectCategory, - categoryActive, - session, -}: SideMenuProps) { - return ( -
    - - - - -
    - ); -} - -function MenuControls() { - return ( -
    - Créer categorie - Créer lien -
    - ); -} diff --git a/components/Categories/UserCard.tsx b/components/Categories/UserCard.tsx deleted file mode 100644 index df7242d..0000000 --- a/components/Categories/UserCard.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { Session } from 'next-auth'; -import { signOut } from 'next-auth/react'; -import Image from 'next/image'; - -import styles from '../../styles/home/categories.module.scss'; - -export default function UserCard({ session }: { session: Session; }) { - return ( -
    -
    - {`${session.user.name}'s - {session.user.name} -
    - -
    - ) -} \ No newline at end of file diff --git a/components/FormLayout.tsx b/components/FormLayout.tsx index 40a44b3..982dac6 100644 --- a/components/FormLayout.tsx +++ b/components/FormLayout.tsx @@ -1,12 +1,10 @@ -import Head from "next/head"; +import { NextSeo } from "next-seo"; import Link from "next/link"; -import MessageManager from "./MessageManager"; +import MessageManager from "./MessageManager/MessageManager"; import styles from "../styles/create.module.scss"; -import { config } from "../config"; - interface FormProps { title: string; errorMessage?: string; @@ -34,11 +32,7 @@ export default function Form({ }: FormProps) { return ( <> - - - {config.siteName} — {title} - - +

    {title}

    diff --git a/components/Links/LinkFavicon.tsx b/components/Links/LinkFavicon.tsx new file mode 100644 index 0000000..d67e3d5 --- /dev/null +++ b/components/Links/LinkFavicon.tsx @@ -0,0 +1,58 @@ +import Image from "next/image"; +import { useState } from "react"; +import { TbLoader3 } from "react-icons/tb"; +import { TfiWorld } from "react-icons/tfi"; + +import { faviconLinkBuilder } from "../../utils/link"; + +import styles from "./links.module.scss"; + +interface LinkFaviconProps { + url: string; + size?: number; + noMargin?: boolean; +} +export default function LinkFavicon({ + url, + size = 32, + noMargin = false, +}: LinkFaviconProps) { + const [isFailed, setFailed] = useState(false); + const [isLoading, setLoading] = useState(true); + + const setFallbackFavicon = () => setFailed(true); + const handleStopLoading = () => setLoading(false); + + const { origin } = new URL(url); + + return ( +
    + {!isFailed ? ( + { + setFallbackFavicon(); + handleStopLoading(); + }} + onLoadingComplete={handleStopLoading} + height={size} + width={size} + alt="icon" + /> + ) : ( + + )} + {isLoading && ( + + + + )} +
    + ); +} diff --git a/components/Links/LinkItem.tsx b/components/Links/LinkItem.tsx new file mode 100644 index 0000000..7eee65a --- /dev/null +++ b/components/Links/LinkItem.tsx @@ -0,0 +1,81 @@ +import LinkTag from "next/link"; +import { useState } from "react"; +import { + AiFillDelete, + AiFillEdit, + AiFillStar, + AiOutlineStar, +} from "react-icons/ai"; + +import { Link } from "../../types"; +import LinkFavicon from "./LinkFavicon"; + +import styles from "./links.module.scss"; + +export default function LinkItem({ link }: { link: Link }) { + const { id, name, url, favorite } = link; + const [isFavorite, setFavorite] = useState(favorite); + + return ( +
  • + + + + {name} {isFavorite && } + + + +
    +
    setFavorite((v) => !v)} className={styles["edit"]}> + {isFavorite ? ( + + ) : ( + + )} +
    + + + + + + +
    +
  • + ); +} + +function LinkItemURL({ url }: { url: string }) { + try { + const { origin, pathname, search } = new URL(url); + let text = ""; + + if (pathname !== "/") { + text += pathname; + } + + if (search !== "") { + if (text === "") { + text += "/"; + } + text += search; + } + + return ( + + {origin} + {text} + + ); + } catch (error) { + console.error("error", error); + return {url}; + } +} diff --git a/components/Links/Links.tsx b/components/Links/Links.tsx index 963ffe0..96f1017 100644 --- a/components/Links/Links.tsx +++ b/components/Links/Links.tsx @@ -1,11 +1,9 @@ import LinkTag from "next/link"; -import { Category, Link } from "../../types"; +import { Category } from "../../types"; +import LinkItem from "./LinkItem"; -import EditSVG from "../../public/icons/edit.svg"; -import RemoveSVG from "../../public/icons/remove.svg"; - -import styles from "../../styles/home/links.module.scss"; +import styles from "./links.module.scss"; export default function Links({ category }: { category: Category }) { if (category === null) { @@ -24,7 +22,9 @@ export default function Links({ category }: { category: Category }) {

    Aucun lien pour {category.name}

    - Créer un lien + + Créer un lien +
    ); } @@ -43,54 +43,3 @@ export default function Links({ category }: { category: Category }) { ); } - -function LinkItem({ link }: { link: Link }) { - const { id, name, url, category } = link; - return ( -
  • - - - {name} - — {category.name} - - - -
    - - - - - - -
    -
  • - ); -} - -function LinkItemURL({ url }: { url: string }) { - try { - const { origin, pathname, search } = new URL(url); - let text = ""; - - if (pathname !== "/") { - text += pathname; - } - - if (search !== "") { - if (text === "") { - text += "/"; - } - text += search; - } - - return ( - - {origin} - {text} - - ); - } catch (error) { - console.error("error", error); - return {url}; - } -} diff --git a/components/Links/links.module.scss b/components/Links/links.module.scss new file mode 100644 index 0000000..d8f8f3f --- /dev/null +++ b/components/Links/links.module.scss @@ -0,0 +1,174 @@ +.no-link, +.no-category { + display: flex; + flex: 1; + align-items: center; + justify-content: center; + flex-direction: column; + animation: fadein 0.3s both; +} + +.links-wrapper { + height: 100%; + padding: 10px; + display: flex; + flex: 1; + flex-direction: column; + overflow-x: hidden; + overflow-y: scroll; + + & h2 { + color: #3f88c5; + margin-bottom: 15px; + font-weight: 500; + + & .links-count { + color: #bbb; + font-weight: 300; + font-size: 0.8em; + } + } +} + +.links { + width: 100%; + display: flex; + flex: 1; + flex-direction: column; + animation: fadein 0.3s both; // bug on drag start +} + +.link { + user-select: none; + cursor: pointer; + height: fit-content; + width: 100%; + color: #3f88c5; + background-color: #fff; + padding: 10px 15px; + border: 1px solid #dadce0; + border-radius: 3px; + margin-bottom: 10px; + outline: 3px solid transparent; + display: flex; + align-items: center; + transition: 0.15s; + + &:hover { + border: 1px solid transparent; + outline: 3px solid #82c5fede; + + & .url-pathname { + animation: fadein 0.3s both; + } + + & .controls { + display: flex; + animation: fadein 0.3s both; + } + } +} + +.link > a { + height: 100%; + max-width: calc(100% - 50px); + text-decoration: none; + display: flex; + flex: 1; + flex-direction: column; + transition: 0.1s; + + &, + &:hover { + border: 0; + } + + & .link-name { + display: flex; + align-items: center; + gap: 0.5em; + } + + & .link-name .link-category { + color: #bbb; + font-size: 0.9em; + } + + & .link-url { + width: 100%; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + color: #bbb; + font-size: 0.8em; + + & .url-pathname { + opacity: 0; + } + } +} + +.link .controls { + display: none; + align-items: center; + justify-content: center; + gap: 10px; + + & > * { + border: 0; + margin: 0; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + transition: 0.1s; + + &:hover { + transform: scale(1.3); + } + + & svg { + height: 20px; + width: 20px; + } + } +} + +.favicon { + position: relative; + display: flex; + align-items: center; + justify-content: center; +} + +.favicon-loader { + position: absolute; + top: 0; + left: 0; + background-color: #fff; + + & > * { + animation: rotate 1s both reverse infinite linear; + } +} + +@keyframes rotate { + to { + transform: rotate(0deg); + } + from { + transform: rotate(360deg); + } +} + +@keyframes fadein { + 0% { + transform: translateX(-15px); + opacity: 0; + } + + 100% { + transform: translateX(0); + opacity: 1; + } +} diff --git a/components/MessageManager.tsx b/components/MessageManager.tsx deleted file mode 100644 index 9e86ada..0000000 --- a/components/MessageManager.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import styles from '../styles/components/message-manager.module.scss'; - -interface MessageManagerProps { - error?: string; - success?: string; - info?: string; -} -export default function MessageManager({ error, success, info }: MessageManagerProps) { - return (<> - {info && (
    {info}
    )} - {error && (
    {error}
    )} - {success && (
    {success}
    )} - ); -} \ No newline at end of file diff --git a/components/MessageManager/MessageManager.tsx b/components/MessageManager/MessageManager.tsx new file mode 100644 index 0000000..893178a --- /dev/null +++ b/components/MessageManager/MessageManager.tsx @@ -0,0 +1,20 @@ +import styles from "./message-manager.module.scss"; + +interface MessageManagerProps { + error?: string; + success?: string; + info?: string; +} +export default function MessageManager({ + error, + success, + info, +}: MessageManagerProps) { + return ( + <> + {info &&
    {info}
    } + {error &&
    {error}
    } + {success &&
    {success}
    } + + ); +} diff --git a/styles/components/message-manager.module.scss b/components/MessageManager/message-manager.module.scss similarity index 100% rename from styles/components/message-manager.module.scss rename to components/MessageManager/message-manager.module.scss diff --git a/components/SideMenu/Categories/Categories.tsx b/components/SideMenu/Categories/Categories.tsx new file mode 100644 index 0000000..f499684 --- /dev/null +++ b/components/SideMenu/Categories/Categories.tsx @@ -0,0 +1,31 @@ +import { Category } from "../../../types"; +import CategoryItem from "./CategoryItem"; + +import styles from "./categories.module.scss"; + +interface CategoriesProps { + categories: Category[]; + categoryActive: Category; + handleSelectCategory: (category: Category) => void; +} +export default function Categories({ + categories, + categoryActive, + handleSelectCategory, +}: CategoriesProps) { + return ( +
    +

    Catégories

    +
      + {categories.map((category, key) => ( + + ))} +
    +
    + ); +} diff --git a/components/Categories/Categories.tsx b/components/SideMenu/Categories/CategoryItem.tsx similarity index 53% rename from components/Categories/Categories.tsx rename to components/SideMenu/Categories/CategoryItem.tsx index 614d049..93d2275 100644 --- a/components/Categories/Categories.tsx +++ b/components/SideMenu/Categories/CategoryItem.tsx @@ -1,44 +1,17 @@ import LinkTag from "next/link"; +import { AiFillDelete, AiFillEdit } from "react-icons/ai"; -import styles from "../../styles/home/categories.module.scss"; -import { Category } from "../../types"; +import { Category } from "../../../types"; -import EditSVG from "../../public/icons/edit.svg"; -import RemoveSVG from "../../public/icons/remove.svg"; - -interface CategoriesProps { - categories: Category[]; - categoryActive: Category; - handleSelectCategory: (category: Category) => void; -} -export default function Categories({ - categories, - categoryActive, - handleSelectCategory, -}: CategoriesProps) { - return ( -
    -

    Catégories

    -
      - {categories.map((category, key) => ( - - ))} -
    -
    - ); -} +import styles from "./categories.module.scss"; interface CategoryItemProps { category: Category; categoryActive: Category; handleSelectCategory: (category: Category) => void; } -function CategoryItem({ + +export default function CategoryItem({ category, categoryActive, handleSelectCategory, @@ -63,13 +36,13 @@ function MenuOptions({ id }: { id: number }): JSX.Element { return (
    - + - +
    ); diff --git a/components/SideMenu/Categories/categories.module.scss b/components/SideMenu/Categories/categories.module.scss new file mode 100644 index 0000000..020a804 --- /dev/null +++ b/components/SideMenu/Categories/categories.module.scss @@ -0,0 +1,90 @@ +.categories { + height: 100%; + width: 100%; + min-height: 0; + display: flex; + flex: 1; + flex-direction: column; +} + +.items { + padding-right: 5px; + overflow-y: scroll; +} + +.item { + display: flex; + align-items: center; + justify-content: space-between; + + &.active { + color: #fff; + background: #3f88c5; + border-color: #3f88c5; + } + + &:hover:not(.active) { + color: #3f88c5; + background: #f0eef6; + border-bottom: 2px solid #3f88c5; + } + + &.active .menu-item .option-edit svg { + fill: #fff; + } + + & .content { + width: 100%; + display: flex; + flex: 1; + align-items: center; + + & .name { + margin-right: 5px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + } + + & .links-count { + min-width: fit-content; + font-size: 0.85em; + color: #bbb; + } + } + &:hover .content { + width: calc(100% - 42px); + } + + & .menu-item { + height: 100%; + min-width: fit-content; + margin-left: 5px; + display: none; + gap: 2px; + align-items: center; + justify-content: center; + animation: fadein 0.3s both; + + & > a { + border: 0; + margin: 0; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + + &:hover { + transform: scale(1.25); + } + + & svg { + height: 20px; + width: 20px; + } + } + } + &:hover .menu-item { + display: flex; + } +} diff --git a/components/SideMenu/Favorites/FavoriteItem.tsx b/components/SideMenu/Favorites/FavoriteItem.tsx new file mode 100644 index 0000000..777ae03 --- /dev/null +++ b/components/SideMenu/Favorites/FavoriteItem.tsx @@ -0,0 +1,19 @@ +import LinkTag from "next/link"; + +import { Link } from "../../../types"; +import LinkFavicon from "../../Links/LinkFavicon"; + +import styles from "./favorites.module.scss"; + +export default function FavoriteItem({ link }: { link: Link }): JSX.Element { + const { name, url, category } = link; + return ( +
  • + + + {name} + - {category.name} + +
  • + ); +} diff --git a/components/SideMenu/Favorites/Favorites.tsx b/components/SideMenu/Favorites/Favorites.tsx new file mode 100644 index 0000000..ca33988 --- /dev/null +++ b/components/SideMenu/Favorites/Favorites.tsx @@ -0,0 +1,19 @@ +import { Link } from "../../../types"; +import FavoriteItem from "./FavoriteItem"; + +import styles from "./favorites.module.scss"; + +export default function Favorites({ favorites }: { favorites: Link[] }) { + return ( + favorites.length !== 0 && ( +
    +

    Favoris

    +
      + {favorites.map((link, key) => ( + + ))} +
    +
    + ) + ); +} diff --git a/components/SideMenu/Favorites/favorites.module.scss b/components/SideMenu/Favorites/favorites.module.scss new file mode 100644 index 0000000..29a9356 --- /dev/null +++ b/components/SideMenu/Favorites/favorites.module.scss @@ -0,0 +1,55 @@ +.favorites { + height: auto; + width: 100%; + margin-bottom: 15px; + + & h4 { + user-select: none; + text-transform: uppercase; + font-size: 0.85em; + font-weight: 500; + color: #bbb; + margin-bottom: 5px; + } +} + +.favorites ul.items li.item { + width: 100%; + background-color: #fff; + padding: 0; + border: 1px solid #dadce0; + border-bottom: 2px solid #dadce0; + border-radius: 3px; + transition: 0.15s; + + & a { + width: 100%; + color: inherit; + padding: 0.65em 1.15em; + border: 0 !important; + display: flex; + align-items: center; + gap: 0.25em; + } + + & .category { + color: #bbb; + font-size: 0.85em; + } + + &:not(:last-child) { + margin-bottom: 5px; + } + + &.active { + color: #fff; + background: #3f88c5; + border-color: #3f88c5; + } + + &:hover:not(.active) { + color: #3f88c5; + background: #f0eef6; + border-bottom: 2px solid #3f88c5; + } +} diff --git a/components/SideMenu/SideMenu.tsx b/components/SideMenu/SideMenu.tsx new file mode 100644 index 0000000..0fad636 --- /dev/null +++ b/components/SideMenu/SideMenu.tsx @@ -0,0 +1,62 @@ +import { Session } from "next-auth"; +import LinkTag from "next/link"; + +import BlockWrapper from "../BlockWrapper/BlockWrapper"; +import Categories from "./Categories/Categories"; +import Favorites from "./Favorites/Favorites"; +import UserCard from "./UserCard/UserCard"; + +import { Category, Link } from "../../types"; + +import styles from "./sidemenu.module.scss"; + +interface SideMenuProps { + categories: Category[]; + favorites: Link[]; + handleSelectCategory: (category: Category) => void; + categoryActive: Category; + session: Session; +} +export default function SideMenu({ + categories, + favorites, + handleSelectCategory, + categoryActive, + session, +}: SideMenuProps) { + return ( +
    + + + + + + + + + + + + +
    + ); +} + +function MenuControls({ + categoryActive, +}: { + categoryActive: SideMenuProps["categoryActive"]; +}) { + return ( +
    + Créer categorie + + Créer lien + +
    + ); +} diff --git a/components/SideMenu/UserCard/UserCard.tsx b/components/SideMenu/UserCard/UserCard.tsx new file mode 100644 index 0000000..8ee9a2d --- /dev/null +++ b/components/SideMenu/UserCard/UserCard.tsx @@ -0,0 +1,28 @@ +import { Session } from "next-auth"; +import { signOut } from "next-auth/react"; +import Image from "next/image"; +import { FiLogOut } from "react-icons/fi"; + +import styles from "./user-card.module.scss"; + +export default function UserCard({ session }: { session: Session }) { + return ( +
    +
    + {`${session.user.name}'s + {session.user.name} +
    + +
    + ); +} diff --git a/components/SideMenu/UserCard/user-card.module.scss b/components/SideMenu/UserCard/user-card.module.scss new file mode 100644 index 0000000..f0f1e12 --- /dev/null +++ b/components/SideMenu/UserCard/user-card.module.scss @@ -0,0 +1,33 @@ +.user-card-wrapper { + user-select: none; + height: fit-content; + width: 100%; + color: #333; + background-color: #fff; + border: 1px solid #dadce0; + padding: 7px 12px; + display: flex; + justify-content: space-between; + align-items: center; + + & .user-card { + display: flex; + gap: 0.5em; + align-items: center; + + & img { + border-radius: 50%; + } + } + + & button { + cursor: pointer; + color: #3d7bab; + display: flex; + transition: 0.15s; + + &:hover { + transform: scale(1.3); + } + } +} diff --git a/components/SideMenu/sidemenu.module.scss b/components/SideMenu/sidemenu.module.scss new file mode 100644 index 0000000..9063339 --- /dev/null +++ b/components/SideMenu/sidemenu.module.scss @@ -0,0 +1,19 @@ +.side-menu { + height: 100%; + width: 300px; + padding: 0 25px 0 10px; + border-right: 1px solid #dadce0; + margin-right: 15px; + display: flex; + align-items: center; + flex-direction: column; + overflow: hidden; +} + +.menu-controls { + margin: 10px 0; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; +} diff --git a/example.env b/example.env index 713d362..7b62040 100644 --- a/example.env +++ b/example.env @@ -9,5 +9,3 @@ NEXTAUTH_SECRET= GOOGLE_CLIENT_ID= GOOGLE_CLIENT_SECRET= - -NEXT_PUBLIC_SITE_NAME= diff --git a/next.config.js b/next.config.js index aa72f7d..40c5938 100644 --- a/next.config.js +++ b/next.config.js @@ -1,14 +1,17 @@ -module.exports = { - reactStrictMode: true, - images: { - domains: ['lh3.googleusercontent.com'] - }, +/** @type {import('next').NextConfig} */ +const config = { webpack(config) { config.module.rules.push({ test: /\.svg$/, - use: ["@svgr/webpack"] + use: ["@svgr/webpack"], }); return config; - } -} + }, + images: { + domains: ["localhost", "t3.gstatic.com", "lh3.googleusercontent.com"], + formats: ["image/webp"], + }, +}; + +module.exports = config; diff --git a/package-lock.json b/package-lock.json index 30b7f6c..e553832 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,13 +12,14 @@ "next": "^13.3.0", "next-auth": "^4.22.0", "next-connect": "^0.13.0", + "next-seo": "^6.0.0", + "node-html-parser": "^6.1.5", "nprogress": "^0.2.0", "react": "^18.2.0", - "react-confirm-alert": "^3.0.6", "react-dom": "^18.2.0", + "react-icons": "^4.8.0", "react-select": "^5.7.2", "sass": "^1.62.0", - "sharp": "^0.32.0", "toastr": "^2.1.4" }, "devDependencies": { @@ -2921,25 +2922,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -2948,16 +2930,6 @@ "node": ">=8" } }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -3011,29 +2983,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -3142,28 +3091,11 @@ "node": ">= 6" } }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, - "node_modules/color": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", - "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - }, - "engines": { - "node": ">=12.5.0" - } - }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -3177,31 +3109,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/color/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -3390,28 +3297,6 @@ } } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -3459,14 +3344,6 @@ "node": ">=0.4.0" } }, - "node_modules/detect-libc": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", - "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", - "engines": { - "node": ">=8" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -3562,14 +3439,6 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/enhanced-resolve": { "version": "5.12.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", @@ -4239,14 +4108,6 @@ "node": ">=0.10.0" } }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "engines": { - "node": ">=6" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -4406,11 +4267,6 @@ "node": ">= 6" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -4509,11 +4365,6 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" - }, "node_modules/glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -4704,6 +4555,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -4712,25 +4571,6 @@ "react-is": "^16.7.0" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -4782,12 +4622,8 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "node_modules/internal-slot": { "version": "1.0.4", @@ -5307,17 +5143,6 @@ "node": ">= 0.6" } }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -5333,12 +5158,8 @@ "node_modules/minimist": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true }, "node_modules/ms": { "version": "2.1.2", @@ -5356,11 +5177,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -5454,35 +5270,24 @@ "trouter": "^3.2.0" } }, - "node_modules/node-abi": { - "version": "3.24.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.24.0.tgz", - "integrity": "sha512-YPG3Co0luSu6GwOBsmIdGW6Wx0NyNDLg/hriIyDllVsNwnI6UeqaWShxC3lbH4LtEQUgoLP3XR1ndXiDAWvmRw==", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-abi/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-addon-api": { + "node_modules/next-seo": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.0.0.tgz", - "integrity": "sha512-GyHvgPvUXBvAkXa0YvYnhilSB1A+FRYMpIVggKzPZqdaZfevZOuzfWzyvgzOwRLHBeo/MMswmJFsrNF4Nw1pmA==" + "resolved": "https://registry.npmjs.org/next-seo/-/next-seo-6.0.0.tgz", + "integrity": "sha512-jKKt1p1z4otMA28AyeoAONixVjdYmgFCWwpEFtu+DwRHQDllVX3RjtyXbuCQiUZEfQ9rFPBpAI90vDeLZlMBdg==", + "peerDependencies": { + "next": "^8.1.1-canary.54 || >=9.0.0", + "react": ">=16.0.0", + "react-dom": ">=16.0.0" + } + }, + "node_modules/node-html-parser": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-6.1.5.tgz", + "integrity": "sha512-fAaM511feX++/Chnhe475a0NHD8M7AxDInsqQpz6x63GRF7xYNdS8Vo5dKsIVPgsOvG7eioRRTZQnWBrhDHBSg==", + "dependencies": { + "css-select": "^5.1.0", + "he": "1.2.0" + } }, "node_modules/node-releases": { "version": "2.0.10", @@ -5643,6 +5448,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, "dependencies": { "wrappy": "1" } @@ -5852,31 +5658,6 @@ "preact": ">=10" } }, - "node_modules/prebuild-install": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", - "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -5923,15 +5704,6 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -5961,28 +5733,6 @@ } ] }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/react": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", @@ -5994,15 +5744,6 @@ "node": ">=0.10.0" } }, - "node_modules/react-confirm-alert": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/react-confirm-alert/-/react-confirm-alert-3.0.6.tgz", - "integrity": "sha512-rplP6Ed9ZSNd0KFV5BUzk4EPQ77BxsrayllBXGFuA8xPXc7sbBjgU5KUrNpl7aWFmP7mXRlVXfuy1IT5DbffYw==", - "peerDependencies": { - "react": ">=18.0.0", - "react-dom": ">=10.0.0" - } - }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -6015,6 +5756,14 @@ "react": "^18.2.0" } }, + "node_modules/react-icons": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.8.0.tgz", + "integrity": "sha512-N6+kOLcihDiAnj5Czu637waJqSnwlMNROzVZMhfX68V/9bu9qHaMIJC4UdozWoOk57gahFCNHwVvWzm0MTzRjg==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -6055,19 +5804,6 @@ "react-dom": ">=16.6.0" } }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -6308,42 +6044,6 @@ "semver": "bin/semver.js" } }, - "node_modules/sharp": { - "version": "0.32.0", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.0.tgz", - "integrity": "sha512-yLAypVcqj1toSAqRSwbs86nEzfyZVDYqjuUX8grhFpeij0DDNagKJXELS/auegDBRDg1XBtELdOGfo2X1cCpeA==", - "hasInstallScript": true, - "dependencies": { - "color": "^4.2.3", - "detect-libc": "^2.0.1", - "node-addon-api": "^6.0.0", - "prebuild-install": "^7.1.1", - "semver": "^7.3.8", - "simple-get": "^4.0.1", - "tar-fs": "^2.1.1", - "tunnel-agent": "^0.6.0" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/sharp/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -6379,62 +6079,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/simple-swizzle/node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -6468,33 +6112,6 @@ "node": ">=10.0.0" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/string.prototype.matchall": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz", @@ -6683,32 +6300,6 @@ "node": ">=6" } }, - "node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -6813,17 +6404,6 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -6973,11 +6553,6 @@ } } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -7049,7 +6624,8 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true }, "node_modules/yallist": { "version": "4.0.0", diff --git a/package.json b/package.json index a163300..34963e1 100644 --- a/package.json +++ b/package.json @@ -14,13 +14,14 @@ "next": "^13.3.0", "next-auth": "^4.22.0", "next-connect": "^0.13.0", + "next-seo": "^6.0.0", + "node-html-parser": "^6.1.5", "nprogress": "^0.2.0", "react": "^18.2.0", - "react-confirm-alert": "^3.0.6", "react-dom": "^18.2.0", + "react-icons": "^4.8.0", "react-select": "^5.7.2", "sass": "^1.62.0", - "sharp": "^0.32.0", "toastr": "^2.1.4" }, "devDependencies": { diff --git a/pages/404.tsx b/pages/404.tsx index 02247c0..9e505d2 100644 --- a/pages/404.tsx +++ b/pages/404.tsx @@ -1,13 +1,12 @@ -import Head from 'next/head'; -import styles from '../styles/error-page.module.scss'; +import { NextSeo } from 'next-seo'; -import { config } from '../config'; +import styles from '../styles/error-page.module.scss'; export default function Custom404() { return (<> - - {config.siteName} — Page introuvable - +

    404

    Cette page est introuvable.

    diff --git a/pages/500.tsx b/pages/500.tsx index f00573d..5afe0ed 100644 --- a/pages/500.tsx +++ b/pages/500.tsx @@ -1,13 +1,12 @@ -import Head from 'next/head'; -import styles from '../styles/error-page.module.scss'; +import { NextSeo } from 'next-seo'; -import { config } from '../config'; +import styles from '../styles/error-page.module.scss'; export default function Custom500() { return (<> - - {config.siteName} — Une erreur côté serveur est survenue - +

    500

    Une erreur côté serveur est survenue.

    diff --git a/pages/_app.tsx b/pages/_app.tsx index 0be770a..ea96d44 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -1,44 +1,44 @@ -import { useEffect } from 'react'; -import { SessionProvider } from 'next-auth/react'; +import { SessionProvider } from "next-auth/react"; +import { useEffect } from "react"; -import { useRouter } from 'next/router'; +import { useRouter } from "next/router"; -import nProgress from 'nprogress'; -import 'nprogress/nprogress.css'; +import nProgress from "nprogress"; +import "nprogress/nprogress.css"; -import AuthRequired from '../components/AuthRequired'; +import AuthRequired from "../components/AuthRequired"; -import '../styles/globals.scss'; +import { DefaultSeo } from "next-seo"; +import "../styles/globals.scss"; -function MyApp({ - Component, - pageProps: { session, ...pageProps } -}) { - const router = useRouter(); +function MyApp({ Component, pageProps: { session, ...pageProps } }) { + const router = useRouter(); - useEffect(() => { // Chargement pages - router.events.on('routeChangeStart', nProgress.start); - router.events.on('routeChangeComplete', nProgress.done); - router.events.on('routeChangeError', nProgress.done); + useEffect(() => { + // Chargement pages + router.events.on("routeChangeStart", nProgress.start); + router.events.on("routeChangeComplete", nProgress.done); + router.events.on("routeChangeError", nProgress.done); - return () => { - router.events.off('routeChangeStart', nProgress.start); - router.events.off('routeChangeComplete', nProgress.done); - router.events.off('routeChangeError', nProgress.done); - } - }); + return () => { + router.events.off("routeChangeStart", nProgress.start); + router.events.off("routeChangeComplete", nProgress.done); + router.events.off("routeChangeError", nProgress.done); + }; + }); - return ( - - {Component.authRequired ? ( - - - - ) : ( - - )} - - ); + return ( + + + {Component.authRequired ? ( + + + + ) : ( + + )} + + ); } -export default MyApp; \ No newline at end of file +export default MyApp; diff --git a/pages/_document.tsx b/pages/_document.tsx index 1dc984c..02e8e54 100644 --- a/pages/_document.tsx +++ b/pages/_document.tsx @@ -1,17 +1,15 @@ -import { Html, Head, Main, NextScript } from 'next/document'; - -import { config } from '../config'; +import { Head, Html, Main, NextScript } from 'next/document'; const Document = () => ( + - {config.siteName}