# Frontend Integration Examples for User Roles

## Overview
This document provides practical examples of how to integrate the user role system into your frontend application.

## Basic Permission Checking

### Check if User Can Create Organization

```typescript
import { hasPermission, type UserRole } from '@izri/shared'

interface User {
  id: string
  email: string
  name: string
  role: string
}

function OrganizationCreateButton({ user }: { user: User }) {
  const canCreate = hasPermission(user.role as UserRole, 'canCreateOrganization')
  
  if (!canCreate) {
    return null // Don't show button if user can't create
  }
  
  return (
    <button onClick={handleCreateOrganization}>
      Create Organization
    </button>
  )
}
```

### Show Role Badge

```typescript
import { USER_ROLES, type UserRole } from '@izri/shared'

function UserRoleBadge({ role }: { role: string }) {
  const userRole = role as UserRole
  
  const badgeColors = {
    [USER_ROLES.USER]: 'bg-blue-100 text-blue-800',
    [USER_ROLES.ADMIN]: 'bg-purple-100 text-purple-800',
    [USER_ROLES.SUSPENDED]: 'bg-red-100 text-red-800',
  }
  
  return (
    <span className={`px-2 py-1 rounded text-xs ${badgeColors[userRole]}`}>
      {role}
    </span>
  )
}
```

### Conditional Navigation Menu

```typescript
import { hasPermission, type UserRole } from '@izri/shared'

function NavigationMenu({ user }: { user: User }) {
  const canCreateOrg = hasPermission(user.role as UserRole, 'canCreateOrganization')
  const canCreateProject = hasPermission(user.role as UserRole, 'canCreateProject')
  const isAdmin = user.role === 'ADMIN'
  
  return (
    <nav>
      <a href="/dashboard">Dashboard</a>
      
      {canCreateOrg && (
        <a href="/organizations/new">New Organization</a>
      )}
      
      {canCreateProject && (
        <a href="/projects/new">New Project</a>
      )}
      
      {isAdmin && (
        <a href="/admin">Admin Panel</a>
      )}
    </nav>
  )
}
```

## React Hook for Permissions

Create a reusable hook:

```typescript
// hooks/usePermission.ts
import { hasPermission, type UserRole, type RolePermissions } from '@izri/shared'
import { useAuth } from './useAuth' // Your auth hook

export function usePermission(permission: keyof RolePermissions): boolean {
  const { user } = useAuth()
  
  if (!user) return false
  
  return hasPermission(user.role as UserRole, permission)
}

export function useIsAdmin(): boolean {
  const { user } = useAuth()
  return user?.role === 'ADMIN'
}
```

Usage:

```typescript
function CreateOrgButton() {
  const canCreate = usePermission('canCreateOrganization')
  
  return canCreate ? (
    <button>Create Organization</button>
  ) : null
}
```

## Handling Permission Errors

```typescript
import { trpc } from '@/utils/trpc'
import { toast } from 'sonner'

function CreateOrganizationForm() {
  const createOrg = trpc.organizations.create.useMutation({
    onError: (error) => {
      if (error.data?.code === 'FORBIDDEN') {
        toast.error('Permission Denied', {
          description: error.message,
        })
      } else {
        toast.error('Failed to create organization')
      }
    },
    onSuccess: () => {
      toast.success('Organization created successfully!')
    },
  })
  
  // ... rest of component
}
```

## Disabled State for Insufficient Permissions

```typescript
function CreateOrgButton({ user }: { user: User }) {
  const canCreate = hasPermission(user.role as UserRole, 'canCreateOrganization')
  
  return (
    <button 
      disabled={!canCreate}
      className={!canCreate ? 'opacity-50 cursor-not-allowed' : ''}
      title={!canCreate ? 'You do not have permission to create organizations' : ''}
    >
      Create Organization
    </button>
  )
}
```

## Protected Routes

```typescript
// components/ProtectedRoute.tsx
import { Navigate } from 'react-router-dom'
import { hasPermission, type UserRole, type RolePermissions } from '@izri/shared'
import { useAuth } from '@/hooks/useAuth'

interface ProtectedRouteProps {
  children: React.ReactNode
  requiredPermission?: keyof RolePermissions
  adminOnly?: boolean
}

export function ProtectedRoute({ 
  children, 
  requiredPermission,
  adminOnly = false 
}: ProtectedRouteProps) {
  const { user, isLoading } = useAuth()
  
  if (isLoading) {
    return <div>Loading...</div>
  }
  
  if (!user) {
    return <Navigate to="/login" />
  }
  
  if (adminOnly && user.role !== 'ADMIN') {
    return <Navigate to="/unauthorized" />
  }
  
  if (requiredPermission && !hasPermission(user.role as UserRole, requiredPermission)) {
    return <Navigate to="/unauthorized" />
  }
  
  return <>{children}</>
}
```

Usage in router:

```typescript
import { ProtectedRoute } from '@/components/ProtectedRoute'

function App() {
  return (
    <Routes>
      <Route path="/login" element={<Login />} />
      
      <Route 
        path="/organizations/new" 
        element={
          <ProtectedRoute requiredPermission="canCreateOrganization">
            <CreateOrganization />
          </ProtectedRoute>
        } 
      />
      
      <Route 
        path="/admin" 
        element={
          <ProtectedRoute adminOnly>
            <AdminPanel />
          </ProtectedRoute>
        } 
      />
    </Routes>
  )
}
```

## Suspended User Notice

