Tiesen Logo

Auth Components

Pre-built authentication components including user buttons, login forms, and other auth-related UI elements

Overview

This collection provides ready-to-use authentication components that you can integrate into your application. Each component is designed to handle common authentication patterns while being customizable to match your design system.

User Button

A user profile button component that displays the authenticated user's information and provides access to account actions.

'use client'import { useTheme } from 'next-themes'import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'import {  DropdownMenu,  DropdownMenuContent,  DropdownMenuGroup,  DropdownMenuItem,  DropdownMenuLabel,  DropdownMenuPortal,  DropdownMenuSeparator,  DropdownMenuShortcut,  DropdownMenuSub,  DropdownMenuSubContent,  DropdownMenuSubTrigger,  DropdownMenuTrigger,} from '@/components/ui/dropdown-menu'import {  BellIcon,  CreditCardIcon,  LaptopIcon,  LogOutIcon,  MoonIcon,  ShieldIcon,  SunIcon,  SunMoonIcon,  UserIcon,} from 'lucide-react'export default function UserButton() {  const { theme, setTheme } = useTheme()  const user = {    name: 'Tiesen',    email: 'yuki@example.con',    image: 'https://github.com/tiesen243.png',  }  return (    <DropdownMenu>      <DropdownMenuTrigger>        <Avatar className='size-9 cursor-pointer'>          <AvatarImage src={user.image} />          <AvatarFallback>{user.name.slice(0, 2)}</AvatarFallback>        </Avatar>        <span className='sr-only'>Open user menu</span>      </DropdownMenuTrigger>      <DropdownMenuContent align='end' className='min-w-60'>        <DropdownMenuLabel className='flex flex-col'>          <p className='text-sm font-medium'>{user.name}</p>          <p className='text-xs text-muted-foreground'>{user.email}</p>        </DropdownMenuLabel>        <DropdownMenuSeparator />        <DropdownMenuGroup>          {userNavItems.map((item) => (            <DropdownMenuItem key={item.label} asChild>              <a href={item.href}>                <item.icon /> {item.label}                <DropdownMenuShortcut>{item.shortcut}</DropdownMenuShortcut>              </a>            </DropdownMenuItem>          ))}          <DropdownMenuSub>            <DropdownMenuSubTrigger className="gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground">              <SunMoonIcon /> Apperance            </DropdownMenuSubTrigger>            <DropdownMenuPortal>              <DropdownMenuSubContent>                <DropdownMenuItem                  className={                    theme === 'light'                      ? 'text-foreground'                      : 'text-muted-foreground'                  }                  onClick={() => {                    setTheme('light')                  }}                >                  <SunIcon /> Light mode                  <DropdownMenuShortcut>⌘L</DropdownMenuShortcut>                </DropdownMenuItem>                <DropdownMenuItem                  className={                    theme === 'dark'                      ? 'text-foreground'                      : 'text-muted-foreground'                  }                  onClick={() => {                    setTheme('dark')                  }}                >                  <MoonIcon /> Dark mode                  <DropdownMenuShortcut>⌘D</DropdownMenuShortcut>                </DropdownMenuItem>                <DropdownMenuItem                  className={                    theme === 'system'                      ? 'text-foreground'                      : 'text-muted-foreground'                  }                  onClick={() => {                    setTheme('system')                  }}                >                  <LaptopIcon /> System                  <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>                </DropdownMenuItem>              </DropdownMenuSubContent>            </DropdownMenuPortal>          </DropdownMenuSub>        </DropdownMenuGroup>        <DropdownMenuSeparator />        <DropdownMenuGroup>          <DropdownMenuItem>            <LogOutIcon /> Sign out          </DropdownMenuItem>        </DropdownMenuGroup>      </DropdownMenuContent>    </DropdownMenu>  )}const userNavItems = [  {    href: '/account/profile',    label: 'Profile',    icon: UserIcon,    shortcut: '⌘P',  },  {    href: '/account/billing',    label: 'Billing',    icon: CreditCardIcon,    shortcut: '⌘B',  },  {    href: '/account/notifications',    label: 'Notifications',    icon: BellIcon,    shortcut: '⌘N',  },  {    href: '/account/security',    label: 'Security',    icon: ShieldIcon,    shortcut: '⌘⇧S',  },]

Features

  • Display user avatar and name
  • Dropdown menu with account actions
  • Sign out functionality
  • Customizable styling

Login Form

A complete login form component with validation and error handling for user authentication.

'use client'import { Button } from '@/components/ui/button'import {  Card,  CardContent,  CardDescription,  CardHeader,  CardTitle,} from '@/components/ui/card'import { Input } from '@/components/ui/input'import {  FormControl,  FormField,  FormLabel,  FormMessage,  useForm,} from '@/components/ui/form'import { PasswordInput } from '@/components/ui/password-input'export default function LoginForm() {  const form = useForm({    defaultValues: { email: '', password: '' },    validator: (value) => {      const issues: { path: string[]; message: string }[] = []      if (value.email.trim() === '')        issues.push({ path: ['email'], message: 'Email is required' })      if (value.password.trim() === '')        issues.push({ path: ['password'], message: 'Password is required' })      if (issues.length > 0) return { issues }      return { value }    },    onSubmit: console.log,  })  return (    <Card className='min-w-md'>      <CardHeader>        <CardTitle>Login to your account</CardTitle>        <CardDescription>          Please enter your email and password to log in.        </CardDescription>      </CardHeader>      <CardContent>        <form className='grid gap-4' onSubmit={form.handleSubmit}>          <FormField            control={form.control}            name='email'            render={({ field, meta }) => (              <div id={meta.id} className='grid gap-2'>                <FormLabel>Email</FormLabel>                <FormControl {...field}>                  <Input type='email' placeholder='Enter your email' />                </FormControl>                <FormMessage />              </div>            )}          />          <FormField            control={form.control}            name='password'            render={({ field, meta }) => (              <div id={meta.id} className='grid gap-2'>                <div className='flex items-center justify-between'>                  <FormLabel>Password</FormLabel>                  <a href='#' tabIndex={-1} className='text-xs hover:underline'>                    Forgot your password?                  </a>                </div>                <FormControl {...field}>                  <PasswordInput placeholder='Enter your password' />                </FormControl>                <FormMessage />              </div>            )}          />          <Button disabled={form.state.isPending}>Login</Button>        </form>      </CardContent>    </Card>  )}

Features

  • Email and password inputs
  • Form validation
  • Error handling and display
  • Loading states
  • Forgot password link

Customization

All components accept standard React props and can be styled using CSS classes or styled-components. Refer to the individual component code for available props and customization options.