# User Authentication Null Issue - Fix Documentation

## Problem Description

The application was throwing errors on admin routes:
```
Uncaught TypeError: Cannot read properties of null (reading 'avatar')
Uncaught TypeError: Cannot read properties of null (reading 'name')
```

Additionally, the admin roles page was incorrectly showing tenant sidebar menu items.

## Root Cause Analysis

### Why was `auth.user` null?

The issue occurred because of multiple problems:

1. **Multiple Authentication Guards**: The application uses two separate authentication guards:
   - `web` guard: For regular tenant users
   - `admin` guard: For central admin users

2. **Middleware Guard Mismatch**: The `HandleInertiaRequests` middleware was using:
   ```php
   $user = Auth::user();  // Uses default 'web' guard
   ```
   And later:
   ```php
   'auth' => [
       'user' => $request->user(),  // Also uses default 'web' guard
   ]
   ```

3. **Admin Routes Problem**: When accessing admin routes (like `/admin/roles`), the user is authenticated via the `admin` guard, but the middleware was checking the `web` guard, resulting in `null`.

4. **Wrong Layout**: The Admin Roles page was using `AppLayout` (tenant layout with tenant sidebar) instead of `AdminLayout` (admin layout with admin sidebar).

5. **Role Data Confusion**: Tenant roles were being passed to admin routes, causing the tenant sidebar to show role-dependent menu items on admin pages.

## Solution Implemented

### 1. Backend Fix - HandleInertiaRequests Middleware

**File**: `app/Http/Middleware/HandleInertiaRequests.php`

**Changes**:

#### a. Guard Detection and User Loading
```php
// Before
$user = Auth::user();  // Always used 'web' guard

// After
$isAdminRoute = $request->route() && str_starts_with($request->route()->getPrefix() ?? '', 'admin');
$user = $isAdminRoute ? Auth::guard('admin')->user() : Auth::user();
```

#### b. Role Loading Logic
```php
// Before - roles were loaded for all users
if ($user && ! $isCentralUser && $isInitializedTenant && ! $user->relationLoaded('roles')) {
    $user->load('roles:id,name,slug');
}

// After - roles only loaded for tenant users, NOT admin users
if ($user && ! $isCentralUser && ! $isAdminRoute && $isInitializedTenant) {
    if (! $user->relationLoaded('roles')) {
        $user->load('roles:id,name,slug');
    }
    // ... role and permission logic
}
```

#### c. Shared Data Updates
```php
// Before
'auth' => [
    'user' => $request->user(),  // Could be null on admin routes
    'permissions' => $permissions ?? collect(),
],
'current_user_roles' => $roles ?? collect(),  // Always passed

// After
'auth' => [
    'user' => $user,  // Uses correct guard
    'permissions' => $permissions ?? collect(),
],
'current_user_roles' => ! $isAdminRoute ? $roles : collect(),  // Empty on admin routes
```

### 2. Frontend Fixes - Null Safety

Updated multiple React components to handle null user gracefully:

#### a. `resources/js/types/index.d.ts`
```typescript
// Before
export interface Auth {
    user: User;
}

// After
export interface Auth {
    user: User | null;
}
```

#### b. `resources/js/components/user-info.tsx`
```typescript
// Before
export function UserInfo({ user, showEmail = false }: { user: User; showEmail?: boolean }) {
    const getInitials = useInitials();
    const avatarUrl = user?.avatar?.startsWith('https://via.placeholder.com') 
        ? '/assets/avatar.png' 
        : user.avatar;

// After
export function UserInfo({ user, showEmail = false }: { user: User | null; showEmail?: boolean }) {
    const getInitials = useInitials();
    
    if (!user) {
        return null;
    }
    
    const avatarUrl = user?.avatar?.startsWith('https://via.placeholder.com') 
        ? '/assets/avatar.png' 
        : user.avatar;
```

#### c. `resources/js/components/nav-user.tsx`
```typescript
// Added null check
export function NavUser() {
    const { auth } = usePage<SharedData>().props;
    const { state } = useSidebar();
    const isMobile = useIsMobile();

    if (!auth?.user) {
        return null;
    }
    // ... rest of component
}
```

#### d. `resources/js/components/user-menu-content.tsx`
```typescript
// Before
interface UserMenuContentProps {
    user: User;
}

export function UserMenuContent({ user }: UserMenuContentProps) {
    const cleanup = useMobileNavigation();

// After
interface UserMenuContentProps {
    user: User | null;
}

export function UserMenuContent({ user }: UserMenuContentProps) {
    const cleanup = useMobileNavigation();
    
    if (!user) {
        return null;
    }
```

#### e. `resources/js/layouts/app/app-header.tsx`
```typescript
// Before
<DropdownMenu>
    <DropdownMenuTrigger asChild>
        <Button variant="ghost" className="h-9 w-9 rounded-full p-0.5 sm:p-1">
            <Avatar className="h-7 w-7 overflow-hidden rounded-full sm:h-9 sm:w-9">
                <AvatarImage src={avatarUrl} alt={auth.user.name} />

// After
{auth?.user && (
    <DropdownMenu>
        <DropdownMenuTrigger asChild>
            <Button variant="ghost" className="h-9 w-9 rounded-full p-0.5 sm:p-1">
                <Avatar className="h-7 w-7 overflow-hidden rounded-full sm:h-9 sm:w-9">
                    <AvatarImage src={avatarUrl} alt={auth.user.name} />
```

## How the Fix Works

1. **Guard Detection**: The middleware now detects if the current route is an admin route by checking the route prefix
2. **Correct Guard Usage**: Uses `Auth::guard('admin')->user()` for admin routes, `Auth::user()` for regular routes
3. **Null Safety**: All frontend components now properly handle null user states
4. **Type Safety**: TypeScript types updated to reflect that user can be null

## Testing

To verify the fix works:

1. ✅ Access admin routes (e.g., `/admin/roles`) - should load without errors
2. ✅ Access tenant routes (e.g., `/dashboard`) - should still work
3. ✅ Check user avatar displays correctly in both contexts
4. ✅ Verify dropdown menu works in both admin and tenant areas

## Additional Notes

- This fix maintains backward compatibility with existing tenant routes
- The solution is scalable for future multi-guard scenarios
- All components now gracefully degrade when user data is unavailable
- TypeScript provides compile-time safety against null reference errors

## Related Files Modified

1. `app/Http/Middleware/HandleInertiaRequests.php`
2. `resources/js/types/index.d.ts`
3. `resources/js/components/user-info.tsx`
4. `resources/js/components/nav-user.tsx`
5. `resources/js/components/user-menu-content.tsx`
6. `resources/js/layouts/app/app-header.tsx`