```typescript
function SuspendedNotice({ user }: { user: User }) {
  if (user.role !== 'SUSPENDED') return null
  
  return (
    <div className="bg-red-50 border border-red-200 rounded-lg p-4 mb-4">
      <h3 className="text-red-800 font-semibold">Account Suspended</h3>
      <p className="text-red-700 text-sm mt-1">
        Your account has been suspended. You have read-only access.
        Please contact support for more information.
      </p>
    </div>
  )
}
```

## Feature Flags Component

```typescript
import { hasPermission, type UserRole, type RolePermissions } from '@izri/shared'
import { useAuth } from '@/hooks/useAuth'

interface FeatureFlagProps {
  permission: keyof RolePermissions
  children: React.ReactNode
  fallback?: React.ReactNode
}

export function FeatureFlag({ permission, children, fallback = null }: FeatureFlagProps) {
  const { user } = useAuth()
  
  if (!user) return <>{fallback}</>
  
  const hasAccess = hasPermission(user.role as UserRole, permission)
  
  return <>{hasAccess ? children : fallback}</>
}
```

Usage:

```typescript
function Dashboard() {
  return (
    <div>
      <h1>Dashboard</h1>
      
      <FeatureFlag 
        permission="canCreateOrganization"
        fallback={<p className="text-gray-500">Upgrade to create organizations</p>}
      >
        <button>Create Organization</button>
      </FeatureFlag>
    </div>
  )
}
```

## Admin Panel User Management Example

```typescript
import { trpc } from '@/utils/trpc'
import { USER_ROLES } from '@izri/shared'

function UserManagementTable() {
  const { data: users } = trpc.users.list.useQuery() // Hypothetical endpoint
  const updateRole = trpc.users.updateRole.useMutation() // Hypothetical endpoint
  
  const handleRoleChange = (userId: string, newRole: string) => {
    updateRole.mutate({ userId, role: newRole })
  }
  
  return (
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Email</th>
          <th>Role</th>
          <th>Actions</th>
        </tr>
      </thead>
      <tbody>
        {users?.map(user => (
          <tr key={user.id}>
            <td>{user.name}</td>
            <td>{user.email}</td>
            <td>
              <select 
                value={user.role} 
                onChange={(e) => handleRoleChange(user.id, e.target.value)}
              >
                <option value={USER_ROLES.USER}>User</option>
                <option value={USER_ROLES.ADMIN}>Admin</option>
                <option value={USER_ROLES.SUSPENDED}>Suspended</option>
              </select>
            </td>
            <td>
              {/* Actions */}
            </td>
          </tr>
        ))}
      </tbody>
    </table>
  )
}
```

## Complete Example: Organization Create Page

```typescript
import { useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { trpc } from '@/utils/trpc'
import { hasPermission, type UserRole } from '@izri/shared'
import { useAuth } from '@/hooks/useAuth'
import { toast } from 'sonner'

export function CreateOrganizationPage() {
  const navigate = useNavigate()
  const { user } = useAuth()
  const [name, setName] = useState('')
  const [slug, setSlug] = useState('')
  const [description, setDescription] = useState('')
  
  const createOrg = trpc.organizations.create.useMutation({
    onSuccess: (data) => {
      toast.success('Organization created!')
      navigate(`/orgs/${data.organization.slug}`)
    },
    onError: (error) => {
      if (error.data?.code === 'FORBIDDEN') {
        toast.error('Permission denied', {
          description: error.message,
        })
      } else {
        toast.error('Failed to create organization')
      }
    },
  })
  
  // Check permission
  const canCreate = user && hasPermission(user.role as UserRole, 'canCreateOrganization')
  
  if (!canCreate) {
    return (
      <div className="p-8">
        <h1 className="text-2xl font-bold text-red-600">Permission Denied</h1>
        <p className="mt-2 text-gray-700">
          You do not have permission to create organizations.
        </p>
      </div>
    )
  }
  
  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()
    createOrg.mutate({
      name,
      slug,
      description,
      userEmail: user.email,
    })
  }
  
  return (
    <div className="p-8 max-w-2xl mx-auto">
      <h1 className="text-2xl font-bold mb-6">Create Organization</h1>
      
      <form onSubmit={handleSubmit} className="space-y-4">
        <div>
          <label className="block text-sm font-medium mb-1">
            Organization Name
          </label>
          <input
            type="text"
            value={name}
            onChange={(e) => setName(e.target.value)}
            className="w-full border rounded px-3 py-2"
            required
          />
        </div>
        
        <div>
          <label className="block text-sm font-medium mb-1">
            Slug
          </label>
          <input
            type="text"
            value={slug}
            onChange={(e) => setSlug(e.target.value)}
            className="w-full border rounded px-3 py-2"
            pattern="[a-z0-9-]+"
            required
          />
        </div>
        
        <div>
          <label className="block text-sm font-medium mb-1">
            Description (optional)
          </label>
          <textarea
            value={description}
            onChange={(e) => setDescription(e.target.value)}
            className="w-full border rounded px-3 py-2"
            rows={3}
          />
        </div>
        
        <button
          type="submit"
          disabled={createOrg.isPending}
          className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 disabled:opacity-50"
        >
          {createOrg.isPending ? 'Creating...' : 'Create Organization'}
        </button>
      </form>
    </div>
  )
}
```

## Best Practices

1. **Always check permissions on both frontend and backend**
   - Frontend checks improve UX
   - Backend checks ensure security

2. **Provide clear feedback**
   - Show why users can't access features
   - Suggest how to gain access (if applicable)

3. **Hide rather than disable when appropriate**
   - Don't show features users can never access
   - Disable features users might gain access to later

4. **Cache permission checks**
   - User role rarely changes during a session
   - Use React hooks to avoid repeated checks

5. **Handle errors gracefully**
   - Show user-friendly messages
   - Log permission errors for monitoring