Skip to main content

Authentication Components

This document covers the reusable React components for authentication and authorization in the BuildAppsWith platform. These components handle common auth UI patterns such as sign-in forms, protected routes, and role-based UI elements.

Form Components

SignInForm

A complete sign-in form component with validation and error handling.
import { SignInForm } from '@/components/auth/sign-in-form';

// Basic usage
<SignInForm />

// With custom redirect
<SignInForm redirectTo="/dashboard" />

// With custom appearance
<SignInForm appearance="modal" className="p-6 rounded-lg shadow-lg" />

Props

PropTypeDefaultDescription
redirectTostring'/'Path to redirect after successful sign-in
appearance'default' | 'minimal' | 'modal''default'Visual style of the form
onSuccess(userId: string) => voidundefinedCallback after successful sign-in
onError(error: string) => voidundefinedCallback after sign-in error
classNamestring''Additional CSS classes

SignUpForm

A complete sign-up form component with validation and error handling.
import { SignUpForm } from '@/components/auth/sign-up-form';

// Basic usage
<SignUpForm />

// With custom redirect
<SignUpForm redirectTo="/onboarding" />

// With custom appearance
<SignUpForm appearance="minimal" className="max-w-md mx-auto" />

Props

PropTypeDefaultDescription
redirectTostring'/'Path to redirect after successful sign-up
appearance'default' | 'minimal' | 'modal''default'Visual style of the form
onSuccess(userId: string) => voidundefinedCallback after successful sign-up
onError(error: string) => voidundefinedCallback after sign-up error
classNamestring''Additional CSS classes

ForgotPasswordForm

A form component for requesting password reset emails.
import { ForgotPasswordForm } from '@/components/auth/forgot-password-form';

// Basic usage
<ForgotPasswordForm />

// With custom appearance
<ForgotPasswordForm appearance="minimal" />

Props

PropTypeDefaultDescription
appearance'default' | 'minimal' | 'modal''default'Visual style of the form
onSuccess() => voidundefinedCallback after successful submission
onError(error: string) => voidundefinedCallback after error
classNamestring''Additional CSS classes

Protection Components

ProtectedRoute

A component wrapper that ensures routes are only accessible to authenticated users.
import { ProtectedRoute } from '@/components/auth/protected-route';

// Basic usage - redirects to /login if not authenticated
<ProtectedRoute>
  <DashboardContent />
</ProtectedRoute>

// With custom redirect
<ProtectedRoute redirectTo="/sign-in?from=dashboard">
  <DashboardContent />
</ProtectedRoute>

// With role requirement
<ProtectedRoute requiredRole="ADMIN">
  <AdminDashboard />
</ProtectedRoute>

Props

PropTypeDefaultDescription
childrenReactNodeRequiredContent to show for authenticated users
redirectTostring'/login'Path to redirect unauthenticated users
requiredRoleUserRoleundefinedRequired role (optional)
requiredPermissionPermissionundefinedRequired permission (optional)
fallbackReactNodenullContent to show during auth loading

RoleGate

A component to conditionally render content based on user roles.
import { RoleGate } from '@/components/auth/role-gate';
import { UserRole } from '@/lib/auth/types';

// Only show content for admins
<RoleGate allowedRole={UserRole.ADMIN}>
  <AdminPanel />
</RoleGate>

// With fallback content for other users
<RoleGate 
  allowedRole={UserRole.BUILDER}
  fallback={<p>You need to be a verified builder to access this content.</p>}
>
  <BuilderTools />
</RoleGate>

Props

PropTypeDefaultDescription
childrenReactNodeRequiredContent to show for users with the allowed role
allowedRoleUserRoleRequiredRequired role to see the content
fallbackReactNodenullContent to show for users without the role

PermissionGate

A component to conditionally render content based on user permissions.
import { PermissionGate } from '@/components/auth/permission-gate';
import { Permission } from '@/lib/auth/types';

// Only show content for users with moderation permission
<PermissionGate requiredPermission={Permission.MODERATE_CONTENT}>
  <ModerationTools />
</PermissionGate>

// With fallback content
<PermissionGate 
  requiredPermission={Permission.CREATE_PROJECT}
  fallback={<RequestAccessButton />}
>
  <CreateProjectForm />
</PermissionGate>

Props

PropTypeDefaultDescription
childrenReactNodeRequiredContent to show for users with the permission
requiredPermissionPermissionRequiredRequired permission to see the content
fallbackReactNodenullContent to show for users without the permission

User Interface Components

UserAvatar

Displays a user’s avatar with authentication state handling.
import { UserAvatar } from '@/components/auth/user-avatar';

// Basic usage
<UserAvatar />

// With custom size
<UserAvatar size="lg" />

// With fallback for unauthenticated users
<UserAvatar fallback={<GuestAvatar />} />

Props

PropTypeDefaultDescription
size'sm' | 'md' | 'lg''md'Size of the avatar
fallbackReactNode<DefaultAvatar />Content to show for unauthenticated users
classNamestring''Additional CSS classes

UserProfile

Displays user profile information with authentication state handling.
import { UserProfile } from '@/components/auth/user-profile';

// Basic usage
<UserProfile />

// With custom appearance
<UserProfile appearance="card" />

// With sign-out button
<UserProfile withSignOut={true} />

Props

PropTypeDefaultDescription
appearance'default' | 'compact' | 'card''default'Visual style of the profile
withSignOutbooleanfalseWhether to show sign-out button
classNamestring''Additional CSS classes

SignOutButton

A button to sign out the current user.
import { SignOutButton } from '@/components/auth/sign-out-button';

// Basic usage
<SignOutButton />

// With custom redirect
<SignOutButton redirectTo="/login" />

