From d482598203b5ac3751442f967e5c54d8180d86e9 Mon Sep 17 00:00:00 2001 From: Sonny Date: Tue, 6 Jun 2023 17:57:14 +0200 Subject: [PATCH] feat(wip): add responsive --- src/components/ButtonLink.tsx | 22 ++++++++ src/components/SideMenu/NavigationLinks.tsx | 38 +++++++++++++ src/components/SideMenu/SideMenu.tsx | 43 ++------------- src/hooks/useMediaQuery.tsx | 25 +++++++++ src/pages/index.tsx | 59 +++++++++++++++------ src/styles/globals.scss | 6 +++ 6 files changed, 138 insertions(+), 55 deletions(-) create mode 100644 src/components/ButtonLink.tsx create mode 100644 src/components/SideMenu/NavigationLinks.tsx create mode 100644 src/hooks/useMediaQuery.tsx diff --git a/src/components/ButtonLink.tsx b/src/components/ButtonLink.tsx new file mode 100644 index 0000000..08c83b8 --- /dev/null +++ b/src/components/ButtonLink.tsx @@ -0,0 +1,22 @@ +import Link from "next/link"; +import { ReactNode } from "react"; + +export default function ButtonLink({ + href = "#", + onClick, + children, +}: { + href?: string; + onClick?: (...args: any) => any; + children: ReactNode; +}) { + const handleClick = (event) => { + event.preventDefault(); + onClick && onClick(); + }; + return ( + + {children} + + ); +} diff --git a/src/components/SideMenu/NavigationLinks.tsx b/src/components/SideMenu/NavigationLinks.tsx new file mode 100644 index 0000000..e2e2bb4 --- /dev/null +++ b/src/components/SideMenu/NavigationLinks.tsx @@ -0,0 +1,38 @@ +import PATHS from "constants/paths"; +import { SideMenuProps } from "./SideMenu"; + +import ButtonLink from "components/ButtonLink"; +import styles from "./sidemenu.module.scss"; + +export default function NavigationLinks({ + categoryActive, + openSearchModal, +}: { + categoryActive: SideMenuProps["categoryActive"]; + openSearchModal: SideMenuProps["openSearchModal"]; +}) { + const handleOpenSearchModal = (event) => { + event.preventDefault(); + openSearchModal(); + }; + return ( +
+
+ Rechercher + S +
+
+ Créer categorie + C +
+
+ + Créer lien + + L +
+
+ ); +} diff --git a/src/components/SideMenu/SideMenu.tsx b/src/components/SideMenu/SideMenu.tsx index 8722f27..abe882d 100644 --- a/src/components/SideMenu/SideMenu.tsx +++ b/src/components/SideMenu/SideMenu.tsx @@ -1,18 +1,17 @@ -import LinkTag from "next/link"; +import { useHotkeys } from "react-hotkeys-hook"; import BlockWrapper from "components/BlockWrapper/BlockWrapper"; import Categories from "./Categories/Categories"; +import NavigationLinks from "./NavigationLinks"; import Favorites from "./Favorites/Favorites"; import UserCard from "./UserCard/UserCard"; import * as Keys from "constants/keys"; -import PATHS from "constants/paths"; import { Category, Link } from "types"; -import { useHotkeys } from "react-hotkeys-hook"; import styles from "./sidemenu.module.scss"; -interface SideMenuProps { +export interface SideMenuProps { categories: Category[]; favorites: Link[]; handleSelectCategory: (category: Category) => void; @@ -20,6 +19,7 @@ interface SideMenuProps { openSearchModal: () => void; isModalShowing: boolean; } + export default function SideMenu({ categories, favorites, @@ -71,7 +71,7 @@ export default function SideMenu({ /> - @@ -82,36 +82,3 @@ export default function SideMenu({ ); } - -function MenuControls({ - categoryActive, - openSearchModal, -}: { - categoryActive: SideMenuProps["categoryActive"]; - openSearchModal: SideMenuProps["openSearchModal"]; -}) { - const handleOpenSearchModal = (event) => { - event.preventDefault(); - openSearchModal(); - }; - return ( -
-
- - Rechercher - - S -
-
- Créer categorie - C -
-
- - Créer lien - - L -
-
- ); -} diff --git a/src/hooks/useMediaQuery.tsx b/src/hooks/useMediaQuery.tsx new file mode 100644 index 0000000..a7fb6e3 --- /dev/null +++ b/src/hooks/useMediaQuery.tsx @@ -0,0 +1,25 @@ +import { useEffect, useState } from "react"; + +export function useMediaQuery(query: string): boolean { + const [matches, setMatches] = useState(getMediaMatches(query)); + + const handleMediaChange = () => setMatches(getMediaMatches(query)); + + useEffect(() => { + const matchMedia = window.matchMedia(query); + handleMediaChange(); + + matchMedia.addEventListener("change", handleMediaChange); + return () => matchMedia.removeEventListener("change", handleMediaChange); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [query]); + + return matches; +} + +function getMediaMatches(query: string): boolean { + if (typeof window !== "undefined") { + return window.matchMedia(query).matches; + } + return false; +} diff --git a/src/pages/index.tsx b/src/pages/index.tsx index dd973fb..ad12794 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -4,6 +4,7 @@ import { useCallback, useMemo, useState } from "react"; import { useHotkeys } from "react-hotkeys-hook"; import Links from "components/Links/Links"; +import Modal from "components/Modal/Modal"; import PageTransition from "components/PageTransition"; import SearchModal from "components/SearchModal/SearchModal"; import SideMenu from "components/SideMenu/SideMenu"; @@ -13,6 +14,7 @@ import PATHS from "constants/paths"; import useModal from "hooks/useModal"; import { Category, Link, SearchItem } from "types"; +import { useMediaQuery } from "hooks/useMediaQuery"; import getUserCategories from "lib/category/getUserCategories"; import getUser from "lib/user/getUser"; import { pushStateVanilla } from "utils/link"; @@ -25,7 +27,10 @@ interface HomePageProps { function Home(props: HomePageProps) { const router = useRouter(); - const modal = useModal(); + const searchModal = useModal(); + + const isMobile = useMediaQuery("(max-width: 768px)"); + const mobileModal = useModal(); const [categories, setCategories] = useState(props.categories); const [categoryActive, setCategoryActive] = useState( @@ -105,12 +110,12 @@ function Home(props: HomePageProps) { Keys.OPEN_SEARCH_KEY, (event) => { event.preventDefault(); - modal.open(); + searchModal.open(); }, - { enabled: !modal.isShowing } + { enabled: !searchModal.isShowing } ); - useHotkeys(Keys.CLOSE_SEARCH_KEY, modal.close, { - enabled: modal.isShowing, + useHotkeys(Keys.CLOSE_SEARCH_KEY, searchModal.close, { + enabled: searchModal.isShowing, enableOnFormTags: ["INPUT"], }); @@ -120,7 +125,7 @@ function Home(props: HomePageProps) { router.push(`${PATHS.LINK.CREATE}?categoryId=${categoryActive.id}`); }, { - enabled: !modal.isShowing, + enabled: !searchModal.isShowing, } ); useHotkeys( @@ -129,25 +134,45 @@ function Home(props: HomePageProps) { router.push("/category/create"); }, { - enabled: !modal.isShowing, + enabled: !searchModal.isShowing, } ); return ( - + {isMobile ? ( + <> + + + {mobileModal.isShowing && ( + + + + )} + + + ) : ( + + )} - {modal.isShowing && ( + {searchModal.isShowing && (