Skip to content

Commit

Permalink
Add profile tabs to URL parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
joshua-rdrgz committed Mar 19, 2024
1 parent 30bb918 commit d58acd3
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 7 deletions.
3 changes: 1 addition & 2 deletions frontend/compositions/profile-nav/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import * as React from "react"
import { ProfileMenu, profileMenuItems } from "../../models/profile"
import styles from "./profile-nav.module.css"

interface ProfileNavProps {
activePage: ProfileMenu
setActivePage: React.Dispatch<React.SetStateAction<ProfileMenu>>
setActivePage: (newTab: ProfileMenu) => void
}

export default function ProfileNav({ activePage, setActivePage }: ProfileNavProps) {
Expand Down
35 changes: 31 additions & 4 deletions frontend/pages/profile/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as React from "react"
import { GetServerSidePropsContext, InferGetServerSidePropsType } from "next"
import {
ProfileInfo,
ProfileNav,
Expand All @@ -12,9 +12,36 @@ import { requireAuth } from "../../helpers"
import { ProfileMenu } from "../../models/profile"
import { Layout } from "../../shared-components"
import styles from "./profile.module.css"
import { useProfileTab } from "./useProfileTab"

export default requireAuth(function Profile() {
const [activePage, setActivePage] = React.useState(ProfileMenu.USER_INFO)
export async function getServerSideProps(context: GetServerSidePropsContext) {
const { query } = context
const initialTab: ProfileMenu = Object.values(ProfileMenu).includes(query.tab as ProfileMenu)
? (query.tab as ProfileMenu)
: ProfileMenu.USER_INFO

if (initialTab !== query.tab) {
// An invalid tab was requested,
// Redirect to ProfileMenu.USER_INFO tab
return {
redirect: {
destination: `/profile?tab=${initialTab}`,
permanent: false
}
}
}

return {
props: {
initialTab
}
}
}

export default requireAuth(function Profile({
initialTab
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
const [activePage, handleTabChange] = useProfileTab(initialTab)

const ActivePageComp = (function (menuItem: ProfileMenu) {
switch (menuItem) {
Expand All @@ -38,7 +65,7 @@ export default requireAuth(function Profile() {
return (
<Layout>
<div className={styles.profileWrapper}>
<ProfileNav activePage={activePage} setActivePage={setActivePage} />
<ProfileNav activePage={activePage} setActivePage={handleTabChange} />
<ActivePageComp />
</div>
</Layout>
Expand Down
34 changes: 34 additions & 0 deletions frontend/pages/profile/useProfileTab.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useRouter } from "next/router"
import { useEffect, useState } from "react"
import { ProfileMenu } from "../../models/profile"

export function useProfileTab(initialTab: ProfileMenu) {
const router = useRouter()
const [activeTab, setActiveTab] = useState<ProfileMenu>(initialTab)

useEffect(() => {
const initialTab = router.query.tab as ProfileMenu
if (Object.values(ProfileMenu).includes(initialTab)) {
setActiveTab(initialTab)
}

const handleRouteChange = () => {
const newTab = router.query.tab as ProfileMenu
if (Object.values(ProfileMenu).includes(newTab)) {
setActiveTab(newTab)
}
}

router.events.on("routeChangeComplete", handleRouteChange)

return () => {
router.events.off("routeChangeComplete", handleRouteChange)
}
}, [router])

const handleTabChange = (newTab: ProfileMenu) => {
router.push(`?tab=${newTab}`)
}

return [activeTab, handleTabChange] as [ProfileMenu, (newTab: ProfileMenu) => void]
}
3 changes: 2 additions & 1 deletion frontend/tests/snapshots/profile.test.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { ProfileMenu } from "../../models/profile"
import Profile from "../../pages/profile"
import { render, setAuthForTest } from "../test-utils"

beforeAll(() => setAuthForTest())

it("renders Profile Page correctly", () => {
const { container } = render(<Profile />)
const { container } = render(<Profile initialTab={ProfileMenu.USER_INFO} />)
expect(container).toMatchSnapshot()
})

0 comments on commit d58acd3

Please sign in to comment.