-
Notifications
You must be signed in to change notification settings - Fork 202
ILR Tab menu changes #14055
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
ILR Tab menu changes #14055
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ import { | |
| Collapsible, | ||
| Drawer, | ||
| IconButton, | ||
| Separator, | ||
| Spacer, | ||
| Tabs, | ||
| Text, | ||
|
|
@@ -24,25 +25,40 @@ import { useState } from "react"; | |
| import { TFunction } from "i18next"; | ||
| import { LuAlignJustify } from "react-icons/lu"; | ||
| import { iconMap } from "@/components/icons/iconMap"; | ||
| import { route } from "nextjs-routes"; | ||
| import { parseActivityCode } from "@/lib/wca/wcif/rounds"; | ||
|
|
||
| function parseActivityCodeOrNull(path: string) { | ||
| try { | ||
| const { eventId } = parseActivityCode(path); | ||
| return eventId; | ||
| } catch { | ||
| return null; | ||
| } | ||
| } | ||
|
|
||
| export default function TabMenu({ | ||
| competitionInfo, | ||
| children, | ||
| tabs, | ||
| isLiveMenu = false, | ||
| }: { | ||
| children: React.ReactNode; | ||
| competitionInfo: components["schemas"]["CompetitionInfo"]; | ||
| tabs: CompetitionNavTab[]; | ||
| isLiveMenu?: boolean; | ||
| }) { | ||
| const [openGroup, setOpenGroup] = useState<string | null>(null); | ||
| const [drawerOpen, setDrawerOpen] = useState(false); | ||
|
|
||
| const pathName = usePathname(); | ||
| const { t } = useT(); | ||
|
|
||
| const path = _.last(pathName.split("/")); | ||
| const currentPath = path === competitionInfo.id ? "general" : path; | ||
|
|
||
| const eventId = parseActivityCodeOrNull(currentPath!); | ||
|
|
||
| const [openGroup, setOpenGroup] = useState<string | null>(eventId); | ||
| const [drawerOpen, setDrawerOpen] = useState(false); | ||
|
|
||
| return ( | ||
| <Tabs.Root | ||
| variant="enclosed" | ||
|
|
@@ -56,7 +72,7 @@ export default function TabMenu({ | |
| <Tabs.List | ||
| height="fit-content" | ||
| position="sticky" | ||
| minWidth="fit-content" | ||
| width="3xs" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why did the previous not work? I think
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's because the content size changes when you open the submenus. So the UI gets jumpy. max-width doesn't change anything here |
||
| textAlign="center" | ||
| hideBelow="md" | ||
| gap="3" | ||
|
|
@@ -68,6 +84,8 @@ export default function TabMenu({ | |
| onToggle={(tab: CompetitionNavTab) => | ||
| setOpenGroup((prev) => (prev === tab.menuKey ? null : tab.menuKey)) | ||
| } | ||
| isLiveMenu={isLiveMenu} | ||
| competitionInfo={competitionInfo} | ||
| /> | ||
| </Tabs.List> | ||
| <Box hideFrom="md" mb="4"> | ||
|
|
@@ -117,6 +135,7 @@ export default function TabMenu({ | |
| prev === tab.menuKey ? null : tab.menuKey, | ||
| ) | ||
| } | ||
| competitionInfo={competitionInfo} | ||
| /> | ||
| </Tabs.List> | ||
| </Drawer.Body> | ||
|
|
@@ -136,28 +155,68 @@ function TabList({ | |
| t, | ||
| onToggle, | ||
| openGroup, | ||
| isLiveMenu, | ||
| competitionInfo, | ||
| }: { | ||
| tabs: CompetitionNavTab[]; | ||
| t: TFunction; | ||
| openGroup: string | null; | ||
| onToggle: (tab: CompetitionNavTab) => void; | ||
| isLiveMenu?: boolean; | ||
| competitionInfo: components["schemas"]["CompetitionInfo"]; | ||
| }) { | ||
| return tabs.map((tab) => | ||
| "href" in tab ? ( | ||
| <Tabs.Trigger value={tab.menuKey} asChild key={tab.menuKey}> | ||
| <Text asChild textStyle="bodyEmphasis" justifyContent="left"> | ||
| <Link href={tab.href}>{t(tab.i18nKey)}</Link> | ||
| </Text> | ||
| </Tabs.Trigger> | ||
| ) : ( | ||
| <CollapsibleTabGroup | ||
| key={tab.menuKey} | ||
| tab={tab} | ||
| t={t} | ||
| isOpen={openGroup === tab.menuKey} | ||
| onToggle={() => onToggle(tab)} | ||
| /> | ||
| ), | ||
| return ( | ||
| <> | ||
| {tabs.map((tab) => | ||
| "href" in tab ? ( | ||
| <Tabs.Trigger value={tab.menuKey} asChild key={tab.menuKey}> | ||
| <Text asChild textStyle="bodyEmphasis" justifyContent="left"> | ||
| <Link href={tab.href}>{t(tab.i18nKey)}</Link> | ||
| </Text> | ||
| </Tabs.Trigger> | ||
| ) : ( | ||
| <CollapsibleTabGroup | ||
| key={tab.menuKey} | ||
| tab={tab} | ||
| t={t} | ||
| isOpen={openGroup === tab.menuKey} | ||
| onToggle={() => onToggle(tab)} | ||
| /> | ||
| ), | ||
| )} | ||
| {!isLiveMenu && ( | ||
| <> | ||
| <Separator /> | ||
| {competitionInfo.tab_names.map((tabName) => ( | ||
| <Tabs.Trigger | ||
| key={tabName} | ||
| value={tabName} | ||
| minHeight="fit-content" | ||
| asChild | ||
| > | ||
| <Text | ||
| textStyle="bodyEmphasis" | ||
| asChild | ||
| maxW="44" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where did this magical constant come from? I know it is defined in Chakra, but why did you choose it?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is from the previous version of the menu code that I accidentally deleted. I think it was the most fitting option for custom tabs |
||
| justifyContent="left" | ||
| > | ||
| <Link | ||
| href={route({ | ||
| pathname: "/competitions/[competitionId]/tabs/[tabName]", | ||
| query: { | ||
| competitionId: competitionInfo.id, | ||
| tabName: encodeURIComponent(tabName), | ||
| }, | ||
| })} | ||
| > | ||
| {tabName} | ||
| </Link> | ||
| </Text> | ||
| </Tabs.Trigger> | ||
| ))} | ||
| </> | ||
| )} | ||
| </> | ||
| ); | ||
| } | ||
|
|
||
|
|
@@ -185,6 +244,7 @@ function CollapsibleTabGroup({ | |
| py="2" | ||
| borderRadius="md" | ||
| _hover={{ bg: "bg.subtle" }} | ||
| cursor="pointer" | ||
| > | ||
| <Text textStyle="bodyEmphasis"> | ||
| <IconComponent /> {t(i18nKey)} | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope. No try-catch. Not at all.
What is causing
parseActivityCodeto raise an exception and how can we detect these edge cases before passing the data intoparseActivityCode?