From eb20ce32a64365d74a2d4d63cc372ef3037322f4 Mon Sep 17 00:00:00 2001 From: Jon Kafton <939376+jonkafton@users.noreply.github.com> Date: Mon, 30 Sep 2024 20:38:55 +0200 Subject: [PATCH 01/17] Prevent scroll to top on drawer close --- .../LearningResourceDrawer/LearningResourceDrawer.tsx | 2 +- frontends/ol-components/src/components/Link/Link.stories.tsx | 1 + .../ol-components/src/components/RoutedDrawer/RoutedDrawer.tsx | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.tsx b/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.tsx index 4d6ba70e75..525dba6257 100644 --- a/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.tsx +++ b/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.tsx @@ -150,7 +150,7 @@ const useOpenLearningResourceDrawer = () => { const openLearningResourceDrawer = useCallback( (resourceId: number) => { - router.push(`?${getOpenDrawerSearchParams(searchParams, resourceId)}`) + router.push(`?${getOpenDrawerSearchParams(searchParams, resourceId)}`, {scroll: false}) }, [router, searchParams], ) diff --git a/frontends/ol-components/src/components/Link/Link.stories.tsx b/frontends/ol-components/src/components/Link/Link.stories.tsx index dff39a9191..6cf58de75e 100644 --- a/frontends/ol-components/src/components/Link/Link.stories.tsx +++ b/frontends/ol-components/src/components/Link/Link.stories.tsx @@ -21,6 +21,7 @@ const SIZES = [ { size: "medium", label: "Medium" }, { size: "large", label: "Large" }, ] as const + const COLORS = [ { color: "black", label: "Black" }, { color: "red", label: "Red" }, diff --git a/frontends/ol-components/src/components/RoutedDrawer/RoutedDrawer.tsx b/frontends/ol-components/src/components/RoutedDrawer/RoutedDrawer.tsx index b09a35b7fa..02fcbb3341 100644 --- a/frontends/ol-components/src/components/RoutedDrawer/RoutedDrawer.tsx +++ b/frontends/ol-components/src/components/RoutedDrawer/RoutedDrawer.tsx @@ -84,7 +84,7 @@ const RoutedDrawer = ( return newSearchParams } const newParams = getNewParams(searchParams) - router.push(`?${newParams}${window.location.hash}`) + router.push(`?${newParams}${window.location.hash}`, {scroll: false}) }, [router, searchParams, params]) return ( From 939bb7a7a9e660dbf95951d5f5f6256aa42c4d7e Mon Sep 17 00:00:00 2001 From: Jon Kafton <939376+jonkafton@users.noreply.github.com> Date: Mon, 30 Sep 2024 20:54:06 +0200 Subject: [PATCH 02/17] Position the search button --- frontends/main/src/page-components/Header/Header.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/frontends/main/src/page-components/Header/Header.tsx b/frontends/main/src/page-components/Header/Header.tsx index d71a606912..4fdfacb4f4 100644 --- a/frontends/main/src/page-components/Header/Header.tsx +++ b/frontends/main/src/page-components/Header/Header.tsx @@ -115,14 +115,22 @@ const Spacer = styled.div` flex: 1; ` +const StyledActionButtonLink = styled(ActionButtonLink)` + align-items: center; + display: inline-flex; + justify-content: center; +` + const StyledSearchIcon = styled(RiSearch2Line)(({ theme }) => ({ color: theme.custom.colors.darkGray2, margin: "4px 0", })) + + const SearchButton: FunctionComponent = () => { return ( - { aria-label="Search" > - + ) } From 62ef755381479f05b0e5c8b97c50c94a40876095 Mon Sep 17 00:00:00 2001 From: Jon Kafton <939376+jonkafton@users.noreply.github.com> Date: Tue, 1 Oct 2024 19:37:55 +0200 Subject: [PATCH 03/17] Fixes ButtonLink icons (withComponent does not pass props filtered by shouldForwardProp) --- .../src/components/Button/Button.tsx | 75 +++++++++++-------- 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/frontends/ol-components/src/components/Button/Button.tsx b/frontends/ol-components/src/components/Button/Button.tsx index 5382ce4620..bb107b121f 100644 --- a/frontends/ol-components/src/components/Button/Button.tsx +++ b/frontends/ol-components/src/components/Button/Button.tsx @@ -3,7 +3,8 @@ import styled from "@emotion/styled" import { pxToRem } from "../ThemeProvider/typography" import tinycolor from "tinycolor2" import Link from "next/link" -import type { Theme } from "@mui/material/styles" +import type { Theme, ThemeOptions } from "@mui/material/styles" + type ButtonVariant = | "primary" @@ -43,7 +44,7 @@ const styleProps: Record = { const shouldForwardProp = (prop: string) => !styleProps[prop] -const defaultProps: Required> = +const DEFAULT_PROPS: Required> = { variant: "primary", size: "medium", @@ -51,22 +52,23 @@ const defaultProps: Required> = responsive: false, } -const borderWidths = { +const BORDER_WIDTHS = { small: 1, medium: 1, large: 2, } -const responsiveSize: Record = { + +const RESPONSIVE_SIZES: Record = { small: "small", medium: "small", large: "medium", } -const sizeStyles = (size: ButtonSize, hasBorder: boolean, theme: Theme) => { - const paddingAdjust = hasBorder ? borderWidths[size] : 0 +const sizeStyles = (size: ButtonSize, hasBorder: boolean, theme: Theme): Partial[] => { + const paddingAdjust = hasBorder ? BORDER_WIDTHS[size] : 0 return [ { - borderWidth: borderWidths[size], + borderWidth: BORDER_WIDTHS[size], }, size === "large" && { padding: `${14 - paddingAdjust}px 24px`, @@ -83,11 +85,15 @@ const sizeStyles = (size: ButtonSize, hasBorder: boolean, theme: Theme) => { ] } -const ButtonStyled = styled("button", { shouldForwardProp })(( - props, +type ButtonProps = ButtonStyleProps & React.ComponentProps<"button"> +type AnchorProps = ButtonStyleProps & React.ComponentProps<"a"> +type LinkProps = ButtonStyleProps & React.ComponentProps + +const buildStyles = ( + props: (ButtonProps | AnchorProps | LinkProps) & { theme: Theme }, ) => { const { size, variant, edge, theme, color, responsive } = { - ...defaultProps, + ...DEFAULT_PROPS, ...props, } const { colors } = theme.custom @@ -114,7 +120,7 @@ const ButtonStyled = styled("button", { shouldForwardProp })(( // responsive responsive && { [theme.breakpoints.down("sm")]: sizeStyles( - responsiveSize[size], + RESPONSIVE_SIZES[size], hasBorder, theme, ), @@ -228,7 +234,11 @@ const ButtonStyled = styled("button", { shouldForwardProp })(( }, }, ] -}) +} + +const ButtonStyled = styled("button", { shouldForwardProp })(buildStyles) +const AnchorStyled = styled("a", { shouldForwardProp })(buildStyles) +const LinkStyled = styled(Link, { shouldForwardProp })(buildStyles) const IconContainer = styled.span<{ side: "start" | "end"; size: ButtonSize }>( ({ size, side }) => [ @@ -266,12 +276,12 @@ const IconContainer = styled.span<{ side: "start" | "end"; size: ButtonSize }>( ], ) -type ButtonProps = ButtonStyleProps & React.ComponentProps<"button"> + const ButtonInner: React.FC< ButtonStyleProps & { children?: React.ReactNode } > = (props) => { - const { children, size = defaultProps.size } = props + const { children, size = DEFAULT_PROPS.size } = props return ( <> {props.startIcon ? ( @@ -293,11 +303,13 @@ const ButtonInner: React.FC< * Our styled button. If you need a link that looks like a button, use ButtonLink */ const Button = React.forwardRef( - ({ children, ...props }, ref) => ( - - {children} - - ), + ({ children, ...props }, ref) => { + return ( + + {children} + + ) + } ) type ButtonLinkProps = ButtonStyleProps & @@ -306,18 +318,17 @@ type ButtonLinkProps = ButtonStyleProps & href: string } -const ButtonLink = ButtonStyled.withComponent( - React.forwardRef( - ({ children, rawAnchor, ...props }: ButtonLinkProps, ref) => { - const Component = rawAnchor ? "a" : Link - return ( - - {children} - - ) - }, - ), +const ButtonLink = React.forwardRef( + ({ children, rawAnchor, ...props }: ButtonLinkProps, ref) => { + const Component = rawAnchor ? AnchorStyled : LinkStyled + return ( + + {children} + + ) + }, ) + ButtonLink.displayName = "ButtonLink" type ActionButtonProps = Omit & @@ -359,11 +370,11 @@ const ActionButton = styled( React.forwardRef((props, ref) => ( )), -)(({ theme, size = defaultProps.size, responsive }) => { +)(({ theme, size = DEFAULT_PROPS.size, responsive }) => { return [ actionStyles(size), responsive && { - [theme.breakpoints.down("sm")]: actionStyles(responsiveSize[size]), + [theme.breakpoints.down("sm")]: actionStyles(RESPONSIVE_SIZES[size]), }, ] }) From 78fdb9a2e7fbd87db0cea2ffe14c08fd16af267b Mon Sep 17 00:00:00 2001 From: Jon Kafton <939376+jonkafton@users.noreply.github.com> Date: Tue, 1 Oct 2024 19:45:07 +0200 Subject: [PATCH 04/17] Lint fixes --- .../src/page-components/Header/Header.tsx | 2 -- .../LearningResourceDrawer.tsx | 4 +++- .../src/components/Button/Button.tsx | 23 ++++++++++++------- .../components/RoutedDrawer/RoutedDrawer.tsx | 2 +- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/frontends/main/src/page-components/Header/Header.tsx b/frontends/main/src/page-components/Header/Header.tsx index 4fdfacb4f4..09e73142fb 100644 --- a/frontends/main/src/page-components/Header/Header.tsx +++ b/frontends/main/src/page-components/Header/Header.tsx @@ -126,8 +126,6 @@ const StyledSearchIcon = styled(RiSearch2Line)(({ theme }) => ({ margin: "4px 0", })) - - const SearchButton: FunctionComponent = () => { return ( { const openLearningResourceDrawer = useCallback( (resourceId: number) => { - router.push(`?${getOpenDrawerSearchParams(searchParams, resourceId)}`, {scroll: false}) + router.push(`?${getOpenDrawerSearchParams(searchParams, resourceId)}`, { + scroll: false, + }) }, [router, searchParams], ) diff --git a/frontends/ol-components/src/components/Button/Button.tsx b/frontends/ol-components/src/components/Button/Button.tsx index bb107b121f..6d4cbf0991 100644 --- a/frontends/ol-components/src/components/Button/Button.tsx +++ b/frontends/ol-components/src/components/Button/Button.tsx @@ -5,7 +5,6 @@ import tinycolor from "tinycolor2" import Link from "next/link" import type { Theme, ThemeOptions } from "@mui/material/styles" - type ButtonVariant = | "primary" | "secondary" @@ -64,7 +63,11 @@ const RESPONSIVE_SIZES: Record = { large: "medium", } -const sizeStyles = (size: ButtonSize, hasBorder: boolean, theme: Theme): Partial[] => { +const sizeStyles = ( + size: ButtonSize, + hasBorder: boolean, + theme: Theme, +): Partial[] => { const paddingAdjust = hasBorder ? BORDER_WIDTHS[size] : 0 return [ { @@ -236,9 +239,15 @@ const buildStyles = ( ] } -const ButtonStyled = styled("button", { shouldForwardProp })(buildStyles) -const AnchorStyled = styled("a", { shouldForwardProp })(buildStyles) -const LinkStyled = styled(Link, { shouldForwardProp })(buildStyles) +const ButtonStyled = styled("button", { shouldForwardProp })( + buildStyles, +) +const AnchorStyled = styled("a", { shouldForwardProp })( + buildStyles, +) +const LinkStyled = styled(Link, { shouldForwardProp })( + buildStyles, +) const IconContainer = styled.span<{ side: "start" | "end"; size: ButtonSize }>( ({ size, side }) => [ @@ -276,8 +285,6 @@ const IconContainer = styled.span<{ side: "start" | "end"; size: ButtonSize }>( ], ) - - const ButtonInner: React.FC< ButtonStyleProps & { children?: React.ReactNode } > = (props) => { @@ -309,7 +316,7 @@ const Button = React.forwardRef( {children} ) - } + }, ) type ButtonLinkProps = ButtonStyleProps & diff --git a/frontends/ol-components/src/components/RoutedDrawer/RoutedDrawer.tsx b/frontends/ol-components/src/components/RoutedDrawer/RoutedDrawer.tsx index 02fcbb3341..8b7e209095 100644 --- a/frontends/ol-components/src/components/RoutedDrawer/RoutedDrawer.tsx +++ b/frontends/ol-components/src/components/RoutedDrawer/RoutedDrawer.tsx @@ -84,7 +84,7 @@ const RoutedDrawer = ( return newSearchParams } const newParams = getNewParams(searchParams) - router.push(`?${newParams}${window.location.hash}`, {scroll: false}) + router.push(`?${newParams}${window.location.hash}`, { scroll: false }) }, [router, searchParams, params]) return ( From e77c66cbe08db950c4e4e31fa8b40288cd2af17a Mon Sep 17 00:00:00 2001 From: Jon Kafton <939376+jonkafton@users.noreply.github.com> Date: Tue, 1 Oct 2024 22:11:59 +0200 Subject: [PATCH 05/17] Preserve hash fragment on drawer open. Prevent scroll to top on drawer open/close --- .../app-pages/OnboardingPage/OnboardingPage.tsx | 1 - .../LearningResourceDrawer.tsx | 14 ++++++++++---- .../src/components/Dialog/Dialog.stories.tsx | 1 - .../src/components/RoutedDrawer/RoutedDrawer.tsx | 12 +++++++++++- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/frontends/main/src/app-pages/OnboardingPage/OnboardingPage.tsx b/frontends/main/src/app-pages/OnboardingPage/OnboardingPage.tsx index 43d154757a..54a6554adc 100644 --- a/frontends/main/src/app-pages/OnboardingPage/OnboardingPage.tsx +++ b/frontends/main/src/app-pages/OnboardingPage/OnboardingPage.tsx @@ -231,7 +231,6 @@ const OnboardingPage: React.FC = () => { } values={formik.values.goals} onChange={(event) => { - console.log(event) formik.handleChange(event) }} /> diff --git a/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.tsx b/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.tsx index 18d46254dc..83649549d3 100644 --- a/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.tsx +++ b/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.tsx @@ -144,15 +144,20 @@ const getOpenDrawerSearchParams = ( return newSearchParams } +// TODO Not used anywhere in project. Remove? const useOpenLearningResourceDrawer = () => { const searchParams = useSearchParams() const router = useRouter() const openLearningResourceDrawer = useCallback( (resourceId: number) => { - router.push(`?${getOpenDrawerSearchParams(searchParams, resourceId)}`, { - scroll: false, - }) + const hash = window?.location.hash + router.push( + `?${getOpenDrawerSearchParams(searchParams, resourceId)}${hash ? `#${hash}` : ""}`, + { + scroll: false, + }, + ) }, [router, searchParams], ) @@ -164,7 +169,8 @@ const useResourceDrawerHref = () => { return useCallback( (resourceId: number) => { - return `?${getOpenDrawerSearchParams(searchParams, resourceId)}` + const hash = window?.location.hash + return `?${getOpenDrawerSearchParams(searchParams, resourceId)}${hash || ""}` }, [searchParams], ) diff --git a/frontends/ol-components/src/components/Dialog/Dialog.stories.tsx b/frontends/ol-components/src/components/Dialog/Dialog.stories.tsx index e0ef3e5973..076aa4959e 100644 --- a/frontends/ol-components/src/components/Dialog/Dialog.stories.tsx +++ b/frontends/ol-components/src/components/Dialog/Dialog.stories.tsx @@ -11,7 +11,6 @@ const StateWrapper = (props: DialogProps) => { }, [props.open]) const close = () => { - console.log("close?", open) setOpen(false) props.onClose() } diff --git a/frontends/ol-components/src/components/RoutedDrawer/RoutedDrawer.tsx b/frontends/ol-components/src/components/RoutedDrawer/RoutedDrawer.tsx index 8b7e209095..a7d97236d5 100644 --- a/frontends/ol-components/src/components/RoutedDrawer/RoutedDrawer.tsx +++ b/frontends/ol-components/src/components/RoutedDrawer/RoutedDrawer.tsx @@ -81,10 +81,20 @@ const RoutedDrawer = ( params.forEach((param) => { newSearchParams.delete(param) }) + return newSearchParams } const newParams = getNewParams(searchParams) - router.push(`?${newParams}${window.location.hash}`, { scroll: false }) + + const hash = window?.location.hash + + // Note that { scroll: true } and { scroll: false } both remove the hash fragment + if (hash) { + router.push(`?${newParams}${hash}`) + } else { + // Prevent scroll to top of page + router.push(`?${newParams}${hash}`, { scroll: false }) + } }, [router, searchParams, params]) return ( From 235c598621069d4c7584be9583e40bb75fcee679 Mon Sep 17 00:00:00 2001 From: Jon Kafton <939376+jonkafton@users.noreply.github.com> Date: Wed, 2 Oct 2024 20:25:21 +0200 Subject: [PATCH 06/17] Fix errors caught here showing the not found page --- .../src/components/ErrorBoundary/ErrorBoundary.tsx | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/frontends/main/src/components/ErrorBoundary/ErrorBoundary.tsx b/frontends/main/src/components/ErrorBoundary/ErrorBoundary.tsx index 1cb3d5f864..15589383a6 100644 --- a/frontends/main/src/components/ErrorBoundary/ErrorBoundary.tsx +++ b/frontends/main/src/components/ErrorBoundary/ErrorBoundary.tsx @@ -1,7 +1,6 @@ "use client" import React, { Component } from "react" -import NotFoundPage from "@/app-pages/ErrorPage/NotFoundPage" import ForbiddenPage from "@/app-pages/ErrorPage/ForbiddenPage" import { ForbiddenError } from "@/common/permissions" import { usePathname } from "next/navigation" @@ -57,12 +56,9 @@ class ErrorBoundaryHandler extends Component< } render() { - if (this.state.hasError) { - if (isForbiddenError(this.state.error)) { - return - } else { - return - } + console.log("ERROR", this.state.error) + if (this.state.hasError && isForbiddenError(this.state.error)) { + return } return this.props.children From c413b4ba63fd9f31faebc6fe4f29f13ba26dcd4b Mon Sep 17 00:00:00 2001 From: Jon Kafton <939376+jonkafton@users.noreply.github.com> Date: Wed, 2 Oct 2024 20:26:02 +0200 Subject: [PATCH 07/17] Relative links for channel urls --- frontends/main/src/app-pages/ChannelPage/ChannelPage.tsx | 2 +- .../DepartmentListingPage/DepartmentListingPage.tsx | 7 ++++++- .../main/src/app-pages/HomePage/BrowseTopicsSection.tsx | 5 ++++- .../src/app-pages/TopicsListingPage/TopicsListingPage.tsx | 4 ++-- frontends/main/src/app-pages/UnitsListingPage/UnitCard.tsx | 2 +- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/frontends/main/src/app-pages/ChannelPage/ChannelPage.tsx b/frontends/main/src/app-pages/ChannelPage/ChannelPage.tsx index 7daf8b4f6e..1bf0838b2d 100644 --- a/frontends/main/src/app-pages/ChannelPage/ChannelPage.tsx +++ b/frontends/main/src/app-pages/ChannelPage/ChannelPage.tsx @@ -62,7 +62,7 @@ const SubTopicsDisplay: React.FC = (props) => { size="large" variant="outlinedWhite" key={topic.id} - href={topic.channel_url} + href={new URL(topic.channel_url).pathname} label={topic.name} /> ))} diff --git a/frontends/main/src/app-pages/DepartmentListingPage/DepartmentListingPage.tsx b/frontends/main/src/app-pages/DepartmentListingPage/DepartmentListingPage.tsx index 26e84e9771..8c55673aed 100644 --- a/frontends/main/src/app-pages/DepartmentListingPage/DepartmentListingPage.tsx +++ b/frontends/main/src/app-pages/DepartmentListingPage/DepartmentListingPage.tsx @@ -150,7 +150,12 @@ const SchoolDepartments: React.FC = ({ if (!department.channel_url) return null return ( - + { {topics?.results.map( ({ id, name, channel_url: channelUrl, icon }) => { return ( - + {name} diff --git a/frontends/main/src/app-pages/TopicsListingPage/TopicsListingPage.tsx b/frontends/main/src/app-pages/TopicsListingPage/TopicsListingPage.tsx index cf6e4cfba3..9e15fafcb6 100644 --- a/frontends/main/src/app-pages/TopicsListingPage/TopicsListingPage.tsx +++ b/frontends/main/src/app-pages/TopicsListingPage/TopicsListingPage.tsx @@ -149,7 +149,7 @@ const TopicBox = ({ size="large" variant="outlinedWhite" key={c.id} - href={c.channel_url} + href={c.channel_url && new URL(c.channel_url).pathname} label={c.name} /> ))} @@ -160,7 +160,7 @@ const TopicBox = ({ size="medium" variant="outlinedWhite" key={c.id} - href={c.channel_url} + href={c.channel_url && new URL(c.channel_url).pathname} label={c.name} /> ))} diff --git a/frontends/main/src/app-pages/UnitsListingPage/UnitCard.tsx b/frontends/main/src/app-pages/UnitsListingPage/UnitCard.tsx index 0068bdadf2..224323731c 100644 --- a/frontends/main/src/app-pages/UnitsListingPage/UnitCard.tsx +++ b/frontends/main/src/app-pages/UnitsListingPage/UnitCard.tsx @@ -139,7 +139,7 @@ const UnitCard: React.FC = (props) => { return channelDetailQuery.isLoading ? ( ) : ( - + From b54192f98b0376b03cc99ba2d75824d3a2cabba8 Mon Sep 17 00:00:00 2001 From: Jon Kafton <939376+jonkafton@users.noreply.github.com> Date: Wed, 2 Oct 2024 21:45:57 +0200 Subject: [PATCH 08/17] No scroll for querystring links --- frontends/main/src/components/ErrorBoundary/ErrorBoundary.tsx | 2 -- frontends/ol-components/src/components/Card/Card.tsx | 2 +- frontends/ol-components/src/components/Card/ListCard.tsx | 2 +- .../ol-components/src/components/Card/ListCardCondensed.tsx | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/frontends/main/src/components/ErrorBoundary/ErrorBoundary.tsx b/frontends/main/src/components/ErrorBoundary/ErrorBoundary.tsx index 15589383a6..14030e669e 100644 --- a/frontends/main/src/components/ErrorBoundary/ErrorBoundary.tsx +++ b/frontends/main/src/components/ErrorBoundary/ErrorBoundary.tsx @@ -56,11 +56,9 @@ class ErrorBoundaryHandler extends Component< } render() { - console.log("ERROR", this.state.error) if (this.state.hasError && isForbiddenError(this.state.error)) { return } - return this.props.children } } diff --git a/frontends/ol-components/src/components/Card/Card.tsx b/frontends/ol-components/src/components/Card/Card.tsx index c88aa84820..a04dc0302a 100644 --- a/frontends/ol-components/src/components/Card/Card.tsx +++ b/frontends/ol-components/src/components/Card/Card.tsx @@ -210,7 +210,7 @@ const Card: Card = ({ children, className, size, href }) => { return ( - <_Container href={href!}> + <_Container href={href!} scroll={!href?.startsWith("?")}> {image && ( // alt text will be checked on Card.Image // eslint-disable-next-line styled-components-a11y/alt-text diff --git a/frontends/ol-components/src/components/Card/ListCard.tsx b/frontends/ol-components/src/components/Card/ListCard.tsx index 7a7880e240..18f0ff33f1 100644 --- a/frontends/ol-components/src/components/Card/ListCard.tsx +++ b/frontends/ol-components/src/components/Card/ListCard.tsx @@ -211,7 +211,7 @@ const ListCard: Card = ({ children, className, href, draggable }) => { return ( - <_Container href={href!}> + <_Container href={href!} scroll={!href?.startsWith("?")}> {draggable && ( diff --git a/frontends/ol-components/src/components/Card/ListCardCondensed.tsx b/frontends/ol-components/src/components/Card/ListCardCondensed.tsx index b95acae538..58a49dfec5 100644 --- a/frontends/ol-components/src/components/Card/ListCardCondensed.tsx +++ b/frontends/ol-components/src/components/Card/ListCardCondensed.tsx @@ -105,7 +105,7 @@ const ListCardCondensed: Card = ({ children, className, href, draggable }) => { return ( - <_Container href={href!}> + <_Container href={href!} scroll={!href?.startsWith("?")}> {draggable && ( From 2ec8ee8b6f927dc134dc0ca75fa66892dfa6ce11 Mon Sep 17 00:00:00 2001 From: Jon Kafton <939376+jonkafton@users.noreply.github.com> Date: Thu, 3 Oct 2024 18:04:28 +0200 Subject: [PATCH 09/17] Update next/navigation mock to fix issue with search params not available on router.asPath --- frontends/main/src/test-utils/index.tsx | 12 ++++++++++-- .../ol-test-utilities/src/mocks/nextNavigation.ts | 6 ++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/frontends/main/src/test-utils/index.tsx b/frontends/main/src/test-utils/index.tsx index 7890d1ab8f..155f46fd02 100644 --- a/frontends/main/src/test-utils/index.tsx +++ b/frontends/main/src/test-utils/index.tsx @@ -70,6 +70,7 @@ const renderWithProviders = ( const user = { ...defaultUser, ...allOpts.user } queryClient.setQueryData(["userMe"], { ...user }) } + mockRouter.setCurrentUrl(url) const view = render( @@ -78,8 +79,15 @@ const renderWithProviders = ( const location = { get current() { - const url = new URL(mockRouter.asPath, "http://localhost") - return { pathname: mockRouter.pathname, search: url.search } + const searchParams = new URLSearchParams( + mockRouter.query as unknown as URLSearchParams, + ) + const search = searchParams.toString() + return { + pathname: mockRouter.pathname, + searchParams, + search: search ? `?${search}` : "", + } }, } diff --git a/frontends/ol-test-utilities/src/mocks/nextNavigation.ts b/frontends/ol-test-utilities/src/mocks/nextNavigation.ts index 671ef498b1..bb3bcb69e4 100644 --- a/frontends/ol-test-utilities/src/mocks/nextNavigation.ts +++ b/frontends/ol-test-utilities/src/mocks/nextNavigation.ts @@ -44,8 +44,10 @@ export const nextNavigationMocks = { }, useSearchParams: () => { const router = nextNavigationMocks.useRouter() - const url = new URL(router.asPath, "http://localhost") - return url.searchParams + const search = new URLSearchParams( + router.query as unknown as URLSearchParams, + ) + return search }, useParams: () => { const router = nextNavigationMocks.useRouter() From d08596f233097a1a86fff498e1d63980c1b45cbe Mon Sep 17 00:00:00 2001 From: Jon Kafton <939376+jonkafton@users.noreply.github.com> Date: Thu, 3 Oct 2024 18:05:44 +0200 Subject: [PATCH 10/17] Test pathname linking for topics and departments --- .../src/test-utils/factories/learningResources.ts | 2 +- .../src/app-pages/ChannelPage/ChannelPage.test.tsx | 5 ++++- .../DepartmentListingPage.test.tsx | 2 +- .../TopicsListingPage/TopicsListingPage.test.tsx | 12 ++++++------ .../TopicsListingPage/TopicsListingPage.tsx | 1 + 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/frontends/api/src/test-utils/factories/learningResources.ts b/frontends/api/src/test-utils/factories/learningResources.ts index 1cbe06e991..c83bf903c1 100644 --- a/frontends/api/src/test-utils/factories/learningResources.ts +++ b/frontends/api/src/test-utils/factories/learningResources.ts @@ -101,7 +101,7 @@ const learningResourceBaseDepartment: Factory< return { department_id: uniqueEnforcerWords.enforce(() => faker.lorem.words()), name: uniqueEnforcerWords.enforce(() => faker.lorem.words()), - channel_url: faker.internet.url(), + channel_url: `${faker.internet.url({ appendSlash: false })}${faker.system.directoryPath()}`, ...overrides, } } diff --git a/frontends/main/src/app-pages/ChannelPage/ChannelPage.test.tsx b/frontends/main/src/app-pages/ChannelPage/ChannelPage.test.tsx index be819654b1..fc025e38d1 100644 --- a/frontends/main/src/app-pages/ChannelPage/ChannelPage.test.tsx +++ b/frontends/main/src/app-pages/ChannelPage/ChannelPage.test.tsx @@ -290,7 +290,10 @@ describe("Channel Pages, Topic only", () => { name: (name) => subTopics?.results.map((t) => t.name).includes(name), }) links.forEach((link, i) => { - expect(link).toHaveAttribute("href", subTopics.results[i].channel_url) + expect(link).toHaveAttribute( + "href", + new URL(subTopics.results[i].channel_url!).pathname, + ) }) }) }) diff --git a/frontends/main/src/app-pages/DepartmentListingPage/DepartmentListingPage.test.tsx b/frontends/main/src/app-pages/DepartmentListingPage/DepartmentListingPage.test.tsx index 3bea375333..42c867e8c8 100644 --- a/frontends/main/src/app-pages/DepartmentListingPage/DepartmentListingPage.test.tsx +++ b/frontends/main/src/app-pages/DepartmentListingPage/DepartmentListingPage.test.tsx @@ -154,7 +154,7 @@ describe("DepartmentListingPage", () => { name: (name) => name.includes(dept.name), }) - expect(link).toHaveAttribute("href", dept.channel_url) + expect(link).toHaveAttribute("href", new URL(dept.channel_url!).pathname) }) test("headings", async () => { diff --git a/frontends/main/src/app-pages/TopicsListingPage/TopicsListingPage.test.tsx b/frontends/main/src/app-pages/TopicsListingPage/TopicsListingPage.test.tsx index 13b8bafc2f..b1c409f593 100644 --- a/frontends/main/src/app-pages/TopicsListingPage/TopicsListingPage.test.tsx +++ b/frontends/main/src/app-pages/TopicsListingPage/TopicsListingPage.test.tsx @@ -115,17 +115,17 @@ describe("TopicsListingPage", () => { expect(subtopics1[1]).toHaveTextContent(sortedSubtopics1[0].name) expect(subtopics1[2]).toHaveTextContent(sortedSubtopics1[1].name) expect(subtopics1[3]).toHaveTextContent(sortedSubtopics1[2].name) - expect(subtopics1.map((el) => el.href)).toEqual([ - topics.t1.channel_url, - ...sortedSubtopics1.map((t) => t.channel_url), + expect(subtopics1.map((el) => new URL(el.href).pathname)).toEqual([ + new URL(topics.t1.channel_url!).pathname, + ...sortedSubtopics1.map((t) => new URL(t.channel_url!).pathname), ]) expect(subtopics2[0]).toHaveTextContent(topics.t2.name) expect(subtopics2[1]).toHaveTextContent(sortedSubtopics2[0].name) expect(subtopics2[2]).toHaveTextContent(sortedSubtopics2[1].name) - expect(subtopics2.map((el) => el.href)).toEqual([ - topics.t2.channel_url, - ...sortedSubtopics2.map((t) => t.channel_url), + expect(subtopics2.map((el) => new URL(el.href).pathname)).toEqual([ + new URL(topics.t2.channel_url!).pathname, + ...sortedSubtopics2.map((t) => new URL(t.channel_url!).pathname), ]) }) diff --git a/frontends/main/src/app-pages/TopicsListingPage/TopicsListingPage.tsx b/frontends/main/src/app-pages/TopicsListingPage/TopicsListingPage.tsx index 9e15fafcb6..dad11a6145 100644 --- a/frontends/main/src/app-pages/TopicsListingPage/TopicsListingPage.tsx +++ b/frontends/main/src/app-pages/TopicsListingPage/TopicsListingPage.tsx @@ -132,6 +132,7 @@ const TopicBox = ({ { label: "Programs", count: programCount }, ].filter((item) => item.count) const { title, href, icon, channels } = topicGroup + return (
  • From 4fa97c4d375b0c43f3eb26f9ded6a88e030a8628 Mon Sep 17 00:00:00 2001 From: Jon Kafton <939376+jonkafton@users.noreply.github.com> Date: Thu, 3 Oct 2024 18:22:26 +0200 Subject: [PATCH 11/17] Update search params tests --- .../LearningResourceDrawer/LearningResourceDrawer.test.tsx | 3 +-- frontends/ol-test-utilities/src/mocks/nextNavigation.test.ts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.test.tsx b/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.test.tsx index 97eaa142d3..9e87ae1706 100644 --- a/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.test.tsx +++ b/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.test.tsx @@ -94,8 +94,7 @@ describe("LearningResourceDrawer", () => { openDrawer(123) }) - const params = new URLSearchParams(location.current.search) - expect(Object.fromEntries(params)).toEqual({ + expect(Object.fromEntries(location.current.searchParams)).toEqual({ [RESOURCE_DRAWER_QUERY_PARAM]: "123", dog: "woof", }) diff --git a/frontends/ol-test-utilities/src/mocks/nextNavigation.test.ts b/frontends/ol-test-utilities/src/mocks/nextNavigation.test.ts index d3c0e43baa..a99c9ab5ce 100644 --- a/frontends/ol-test-utilities/src/mocks/nextNavigation.test.ts +++ b/frontends/ol-test-utilities/src/mocks/nextNavigation.test.ts @@ -36,7 +36,7 @@ describe("Mock Navigation", () => { test("useSearchParams returns the current search params", () => { mockRouter.setCurrentUrl("/dynamic/bar?a=1&b=2&b=3") const { result } = renderHook(() => useSearchParams()) - expect(result.current).toEqual(new URLSearchParams("a=1&b=2&b=3")) + expect(result.current.toString()).toEqual("a=1&b=2%2C3&id=bar") }) test("useParams returns the current params", () => { From 9ac979a32ef38ba986941b6cec9cf7f4bc465e6e Mon Sep 17 00:00:00 2001 From: Jon Kafton <939376+jonkafton@users.noreply.github.com> Date: Thu, 3 Oct 2024 19:21:40 +0200 Subject: [PATCH 12/17] Align mock useSearchParams with querystring output for multiple same keys --- .../app-pages/SearchPage/SearchPage.test.tsx | 1 + .../src/mocks/nextNavigation.test.ts | 8 ++++++- .../src/mocks/nextNavigation.ts | 21 ++++++++++++++++--- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/frontends/main/src/app-pages/SearchPage/SearchPage.test.tsx b/frontends/main/src/app-pages/SearchPage/SearchPage.test.tsx index 16186eebaa..c9943bc5ea 100644 --- a/frontends/main/src/app-pages/SearchPage/SearchPage.test.tsx +++ b/frontends/main/src/app-pages/SearchPage/SearchPage.test.tsx @@ -146,6 +146,7 @@ describe("SearchPage", () => { }, }, }) + const { location } = renderWithProviders(, { url: "?topic=Physics&topic=Chemistry", }) diff --git a/frontends/ol-test-utilities/src/mocks/nextNavigation.test.ts b/frontends/ol-test-utilities/src/mocks/nextNavigation.test.ts index a99c9ab5ce..8d3efe111c 100644 --- a/frontends/ol-test-utilities/src/mocks/nextNavigation.test.ts +++ b/frontends/ol-test-utilities/src/mocks/nextNavigation.test.ts @@ -34,9 +34,15 @@ describe("Mock Navigation", () => { }) test("useSearchParams returns the current search params", () => { + mockRouter.setCurrentUrl("/dynamic/bar?a=1&b=2") + const { result } = renderHook(() => useSearchParams()) + expect(result.current.toString()).toEqual("a=1&b=2&id=bar") + }) + + test("useSearchParams repeats duplicate keys on the querystring", () => { mockRouter.setCurrentUrl("/dynamic/bar?a=1&b=2&b=3") const { result } = renderHook(() => useSearchParams()) - expect(result.current.toString()).toEqual("a=1&b=2%2C3&id=bar") + expect(result.current.toString()).toEqual("a=1&b=2&b=3&id=bar") }) test("useParams returns the current params", () => { diff --git a/frontends/ol-test-utilities/src/mocks/nextNavigation.ts b/frontends/ol-test-utilities/src/mocks/nextNavigation.ts index bb3bcb69e4..9cc1119f3d 100644 --- a/frontends/ol-test-utilities/src/mocks/nextNavigation.ts +++ b/frontends/ol-test-utilities/src/mocks/nextNavigation.ts @@ -7,6 +7,7 @@ * See https://github.com/scottrippey/next-router-mock/issues */ import * as mocks from "next-router-mock" +import { ParsedUrlQuery } from "querystring" import { createDynamicRouteParser } from "next-router-mock/dynamic-routes" const getParams = (template: string, pathname: string) => { @@ -22,6 +23,20 @@ const getParams = (template: string, pathname: string) => { }, {}) } +/* Converts router.query objects with multiple key arrays + * e.g. { topic: [ 'Physics', 'Chemistry' ] } + * to [ [ 'topic', 'Physics' ], [ 'topic', 'Chemistry' ] ] + * so that new URLSearchParams(value).toString() + * produces topic=Physics&topic=Chemistry + * and not topic=Physics%2CChemistry + */ +const convertObjectToUrlParams = (obj: ParsedUrlQuery): [string, string][] => + Object.entries(obj).flatMap(([key, value]) => + Array.isArray(value) + ? value.map((v) => [key, v] as [string, string]) + : [[key, value] as [string, string]], + ) + export const nextNavigationMocks = { ...mocks, notFound: jest.fn(), @@ -44,9 +59,9 @@ export const nextNavigationMocks = { }, useSearchParams: () => { const router = nextNavigationMocks.useRouter() - const search = new URLSearchParams( - router.query as unknown as URLSearchParams, - ) + + const search = new URLSearchParams(convertObjectToUrlParams(router.query)) + return search }, useParams: () => { From 66908f588298d32c0817f02291f23d8ded6baead Mon Sep 17 00:00:00 2001 From: Jon Kafton <939376+jonkafton@users.noreply.github.com> Date: Mon, 7 Oct 2024 20:07:27 +0200 Subject: [PATCH 13/17] Targeted params test --- .../main/src/app-pages/ChannelPage/ChannelSearch.test.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/frontends/main/src/app-pages/ChannelPage/ChannelSearch.test.tsx b/frontends/main/src/app-pages/ChannelPage/ChannelSearch.test.tsx index e3413496c2..f583bbb821 100644 --- a/frontends/main/src/app-pages/ChannelPage/ChannelSearch.test.tsx +++ b/frontends/main/src/app-pages/ChannelPage/ChannelSearch.test.tsx @@ -301,7 +301,6 @@ describe("ChannelSearch", () => { setMockResponse.get(urls.userMe.get(), {}) const initialSearch = "?q=meow&page=2" - const finalSearch = "?q=woof" const { location } = renderWithProviders(, { url: `/c/${channel.channel_type}/${channel.name}${initialSearch}`, @@ -313,8 +312,8 @@ describe("ChannelSearch", () => { expect(queryInput.value).toBe("meow") await user.clear(queryInput) await user.paste("woof") - expect(location.current.search).toBe(initialSearch) + expect(location.current.searchParams.get("q")).toBe("meow") await user.click(screen.getByRole("button", { name: "Search" })) - expect(location.current.search).toBe(finalSearch) + expect(location.current.searchParams.get("q")).toBe("woof") }) }) From 2479914394bb43d228535fd5e68f291f88f23842 Mon Sep 17 00:00:00 2001 From: Jon Kafton <939376+jonkafton@users.noreply.github.com> Date: Tue, 8 Oct 2024 15:32:59 +0200 Subject: [PATCH 14/17] Remove useOpenLearningResourceDrawer not in use --- .../LearningResourceDrawer.test.tsx | 27 +------------------ .../LearningResourceDrawer.tsx | 20 -------------- 2 files changed, 1 insertion(+), 46 deletions(-) diff --git a/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.test.tsx b/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.test.tsx index 31a4c38cfd..9b895813db 100644 --- a/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.test.tsx +++ b/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.test.tsx @@ -1,15 +1,12 @@ import React from "react" import { - act, expectProps, renderWithProviders, screen, waitFor, within, } from "@/test-utils" -import LearningResourceDrawer, { - useOpenLearningResourceDrawer, -} from "./LearningResourceDrawer" +import LearningResourceDrawer from "./LearningResourceDrawer" import { urls, factories, setMockResponse } from "api/test-utils" import { LearningResourceExpanded } from "ol-components" import { RESOURCE_DRAWER_QUERY_PARAM } from "@/common/urls" @@ -77,28 +74,6 @@ describe("LearningResourceDrawer", () => { expect(LearningResourceExpanded).not.toHaveBeenCalled() }) - test("useOpenLearningResourceDrawer sets correct parameter", () => { - let openDrawer = (_id: number): void => { - throw new Error("Not implemented") - } - const TestComponent = () => { - openDrawer = useOpenLearningResourceDrawer() - return null - } - const { location } = renderWithProviders(, { - url: "?dog=woof", - }) - - act(() => { - openDrawer(123) - }) - - expect(Object.fromEntries(location.current.searchParams)).toEqual({ - [RESOURCE_DRAWER_QUERY_PARAM]: "123", - dog: "woof", - }) - }) - test.each([ { isLearningPathEditor: true, diff --git a/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.tsx b/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.tsx index 58e8692faa..e880d3e19d 100644 --- a/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.tsx +++ b/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.tsx @@ -142,26 +142,6 @@ const getOpenDrawerSearchParams = ( return newSearchParams } -// TODO Not used anywhere in project. Remove? -const useOpenLearningResourceDrawer = () => { - const searchParams = useSearchParams() - const router = useRouter() - - const openLearningResourceDrawer = useCallback( - (resourceId: number) => { - const hash = window?.location.hash - router.push( - `?${getOpenDrawerSearchParams(searchParams, resourceId)}${hash ? `#${hash}` : ""}`, - { - scroll: false, - }, - ) - }, - [router, searchParams], - ) - return openLearningResourceDrawer -} - const useResourceDrawerHref = () => { const searchParams = useSearchParams() From 9f7d7615957f043c3b5cf1dcd817cf4e78ada616 Mon Sep 17 00:00:00 2001 From: Jon Kafton <939376+jonkafton@users.noreply.github.com> Date: Tue, 8 Oct 2024 16:18:43 +0200 Subject: [PATCH 15/17] Remove redundanct hash. Clean out unnecessary types --- .../ol-components/src/components/Button/Button.tsx | 10 +++------- .../src/components/RoutedDrawer/RoutedDrawer.tsx | 2 +- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/frontends/ol-components/src/components/Button/Button.tsx b/frontends/ol-components/src/components/Button/Button.tsx index d87c3cc003..d30d7c6ac1 100644 --- a/frontends/ol-components/src/components/Button/Button.tsx +++ b/frontends/ol-components/src/components/Button/Button.tsx @@ -92,13 +92,7 @@ const sizeStyles = ( ] } -type ButtonProps = ButtonStyleProps & React.ComponentProps<"button"> -type AnchorProps = ButtonStyleProps & React.ComponentProps<"a"> -type LinkProps = ButtonStyleProps & React.ComponentProps - -const buildStyles = ( - props: (ButtonProps | AnchorProps | LinkProps) & { theme: Theme }, -) => { +const buildStyles = (props: ButtonStyleProps & { theme: Theme }) => { const { size, variant, edge, theme, color, responsive } = { ...DEFAULT_PROPS, ...props, @@ -309,6 +303,8 @@ const ButtonInner: React.FC< ) } +type ButtonProps = ButtonStyleProps & React.ComponentProps<"button"> + /** * Our styled button. If you need a link that looks like a button, use ButtonLink */ diff --git a/frontends/ol-components/src/components/RoutedDrawer/RoutedDrawer.tsx b/frontends/ol-components/src/components/RoutedDrawer/RoutedDrawer.tsx index a7d97236d5..59e73ae447 100644 --- a/frontends/ol-components/src/components/RoutedDrawer/RoutedDrawer.tsx +++ b/frontends/ol-components/src/components/RoutedDrawer/RoutedDrawer.tsx @@ -93,7 +93,7 @@ const RoutedDrawer = ( router.push(`?${newParams}${hash}`) } else { // Prevent scroll to top of page - router.push(`?${newParams}${hash}`, { scroll: false }) + router.push(`?${newParams}`, { scroll: false }) } }, [router, searchParams, params]) From a61b8490a9aa74b6ea011193843055f469a674b6 Mon Sep 17 00:00:00 2001 From: Jon Kafton <939376+jonkafton@users.noreply.github.com> Date: Tue, 8 Oct 2024 16:28:12 +0200 Subject: [PATCH 16/17] Remove unused --- .../LearningResourceDrawer/LearningResourceDrawer.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.tsx b/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.tsx index e880d3e19d..bdc487db84 100644 --- a/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.tsx +++ b/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.tsx @@ -11,7 +11,6 @@ import type { import { useLearningResourcesDetail } from "api/hooks/learningResources" import { useSearchParams, - useRouter, ReadonlyURLSearchParams, } from "next/navigation" @@ -155,4 +154,4 @@ const useResourceDrawerHref = () => { } export default LearningResourceDrawer -export { useOpenLearningResourceDrawer, useResourceDrawerHref } +export { useResourceDrawerHref } From 9470b67f9501fca19b2055612e93bcdfa3c7373c Mon Sep 17 00:00:00 2001 From: Jon Kafton <939376+jonkafton@users.noreply.github.com> Date: Tue, 8 Oct 2024 16:42:06 +0200 Subject: [PATCH 17/17] Format --- .../LearningResourceDrawer/LearningResourceDrawer.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.tsx b/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.tsx index bdc487db84..f4a7aaf3f4 100644 --- a/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.tsx +++ b/frontends/main/src/page-components/LearningResourceDrawer/LearningResourceDrawer.tsx @@ -9,10 +9,7 @@ import type { RoutedDrawerProps, } from "ol-components" import { useLearningResourcesDetail } from "api/hooks/learningResources" -import { - useSearchParams, - ReadonlyURLSearchParams, -} from "next/navigation" +import { useSearchParams, ReadonlyURLSearchParams } from "next/navigation" import { RESOURCE_DRAWER_QUERY_PARAM } from "@/common/urls" import { useUserMe } from "api/hooks/user"