Skip to content

Commit afccd8a

Browse files
feat: improved navbar (#347)
* feat: improved buttons light theme visibility by adding a border * feat: added support for using search params to navigate tabs via the url * feat: the user menu settings button takes you to user account settings * fix: tweak secondary button light theme style * refactor: rework tab switching and search param logic --------- Co-authored-by: Rohan <[email protected]>
1 parent f4c2191 commit afccd8a

File tree

3 files changed

+35
-10
lines changed

3 files changed

+35
-10
lines changed

frontend/app/[team]/settings/page.tsx

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use client'
22

3+
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
34
import { Avatar } from '@/components/common/Avatar'
45
import { ModeToggle } from '@/components/common/ModeToggle'
56
import { TrustedDeviceManager } from '@/components/settings/account/TrustedDeviceManager'
@@ -11,26 +12,50 @@ import { userIsAdmin } from '@/utils/permissions'
1112
import { Tab } from '@headlessui/react'
1213
import clsx from 'clsx'
1314
import { useSession } from 'next-auth/react'
14-
import { Fragment, useContext } from 'react'
15+
import { Fragment, useContext, useEffect, useState } from 'react'
1516
import { FaMoon, FaSun } from 'react-icons/fa'
1617
import Spinner from '@/components/common/Spinner'
1718

1819
export default function Settings({ params }: { params: { team: string } }) {
20+
const searchParams = useSearchParams()
21+
const router = useRouter()
22+
const pathname = usePathname()
23+
1924
const { activeOrganisation } = useContext(organisationContext)
2025

2126
const { data: session } = useSession()
2227

2328
const activeUserIsAdmin = activeOrganisation ? userIsAdmin(activeOrganisation.role!) : false
2429

25-
const tabList = () => [
30+
const [tabIndex, setTabIndex] = useState(0)
31+
32+
const tabList = [
2633
...(activeUserIsAdmin ? [{ name: 'Organisation' }] : []),
27-
...[{ name: 'Account' }, { name: 'App' }],
34+
{ name: 'Account' },
35+
{ name: 'App' },
2836
]
2937

38+
useEffect(() => {
39+
const initialTabName = searchParams?.get('tab') ?? 'organisation'
40+
const initialTabIndex = tabList.findIndex(
41+
(tab) => tab.name.toLowerCase() === initialTabName.toLowerCase()
42+
)
43+
44+
if (initialTabIndex !== -1) setTabIndex(initialTabIndex)
45+
// eslint-disable-next-line react-hooks/exhaustive-deps
46+
}, [activeUserIsAdmin, searchParams])
47+
48+
const updateTab = (index: number) => {
49+
const tab = tabList[index]
50+
const params = new URLSearchParams(searchParams?.toString())
51+
params.set('tab', tab.name)
52+
router.push(`${pathname}?${params.toString()}`)
53+
}
54+
3055
if (!activeOrganisation)
3156
return (
3257
<div className="flex items-center justify-center py-40">
33-
<Spinner size="md" />{' '}
58+
<Spinner size="md" />
3459
</div>
3560
)
3661

@@ -39,17 +64,17 @@ export default function Settings({ params }: { params: { team: string } }) {
3964
<h1 className="text-3xl font-semibold">Settings</h1>
4065

4166
<div className="pt-8">
42-
<Tab.Group>
67+
<Tab.Group selectedIndex={tabIndex} onChange={(index) => updateTab(index)}>
4368
<Tab.List className="flex gap-4 w-full border-b border-neutral-500/20">
44-
{tabList().map((tab) => (
69+
{tabList.map((tab) => (
4570
<Tab key={tab.name} as={Fragment}>
4671
{({ selected }) => (
4772
<div
4873
className={clsx(
4974
'p-3 font-medium border-b focus:outline-none text-black dark:text-white',
5075
selected
5176
? 'border-emerald-500 font-semibold'
52-
: ' border-transparent cursor-pointer'
77+
: 'border-transparent cursor-pointer'
5378
)}
5479
>
5580
{tab.name}
@@ -63,7 +88,7 @@ export default function Settings({ params }: { params: { team: string } }) {
6388
<div className="max-h-[80vh] overflow-y-auto px-4">
6489
{activeUserIsAdmin && (
6590
<Tab.Panel>
66-
<div className="space-y-10 py-4">
91+
<div className="space-y-10 py-4">
6792
<div className="space-y-1">
6893
<h2 className="text-2xl font-semibold">Organisation</h2>
6994
<p className="text-neutral-500">Organisation info and settings</p>

frontend/components/UserMenu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export default function UserMenu() {
7979
<div className="flex items-center justify-between p-2">
8080
<div>
8181
{activeOrganisation && (
82-
<Link href={`/${activeOrganisation.name}/settings`}>
82+
<Link href={`/${activeOrganisation.name}/settings?tab=account`}>
8383
<Button variant="outline">
8484
<div className="flex items-center gap-1 text-xs">
8585
<FaCog />

frontend/components/common/Button.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const variantStyles: Record<string, string> = {
3737
danger:
3838
'rounded-full bg-red-700 py-1 px-3 text-white hover:bg-red-600 dark:bg-red-400/10 dark:text-red-400 dark:ring-1 dark:ring-inset dark:ring-red-400/20 dark:hover:bg-red-400/10 dark:hover:text-red-300 dark:hover:ring-red-300',
3939
secondary:
40-
'rounded-full bg-zinc-100 py-1 px-3 text-zinc-900 hover:bg-zinc-200 dark:bg-zinc-800/40 dark:text-zinc-400 dark:ring-1 dark:ring-inset dark:ring-zinc-800 dark:hover:bg-zinc-800 dark:hover:text-zinc-300',
40+
'rounded-full bg-zinc-100 py-1 px-3 text-zinc-900 hover:bg-zinc-200 ring-1 ring-zinc-300 dark:bg-zinc-800/40 dark:text-zinc-400 dark:ring-1 dark:ring-inset dark:ring-zinc-800 dark:hover:bg-zinc-800 dark:hover:text-zinc-300',
4141
filled:
4242
'rounded-full bg-zinc-900 py-1 px-3 text-white hover:bg-zinc-700 dark:bg-emerald-500 dark:text-white dark:hover:bg-emerald-400',
4343
outline:

0 commit comments

Comments
 (0)