Skip to content

Commit

Permalink
NEOS-500, NEOS-554 clicking home should route to home page for curren…
Browse files Browse the repository at this point in the history
…tly (#1006)
  • Loading branch information
nickzelei committed Jan 2, 2024
1 parent 34756d3 commit 52ce895
Show file tree
Hide file tree
Showing 12 changed files with 114 additions and 64 deletions.
2 changes: 1 addition & 1 deletion frontend/apps/web/app/BaseLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import SiteFooter from '@/components/SiteFooter';
import SiteHeader from '@/components/SiteHeader';
import AccountProvider from '@/components/providers/account-provider';
import { PostHogIdentifier } from '@/components/providers/posthog-provider';
import { SessionProvider } from '@/components/providers/session-provider';
import SiteHeader from '@/components/site-header/SiteHeader';
import { Toaster } from '@/components/ui/toaster';
import { ReactElement, ReactNode, Suspense } from 'react';
import { auth, signIn } from './api/auth/[...nextauth]/auth';
Expand Down
13 changes: 5 additions & 8 deletions frontend/apps/web/app/[account]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
'use client';
import OverviewContainer from '@/components/containers/OverviewContainer';
import PageHeader from '@/components/headers/PageHeader';
import { useAccount } from '@/components/providers/account-provider';
import SkeletonTable from '@/components/skeleton/SkeletonTable';
import { PageProps } from '@/components/types';
import { Skeleton } from '@/components/ui/skeleton';
import { useGetUserAccounts } from '@/libs/hooks/useUserAccounts';
import Error from 'next/error';
import { useRouter } from 'next/navigation';
import { ReactElement, useEffect } from 'react';

export default function AccountPage({ params }: PageProps): ReactElement {
export default function AccountPage(): ReactElement {
const router = useRouter();
const { data, isLoading } = useGetUserAccounts();
const accountName = params?.account ?? 'personal'; // if not present, may need to update url to include personal
const account = data?.accounts.find((a) => a.name === accountName);
const { account, isLoading } = useAccount();

useEffect(() => {
if (isLoading || !account?.name) {
return;
}
router.push(`/${account.name}/jobs`);
}, [isLoading, accountName, account?.id]);
}, [isLoading, account?.name, account?.id]);

if (isLoading) {
return <Skeleton className="w-full h-full" />;
return <Skeleton className="w-full h-full py-2" />;
}

if (!account) {
Expand Down
5 changes: 2 additions & 3 deletions frontend/apps/web/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { PageProps } from '@/components/types';
import { ReactElement } from 'react';
import BaseLayout from './BaseLayout';
import AccountPage from './[account]/page';

export default function Home(props: PageProps): ReactElement {
export default function Home(): ReactElement {
return (
<BaseLayout>
<AccountPage {...props} />
<AccountPage />
</BaseLayout>
);
}
49 changes: 47 additions & 2 deletions frontend/apps/web/components/providers/account-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
useEffect,
useState,
} from 'react';
import { useLocalStorage } from 'usehooks-ts';

interface AccountContextType {
account: UserAccount | undefined;
Expand All @@ -28,10 +29,17 @@ interface Props {
children: ReactNode;
}

const DEFAULT_ACCOUNT_NAME = 'personal';
const STORAGE_ACCOUNT_KEY = 'account';

export default function AccountProvider(props: Props): ReactElement {
const { children } = props;
const { account } = useParams();
const accountName = account ?? 'personal';
const accountName = useGetAccountName();
const [, setLastSelectedAccount] = useLocalStorage(
STORAGE_ACCOUNT_KEY,
accountName ?? DEFAULT_ACCOUNT_NAME
);

const { data: accountsResponse, isLoading, mutate } = useGetUserAccounts();
const router = useRouter();
Expand All @@ -55,13 +63,25 @@ export default function AccountProvider(props: Props): ReactElement {
}
if (foundAccount) {
setUserAccount(foundAccount);
setLastSelectedAccount(foundAccount.name);
const accountParam = getSingleOrUndefined(account);
if (!accountParam || accountParam !== foundAccount.name) {
router.push(`/${foundAccount.name}/jobs`);
}
}
}, [userAccount, accountsResponse?.accounts.length, isLoading, accountName]);
}, [
userAccount?.id,
userAccount?.name,
accountsResponse?.accounts.length,
isLoading,
accountName,
]);

