From cedea2621fed0ccec6405397c4649a6b80711e61 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Wed, 15 Feb 2023 10:48:22 +0700 Subject: [PATCH 1/7] feat: icon sidebar --- CHANGELOG.md | 3 +- src/lib/layout/Navbar.tsx | 523 +++++++++++++++++++++++++------------- src/lib/layout/index.tsx | 14 +- 3 files changed, 357 insertions(+), 183 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd24c6765..9d8e7e63a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Features +- [#192](https://github.com/alleslabs/celatone-frontend/pull/192) Add alternative sidebar with only icons - [#133](https://github.com/alleslabs/celatone-frontend/pull/133) Add OG and default SEO with next-seo - [#160](https://github.com/alleslabs/celaotne-frontend/pull/160) Add remaining public codes and contracts info - [#162](https://github.com/alleslabs/celatone-frontend/pull/162) Add sentry.io for error logging and stack tracing @@ -144,7 +145,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Bug fixes -- [#188](https://github.com/alleslabs/celatone-frontend/pull/188) Fix "No contact description" prefill in description section in contract detail page +- [#188](https://github.com/alleslabs/celatone-frontend/pull/188) Fix "No contact description" prefill in description section in contract detail page - [#187](https://github.com/alleslabs/celatone-frontend/pull/187) Fix renaming list flicker to the all lists for a second - [#184](https://github.com/alleslabs/celatone-frontend/pull/184) Fix next seo to use default seo - [#186](https://github.com/alleslabs/celatone-frontend/pull/186) Fix logo navigation diff --git a/src/lib/layout/Navbar.tsx b/src/lib/layout/Navbar.tsx index 7e4be83d4..29ce622cd 100644 --- a/src/lib/layout/Navbar.tsx +++ b/src/lib/layout/Navbar.tsx @@ -1,4 +1,14 @@ -import { Flex, Box, Text, Icon, Image } from "@chakra-ui/react"; +import { + Flex, + Box, + Text, + Icon, + Image, + Button, + IconButton, + chakra, + Tooltip, +} from "@chakra-ui/react"; import { useWallet } from "@cosmos-kit/react"; import { observer } from "mobx-react-lite"; import { useRouter } from "next/router"; @@ -15,6 +25,7 @@ import { MdOutlineHistory, MdPublic, MdReadMore, + MdDoubleArrow, } from "react-icons/md"; import { AppLink } from "lib/components/AppLink"; @@ -24,6 +35,23 @@ import { useContractStore, usePublicProjectStore } from "lib/hooks"; import { cmpContractListInfo } from "lib/stores/contract"; import { formatSlugName } from "lib/utils"; +const pebble800 = "pebble.800"; + +const StyledIconButton = chakra(IconButton, { + baseStyle: { + display: "flex", + alignItems: "center", + fontSize: "24px", + h: "fit-content", + minW: "fit-content", + transition: "all .25s ease-in-out", + borderRadius: "0px", + p: 1, + mt: 2, + mx: 2, + }, +}); + interface SubmenuInfo { name: string; slug: string; @@ -36,189 +64,326 @@ interface MenuInfo { submenu: SubmenuInfo[]; } -const Navbar = observer(() => { - const { getContractLists } = useContractStore(); - const { getSavedPublicProjects } = usePublicProjectStore(); - const { currentChainRecord } = useWallet(); - - const navMenu: MenuInfo[] = [ - { - category: "Overview", - submenu: [ - { name: "Overview", slug: "/", icon: MdHome }, - { - name: "Past Transactions", - slug: "/past-txs", - icon: MdOutlineHistory, - }, - ], - }, - { - category: "Quick Actions", - submenu: [ - { - name: "Deploy Contract", - slug: "/deploy", - icon: MdOutlineAdd, - }, - { - name: "Query", - slug: "/query", - icon: MdSearch, - }, - { - name: "Execute", - slug: "/execute", - icon: MdInput, - }, - { - name: "Migrate", - slug: "/migrate", - icon: MdReadMore, - }, - ], - }, - { - category: "Codes", - submenu: [ - { name: "My Codes", slug: "/codes", icon: MdCode }, - { name: "Recent Codes", slug: "/recent-codes", icon: MdPublic }, - ], - }, - { - category: "Contracts", - submenu: [ - { - name: INSTANTIATED_LIST_NAME, - slug: `/contract-list/${formatSlugName(INSTANTIATED_LIST_NAME)}`, - icon: getListIcon(INSTANTIATED_LIST_NAME), - }, - { - name: SAVED_LIST_NAME, - slug: `/contract-list/${formatSlugName(SAVED_LIST_NAME)}`, - icon: getListIcon(SAVED_LIST_NAME), - }, - ...getContractLists() - .filter((list) => list.slug !== formatSlugName(SAVED_LIST_NAME)) - .sort(cmpContractListInfo) - .slice(0, 3) - .map((list) => ({ - name: list.name, - slug: `/contract-list/${list.slug}`, - icon: getListIcon(list.name), - })), - { - name: "View All Lists", - slug: "/contract-list", - icon: MdMoreHoriz, - }, - ], - }, - ]; - - if (currentChainRecord?.chain.network_type === "mainnet") { - navMenu.push({ - category: "Public Projects", - submenu: [ - ...getSavedPublicProjects().map((list) => ({ - name: list.name, - slug: `/public-project/${list.slug}`, - logo: list.logo, - })), - { - name: "View All Projects", - slug: "/public-project", - icon: MdMoreHoriz, - }, - ], - }); - } - const router = useRouter(); - const { network } = router.query; - const pathName = router.asPath; - - const isCurrentPage = useCallback( - (slug: string) => { - if (network) { - return slug === "/" - ? pathName === `/${network}` - : pathName === `/${network}${slug}`; - } - return pathName === `${slug}`; - }, - [network, pathName] - ); - - return ( - - - {navMenu.map((item) => ( - - - - {item.category} - - {item.category === "Contracts" && ( - , - children: "NEW LIST", - }} +interface NavMenuProps { + navMenu: MenuInfo[]; + isCurrentPage: (slug: string) => boolean; + handleResize?: () => void; +} + +interface NavbarProps { + isFull: boolean; + handleCollapse: () => void; + handleExpand?: () => void; +} + +const FullNavMenu = ({ + navMenu, + isCurrentPage, + handleResize, +}: NavMenuProps) => ( + + {navMenu.map((item) => ( + + + + {item.category} + + {item.category === "Overview" && ( + + )} + {item.category === "Contracts" && ( + , + children: "NEW LIST", + }} + /> + )} + + {item.submenu.map((submenu) => ( + + + {submenu.icon && ( + + )} + {submenu.logo && ( + {submenu.slug} )} + + {submenu.name} + - {item.submenu.map((submenu) => ( - - + ))} + + ))} + +); + +const IconNavMenu = ({ + navMenu, + isCurrentPage, + handleResize, +}: NavMenuProps) => ( + + {navMenu.map((item) => ( + + + {item.category === "Overview" && ( + + } + onClick={handleResize} + _hover={{ bg: pebble800, borderRadius: "8px" }} + /> + + )} + {item.category === "Contracts" && ( + - {submenu.icon && ( - - )} - {submenu.logo && ( - {submenu.slug} - )} - - {submenu.name} - - - - ))} - + } + _hover={{ bg: pebble800, borderRadius: "8px" }} + /> + + } + /> + )} + + {item.submenu.map((submenu) => ( + + + + {submenu.icon && ( + + )} + {submenu.logo && ( + {submenu.slug} + )} + + + ))} - - ); -}); + ))} + +); + +const Navbar = observer( + ({ isFull, handleCollapse, handleExpand }: NavbarProps) => { + const { getContractLists } = useContractStore(); + const { getSavedPublicProjects } = usePublicProjectStore(); + const { currentChainRecord } = useWallet(); + + const router = useRouter(); + const { network } = router.query; + const pathName = router.asPath; + + const isCurrentPage = useCallback( + (slug: string) => { + if (network) { + return slug === "/" + ? pathName === `/${network}` + : pathName === `/${network}${slug}`; + } + return pathName === `${slug}`; + }, + [network, pathName] + ); + + const navMenu: MenuInfo[] = [ + { + category: "Overview", + submenu: [ + { name: "Overview", slug: "/", icon: MdHome }, + { + name: "Past Transactions", + slug: "/past-txs", + icon: MdOutlineHistory, + }, + ], + }, + { + category: "Quick Actions", + submenu: [ + { + name: "Deploy Contract", + slug: "/deploy", + icon: MdOutlineAdd, + }, + { + name: "Query", + slug: "/query", + icon: MdSearch, + }, + { + name: "Execute", + slug: "/execute", + icon: MdInput, + }, + { + name: "Migrate", + slug: "/migrate", + icon: MdReadMore, + }, + ], + }, + { + category: "Codes", + submenu: [ + { name: "My Codes", slug: "/codes", icon: MdCode }, + { name: "Recent Codes", slug: "/recent-codes", icon: MdPublic }, + ], + }, + { + category: "Contracts", + submenu: [ + { + name: INSTANTIATED_LIST_NAME, + slug: `/contract-list/${formatSlugName(INSTANTIATED_LIST_NAME)}`, + icon: getListIcon(INSTANTIATED_LIST_NAME), + }, + { + name: SAVED_LIST_NAME, + slug: `/contract-list/${formatSlugName(SAVED_LIST_NAME)}`, + icon: getListIcon(SAVED_LIST_NAME), + }, + ...getContractLists() + .filter((list) => list.slug !== formatSlugName(SAVED_LIST_NAME)) + .sort(cmpContractListInfo) + .slice(0, 3) + .map((list) => ({ + name: list.name, + slug: `/contract-list/${list.slug}`, + icon: getListIcon(list.name), + })), + { + name: "View All Lists", + slug: "/contract-list", + icon: MdMoreHoriz, + }, + ], + }, + ]; + + if (currentChainRecord?.chain.network_type === "mainnet") { + navMenu.push({ + category: "Public Projects", + submenu: [ + ...getSavedPublicProjects().map((list) => ({ + name: list.name, + slug: `/public-project/${list.slug}`, + logo: list.logo, + })), + { + name: "View All Projects", + slug: "/public-project", + icon: MdMoreHoriz, + }, + ], + }); + } + + return ( + + {isFull ? ( + + ) : ( + + )} + + ); + } +); export default Navbar; diff --git a/src/lib/layout/index.tsx b/src/lib/layout/index.tsx index ff873a3ff..739e8222b 100644 --- a/src/lib/layout/index.tsx +++ b/src/lib/layout/index.tsx @@ -1,8 +1,9 @@ import { Grid, GridItem } from "@chakra-ui/react"; import { useRouter } from "next/router"; import type { ReactNode } from "react"; -import { useEffect } from "react"; +import { useState, useEffect } from "react"; +import { useMobile } from "lib/hooks"; import { scrollToTop } from "lib/utils"; import Footer from "./Footer"; @@ -15,6 +16,9 @@ type LayoutProps = { const Layout = ({ children }: LayoutProps) => { const router = useRouter(); + const isMobile = useMobile(); + + const [isFull, setIsFull] = useState(!isMobile); useEffect(() => { scrollToTop(); @@ -24,7 +28,7 @@ const Layout = ({ children }: LayoutProps) => { templateAreas={`"header header" "nav main"`} gridTemplateRows="70px 1fr" - gridTemplateColumns="224px 1fr" + gridTemplateColumns={isFull ? "224px 1fr" : "48px 1fr"} h="100vh" overflowX="hidden" bg="background.main" @@ -33,7 +37,11 @@ const Layout = ({ children }: LayoutProps) => {
- + setIsFull(false)} + handleExpand={isMobile ? undefined : () => setIsFull(true)} + />
{children}
From 3f6605b36c57b5697f27980b92046dfee3e87829 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Wed, 15 Feb 2023 17:25:35 +0700 Subject: [PATCH 2/7] fix: hover color --- src/lib/layout/Navbar.tsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/lib/layout/Navbar.tsx b/src/lib/layout/Navbar.tsx index 29ce622cd..e03423335 100644 --- a/src/lib/layout/Navbar.tsx +++ b/src/lib/layout/Navbar.tsx @@ -49,6 +49,7 @@ const StyledIconButton = chakra(IconButton, { p: 1, mt: 2, mx: 2, + _hover: { borderRadius: "8px" }, }, }); @@ -188,7 +189,6 @@ const IconNavMenu = ({ variant="ghost-info" icon={} onClick={handleResize} - _hover={{ bg: pebble800, borderRadius: "8px" }} /> )} @@ -201,11 +201,7 @@ const IconNavMenu = ({ placement="right" bg="honeydew.darker" > - } - _hover={{ bg: pebble800, borderRadius: "8px" }} - /> + } /> } /> From 6a8c6853bd3345018a627ea40f0dc4c493b409c2 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Thu, 16 Feb 2023 15:36:58 +0700 Subject: [PATCH 3/7] fix: remove new list icon --- src/lib/layout/Navbar.tsx | 40 ++++++++------------------------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/src/lib/layout/Navbar.tsx b/src/lib/layout/Navbar.tsx index e03423335..45691705a 100644 --- a/src/lib/layout/Navbar.tsx +++ b/src/lib/layout/Navbar.tsx @@ -6,7 +6,6 @@ import { Image, Button, IconButton, - chakra, Tooltip, } from "@chakra-ui/react"; import { useWallet } from "@cosmos-kit/react"; @@ -37,22 +36,6 @@ import { formatSlugName } from "lib/utils"; const pebble800 = "pebble.800"; -const StyledIconButton = chakra(IconButton, { - baseStyle: { - display: "flex", - alignItems: "center", - fontSize: "24px", - h: "fit-content", - minW: "fit-content", - transition: "all .25s ease-in-out", - borderRadius: "0px", - p: 1, - mt: 2, - mx: 2, - _hover: { borderRadius: "8px" }, - }, -}); - interface SubmenuInfo { name: string; slug: string; @@ -185,27 +168,20 @@ const IconNavMenu = ({ placement="right" bg="honeydew.darker" > - } onClick={handleResize} /> )} - {item.category === "Contracts" && ( - - } /> - - } - /> - )} {item.submenu.map((submenu) => ( From ff29dc64636eabf60877bfb4a6e891fe0f0d7e06 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Mon, 20 Feb 2023 10:45:24 +0700 Subject: [PATCH 4/7] fix: move change to unrelease --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2f9c894e..96a571d52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Features + +- [#192](https://github.com/alleslabs/celatone-frontend/pull/192) Add alternative sidebar with only icons + ### Bug fixes - [#213](https://github.com/alleslabs/celatone-frontend/pull/213) Fix `window.crypto.randomUUID()` in old safari version (< 15.4) and `at()` of array @@ -45,7 +49,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Features -- [#192](https://github.com/alleslabs/celatone-frontend/pull/192) Add alternative sidebar with only icons - [#199](https://github.com/alleslabs/celatone-frontend/pull/199) Final prelaunch cleanup - [#202](https://github.com/alleslabs/celatone-frontend/pull/202) Reorder absolute and relative timestmap in stored block height - [#201](https://github.com/alleslabs/celatone-frontend/pull/201) Add GPLv3 license From 303317dba608385e6fef4bab9023edd1ae25d82b Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Mon, 20 Feb 2023 16:09:15 +0700 Subject: [PATCH 5/7] fix: icon size --- src/lib/layout/Navbar.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib/layout/Navbar.tsx b/src/lib/layout/Navbar.tsx index 7d41b0b57..fe4c2d882 100644 --- a/src/lib/layout/Navbar.tsx +++ b/src/lib/layout/Navbar.tsx @@ -66,7 +66,7 @@ const FullNavMenu = ({ isCurrentPage, handleResize, }: NavMenuProps) => ( - + {navMenu.map((item) => ( ( - + {navMenu.map((item) => ( Date: Mon, 20 Feb 2023 16:19:19 +0700 Subject: [PATCH 6/7] fix: comments --- src/lib/layout/Navbar.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/lib/layout/Navbar.tsx b/src/lib/layout/Navbar.tsx index fe4c2d882..6187fa559 100644 --- a/src/lib/layout/Navbar.tsx +++ b/src/lib/layout/Navbar.tsx @@ -35,8 +35,6 @@ import { AmpEvent, AmpTrack } from "lib/services/amplitude"; import { cmpContractListInfo } from "lib/stores/contract"; import { formatSlugName } from "lib/utils"; -const pebble800 = "pebble.800"; - interface SubmenuInfo { name: string; slug: string; @@ -118,11 +116,13 @@ const FullNavMenu = ({ gap="2" p={2} cursor="pointer" - _hover={{ bg: pebble800, borderRadius: "8px" }} + _hover={{ bg: "pebble.700", borderRadius: "8px" }} my="1px" transition="all .25s ease-in-out" alignItems="center" - bgColor={isCurrentPage(submenu.slug) ? pebble800 : "transparent"} + bgColor={ + isCurrentPage(submenu.slug) ? "pebble.800" : "transparent" + } borderRadius={isCurrentPage(submenu.slug) ? "8px" : "0px"} > {submenu.icon && ( @@ -155,6 +155,7 @@ const IconNavMenu = ({ {navMenu.map((item) => ( From 5651900cc4a54660b1cf3d7dc8d7ea5da38ee85a Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Tue, 21 Feb 2023 11:18:08 +0700 Subject: [PATCH 7/7] refactor: separate each nav into its comp --- CHANGELOG.md | 3 - src/lib/layout/Navbar.tsx | 372 ----------------------------- src/lib/layout/index.tsx | 12 +- src/lib/layout/navbar/Collapse.tsx | 99 ++++++++ src/lib/layout/navbar/Expand.tsx | 96 ++++++++ src/lib/layout/navbar/index.tsx | 165 +++++++++++++ src/lib/layout/navbar/type.ts | 19 ++ 7 files changed, 383 insertions(+), 383 deletions(-) delete mode 100644 src/lib/layout/Navbar.tsx create mode 100644 src/lib/layout/navbar/Collapse.tsx create mode 100644 src/lib/layout/navbar/Expand.tsx create mode 100644 src/lib/layout/navbar/index.tsx create mode 100644 src/lib/layout/navbar/type.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 96a571d52..b687ce690 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -162,15 +162,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Bug fixes -# <<<<<<< HEAD - - [#211](https://github.com/alleslabs/celatone-frontend/pull/211) Fix contract count not display for code table in public project - [#208](https://github.com/alleslabs/celatone-frontend/pull/208) Fix messages shown in past tx page (should show only wasm and send messages) - [#200](https://github.com/alleslabs/celatone-frontend/pull/200) Fix add attached assets property - [#198](https://github.com/alleslabs/celatone-frontend/pull/198) Fix handle keplr wallet ready - [#194](https://github.com/alleslabs/celatone-frontend/pull/194) Fix "connect wallet state" for tables - [#196](https://github.com/alleslabs/celatone-frontend/pull/196) Fix rewrite rule for amplitude - > > > > > > > develop - [#188](https://github.com/alleslabs/celatone-frontend/pull/188) Fix "No contact description" prefill in description section in contract detail page - [#187](https://github.com/alleslabs/celatone-frontend/pull/187) Fix renaming list flicker to the all lists for a second - [#184](https://github.com/alleslabs/celatone-frontend/pull/184) Fix next seo to use default seo diff --git a/src/lib/layout/Navbar.tsx b/src/lib/layout/Navbar.tsx deleted file mode 100644 index 6187fa559..000000000 --- a/src/lib/layout/Navbar.tsx +++ /dev/null @@ -1,372 +0,0 @@ -import { - Flex, - Box, - Text, - Icon, - Image, - Button, - IconButton, - Tooltip, -} from "@chakra-ui/react"; -import { useWallet } from "@cosmos-kit/react"; -import { observer } from "mobx-react-lite"; -import { useRouter } from "next/router"; -import { useCallback } from "react"; -import type { IconType } from "react-icons"; -import { - MdHome, - MdCode, - MdMoreHoriz, - MdOutlineAdd, - MdSearch, - MdInput, - MdAdd, - MdOutlineHistory, - MdPublic, - MdReadMore, - MdDoubleArrow, -} from "react-icons/md"; - -import { AppLink } from "lib/components/AppLink"; -import { CreateNewListModal } from "lib/components/modal"; -import { INSTANTIATED_LIST_NAME, getListIcon, SAVED_LIST_NAME } from "lib/data"; -import { useContractStore, usePublicProjectStore } from "lib/hooks"; -import { AmpEvent, AmpTrack } from "lib/services/amplitude"; -import { cmpContractListInfo } from "lib/stores/contract"; -import { formatSlugName } from "lib/utils"; - -interface SubmenuInfo { - name: string; - slug: string; - icon?: IconType; - logo?: string; -} - -interface MenuInfo { - category: string; - submenu: SubmenuInfo[]; -} - -interface NavMenuProps { - navMenu: MenuInfo[]; - isCurrentPage: (slug: string) => boolean; - handleResize?: () => void; -} - -interface NavbarProps { - isFull: boolean; - handleCollapse: () => void; - handleExpand?: () => void; -} - -const FullNavMenu = ({ - navMenu, - isCurrentPage, - handleResize, -}: NavMenuProps) => ( - - {navMenu.map((item) => ( - - - - {item.category} - - {item.category === "Overview" && ( - - )} - {item.category === "Contracts" && ( - , - children: "NEW LIST", - onClick: () => AmpTrack(AmpEvent.USE_SIDEBAR), - }} - /> - )} - - {item.submenu.map((submenu) => ( - AmpTrack(AmpEvent.USE_SIDEBAR)} - > - - {submenu.icon && ( - - )} - {submenu.logo && ( - {submenu.slug} - )} - - {submenu.name} - - - - ))} - - ))} - -); - -const IconNavMenu = ({ - navMenu, - isCurrentPage, - handleResize, -}: NavMenuProps) => ( - - {navMenu.map((item) => ( - - - {item.category === "Overview" && ( - - } - onClick={handleResize} - /> - - )} - - {item.submenu.map((submenu) => ( - AmpTrack(AmpEvent.USE_SIDEBAR)} - > - - - {submenu.icon && ( - - )} - {submenu.logo && ( - {submenu.slug} - )} - - - - ))} - - ))} - -); - -const Navbar = observer( - ({ isFull, handleCollapse, handleExpand }: NavbarProps) => { - const { getContractLists } = useContractStore(); - const { getSavedPublicProjects } = usePublicProjectStore(); - const { currentChainRecord } = useWallet(); - - const router = useRouter(); - const { network } = router.query; - const pathName = router.asPath; - - const isCurrentPage = useCallback( - (slug: string) => { - if (network) { - return slug === "/" - ? pathName === `/${network}` - : pathName === `/${network}${slug}`; - } - return pathName === `${slug}`; - }, - [network, pathName] - ); - - const navMenu: MenuInfo[] = [ - { - category: "Overview", - submenu: [ - { name: "Overview", slug: "/", icon: MdHome }, - { - name: "Past Transactions", - slug: "/past-txs", - icon: MdOutlineHistory, - }, - ], - }, - { - category: "Quick Actions", - submenu: [ - { - name: "Deploy Contract", - slug: "/deploy", - icon: MdOutlineAdd, - }, - { - name: "Query", - slug: "/query", - icon: MdSearch, - }, - { - name: "Execute", - slug: "/execute", - icon: MdInput, - }, - { - name: "Migrate", - slug: "/migrate", - icon: MdReadMore, - }, - ], - }, - { - category: "Codes", - submenu: [ - { name: "My Codes", slug: "/codes", icon: MdCode }, - { name: "Recent Codes", slug: "/recent-codes", icon: MdPublic }, - ], - }, - { - category: "Contracts", - submenu: [ - { - name: INSTANTIATED_LIST_NAME, - slug: `/contract-list/${formatSlugName(INSTANTIATED_LIST_NAME)}`, - icon: getListIcon(INSTANTIATED_LIST_NAME), - }, - { - name: SAVED_LIST_NAME, - slug: `/contract-list/${formatSlugName(SAVED_LIST_NAME)}`, - icon: getListIcon(SAVED_LIST_NAME), - }, - ...getContractLists() - .filter((list) => list.slug !== formatSlugName(SAVED_LIST_NAME)) - .sort(cmpContractListInfo) - .slice(0, 3) - .map((list) => ({ - name: list.name, - slug: `/contract-list/${list.slug}`, - icon: getListIcon(list.name), - })), - { - name: "View All Lists", - slug: "/contract-list", - icon: MdMoreHoriz, - }, - ], - }, - ]; - - if (currentChainRecord?.chain.network_type === "mainnet") { - navMenu.push({ - category: "Public Projects", - submenu: [ - ...getSavedPublicProjects().map((list) => ({ - name: list.name, - slug: `/public-project/${list.slug}`, - logo: list.logo, - })), - { - name: "View All Projects", - slug: "/public-project", - icon: MdMoreHoriz, - }, - ], - }); - } - - return ( - - {isFull ? ( - - ) : ( - - )} - - ); - } -); - -export default Navbar; diff --git a/src/lib/layout/index.tsx b/src/lib/layout/index.tsx index 739e8222b..72f159472 100644 --- a/src/lib/layout/index.tsx +++ b/src/lib/layout/index.tsx @@ -8,7 +8,7 @@ import { scrollToTop } from "lib/utils"; import Footer from "./Footer"; import Header from "./Header"; -import Navbar from "./Navbar"; +import Navbar from "./navbar"; type LayoutProps = { children: ReactNode; @@ -18,7 +18,7 @@ const Layout = ({ children }: LayoutProps) => { const router = useRouter(); const isMobile = useMobile(); - const [isFull, setIsFull] = useState(!isMobile); + const [isExpand, setIsExpand] = useState(!isMobile); useEffect(() => { scrollToTop(); @@ -28,7 +28,7 @@ const Layout = ({ children }: LayoutProps) => { templateAreas={`"header header" "nav main"`} gridTemplateRows="70px 1fr" - gridTemplateColumns={isFull ? "224px 1fr" : "48px 1fr"} + gridTemplateColumns={isExpand ? "224px 1fr" : "48px 1fr"} h="100vh" overflowX="hidden" bg="background.main" @@ -37,11 +37,7 @@ const Layout = ({ children }: LayoutProps) => {
- setIsFull(false)} - handleExpand={isMobile ? undefined : () => setIsFull(true)} - /> +
{children}
diff --git a/src/lib/layout/navbar/Collapse.tsx b/src/lib/layout/navbar/Collapse.tsx new file mode 100644 index 000000000..93e250d92 --- /dev/null +++ b/src/lib/layout/navbar/Collapse.tsx @@ -0,0 +1,99 @@ +import { Box, Flex, Icon, IconButton, Image, Tooltip } from "@chakra-ui/react"; +import { MdDoubleArrow } from "react-icons/md"; + +import { AppLink } from "lib/components/AppLink"; +import { useMobile } from "lib/hooks"; +import { AmpEvent, AmpTrack } from "lib/services/amplitude"; + +import type { NavMenuProps } from "./type"; + +export const CollapseNavMenu = ({ + navMenu, + isCurrentPage, + setIsExpand, +}: NavMenuProps) => { + const isMobile = useMobile(); + + return ( + + {navMenu.map((item) => ( + + + {!isMobile && item.category === "Overview" && ( + + } + onClick={() => setIsExpand(true)} + /> + + )} + + {item.submenu.map((submenu) => ( + AmpTrack(AmpEvent.USE_SIDEBAR)} + > + + + {submenu.icon && ( + + )} + {submenu.logo && ( + {submenu.slug} + )} + + + + ))} + + ))} + + ); +}; diff --git a/src/lib/layout/navbar/Expand.tsx b/src/lib/layout/navbar/Expand.tsx new file mode 100644 index 000000000..1c1c3fb7e --- /dev/null +++ b/src/lib/layout/navbar/Expand.tsx @@ -0,0 +1,96 @@ +import { Box, Button, Flex, Icon, Image, Text } from "@chakra-ui/react"; +import { MdAdd, MdDoubleArrow } from "react-icons/md"; + +import { AppLink } from "lib/components/AppLink"; +import { CreateNewListModal } from "lib/components/modal"; +import { AmpEvent, AmpTrack } from "lib/services/amplitude"; + +import type { NavMenuProps } from "./type"; + +export const ExpandNavMenu = ({ + navMenu, + isCurrentPage, + setIsExpand, +}: NavMenuProps) => ( + + {navMenu.map((item) => ( + + + + {item.category} + + {item.category === "Overview" && ( + + )} + {item.category === "Contracts" && ( + , + children: "NEW LIST", + onClick: () => AmpTrack(AmpEvent.USE_SIDEBAR), + }} + /> + )} + + {item.submenu.map((submenu) => ( + AmpTrack(AmpEvent.USE_SIDEBAR)} + > + + {submenu.icon && ( + + )} + {submenu.logo && ( + {submenu.slug} + )} + + {submenu.name} + + + + ))} + + ))} + +); diff --git a/src/lib/layout/navbar/index.tsx b/src/lib/layout/navbar/index.tsx new file mode 100644 index 000000000..131c78bcb --- /dev/null +++ b/src/lib/layout/navbar/index.tsx @@ -0,0 +1,165 @@ +import { Flex } from "@chakra-ui/react"; +import { useWallet } from "@cosmos-kit/react"; +import { observer } from "mobx-react-lite"; +import { useRouter } from "next/router"; +import { useCallback } from "react"; +import { + MdHome, + MdCode, + MdMoreHoriz, + MdOutlineAdd, + MdSearch, + MdInput, + MdOutlineHistory, + MdPublic, + MdReadMore, +} from "react-icons/md"; + +import { INSTANTIATED_LIST_NAME, getListIcon, SAVED_LIST_NAME } from "lib/data"; +import { useContractStore, usePublicProjectStore } from "lib/hooks"; +import { cmpContractListInfo } from "lib/stores/contract"; +import { formatSlugName } from "lib/utils"; + +import { CollapseNavMenu } from "./Collapse"; +import { ExpandNavMenu } from "./Expand"; +import type { MenuInfo } from "./type"; + +interface NavbarProps { + isExpand: boolean; + setIsExpand: (value: boolean) => void; +} + +const Navbar = observer(({ isExpand, setIsExpand }: NavbarProps) => { + const { getContractLists } = useContractStore(); + const { getSavedPublicProjects } = usePublicProjectStore(); + const { currentChainRecord } = useWallet(); + + const router = useRouter(); + const { network } = router.query; + const pathName = router.asPath; + + const isCurrentPage = useCallback( + (slug: string) => { + if (network) { + return slug === "/" + ? pathName === `/${network}` + : pathName === `/${network}${slug}`; + } + return pathName === `${slug}`; + }, + [network, pathName] + ); + + const navMenu: MenuInfo[] = [ + { + category: "Overview", + submenu: [ + { name: "Overview", slug: "/", icon: MdHome }, + { + name: "Past Transactions", + slug: "/past-txs", + icon: MdOutlineHistory, + }, + ], + }, + { + category: "Quick Actions", + submenu: [ + { + name: "Deploy Contract", + slug: "/deploy", + icon: MdOutlineAdd, + }, + { + name: "Query", + slug: "/query", + icon: MdSearch, + }, + { + name: "Execute", + slug: "/execute", + icon: MdInput, + }, + { + name: "Migrate", + slug: "/migrate", + icon: MdReadMore, + }, + ], + }, + { + category: "Codes", + submenu: [ + { name: "My Codes", slug: "/codes", icon: MdCode }, + { name: "Recent Codes", slug: "/recent-codes", icon: MdPublic }, + ], + }, + { + category: "Contracts", + submenu: [ + { + name: INSTANTIATED_LIST_NAME, + slug: `/contract-list/${formatSlugName(INSTANTIATED_LIST_NAME)}`, + icon: getListIcon(INSTANTIATED_LIST_NAME), + }, + { + name: SAVED_LIST_NAME, + slug: `/contract-list/${formatSlugName(SAVED_LIST_NAME)}`, + icon: getListIcon(SAVED_LIST_NAME), + }, + ...getContractLists() + .filter((list) => list.slug !== formatSlugName(SAVED_LIST_NAME)) + .sort(cmpContractListInfo) + .slice(0, 3) + .map((list) => ({ + name: list.name, + slug: `/contract-list/${list.slug}`, + icon: getListIcon(list.name), + })), + { + name: "View All Lists", + slug: "/contract-list", + icon: MdMoreHoriz, + }, + ], + }, + ]; + + if (currentChainRecord?.chain.network_type === "mainnet") { + navMenu.push({ + category: "Public Projects", + submenu: [ + ...getSavedPublicProjects().map((list) => ({ + name: list.name, + slug: `/public-project/${list.slug}`, + logo: list.logo, + })), + { + name: "View All Projects", + slug: "/public-project", + icon: MdMoreHoriz, + }, + ], + }); + } + + return ( + + {isExpand ? ( + + ) : ( + + )} + + ); +}); + +export default Navbar; diff --git a/src/lib/layout/navbar/type.ts b/src/lib/layout/navbar/type.ts new file mode 100644 index 000000000..95a796a51 --- /dev/null +++ b/src/lib/layout/navbar/type.ts @@ -0,0 +1,19 @@ +import type { IconType } from "react-icons"; + +export interface SubmenuInfo { + name: string; + slug: string; + icon?: IconType; + logo?: string; +} + +export interface MenuInfo { + category: string; + submenu: SubmenuInfo[]; +} + +export interface NavMenuProps { + navMenu: MenuInfo[]; + isCurrentPage: (slug: string) => boolean; + setIsExpand: (value: boolean) => void; +}