Fix group navigation
This commit is contained in:
parent
6c3338f5d7
commit
64cb7c2474
|
@ -6,15 +6,29 @@ import { trackCallback } from 'web/lib/service/analytics'
|
||||||
import TrophyIcon from 'web/lib/icons/trophy-icon'
|
import TrophyIcon from 'web/lib/icons/trophy-icon'
|
||||||
import { useUser } from 'web/hooks/use-user'
|
import { useUser } from 'web/hooks/use-user'
|
||||||
import NotificationsIcon from '../notifications-icon'
|
import NotificationsIcon from '../notifications-icon'
|
||||||
import router from 'next/router'
|
|
||||||
import { userProfileItem } from './bottom-nav-bar'
|
import { userProfileItem } from './bottom-nav-bar'
|
||||||
|
import Link from 'next/link'
|
||||||
|
|
||||||
const mobileGroupNavigation = [
|
const mobileGroupNavigation = (slug: string) => [
|
||||||
{ name: 'Markets', key: 'markets', icon: HomeIcon },
|
{
|
||||||
{ name: 'Leaderboard', key: 'leaderboards', icon: TrophyIcon },
|
name: 'Markets',
|
||||||
{ name: 'About', key: 'about', icon: ClipboardIcon },
|
key: 'markets',
|
||||||
|
icon: HomeIcon,
|
||||||
|
href: `/group/${slug}/markets`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'About',
|
||||||
|
key: 'about',
|
||||||
|
icon: ClipboardIcon,
|
||||||
|
href: `/group/${slug}/about`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Leaderboard',
|
||||||
|
key: 'leaderboards',
|
||||||
|
icon: TrophyIcon,
|
||||||
|
href: `/group/${slug}/leaderboards`,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const mobileGeneralNavigation = [
|
const mobileGeneralNavigation = [
|
||||||
{
|
{
|
||||||
name: 'Notifications',
|
name: 'Notifications',
|
||||||
|
@ -24,42 +38,24 @@ const mobileGeneralNavigation = [
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
export function GroupNavBar(props: {
|
export function GroupNavBar(props: { currentPage: string; groupSlug: string }) {
|
||||||
currentPage: string
|
const { currentPage, groupSlug } = props
|
||||||
onClick: (key: string) => void
|
|
||||||
}) {
|
|
||||||
const { currentPage } = props
|
|
||||||
const user = useUser()
|
const user = useUser()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav className="z-20 flex justify-between border-t-2 bg-white text-xs text-gray-700 lg:hidden">
|
<nav className="z-20 flex justify-between border-t-2 bg-white text-xs text-gray-700 lg:hidden">
|
||||||
{mobileGroupNavigation.map((item) => (
|
{mobileGroupNavigation(groupSlug).map((item) => (
|
||||||
<NavBarItem
|
<NavBarItem key={item.name} item={item} currentPage={currentPage} />
|
||||||
key={item.name}
|
|
||||||
item={item}
|
|
||||||
currentPage={currentPage}
|
|
||||||
onClick={props.onClick}
|
|
||||||
/>
|
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{mobileGeneralNavigation.map((item) => (
|
{mobileGeneralNavigation.map((item) => (
|
||||||
<NavBarItem
|
<NavBarItem key={item.name} item={item} currentPage={currentPage} />
|
||||||
key={item.name}
|
|
||||||
item={item}
|
|
||||||
currentPage={currentPage}
|
|
||||||
onClick={() => {
|
|
||||||
router.push(item.href)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{user && (
|
{user && (
|
||||||
<NavBarItem
|
<NavBarItem
|
||||||
key={'profile'}
|
key={'profile'}
|
||||||
currentPage={currentPage}
|
currentPage={currentPage}
|
||||||
onClick={() => {
|
|
||||||
router.push(`/${user.username}?tab=trades`)
|
|
||||||
}}
|
|
||||||
item={userProfileItem(user)}
|
item={userProfileItem(user)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -67,18 +63,14 @@ export function GroupNavBar(props: {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function NavBarItem(props: {
|
function NavBarItem(props: { item: Item; currentPage: string }) {
|
||||||
item: Item
|
|
||||||
currentPage: string
|
|
||||||
onClick: (key: string) => void
|
|
||||||
}) {
|
|
||||||
const { item, currentPage } = props
|
const { item, currentPage } = props
|
||||||
const track = trackCallback(
|
const track = trackCallback(
|
||||||
`group navbar: ${item.trackingEventName ?? item.name}`
|
`group navbar: ${item.trackingEventName ?? item.name}`
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button onClick={() => props.onClick(item.key ?? '#')}>
|
<Link href={item.href}>
|
||||||
<a
|
<a
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'block w-full py-1 px-3 text-center hover:bg-indigo-200 hover:text-indigo-700',
|
'block w-full py-1 px-3 text-center hover:bg-indigo-200 hover:text-indigo-700',
|
||||||
|
@ -89,6 +81,6 @@ function NavBarItem(props: {
|
||||||
{item.icon && <item.icon className="my-1 mx-auto h-6 w-6" />}
|
{item.icon && <item.icon className="my-1 mx-auto h-6 w-6" />}
|
||||||
{item.name}
|
{item.name}
|
||||||
</a>
|
</a>
|
||||||
</button>
|
</Link>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,25 @@ import { User } from 'common/user'
|
||||||
import { Row } from '../layout/row'
|
import { Row } from '../layout/row'
|
||||||
import { Spacer } from '../layout/spacer'
|
import { Spacer } from '../layout/spacer'
|
||||||
|
|
||||||
const groupNavigation = [
|
const groupNavigation = (slug: string) => [
|
||||||
{ name: 'Markets', key: 'markets', icon: HomeIcon },
|
{
|
||||||
{ name: 'About', key: 'about', icon: ClipboardIcon },
|
name: 'Markets',
|
||||||
{ name: 'Leaderboard', key: 'leaderboards', icon: TrophyIcon },
|
key: 'markets',
|
||||||
|
icon: HomeIcon,
|
||||||
|
href: `/group/${slug}/markets`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'About',
|
||||||
|
key: 'about',
|
||||||
|
icon: ClipboardIcon,
|
||||||
|
href: `/group/${slug}/about`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Leaderboard',
|
||||||
|
key: 'leaderboards',
|
||||||
|
icon: TrophyIcon,
|
||||||
|
href: `/group/${slug}/leaderboards`,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const generalNavigation = (user?: User | null) =>
|
const generalNavigation = (user?: User | null) =>
|
||||||
|
@ -31,12 +46,12 @@ const generalNavigation = (user?: User | null) =>
|
||||||
|
|
||||||
export function GroupSidebar(props: {
|
export function GroupSidebar(props: {
|
||||||
groupName: string
|
groupName: string
|
||||||
|
groupSlug: string
|
||||||
className?: string
|
className?: string
|
||||||
onClick: (key: string) => void
|
|
||||||
joinOrAddQuestionsButton: React.ReactNode
|
joinOrAddQuestionsButton: React.ReactNode
|
||||||
currentKey: string
|
currentKey: string
|
||||||
}) {
|
}) {
|
||||||
const { className, groupName, currentKey } = props
|
const { className, groupName, currentKey, groupSlug } = props
|
||||||
|
|
||||||
const user = useUser()
|
const user = useUser()
|
||||||
|
|
||||||
|
@ -57,21 +72,11 @@ export function GroupSidebar(props: {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Desktop navigation */}
|
{/* Desktop navigation */}
|
||||||
{groupNavigation.map((item) => (
|
{groupNavigation(groupSlug).map((item) => (
|
||||||
<SidebarItem
|
<SidebarItem key={item.key} item={item} currentPage={currentKey} />
|
||||||
key={item.key}
|
|
||||||
item={item}
|
|
||||||
currentPage={currentKey}
|
|
||||||
onClick={props.onClick}
|
|
||||||
/>
|
|
||||||
))}
|
))}
|
||||||
{generalNavigation(user).map((item) => (
|
{generalNavigation(user).map((item) => (
|
||||||
<SidebarItem
|
<SidebarItem key={item.key} item={item} currentPage={currentKey} />
|
||||||
key={item.key}
|
|
||||||
item={item}
|
|
||||||
currentPage={currentKey}
|
|
||||||
onClick={props.onClick}
|
|
||||||
/>
|
|
||||||
))}
|
))}
|
||||||
|
|
||||||
<Spacer h={2} />
|
<Spacer h={2} />
|
||||||
|
|
|
@ -7,23 +7,21 @@ import { trackCallback } from 'web/lib/service/analytics'
|
||||||
export type Item = {
|
export type Item = {
|
||||||
name: string
|
name: string
|
||||||
trackingEventName?: string
|
trackingEventName?: string
|
||||||
href?: string
|
href: string
|
||||||
key?: string
|
key?: string
|
||||||
icon?: React.ComponentType<{ className?: string }>
|
icon?: React.ComponentType<{ className?: string }>
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SidebarItem(props: {
|
export function SidebarItem(props: { item: Item; currentPage: string }) {
|
||||||
item: Item
|
const { item, currentPage } = props
|
||||||
currentPage: string
|
|
||||||
onClick?: (key: string) => void
|
|
||||||
}) {
|
|
||||||
const { item, currentPage, onClick } = props
|
|
||||||
const isCurrentPage =
|
const isCurrentPage =
|
||||||
item.href != null ? item.href === currentPage : item.key === currentPage
|
item.href != null ? item.href === currentPage : item.key === currentPage
|
||||||
|
|
||||||
const sidebarItem = (
|
const sidebarItem = (
|
||||||
<a
|
<a
|
||||||
onClick={trackCallback('sidebar: ' + item.name)}
|
onClick={() => {
|
||||||
|
trackCallback('sidebar: ' + item.name)
|
||||||
|
}}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
isCurrentPage
|
isCurrentPage
|
||||||
? 'bg-gray-200 text-gray-900'
|
? 'bg-gray-200 text-gray-900'
|
||||||
|
@ -47,17 +45,5 @@ export function SidebarItem(props: {
|
||||||
</a>
|
</a>
|
||||||
)
|
)
|
||||||
|
|
||||||
if (item.href) {
|
return <Link href={item.href}>{sidebarItem}</Link>
|
||||||
return (
|
|
||||||
<Link href={item.href} key={item.name}>
|
|
||||||
{sidebarItem}
|
|
||||||
</Link>
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
return onClick ? (
|
|
||||||
<button onClick={() => onClick(item.key ?? '#')}>{sidebarItem}</button>
|
|
||||||
) : (
|
|
||||||
<> </>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import { toast, Toaster } from 'react-hot-toast'
|
import { toast, Toaster } from 'react-hot-toast'
|
||||||
|
@ -140,10 +140,16 @@ export default function GroupPage(props: {
|
||||||
const user = useUser()
|
const user = useUser()
|
||||||
const isAdmin = useAdmin()
|
const isAdmin = useAdmin()
|
||||||
const memberIds = useMemberIds(group?.id ?? null) ?? props.memberIds
|
const memberIds = useMemberIds(group?.id ?? null) ?? props.memberIds
|
||||||
|
|
||||||
// Note: Keep in sync with sidebarPages
|
// Note: Keep in sync with sidebarPages
|
||||||
const [sidebarIndex, setSidebarIndex] = useState(
|
const [sidebarIndex, setSidebarIndex] = useState(
|
||||||
['markets', 'leaderboards', 'about'].indexOf(page ?? 'markets')
|
['markets', 'leaderboards', 'about'].indexOf(page ?? 'markets')
|
||||||
)
|
)
|
||||||
|
useEffect(() => {
|
||||||
|
setSidebarIndex(
|
||||||
|
['markets', 'leaderboards', 'about'].indexOf(page ?? 'markets')
|
||||||
|
)
|
||||||
|
}, [page])
|
||||||
|
|
||||||
useSaveReferral(user, {
|
useSaveReferral(user, {
|
||||||
defaultReferrerUsername: creator.username,
|
defaultReferrerUsername: creator.username,
|
||||||
|
@ -241,16 +247,6 @@ export default function GroupPage(props: {
|
||||||
]
|
]
|
||||||
|
|
||||||
const pageContent = sidebarPages[sidebarIndex].content
|
const pageContent = sidebarPages[sidebarIndex].content
|
||||||
const onSidebarClick = (key: string) => {
|
|
||||||
const index = sidebarPages.findIndex((t) => t.key === key)
|
|
||||||
setSidebarIndex(index)
|
|
||||||
// Append the page to the URL, e.g. /group/mexifold/markets
|
|
||||||
router.replace(
|
|
||||||
{ query: { ...router.query, slugs: [group.slug, key] } },
|
|
||||||
undefined,
|
|
||||||
{ shallow: true }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const joinOrAddQuestionsButton = (
|
const joinOrAddQuestionsButton = (
|
||||||
<JoinOrAddQuestionsButtons
|
<JoinOrAddQuestionsButtons
|
||||||
|
@ -265,7 +261,6 @@ export default function GroupPage(props: {
|
||||||
<TopGroupNavBar
|
<TopGroupNavBar
|
||||||
group={group}
|
group={group}
|
||||||
currentPage={sidebarPages[sidebarIndex].key}
|
currentPage={sidebarPages[sidebarIndex].key}
|
||||||
onClick={onSidebarClick}
|
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
|
@ -276,8 +271,8 @@ export default function GroupPage(props: {
|
||||||
<Toaster />
|
<Toaster />
|
||||||
<GroupSidebar
|
<GroupSidebar
|
||||||
groupName={group.name}
|
groupName={group.name}
|
||||||
|
groupSlug={group.slug}
|
||||||
className="sticky top-0 hidden divide-gray-300 self-start pl-2 lg:col-span-2 lg:flex"
|
className="sticky top-0 hidden divide-gray-300 self-start pl-2 lg:col-span-2 lg:flex"
|
||||||
onClick={onSidebarClick}
|
|
||||||
joinOrAddQuestionsButton={joinOrAddQuestionsButton}
|
joinOrAddQuestionsButton={joinOrAddQuestionsButton}
|
||||||
currentKey={sidebarPages[sidebarIndex].key}
|
currentKey={sidebarPages[sidebarIndex].key}
|
||||||
/>
|
/>
|
||||||
|
@ -296,11 +291,7 @@ export default function GroupPage(props: {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function TopGroupNavBar(props: {
|
export function TopGroupNavBar(props: { group: Group; currentPage: string }) {
|
||||||
group: Group
|
|
||||||
currentPage: string
|
|
||||||
onClick: (key: string) => void
|
|
||||||
}) {
|
|
||||||
return (
|
return (
|
||||||
<header className="sticky top-0 z-50 w-full border-b border-gray-200 md:hidden lg:col-span-12">
|
<header className="sticky top-0 z-50 w-full border-b border-gray-200 md:hidden lg:col-span-12">
|
||||||
<div className="flex items-center bg-white px-4">
|
<div className="flex items-center bg-white px-4">
|
||||||
|
@ -317,7 +308,10 @@ export function TopGroupNavBar(props: {
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<GroupNavBar currentPage={props.currentPage} onClick={props.onClick} />
|
<GroupNavBar
|
||||||
|
groupSlug={props.group.slug}
|
||||||
|
currentPage={props.currentPage}
|
||||||
|
/>
|
||||||
</header>
|
</header>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user