function setAccount(userAccount: UserAccount): void {
if (userAccount.name !== accountName) {
router.push(`/${userAccount.name}`);
setUserAccount(userAccount);
setLastSelectedAccount(userAccount.name);
}
}

Expand All @@ -79,6 +99,31 @@ export default function AccountProvider(props: Props): ReactElement {
);
}

function useGetAccountName(): string {
const { account } = useParams();
const [storedAccount] = useLocalStorage(
STORAGE_ACCOUNT_KEY,
account ?? DEFAULT_ACCOUNT_NAME
);

const accountParam = getSingleOrUndefined(account);
if (accountParam) {
return accountParam;
}
const singleStoredAccount = getSingleOrUndefined(storedAccount);
if (singleStoredAccount) {
return singleStoredAccount;
}
return DEFAULT_ACCOUNT_NAME;
}

function getSingleOrUndefined(val: string | string[]): string | undefined {
if (Array.isArray(val)) {
return val.length > 0 ? val[0] : undefined;
}
return val;
}

export function useAccount(): AccountContextType {
const account = useContext(AccountContext);
return account;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import {
CreateTeamAccountResponse,
UserAccountType,
} from '@neosync/sdk';
import { useAccount } from './providers/account-provider';
import { Avatar, AvatarFallback, AvatarImage } from './ui/avatar';
import { Button } from './ui/button';
import { useAccount } from '../providers/account-provider';
import { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar';
import { Button } from '../ui/button';
import {
Command,
CommandEmpty,
Expand All @@ -26,7 +26,7 @@ import {
CommandItem,
CommandList,
CommandSeparator,
} from './ui/command';
} from '../ui/command';
import {
Dialog,
DialogContent,
Expand All @@ -35,12 +35,12 @@ import {
DialogHeader,
DialogTitle,
DialogTrigger,
} from './ui/dialog';
import { Input } from './ui/input';
import { Label } from './ui/label';
import { Popover, PopoverContent, PopoverTrigger } from './ui/popover';
import { Skeleton } from './ui/skeleton';
import { toast } from './ui/use-toast';
} from '../ui/dialog';
import { Input } from '../ui/input';
import { Label } from '../ui/label';
import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover';
import { Skeleton } from '../ui/skeleton';
import { toast } from '../ui/use-toast';

interface Props {}

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import Link from 'next/link';

import { cn } from '@/libs/utils';
import { usePathname } from 'next/navigation';
import { useAccount } from '../providers/account-provider';
import Logo from './Logo';
import { useAccount } from './providers/account-provider';
import { getPathNameHighlight } from './util';

export function MainNav({
className,
Expand All @@ -14,6 +15,8 @@ export function MainNav({
const pathname = usePathname();
const { account } = useAccount();

const accountName = account?.name ?? 'personal';

return (
<div className="mr-4 hidden lg:flex">
<Link href="/" className="mr-6 flex items-center space-x-2">
Expand All @@ -27,63 +30,53 @@ export function MainNav({
href="/"
className={cn(
'text-sm font-medium transition-colors hover:text-primary',
highlightPathName('/') ? 'text-foreground' : 'text-foreground/60'
getPathNameHighlight('/')
)}
>
Overview
</Link> */}
<Link
href={`/${account?.name}/jobs`}
href={`/${accountName}/jobs`}
className={cn(
'text-sm font-medium text-muted-foreground transition-colors hover:text-black dark:hover:text-white',
highlightPathName('/job', pathname)
? 'text-foreground'
: 'text-foreground/60'
getPathNameHighlight('/job', pathname)
)}
>
Jobs
</Link>
<Link
href={`/${account?.name}/runs`}
href={`/${accountName}/runs`}
className={cn(
'text-sm font-medium text-muted-foreground transition-colors hover:text-black dark:hover:text-white',
highlightPathName('/run', pathname)
? 'text-foreground'
: 'text-foreground/60'
getPathNameHighlight('/run', pathname)
)}
>
Runs
</Link>
<Link
href={`/${account?.name}/transformers`}
href={`/${accountName}/transformers`}
className={cn(
'text-sm font-medium text-muted-foreground transition-colors hover:text-black dark:hover:text-white',
highlightPathName('/transformer', pathname)
? 'text-foreground'
: 'text-foreground/60'
getPathNameHighlight('/transformer', pathname)
)}
>
Transformers
</Link>
<Link
href={`/${account?.name}/connections`}
href={`/${accountName}/connections`}
className={cn(
'text-sm font-medium text-muted-foreground transition-colors hover:text-black dark:hover:text-white',
highlightPathName('connection', pathname)
? 'text-foreground'
: 'text-foreground/60'
getPathNameHighlight('connection', pathname)
)}
>
Connections
</Link>

<Link
href={`/${account?.name}/settings`}
href={`/${accountName}/settings`}
className={cn(
'text-sm font-medium text-muted-foreground transition-colors hover:text-black dark:hover:text-white',
highlightPathName('/settings', pathname)
? 'text-foreground'
: 'text-foreground/60'
getPathNameHighlight('/settings', pathname)
)}
>
Settings
Expand All @@ -92,10 +85,3 @@ export function MainNav({
</div>
);
}

export const highlightPathName = (href: string, pathname: string): boolean => {
if (href === '/' && pathname === '/') {
return true;
}
return href !== '/' && pathname.includes(href);
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import { usePathname, useRouter } from 'next/navigation';
import * as React from 'react';

import { getMobileMainNav } from '@/app/config/mobile-nav-config';
import Logo from '@/components/Logo';
import Logo from '@/components/site-header/Logo';
import { Button } from '@/components/ui/button';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Sheet, SheetContent, SheetTrigger } from '@/components/ui/sheet';
import { cn } from '@/libs/utils';
import { highlightPathName } from './MainNav';
import { useAccount } from './providers/account-provider';
import { useAccount } from '../providers/account-provider';
import { getPathNameHighlight } from './util';

export function MobileNav() {
const [open, setOpen] = React.useState(false);
Expand Down Expand Up @@ -49,9 +49,10 @@ export function MobileNav() {
onOpenChange={setOpen}
className={cn(
'text-sm font-medium text-muted-foreground transition-colors hover:text-black dark:hover:text-white',
highlightPathName(`${item.href.split('/')[2]}`, pathname)
? 'text-foreground'
: 'text-foreground/60'
getPathNameHighlight(
`${item.href.split('/')[2]}`,
pathname
)
)}
>
{item.title}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,22 @@ export function ModeToggle() {
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setTheme('light')}>
<DropdownMenuItem
className="cursor-pointer"
onClick={() => setTheme('light')}
>
Light
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('dark')}>
<DropdownMenuItem
className="cursor-pointer"
onClick={() => setTheme('dark')}
>
Dark
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('system')}>
<DropdownMenuItem
className="cursor-pointer"
onClick={() => setTheme('system')}
>
System
</DropdownMenuItem>
</DropdownMenuContent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import { siteConfig } from '@/app/config/site';
import { cn } from '@/libs/utils';
import { GitHubLogoIcon, TwitterLogoIcon } from '@radix-ui/react-icons';
import Link from 'next/link';
import { ReactElement } from 'react';
import { buttonVariants } from '../ui/button';
import AccountSwitcher from './AccountSwitcher';
import { MainNav } from './MainNav';
import { MobileNav } from './MobileNav';
import { ModeToggle } from './ModeToggle';
import { UserNav } from './UserNav';
import { buttonVariants } from './ui/button';

export default function SiteHeader() {
export default function SiteHeader(): ReactElement {
const systemAppConfig = getSystemAppConfig();
const iconButtonClassNames = cn(
buttonVariants({
Expand Down
File renamed without changes.
12 changes: 12 additions & 0 deletions frontend/apps/web/components/site-header/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
function shouldHighlightPathName(href: string, pathname: string): boolean {
if (href === '/' && pathname === '/') {
return true;
}
return href !== '/' && pathname.includes(href);
}

export function getPathNameHighlight(href: string, pathname: string): string {
return shouldHighlightPathName(href, pathname)
? 'text-foreground'
: 'text-foreground/60';
}

1 comment on commit 52ce895

@vercel
Copy link

@vercel vercel bot commented on 52ce895 Jan 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.