feat(wip): add responsive

This commit is contained in:
Sonny
2023-06-06 17:57:14 +02:00
parent d22d56bce3
commit d482598203
6 changed files with 138 additions and 55 deletions

View File

@@ -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 (
<Link href={href} onClick={handleClick}>
{children}
</Link>
);
}

View File

@@ -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 (
<div className={styles["menu-controls"]}>
<div className={styles["action"]}>
<ButtonLink onClick={openSearchModal}>Rechercher</ButtonLink>
<kbd>S</kbd>
</div>
<div className={styles["action"]}>
<ButtonLink href={PATHS.CATEGORY.CREATE}>Créer categorie</ButtonLink>
<kbd>C</kbd>
</div>
<div className={styles["action"]}>
<ButtonLink
href={`${PATHS.LINK.CREATE}?categoryId=${categoryActive.id}`}
>
Créer lien
</ButtonLink>
<kbd>L</kbd>
</div>
</div>
);
}

View File

@@ -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({
/>
</BlockWrapper>
<BlockWrapper>
<MenuControls
<NavigationLinks
categoryActive={categoryActive}
openSearchModal={openSearchModal}
/>
@@ -82,36 +82,3 @@ export default function SideMenu({
</div>
);
}
function MenuControls({
categoryActive,
openSearchModal,
}: {
categoryActive: SideMenuProps["categoryActive"];
openSearchModal: SideMenuProps["openSearchModal"];
}) {
const handleOpenSearchModal = (event) => {
event.preventDefault();
openSearchModal();
};
return (
<div className={styles["menu-controls"]}>
<div className={styles["action"]}>
<LinkTag href={"/#"} onClick={handleOpenSearchModal}>
Rechercher
</LinkTag>
<kbd>S</kbd>
</div>
<div className={styles["action"]}>
<LinkTag href={PATHS.CATEGORY.CREATE}>Créer categorie</LinkTag>
<kbd>C</kbd>
</div>
<div className={styles["action"]}>
<LinkTag href={`${PATHS.LINK.CREATE}?categoryId=${categoryActive.id}`}>
Créer lien
</LinkTag>
<kbd>L</kbd>
</div>
</div>
);
}

View File

@@ -0,0 +1,25 @@
import { useEffect, useState } from "react";
export function useMediaQuery(query: string): boolean {
const [matches, setMatches] = useState<boolean>(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;
}

View File

@@ -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<Category[]>(props.categories);
const [categoryActive, setCategoryActive] = useState<Category | null>(
@@ -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 (
<PageTransition className="App">
<SideMenu
categories={categories}
favorites={favorites}
handleSelectCategory={handleSelectCategory}
categoryActive={categoryActive}
openSearchModal={modal.open}
isModalShowing={modal.isShowing}
/>
{isMobile ? (
<>
<button onClick={mobileModal.open}>open mobile modal</button>
<AnimatePresence>
{mobileModal.isShowing && (
<Modal close={mobileModal.close}>
<SideMenu
categories={categories}
favorites={favorites}
handleSelectCategory={handleSelectCategory}
categoryActive={categoryActive}
openSearchModal={searchModal.open}
isModalShowing={searchModal.isShowing}
/>
</Modal>
)}
</AnimatePresence>
</>
) : (
<SideMenu
categories={categories}
favorites={favorites}
handleSelectCategory={handleSelectCategory}
categoryActive={categoryActive}
openSearchModal={searchModal.open}
isModalShowing={searchModal.isShowing}
/>
)}
<Links category={categoryActive} toggleFavorite={toggleFavorite} />
<AnimatePresence>
{modal.isShowing && (
{searchModal.isShowing && (
<SearchModal
close={modal.close}
close={searchModal.close}
categories={categories}
items={itemsSearch}
handleSelectCategory={handleSelectCategory}

View File

@@ -198,3 +198,9 @@ kbd {
width: 100%;
}
}
@media (max-width: 768px) {
.App {
flex-direction: column;
}
}