Spaces:
Running
Running
| "use client"; | |
| import { useEffect, useState } from "react"; | |
| import { Button } from "@/components/ui/button"; | |
| import { | |
| DropdownMenu, | |
| DropdownMenuContent, | |
| DropdownMenuItem, | |
| DropdownMenuLabel, | |
| DropdownMenuSeparator, | |
| DropdownMenuTrigger, | |
| } from "@/components/ui/dropdown-menu"; | |
| import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; | |
| import { LogOut, User, CreditCard } from "lucide-react"; | |
| import Link from "next/link"; | |
| import { useRouter } from "next/navigation"; | |
| import { supabaseClient } from "@/lib/supabase-client"; | |
| import { LoginButton } from "./LoginButton"; | |
| import { cn } from "@/lib/utils"; | |
| export function UserAuth() { | |
| const [user, setUser] = useState<any>(null); | |
| const supabase = supabaseClient; | |
| const router = useRouter(); | |
| useEffect(() => { | |
| const getUser = async () => { | |
| const { data: { user } } = await supabase.auth.getUser(); | |
| setUser(user); | |
| if (user) { | |
| console.log("π UserAuth: Calling RPC handle_user_login on mount"); | |
| await supabase.rpc('handle_user_login', { | |
| user_email: user.email, | |
| user_full_name: user.user_metadata.full_name || '', | |
| user_avatar_url: user.user_metadata.avatar_url || '' | |
| }).then(({ error }) => { | |
| if (error) console.error("β RPC Error:", error); | |
| else console.log("β RPC Success: User synced"); | |
| }); | |
| } | |
| }; | |
| getUser(); | |
| const { data: { subscription } } = supabase.auth.onAuthStateChange(async (_event, session) => { | |
| setUser(session?.user ?? null); | |
| if (session?.user) { | |
| console.log("π UserAuth: Calling RPC handle_user_login on auth change"); | |
| await supabase.rpc('handle_user_login', { | |
| user_email: session.user.email, | |
| user_full_name: session.user.user_metadata.full_name || '', | |
| user_avatar_url: session.user.user_metadata.avatar_url || '' | |
| }).then(({ error }) => { | |
| if (error) console.error("β RPC Error:", error); | |
| else { | |
| console.log("β RPC Success: User synced"); | |
| router.refresh(); | |
| } | |
| }); | |
| } | |
| router.refresh(); | |
| }); | |
| return () => subscription.unsubscribe(); | |
| }, [supabase, router]); | |
| const handleLogin = async () => { | |
| await supabase.auth.signInWithOAuth({ | |
| provider: "google", | |
| options: { | |
| redirectTo: `${location.origin}/auth/callback`, | |
| }, | |
| }); | |
| }; | |
| const handleLogout = async () => { | |
| await supabase.auth.signOut(); | |
| router.refresh(); | |
| }; | |
| if (!user) { | |
| return ( | |
| <LoginButton text="Sign In" className="bg-blue-600 hover:bg-blue-700 text-white font-medium px-6" /> | |
| ); | |
| } | |
| return ( | |
| <DropdownMenu> | |
| <DropdownMenuTrigger asChild> | |
| <Button variant="ghost" className="relative h-10 w-10 rounded-full"> | |
| <Avatar className="h-10 w-10 border border-slate-700"> | |
| <AvatarImage src={user.user_metadata?.avatar_url} alt={user.user_metadata?.full_name} /> | |
| <AvatarFallback>{user.email?.charAt(0).toUpperCase()}</AvatarFallback> | |
| </Avatar> | |
| </Button> | |
| </DropdownMenuTrigger> | |
| <DropdownMenuContent className="w-56 bg-slate-900 border-slate-800 text-slate-200" align="end" forceMount> | |
| <DropdownMenuLabel className="font-normal"> | |
| <div className="flex flex-col space-y-1"> | |
| <p className="text-sm font-medium leading-none text-white">{user.user_metadata?.full_name}</p> | |
| <p className="text-xs leading-none text-slate-400">{user.email}</p> | |
| </div> | |
| </DropdownMenuLabel> | |
| <DropdownMenuSeparator className="bg-slate-800" /> | |
| <DropdownMenuItem asChild> | |
| <Link href="/profile" className="cursor-pointer hover:bg-slate-800 focus:bg-slate-800"> | |
| <User className="mr-2 h-4 w-4" /> | |
| <span>Profile</span> | |
| </Link> | |
| </DropdownMenuItem> | |
| <DropdownMenuItem asChild> | |
| <Link href="/billing" className="cursor-pointer hover:bg-slate-800 focus:bg-slate-800"> | |
| <CreditCard className="mr-2 h-4 w-4" /> | |
| <span>Billing</span> | |
| </Link> | |
| </DropdownMenuItem> | |
| <DropdownMenuSeparator className="bg-slate-800" /> | |
| <DropdownMenuItem onClick={handleLogout} className="cursor-pointer text-red-400 hover:bg-red-950/30 focus:bg-red-950/30 hover:text-red-300 focus:text-red-300"> | |
| <LogOut className="mr-2 h-4 w-4" /> | |
| <span>Log out</span> | |
| </DropdownMenuItem> | |
| </DropdownMenuContent> | |
| </DropdownMenu> | |
| ); | |
| } | |