From 05166680b035f65c86fea7839208bc8900f1f9f4 Mon Sep 17 00:00:00 2001 From: saml33 Date: Fri, 22 Dec 2023 13:42:24 +1100 Subject: [PATCH] add categories page --- .../{ => categories}/[category]/page.tsx | 14 +- app/(pages)/explore/categories/page.tsx | 47 +++++++ .../tokens}/[slug]/layout.tsx | 2 +- .../{token => explore/tokens}/[slug]/page.tsx | 17 ++- app/(pages)/explore/{ => tokens}/page.tsx | 28 ++-- app/components/explore/Category.tsx | 10 +- app/components/explore/CategorySwitcher.tsx | 4 +- app/components/explore/ExploreCategories.tsx | 120 ++++++++++++++++++ .../{Explore.tsx => ExploreTokens.tsx} | 16 +-- app/components/explore/NoResults.tsx | 9 ++ app/components/explore/TokenTable.tsx | 13 +- .../explore/token-page/TokenInfo.tsx | 2 +- app/components/footer/Footer.tsx | 6 +- .../navigation/DesktopNavigation.tsx | 44 ++++--- .../navigation/MobileNavigation.tsx | 18 +-- app/components/shared/BackButton.tsx | 2 +- app/sitemap.ts | 10 +- .../categories/bridged-portal-small.png | Bin 0 -> 107438 bytes public/images/categories/bridged-portal.png | Bin 0 -> 212771 bytes public/images/categories/defi-small.png | Bin 0 -> 59450 bytes public/images/categories/depin-small.png | Bin 0 -> 69301 bytes .../categories/liquid-staking-small.png | Bin 0 -> 96560 bytes public/images/categories/meme-small.png | Bin 0 -> 47130 bytes public/images/categories/placeholder.png | Bin 206393 -> 16917 bytes tsconfig.tsbuildinfo | 2 +- 25 files changed, 263 insertions(+), 101 deletions(-) rename app/(pages)/explore/{ => categories}/[category]/page.tsx (84%) create mode 100644 app/(pages)/explore/categories/page.tsx rename app/(pages)/{token => explore/tokens}/[slug]/layout.tsx (82%) rename app/(pages)/{token => explore/tokens}/[slug]/page.tsx (82%) rename app/(pages)/explore/{ => tokens}/page.tsx (55%) create mode 100644 app/components/explore/ExploreCategories.tsx rename app/components/explore/{Explore.tsx => ExploreTokens.tsx} (88%) create mode 100644 app/components/explore/NoResults.tsx create mode 100644 public/images/categories/bridged-portal-small.png create mode 100644 public/images/categories/bridged-portal.png create mode 100644 public/images/categories/defi-small.png create mode 100644 public/images/categories/depin-small.png create mode 100644 public/images/categories/liquid-staking-small.png create mode 100644 public/images/categories/meme-small.png diff --git a/app/(pages)/explore/[category]/page.tsx b/app/(pages)/explore/categories/[category]/page.tsx similarity index 84% rename from app/(pages)/explore/[category]/page.tsx rename to app/(pages)/explore/categories/[category]/page.tsx index e3d427eb..70bca52e 100644 --- a/app/(pages)/explore/[category]/page.tsx +++ b/app/(pages)/explore/categories/[category]/page.tsx @@ -1,16 +1,16 @@ import { Metadata } from 'next' import { draftMode } from 'next/headers' import { notFound } from 'next/navigation' -import { fetchTokenPagesForCategory } from '../../../../contentful/tokenPage' +import { fetchTokenPagesForCategory } from '../../../../../contentful/tokenPage' import { fetchTokenCategoryPage, fetchTokenCategoryPages, -} from '../../../../contentful/tokenCategoryPage' -import { fetchMangoTokenData } from '../../../utils/mango' -import Category from '../../../components/explore/Category' -import { MAX_CONTENT_WIDTH } from '../../../utils/constants' -import RichTextDisplay from '../../../components/rich-text/RichTextDisplay' -import DataDisclaimer from '../../../components/explore/DataDisclaimer' +} from '../../../../../contentful/tokenCategoryPage' +import { fetchMangoTokenData } from '../../../../utils/mango' +import Category from '../../../../components/explore/Category' +import { MAX_CONTENT_WIDTH } from '../../../../utils/constants' +import RichTextDisplay from '../../../../components/rich-text/RichTextDisplay' +import DataDisclaimer from '../../../../components/explore/DataDisclaimer' interface TokenCategoryPageParams { category: string diff --git a/app/(pages)/explore/categories/page.tsx b/app/(pages)/explore/categories/page.tsx new file mode 100644 index 00000000..95a2ea9f --- /dev/null +++ b/app/(pages)/explore/categories/page.tsx @@ -0,0 +1,47 @@ +import { fetchTokenPages } from '../../../../contentful/tokenPage' +import { draftMode } from 'next/headers' +import { Metadata } from 'next' +import { Suspense } from 'react' +import { MAX_CONTENT_WIDTH } from '../../../utils/constants' +import { fetchTokenCategoryPages } from '../../../../contentful/tokenCategoryPage' +import DataDisclaimer from '../../../components/explore/DataDisclaimer' +import ExploreCategories from '../../../components/explore/ExploreCategories' + +export const metadata: Metadata = { + title: 'Explore Listed Token Categories on Mango Markets', + description: + 'Discover and learn about the different types of tokens listed on Mango', +} + +function ExploreCategoriesFallback() { + return <> +} + +async function ExploreCategoriesPage() { + const tokens = await fetchTokenPages({ + preview: draftMode().isEnabled, + }) + const categoryPages = await fetchTokenCategoryPages({ + preview: draftMode().isEnabled, + }) + return tokens && tokens?.length ? ( + }> + +
+ +
+
+ ) : ( +
+
+

+ Something went wrong. Try refreshing the page. +

+
+
+ ) +} + +export default ExploreCategoriesPage diff --git a/app/(pages)/token/[slug]/layout.tsx b/app/(pages)/explore/tokens/[slug]/layout.tsx similarity index 82% rename from app/(pages)/token/[slug]/layout.tsx rename to app/(pages)/explore/tokens/[slug]/layout.tsx index 37d3d756..32985df4 100644 --- a/app/(pages)/token/[slug]/layout.tsx +++ b/app/(pages)/explore/tokens/[slug]/layout.tsx @@ -1,4 +1,4 @@ -import BackButton from '../../../components/shared/BackButton' +import BackButton from '../../../../components/shared/BackButton' export default function TokenPageLayout({ children, diff --git a/app/(pages)/token/[slug]/page.tsx b/app/(pages)/explore/tokens/[slug]/page.tsx similarity index 82% rename from app/(pages)/token/[slug]/page.tsx rename to app/(pages)/explore/tokens/[slug]/page.tsx index 16666980..fcb37c39 100644 --- a/app/(pages)/token/[slug]/page.tsx +++ b/app/(pages)/explore/tokens/[slug]/page.tsx @@ -4,13 +4,16 @@ import { notFound } from 'next/navigation' import { fetchTokenPage, fetchTokenPages, -} from '../../../../contentful/tokenPage' -import RichTextDisplay from '../../../components/rich-text/RichTextDisplay' -import { fetchMangoMarketData, fetchMangoTokenData } from '../../../utils/mango' -import { MangoMarketsData, MangoTokenData } from '../../../types/mango' -import TokenMangoStats from '../../../components/explore/token-page/TokenMangoStats' -import DataDisclaimer from '../../../components/explore/DataDisclaimer' -import InfoAndStats from '../../../components/explore/token-page/InfoAndStats' +} from '../../../../../contentful/tokenPage' +import RichTextDisplay from '../../../../components/rich-text/RichTextDisplay' +import { + fetchMangoMarketData, + fetchMangoTokenData, +} from '../../../../utils/mango' +import { MangoMarketsData, MangoTokenData } from '../../../../types/mango' +import TokenMangoStats from '../../../../components/explore/token-page/TokenMangoStats' +import DataDisclaimer from '../../../../components/explore/DataDisclaimer' +import InfoAndStats from '../../../../components/explore/token-page/InfoAndStats' const SECTION_WRAPPER_CLASSES = 'border-t border-th-bkg-3 pt-6 mt-12' diff --git a/app/(pages)/explore/page.tsx b/app/(pages)/explore/tokens/page.tsx similarity index 55% rename from app/(pages)/explore/page.tsx rename to app/(pages)/explore/tokens/page.tsx index 41f8268e..5dc65ebe 100644 --- a/app/(pages)/explore/page.tsx +++ b/app/(pages)/explore/tokens/page.tsx @@ -1,12 +1,11 @@ -import { fetchTokenPages } from '../../../contentful/tokenPage' -import Explore from '../../components/explore/Explore' +import { fetchTokenPages } from '../../../../contentful/tokenPage' +import ExploreTokens from '../../../components/explore/ExploreTokens' import { draftMode } from 'next/headers' -import { fetchMangoTokensData } from '../../utils/mango' +import { fetchMangoTokensData } from '../../../utils/mango' import { Metadata } from 'next' import { Suspense } from 'react' -import { MAX_CONTENT_WIDTH } from '../../utils/constants' -import { fetchTokenCategoryPages } from '../../../contentful/tokenCategoryPage' -import DataDisclaimer from '../../components/explore/DataDisclaimer' +import { MAX_CONTENT_WIDTH } from '../../../utils/constants' +import DataDisclaimer from '../../../components/explore/DataDisclaimer' export const metadata: Metadata = { title: 'Explore Listed Tokens on Mango Markets', @@ -14,25 +13,18 @@ export const metadata: Metadata = { 'Live prices, charts, stats and alpha on every token listed on Mango Markets.', } -function ExploreFallback() { +function ExploreTokensFallback() { return <> } -async function ExplorePage() { +async function ExploreTokensPage() { const tokens = await fetchTokenPages({ preview: draftMode().isEnabled, }) const mangoTokensData = await fetchMangoTokensData() - const categoryPages = await fetchTokenCategoryPages({ - preview: draftMode().isEnabled, - }) return tokens && tokens?.length ? ( - }> - + }> +
@@ -50,4 +42,4 @@ async function ExplorePage() { ) } -export default ExplorePage +export default ExploreTokensPage diff --git a/app/components/explore/Category.tsx b/app/components/explore/Category.tsx index e0b9cae6..ed8abef6 100644 --- a/app/components/explore/Category.tsx +++ b/app/components/explore/Category.tsx @@ -7,8 +7,9 @@ import CategorySwitcher from './CategorySwitcher' import TableViewToggle from './TableViewToggle' import TokenTable from './TokenTable' import { TokenCategoryPage } from '../../../contentful/tokenCategoryPage' -import { sortTokens } from './Explore' +import { sortTokens } from './ExploreTokens' import { MAX_CONTENT_WIDTH } from '../../utils/constants' +import BackButton from '../shared/BackButton' const Category = ({ categoryPages, @@ -35,13 +36,16 @@ const Category = ({ return ( <>
+
+ +
-
+

{`Explore ${category}`}

diff --git a/app/components/explore/CategorySwitcher.tsx b/app/components/explore/CategorySwitcher.tsx index 270eb433..fccfa72a 100644 --- a/app/components/explore/CategorySwitcher.tsx +++ b/app/components/explore/CategorySwitcher.tsx @@ -5,7 +5,7 @@ import { useParams, useRouter } from 'next/navigation' import { TokenCategoryPage } from '../../../contentful/tokenCategoryPage' const goToCategoryPage = (categorySlug: string, router: AppRouterInstance) => { - router.push(`/explore/${categorySlug}`) + router.push(`/explore/categories/${categorySlug}`) } const CategorySwitcher = ({ @@ -40,7 +40,7 @@ const CategorySwitcher = ({ const handleSetCategory = (cat: string) => { setSelectedCategory(cat) if (cat === 'All') { - router.push('/explore', { shallow: true }) + router.push('/explore/categories', { shallow: true }) } else { const slug = categories.find((category) => category.category === cat) ?.slug diff --git a/app/components/explore/ExploreCategories.tsx b/app/components/explore/ExploreCategories.tsx new file mode 100644 index 00000000..27a6a2c4 --- /dev/null +++ b/app/components/explore/ExploreCategories.tsx @@ -0,0 +1,120 @@ +'use client' + +import { MagnifyingGlassIcon } from '@heroicons/react/20/solid' +import { ChangeEvent, useMemo, useState } from 'react' +import Input from '../forms/Input' +import { TokenCategoryPage } from '../../../contentful/tokenCategoryPage' +import { MAX_CONTENT_WIDTH } from '../../utils/constants' +import Link from 'next/link' +import NoResults from './NoResults' + +const generateSearchTerm = (item: TokenCategoryPage, searchValue: string) => { + const normalizedSearchValue = searchValue.toLowerCase() + const value = item.category.toLowerCase() + + const isMatching = value.includes(normalizedSearchValue) + const matchingPercent = isMatching + ? normalizedSearchValue.length / item.category.length + : 0 + + const matchingIdx = value.indexOf(normalizedSearchValue) + + return { + category: item, + matchingIdx, + matchingPercent, + } +} + +const startSearch = (items: TokenCategoryPage[], searchValue: string) => { + return items + .map((item) => generateSearchTerm(item, searchValue)) + .filter((item) => item.matchingIdx >= 0) + .sort((i1, i2) => i1.matchingIdx - i2.matchingIdx) + .sort((i1, i2) => i2.matchingPercent - i1.matchingPercent) + .map((item) => item.category) +} + +const ExploreCategories = ({ + categoryPages, +}: { + categoryPages: TokenCategoryPage[] +}) => { + const [searchString, setSearchString] = useState('') + + const filteredCategories = useMemo(() => { + return searchString + ? startSearch(categoryPages, searchString) + : categoryPages + }, [searchString, categoryPages]) + + const handleUpdateSearch = (e: ChangeEvent) => { + setSearchString(e.target.value) + } + + return ( + <> +
+
+
+

+ Explore listed token categories +

+
+
+
+
+
+

{`${categoryPages?.length} token categories`}

+
+ + +
+
+ {filteredCategories?.length ? ( +
+ {filteredCategories.map((cat) => { + const { category, description, slug } = cat + const imgSrc = description + ? `/images/categories/${slug}-small.png` + : '/images/new/cube-bg.png' + return ( +
+ +
+
+
+
+

{category}

+
+ +
+ ) + })} +
+ ) : ( + + )} +
+ + ) +} + +export default ExploreCategories diff --git a/app/components/explore/Explore.tsx b/app/components/explore/ExploreTokens.tsx similarity index 88% rename from app/components/explore/Explore.tsx rename to app/components/explore/ExploreTokens.tsx index 3b0ca3bd..e76897c3 100644 --- a/app/components/explore/Explore.tsx +++ b/app/components/explore/ExploreTokens.tsx @@ -6,9 +6,7 @@ import { MagnifyingGlassIcon } from '@heroicons/react/20/solid' import { ChangeEvent, useMemo, useState } from 'react' import Input from '../forms/Input' import TokenTable from './TokenTable' -import CategorySwitcher from './CategorySwitcher' import TableViewToggle from './TableViewToggle' -import { TokenCategoryPage } from '../../../contentful/tokenCategoryPage' import { MAX_CONTENT_WIDTH } from '../../utils/constants' const generateSearchTerm = (item: TokenPageWithData, searchValue: string) => { @@ -65,12 +63,10 @@ export const sortTokens = (tokens: TokenPageWithData[]) => { }) } -const Explore = ({ - categoryPages, +const ExploreTokens = ({ tokens, mangoTokensData, }: { - categoryPages: TokenCategoryPage[] tokens: TokenPageWithData[] mangoTokensData: MangoTokenData[] }) => { @@ -91,7 +87,7 @@ const Explore = ({ className={`flex flex-col items-start justify-end h-[264px] bg-[url('/images/new/cube-bg.png')] bg-repeat`} >
-
+

Explore listed tokens

@@ -99,11 +95,11 @@ const Explore = ({
-
+

{`${tokens?.length} tokens listed on Mango`}

- -
+ {/* */} +
{ + return ( +
+

{message}

+
+ ) +} + +export default NoResults diff --git a/app/components/explore/TokenTable.tsx b/app/components/explore/TokenTable.tsx index d29589fa..310e057b 100644 --- a/app/components/explore/TokenTable.tsx +++ b/app/components/explore/TokenTable.tsx @@ -26,6 +26,7 @@ import { AppRouterInstance } from 'next/dist/shared/lib/app-router-context.share import { useRouter } from 'next/navigation' import { BirdeyePriceHistoryData } from '../../types/birdeye' import SheenLoader from '../shared/SheenLoader' +import NoResults from './NoResults' export type FormattedTableData = { change: number | undefined @@ -43,7 +44,7 @@ export type FormattedTableData = { } const goToTokenPage = (slug: string, router: AppRouterInstance) => { - router.push(`/token/${slug}`) + router.push(`/explore/tokens/${slug}`) } const TokenTable = ({ @@ -284,16 +285,8 @@ const TokenTable = ({
) ) : ( - + ) } export default TokenTable - -const NoTokenResults = () => { - return ( -
-

No tokens found...

-
- ) -} diff --git a/app/components/explore/token-page/TokenInfo.tsx b/app/components/explore/token-page/TokenInfo.tsx index 1533d720..767ed978 100644 --- a/app/components/explore/token-page/TokenInfo.tsx +++ b/app/components/explore/token-page/TokenInfo.tsx @@ -197,7 +197,7 @@ const TokenInfo = ({ return ( diff --git a/app/components/footer/Footer.tsx b/app/components/footer/Footer.tsx index b9216eaa..291b46f4 100644 --- a/app/components/footer/Footer.tsx +++ b/app/components/footer/Footer.tsx @@ -39,10 +39,8 @@ const Footer = () => {
- - - - + + { return (
- + + + + + + {/* */} @@ -178,19 +184,19 @@ const NavigationItemPanel = ({ children }: { children: ReactNode }) => { return
{children}
} -const NavigationLink = ({ path, text }: { path: string; text: string }) => { - const pathname = usePathname() - return ( - - - {text} - - - ) -} +// const NavigationLink = ({ path, text }: { path: string; text: string }) => { +// const pathname = usePathname() +// return ( +// +// +// {text} +// +// +// ) +// } diff --git a/app/components/navigation/MobileNavigation.tsx b/app/components/navigation/MobileNavigation.tsx index 18b7a4df..3c5f319d 100644 --- a/app/components/navigation/MobileNavigation.tsx +++ b/app/components/navigation/MobileNavigation.tsx @@ -49,24 +49,14 @@ const MenuPanel = ({

Explore

- -
diff --git a/app/components/shared/BackButton.tsx b/app/components/shared/BackButton.tsx index caf25361..90e985c5 100644 --- a/app/components/shared/BackButton.tsx +++ b/app/components/shared/BackButton.tsx @@ -7,7 +7,7 @@ const BackButton = () => { const router = useRouter() return (