Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mobile and desktop menu authentication display - team_bulldozer #793

Closed
wants to merge 11 commits into from
3 changes: 3 additions & 0 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { Inter } from "next/font/google";

import "./globals.css";

import { SessionProvider } from "next-auth/react";

import Providers from "~/components/providers";
import { Toaster } from "~/components/ui/toaster";
import AuthProvider from "~/contexts/authContext";
Expand All @@ -23,6 +25,7 @@ export default function RootLayout({
<body className={inter.className}>
<div className="mx-auto w-full">
<Providers />
<SessionProvider>{children}</SessionProvider>
<AuthProvider>{children}</AuthProvider>
<Toaster />
</div>
Expand Down
21 changes: 21 additions & 0 deletions src/components/card/user-card.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Avatar, AvatarImage } from "@radix-ui/react-avatar";
import { AnimatePresence, motion } from "framer-motion";
import { signOut } from "next-auth/react";
import Image from "next/image";
Expand All @@ -6,6 +7,14 @@ import { useEffect, useState } from "react";
import { cn } from "~/lib/utils";
import CustomButton from "../common/common-button/common-button";

const UserCard = ({ image }: { image: string | undefined }) => {
const { updateUser } = useUser();
const [isLogout, setIsLogout] = useState(false);

const handleLogout = () => {
updateUser({ email: "", name: "" });
setIsLogout(false);
};
interface User {
email: string;
image: string;
Expand All @@ -30,6 +39,18 @@ const UserCard = ({ user }: { user: User }) => {

return (
<div className="relative w-fit">
<Button
variant={"ghost"}
size={"icon"}
onClick={() => setIsLogout(!isLogout)}
className={cn(
"grid size-9 place-items-center rounded-full bg-orange-500 text-xl font-medium text-white sm:text-2xl sm:font-bold",
)}
>
<Avatar className="rounded-full">
<AvatarImage src={image} className="rounded-full" />
</Avatar>
</Button>
{user?.image ? (
<div
className="flex h-full w-full cursor-pointer items-center justify-center overflow-hidden rounded-full"
Expand Down
8 changes: 8 additions & 0 deletions src/components/layouts/navbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ interface User {

const Navbar = () => {
const [scrolling, setIsScrolling] = useState<boolean>(false);

const { data: session } = useSession();
const { user } = useUser();
const { data: session, status } = useSession();

const handleScrollEvent = () => {
Expand Down Expand Up @@ -61,6 +64,11 @@ const Navbar = () => {
);
})}
</div>
{session?.user?.email ? (
<div className="hidden md:flex">
<UserCard image={session?.user?.image as string} />
</div>
) : (
{status !== "authenticated" && (
<div className="w-fullx hidden items-center justify-end gap-x-4 justify-self-end md:flex lg:gap-x-8">
<Link
Expand Down
60 changes: 31 additions & 29 deletions src/components/layouts/navbar/mobile-navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,27 @@
import "./menu.css";

import { motion, stagger, useAnimate } from "framer-motion";
import { useSession } from "next-auth/react";
import Link from "next/link";
import { useEffect, useState } from "react";

import { useUser } from "~/hooks/user/use-user";
import UserCard from "~/components/card/user-card";
import { cn } from "~/lib/utils";
import { NAV_LINKS } from "./links";

export default function MobileNav() {
const [open, setOpen] = useState(false);
const [scope, animate] = useAnimate();
const { user } = useUser();
const { data: session } = useSession();

// the stagger effect
const staggerList = stagger(0.1, { startDelay: 0.25 });

// create the animations that will be applied
// whenever the open state is toggled

useEffect(() => {
animate(
"ul",
{
width: open ? 180 : 0,
height: open && user.email ? 140 : open ? 250 : 0,
height: open && session?.user?.email ? 200 : open ? 250 : 0,
opacity: open ? 1 : 0,
},
{
Expand Down Expand Up @@ -103,29 +100,34 @@ export default function MobileNav() {
</Link>
</motion.li>
))}
<motion.li key={NAV_LINKS.length + 1}>
<Link
href="/login"
className={cn(
"grid max-w-[100px] place-items-center whitespace-nowrap rounded-md border border-primary px-2 py-2 text-sm text-primary",
user?.email ? "hidden" : "",
)}
>
Log in
</Link>
</motion.li>

<motion.li key={NAV_LINKS.length + 2}>
<Link
href="/register"
className={cn(
"grid max-w-[100px] place-items-center whitespace-nowrap rounded-md border border-primary bg-primary px-2 py-2 text-sm text-white",
user?.email ? "hidden" : "",
)}
>
Get Started
</Link>
</motion.li>
{!session?.user?.email && (
<>
<motion.li key={NAV_LINKS.length + 1}>
<Link
href="/login"
className="grid max-w-[100px] place-items-center whitespace-nowrap rounded-md border border-primary px-2 py-2 text-sm text-primary"
>
Log in
</Link>
</motion.li>

<motion.li key={NAV_LINKS.length + 2}>
<Link
href="/register"
className="grid max-w-[100px] place-items-center whitespace-nowrap rounded-md border border-primary bg-primary px-2 py-2 text-sm text-white"
>
Get Started
</Link>
</motion.li>
</>
)}

{session?.user?.email && (
<motion.li key={NAV_LINKS.length + 3}>
<UserCard image={session.user.image as string} />
</motion.li>
)}
</ul>
</div>
</>
Expand Down
31 changes: 31 additions & 0 deletions src/components/layouts/rootLayout/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"use client";

import { SessionProvider } from "next-auth/react";
import { Suspense } from "react";

import Footer from "~/components/layouts/footer";
import Navbar from "~/components/layouts/navbar";

function Layout({ children }: { children: React.ReactNode }) {
return (
<>
<Navbar />
<div className="mx-auto w-5/6">
<Suspense>{children}</Suspense>
</div>
<Footer />
</>
);
}

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<SessionProvider>
<Layout>{children}</Layout>
</SessionProvider>
);
}
4 changes: 4 additions & 0 deletions src/config/auth.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@ export default {
const response: ApiResponse = (await googleAuth(
account as Profile,
)) as ApiResponse;
if (account && account.provider !== "google") {
return { ...token, ...response.data };
}

return { ...token, ...user };
user = response?.data?.user;

return { ...token };
Expand Down
18 changes: 18 additions & 0 deletions src/utils/googleAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,24 @@ const googleAuth = async (profile: Profile) => {
id_token: profile.id_token,
});

return response?.data;
} catch (error) {
return {
status: "error " + error,
status_code: 500,
message: "Google authentication failed",
data: {
id_token: "",
user: {
id: "",
email: "",
fullname: "",
avatar_url: "",
expires_in: "",
role: "",
},
},
};
return response.data;
} catch (error) {
return error;
Expand Down
Loading