Make navbar dynamically render according to session

This commit is contained in:
sirin 2024-09-10 03:42:22 +07:00
parent a9aedcf3c2
commit d1f474f6f4
4 changed files with 121 additions and 7 deletions

26
package-lock.json generated
View File

@ -8,6 +8,7 @@
"name": "b2d-ventures",
"version": "0.1.0",
"dependencies": {
"@radix-ui/react-avatar": "^1.1.0",
"@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-navigation-menu": "^1.2.0",
"@radix-ui/react-progress": "^1.1.0",
@ -475,6 +476,31 @@
}
}
},
"node_modules/@radix-ui/react-avatar": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.0.tgz",
"integrity": "sha512-Q/PbuSMk/vyAd/UoIShVGZ7StHHeRFYU7wXmi5GV+8cLXflZAEpHL/F697H1klrzxKXNtZ97vWiC0q3RKUH8UA==",
"dependencies": {
"@radix-ui/react-context": "1.1.0",
"@radix-ui/react-primitive": "2.0.0",
"@radix-ui/react-use-callback-ref": "1.1.0",
"@radix-ui/react-use-layout-effect": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-collection": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz",

View File

@ -17,7 +17,11 @@ import {
NavigationMenuTrigger,
navigationMenuTriggerStyle,
} from "@/components/ui/navigation-menu";
import { Search } from "lucide-react";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Skeleton } from "@/components/ui/skeleton";
import { Search, Bell, Heart, Wallet } from "lucide-react";
import useSession from "@/lib/supabase/useSession";
const landings = [
{
@ -54,7 +58,44 @@ const ListItem = React.forwardRef<React.ElementRef<"a">, React.ComponentPropsWit
);
ListItem.displayName = "ListItem";
const unAuthenticatedComponents = () => {
return (
<div className="flex gap-2 pl-2">
<Link href="/auth">
<Button variant="secondary" className="border-2 border-border">
Login
</Button>
</Link>
<Button>Sign up</Button>
</div>
);
};
const authenticatedComponents = () => {
return (
<div className="flex gap-3 pl-2 items-center">
<Bell />
<Heart />
<Wallet />
<Avatar className="ml-2">
<AvatarImage src="https://api.dicebear.com/9.x/pixel-art/svg" />
<AvatarFallback>1</AvatarFallback>
</Avatar>
</div>
);
};
export function UnsignedNav() {
const { session, loading } = useSession();
const user = session?.user;
const [sessionLoaded, setSessionLoaded] = React.useState(false);
React.useEffect(() => {
if (!loading) {
setSessionLoaded(true);
}
}, [loading]);
const businessComponents = [
{
title: "Businesses",
@ -151,12 +192,17 @@ export function UnsignedNav() {
<div className="flex gap-2 pl-2">
<ThemeToggle />
<Separator orientation="vertical" className="mx-3" />
<Link href="/auth">
<Button variant="secondary" className="border-2 border-border">
Login
</Button>
</Link>
<Button>Sign up</Button>
{sessionLoaded ? (
user ? (
authenticatedComponents()
) : (
unAuthenticatedComponents()
)
) : (
<div>
<Skeleton className="rounded-lg h-full w-[160px]" />
</div>
)}
</div>
</div>
</div>

View File

@ -0,0 +1,15 @@
import { cn } from "@/lib/utils"
function Skeleton({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) {
return (
<div
className={cn("animate-pulse rounded-md bg-muted", className)}
{...props}
/>
)
}
export { Skeleton }

View File

@ -0,0 +1,27 @@
"use client";
import { useEffect, useState } from "react";
import { createSupabaseClient } from "./clientComponentClient";
import { Session } from "@supabase/supabase-js";
export default function useSession() {
const [session, setSession] = useState<Session | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const supabase = createSupabaseClient();
const getSession = async () => {
const {
data: { session },
} = await supabase.auth.getSession();
setSession(session);
setLoading(false);
};
getSession();
}, []);
return { session, loading };
}