// With custom label and styling
<SignOutButton 
  label="Logout" 
  className="bg-red-500 text-white" 
/>

Props

PropTypeDefaultDescription
redirectTostring'/'Path to redirect after sign-out
labelstring'Sign Out'Button label
onClick() => voidundefinedAdditional click handler
classNamestring''Additional CSS classes

Status Components

AuthStatus

Displays the current authentication status.
import { AuthStatus } from '@/components/auth/auth-status';

// Basic usage
<AuthStatus />

// With custom appearance
<AuthStatus appearance="compact" />

Props

PropTypeDefaultDescription
appearance'default' | 'compact' | 'text''default'Visual style of the status
classNamestring''Additional CSS classes

Message Components

AuthError

Displays authentication error messages.
import { AuthError } from '@/components/auth/auth-error';

// With error message
<AuthError message="Invalid email or password" />

// With error code
<AuthError code="invalid_credentials" />

Props

PropTypeDefaultDescription
messagestring''Error message to display
codestring''Error code (translates to a message)
classNamestring''Additional CSS classes

AuthSuccess

Displays authentication success messages.
import { AuthSuccess } from '@/components/auth/auth-success';

// With success message
<AuthSuccess message="Successfully signed in" />

Props

PropTypeDefaultDescription
messagestring''Success message to display
classNamestring''Additional CSS classes

Implementation Examples

Complete Authentication Page

import { SignInForm } from '@/components/auth/sign-in-form';
import { AuthTabs } from '@/components/auth/auth-tabs';
import { SignUpForm } from '@/components/auth/sign-up-form';
import { ForgotPasswordForm } from '@/components/auth/forgot-password-form';
import { useSearchParams } from 'next/navigation';

function AuthPage() {
  const searchParams = useSearchParams();
  const tab = searchParams.get('tab') || 'sign-in';
  const redirectTo = searchParams.get('redirectTo') || '/dashboard';
  
  return (
    <div className="max-w-md mx-auto py-12">
      <h1 className="text-3xl font-bold mb-8 text-center">
        Welcome to BuildAppsWith
      </h1>
      
      <AuthTabs 
        defaultTab={tab} 
        tabs={[
          {
            id: 'sign-in',
            label: 'Sign In',
            content: <SignInForm redirectTo={redirectTo} />
          },
          {
            id: 'sign-up',
            label: 'Sign Up',
            content: <SignUpForm redirectTo={redirectTo} />
          },
          {
            id: 'forgot-password',
            label: 'Forgot Password',
            content: <ForgotPasswordForm />
          }
        ]}
      />
    </div>
  );
}

Protected Dashboard

import { ProtectedRoute } from '@/components/auth/protected-route';
import { UserProfile } from '@/components/auth/user-profile';
import { RoleGate } from '@/components/auth/role-gate';
import { UserRole } from '@/lib/auth/types';

function Dashboard() {
  return (
    <ProtectedRoute>
      <div className="container mx-auto py-8">
        <div className="flex justify-between items-center mb-8">
          <h1 className="text-3xl font-bold">Dashboard</h1>
          <UserProfile withSignOut={true} />
        </div>
        
        <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
          {/* Standard user content */}
          <DashboardCard title="Your Projects" />
          <DashboardCard title="Recent Activity" />
          <DashboardCard title="Notifications" />
          
          {/* Builder-specific content */}
          <RoleGate allowedRole={UserRole.BUILDER}>
            <DashboardCard title="Builder Requests" className="col-span-3" />
          </RoleGate>
          
          {/* Admin-specific content */}
          <RoleGate allowedRole={UserRole.ADMIN}>
            <DashboardCard title="Admin Panel" className="col-span-3 bg-purple-50" />
          </RoleGate>
        </div>
      </div>
    </ProtectedRoute>
  );
}
import { useAuth } from '@/lib/auth/hooks';
import { SignOutButton } from '@/components/auth/sign-out-button';
import { RoleGate } from '@/components/auth/role-gate';
import { UserRole } from '@/lib/auth/types';

function Navigation() {
  const { isAuthenticated } = useAuth();
  
  return (
    <nav className="bg-white shadow">
      <div className="container mx-auto px-4">
        <div className="flex justify-between h-16">
          <div className="flex">
            <a href="/" className="flex-shrink-0 flex items-center">
              BuildAppsWith
            </a>
            <div className="hidden sm:ml-6 sm:flex sm:space-x-8">
              <a href="/" className="nav-link">Home</a>
              <a href="/marketplace" className="nav-link">Marketplace</a>
              
              {/* Authenticated links */}
              {isAuthenticated && (
                <>
                  <a href="/dashboard" className="nav-link">Dashboard</a>
                  <a href="/projects" className="nav-link">Projects</a>
                </>
              )}
              
              {/* Role-specific links */}
              <RoleGate allowedRole={UserRole.BUILDER}>
                <a href="/builder-profile" className="nav-link">
                  Builder Profile
                </a>
              </RoleGate>
              
              <RoleGate allowedRole={UserRole.ADMIN}>
                <a href="/admin" className="nav-link">
                  Admin
                </a>
              </RoleGate>
            </div>
          </div>
          
          <div className="flex items-center">
            {isAuthenticated ? (
              <SignOutButton />
            ) : (
              <a href="/login" className="btn-primary">
                Sign In
              </a>
            )}
          </div>
        </div>
      </div>
    </nav>
  );
}

Best Practices

  1. Use composition for complex auth UIs - Combine smaller components
  2. Always handle loading states - Show skeletons or spinners during auth checks
  3. Provide meaningful fallbacks - Show helpful messages when access is denied
  4. Use typed props - Leverage TypeScript for component props
  5. Maintain accessibility - Ensure all auth components are accessible

See Also