DocsDeveloper

User Button

Component Type: Next/OAuth/Firebase

Overview

The UserButton component serves as a versatile solution for managing user authentication and profile interactions within Next.js applications. Seamlessly integrating with Next.js authentication library and Firebase authentication, this component empowers you to create tailored user experiences that align with their application's requirements and design aesthetics. With its flexible design and powerful functionality, the UserButton component empowers you to create immersive and user-centric experiences that drive engagement and satisfaction.

Demo

Easy CLI Install

jrui add userButton userAvatarNextOAuthFirebase

Note: This may override any custom styles you have in your globals.css file. Make sure to have those ready to paste back in after installing.

Props

The `UserButton` component accepts the following props for controlling its behavior:

  • size?: number
    The size of the user avatar in pixels. Defaults to 50 if not provided.
  • className?: string
    Additional CSS classes to apply to the user avatar for custom styling.

Component File

components > UserButton.tsx

"use client";
import React from "react";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuSeparator,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import Link from "next/link";
import { signIn, useSession, signOut } from "next-auth/react";
import UserAvatar from "./UserAvatarNextOAuthFirebase";
import { CircleUserRound } from "lucide-react";

interface UserButtonProps {
size?: number;
className?: string;
}

function UserButton({ size = 50, className }: UserButtonProps) {
const { data: session } = useSession();
const userName = session?.user.name;

return (
    <DropdownMenu>
    {session ? (
        <DropdownMenuTrigger>
        <UserAvatar size={size} className={className} />
        </DropdownMenuTrigger>
    ) : (
        // User is not signed in, render the Open button
        <button onClick={() => signIn()}>
        <CircleUserRound
            size={size}
            className={`${className} rounded-full`}
            strokeWidth={1}
        />
        </button>
    )}

    {session && (
        <DropdownMenuContent>
        <DropdownMenuItem className="text-primary font-semibold">
            {userName}
        </DropdownMenuItem>
        <DropdownMenuSeparator />
        <Link href="#">
            <DropdownMenuItem>Profile</DropdownMenuItem>
        </Link>
        <Link href={"#"}>
            <DropdownMenuItem>Billing</DropdownMenuItem>
        </Link>
        <Link href={"#"}>
            <DropdownMenuItem>Settings</DropdownMenuItem>
        </Link>
        <DropdownMenuSeparator />
        <DropdownMenuItem
            className={"text-primary hover:cursor-pointer"}
            onClick={() => signOut()}
        >
            Log out
        </DropdownMenuItem>
        </DropdownMenuContent>
    )}
    </DropdownMenu>
);
}

export default UserButton;
              

components > UserAvatar.tsx

"use client";
import React from "react";
import Image from "next/image";
import { useSession } from "next-auth/react";

interface UserAvatarProps {
  size?: number;
  className?: string;
  alt?: string;
}

function UserAvatar({
  size = 50,
  className,
  alt = "User profile image",
}: UserAvatarProps) {
  const { data: session } = useSession();
  const imgUrl = session?.user?.image;

  return (
    <>
      {imgUrl && (
        <Image
          alt={alt}
          src={imgUrl}
          width={size}
          height={size}
          className={`${className} shadow-sm border rounded-full`}
          loading="lazy"
        />
      )}
    </>
  );
}

export default UserAvatar;

Example Use Case

Example.tsx

import React from "react";
import UserButton from "./UserButton"; // Adjust the import path based on your project structure

const Example: React.FC = () => {
  return (
    <UserButton size={45} className={"border border-white"}/>
  );
};

export default Example;