Skip to content

Commit

Permalink
Auth checker and logged in nav bar (#91)
Browse files Browse the repository at this point in the history
Fixes #88 and Fixes #89
  • Loading branch information
ckcherry23 authored Oct 12, 2023
1 parent df277e3 commit d0b916b
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 9 deletions.
34 changes: 34 additions & 0 deletions frontend/src/components/common/auth-checker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useEffect } from 'react';
import { useRouter } from 'next/router';
import { AuthContext } from "@/contexts/AuthContext";
import { getAuth, onAuthStateChanged } from "firebase/auth";
import { useContext } from "react";

interface AuthCheckerProps {
children: React.ReactNode;
}

export default function AuthChecker({ children }: AuthCheckerProps) {
const auth = getAuth();
const router = useRouter();
const { user: currentUser, authIsReady } = useContext(AuthContext);

const currentPage = router.pathname;

useEffect(() => {
if (!currentUser && currentPage !== "/") {
onAuthStateChanged(auth, (user) => {
if (!user) {
router.push("/");
}
});
}
});

if (currentPage === "/") {
return children;
}

return (currentUser && children)
}

92 changes: 87 additions & 5 deletions frontend/src/components/common/navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,98 @@
import Link from "next/link";
import { Button } from "../ui/button";
import Image from "next/image";
import { AuthContext } from "@/contexts/AuthContext";
import { useContext, useEffect, useState } from "react";
import { Tabs, TabsList, TabsTrigger } from "../ui/tabs";
import { useRouter } from "next/router";
import { Avatar, AvatarImage } from "@radix-ui/react-avatar";
import { ChevronDown } from "lucide-react";
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuLabel,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { useLogout } from "@/firebase-client/useLogout";
import { useLogin } from "@/firebase-client/useLogin";

enum TabsOptions {
INTERVIEWS = "interviews",
QUESTIONS = "questions",
NULL = "",
}


export default function Navbar() {
const { user: currentUser, authIsReady } = useContext(AuthContext);
const [activeTab, setActiveTab] = useState<TabsOptions>(TabsOptions.NULL);

const { login } = useLogin();
const { logout } = useLogout();
const router = useRouter();

const currentPage = router.pathname;

useEffect(() => {
if (currentPage === "/interviews") {
setActiveTab(TabsOptions.INTERVIEWS);
} else if (currentPage === "/questions") {
setActiveTab(TabsOptions.QUESTIONS);
} else {
setActiveTab(TabsOptions.NULL);
}
}, [currentPage]);

return (
<header>
<div className="flex py-4 bg-card justify-between items-center px-12">
<Link href="/"><Image src="/CodeParty.svg" alt="CodeParty logo" width={125} height={25}/></Link>
<div className="grid grid-cols-2 gap-4">
<Link href="/interviews"><Button variant={"outline"}>Log In</Button></Link>
<Button>Sign Up</Button>
<div className="flex h-20 bg-card justify-between items-center px-12">
<div className="flex gap-20 justify-center items-center">
<Link href="/"><Image src="/CodeParty.svg" alt="CodeParty logo" width={125} height={25} /></Link>
{currentUser && <div className="h-12 flex justify-center items-center">
<Tabs value={activeTab}>
<TabsList>
<Link href="/interviews">
<TabsTrigger value="interviews" className="h-20 w-36 hover:bg-accent duration-100">
Interviews
</TabsTrigger>
</Link>
<Link href="/questions">
<TabsTrigger value="questions" className="h-20 w-36 hover:bg-accent duration-100">
Questions
</TabsTrigger>
</Link>
</TabsList>
</Tabs>
</div>}
</div>
{!currentUser && <div className="grid grid-cols-2 gap-4">
<Button variant={"outline"} onClick={login}>Log In</Button>
<Button onClick={login}>Sign Up</Button>
</div>}
{currentUser &&
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="flex justify-center items-center gap-2 h-14">
<Avatar className="h-10 w-10">
<AvatarImage src={currentUser.photoURL || ''} className="rounded-full" />
</Avatar>
<ChevronDown className="w-6 h-6" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuLabel className="hover:bg-card" onClick={() => router.push("/profile")}>
Profile
</DropdownMenuLabel>
<DropdownMenuLabel className="hover:bg-card">
Settings
</DropdownMenuLabel>
<DropdownMenuLabel className="hover:bg-card" onClick={logout}>
Log Out
</DropdownMenuLabel>
</DropdownMenuContent>
</DropdownMenu>
}
</div>
</header>
)
Expand Down
9 changes: 6 additions & 3 deletions frontend/src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { AppProps } from 'next/app'
import Layout from '../components/common/layout'
import { Noto_Sans } from 'next/font/google'
import AuthContextProvider from "@/contexts/AuthContext";
import AuthChecker from '@/components/common/auth-checker';

const notoSans = Noto_Sans({
weight: ['400', '500', '600', '700', '800', '900'],
Expand All @@ -19,9 +20,11 @@ export default function App({ Component, pageProps }: AppProps) {
`}</style>
<main>
<AuthContextProvider>
<Layout>
<Component {...pageProps} />
</Layout>
<AuthChecker>
<Layout>
<Component {...pageProps} />
</Layout>
</AuthChecker>
</AuthContextProvider>
</main>
</>
Expand Down
1 change: 0 additions & 1 deletion frontend/src/pages/questions/[id]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { TypographyBody } from "@/components/ui/typography";
import { useRouter } from "next/router";
import { useContext, useEffect, useState } from "react";
import { Question } from "../../../../types/QuestionTypes";
import { auth } from "@/firebase-client/firebase_config";
import { questionApiPathAddress } from "@/firebase-client/gateway-address";
import { AuthContext } from "@/contexts/AuthContext";

Expand Down

0 comments on commit d0b916b

Please sign in to comment.