# Migration Guide: Update to Centralized Auth Utilities

## 🎯 Overview

This guide helps you migrate from direct `localStorage` access to centralized auth utilities.

**Why migrate?**
- ✅ Prevents JSON parsing crashes
- ✅ Eliminates hardcoding
- ✅ Type-safe
- ✅ Consistent behavior
- ✅ Easier to maintain

---

## 📋 Quick Reference

### Pattern 1: Get User Data

#### ❌ Old Way (Unsafe)
```typescript
const userData = localStorage.getItem('adminUser')
if (userData) {
  setUser(JSON.parse(userData))  // Can crash!
}
```

#### ✅ New Way (Safe)
```typescript
import { getAdminUser } from '@/lib/auth'

const userData = getAdminUser()  // Never crashes
if (userData) {
  setUser(userData)
}
```

---

### Pattern 2: Get Token

#### ❌ Old Way
```typescript
const token = localStorage.getItem('adminToken')
if (!token) {
  router.push('/admin')
}
```

#### ✅ New Way
```typescript
import { getAdminToken } from '@/lib/auth'

const token = getAdminToken()
if (!token) {
  router.push('/admin')
}
```

---

### Pattern 3: Check Authentication

#### ❌ Old Way
```typescript
const token = localStorage.getItem('adminToken')
const userData = localStorage.getItem('adminUser')

if (!token || !userData) {
  router.push('/admin')
  return
}
```

#### ✅ New Way
```typescript
import { isAuthenticated } from '@/lib/auth'

if (!isAuthenticated()) {
  router.push('/admin')
  return
}
```

---

### Pattern 4: API Requests with Token

#### ❌ Old Way
```typescript
const token = localStorage.getItem('adminToken')
const response = await fetch(`${API_URL}/users`, {
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json',
  },
})
```

#### ✅ New Way (Option 1: Manual)
```typescript
import { getAdminToken } from '@/lib/auth'
import { API_BASE_URL } from '@/config/api'

const token = getAdminToken()
const response = await fetch(`${API_BASE_URL}/users`, {
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json',
  },
})
```

#### ✅ New Way (Option 2: API Client - RECOMMENDED)
```typescript
import { apiGet } from '@/lib/apiClient'

// Token is automatically included!
const result = await apiGet('/users')
```

---

### Pattern 5: Store Auth Data (Login)

#### ❌ Old Way
```typescript
localStorage.setItem('adminToken', data.accessToken)
localStorage.setItem('adminUser', JSON.stringify(data.user))
```

#### ✅ New Way
```typescript
import { setAdminAuth } from '@/lib/auth'

setAdminAuth({
  token: data.token,
  user: data.user
})
```

---

### Pattern 6: Clear Auth Data (Logout)

#### ❌ Old Way
```typescript
localStorage.removeItem('adminToken')
localStorage.removeItem('adminUser')
```

#### ✅ New Way
```typescript
import { clearAdminAuth } from '@/lib/auth'

clearAdminAuth()
```

---

## 🔧 Step-by-Step Migration

### Step 1: Import Auth Utilities

At the top of your file, add:

```typescript
import { 
  getAdminUser, 
  getAdminToken, 
  isAuthenticated,
  setAdminAuth,
  clearAdminAuth 
} from '@/lib/auth'
```

### Step 2: Replace localStorage.getItem('adminUser')

**Find:**
```typescript
const userData = localStorage.getItem('adminUser')
const user = JSON.parse(userData)
```

**Replace with:**
```typescript
const user = getAdminUser()
```

### Step 3: Replace localStorage.getItem('adminToken')

**Find:**
```typescript
const token = localStorage.getItem('adminToken')
```

**Replace with:**
```typescript
const token = getAdminToken()
```

### Step 4: Replace Authentication Checks

**Find:**
```typescript
const token = localStorage.getItem('adminToken')
if (!token) {
  router.push('/admin')
}
```

**Replace with:**
```typescript
if (!isAuthenticated()) {
  router.push('/admin')
}
```

### Step 5: Update API Calls (RECOMMENDED)

**Find:**
```typescript
const token = localStorage.getItem('adminToken')
const response = await fetch(`${API_URL}/endpoint`, {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json',
  },
})
const data = await response.json()
```

**Replace with:**
```typescript
import { apiGet } from '@/lib/apiClient'

const result = await apiGet('/endpoint')
// result.data contains your data
```

---

## 📝 API Client Usage Examples

The new `apiClient` automatically handles:
- ✅ Token injection
- ✅ Base URL
- ✅ Error handling
- ✅ JSON parsing

### GET Request
```typescript
import { apiGet } from '@/lib/apiClient'

try {
  const result = await apiGet('/users')
  if (result.success) {
    console.log(result.data)
  }
} catch (error) {
  console.error('Error:', error.message)
}
```

### POST Request
```typescript
import { apiPost } from '@/lib/apiClient'

try {
  const result = await apiPost('/users', {
    firstName: 'John',
    lastName: 'Doe',
    email: 'john@example.com'
  })
  
  if (result.success) {
    console.log('User created:', result.data)
  }
} catch (error) {
  console.error('Error:', error.message)
}
```

### PUT Request
```typescript
import { apiPut } from '@/lib/apiClient'

try {
  const result = await apiPut(`/users/${userId}`, {
    firstName: 'Jane'
  })
  
  if (result.success) {
    console.log('User updated:', result.data)
  }
} catch (error) {
  console.error('Error:', error.message)
}
```

### DELETE Request
```typescript
import { apiDelete } from '@/lib/apiClient'

try {
  const result = await apiDelete(`/users/${userId}`)
  
  if (result.success) {
    console.log('User deleted')
  }
} catch (error) {
  console.error('Error:', error.message)
}
```

### File Upload
```typescript
import { apiUpload } from '@/lib/apiClient'

const formData = new FormData()
formData.append('file', file)
formData.append('title', 'My Image')

try {
  const result = await apiUpload('/media/upload', formData)
  
  if (result.success) {
    console.log('File uploaded:', result.data)
  }
} catch (error) {
  console.error('Error:', error.message)
}
```

---

## 🗂️ Files That Need Migration

### High Priority (User Data Access)
These files access user data and need immediate migration:

- [x] `src/components/admin/AdminHeader.tsx` ✅ DONE
- [x] `src/components/admin/AdminSidebar.tsx` ✅ DONE
- [x] `src/app/admin/page.tsx` (Login) ✅ DONE
- [x] `src/app/admin/dashboard/page.tsx` ✅ DONE
- [ ] `src/app/admin/users/page.tsx`
- [ ] `src/app/admin/users/new/page.tsx`
- [ ] `src/app/admin/users/[id]/page.tsx`
- [ ] `src/app/admin/roles/page.tsx`
- [ ] `src/app/admin/departments/page.tsx`
- [ ] `src/app/admin/news-articles/page.tsx`
- [ ] `src/app/admin/news-articles/new/page.tsx`
- [ ] `src/app/admin/events/page.tsx`
- [ ] `src/app/admin/events/new/page.tsx`

### Medium Priority (Token Only)
These files only access tokens and can be migrated to API client:

- All files listed above can benefit from using `apiClient` instead of manual fetch

---

## 🎯 Example: Complete File Migration

### Before
```typescript
'use client'

import { useState, useEffect } from 'react'
import { useRouter } from 'next/navigation'

export default function UsersPage() {
  const router = useRouter()
  const [users, setUsers] = useState([])

  useEffect(() => {
    // Check auth
    const token = localStorage.getItem('adminToken')
    if (!token) {
      router.push('/admin')
      return
    }

    // Fetch users
    fetchUsers()
  }, [])

  const fetchUsers = async () => {
    const token = localStorage.getItem('adminToken')
    const response = await fetch('http://localhost:5000/api/users', {
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json',
      },
    })
    const data = await response.json()
    setUsers(data.data)
  }

  const deleteUser = async (id: string) => {
    const token = localStorage.getItem('adminToken')
    await fetch(`http://localhost:5000/api/users/${id}`, {
      method: 'DELETE',
      headers: {
        'Authorization': `Bearer ${token}`,
      },
    })
    fetchUsers()
  }

  return <div>...</div>
}
```

### After
```typescript
'use client'

import { useState, useEffect } from 'react'
import { useRouter } from 'next/navigation'
import { isAuthenticated } from '@/lib/auth'
import { apiGet, apiDelete } from '@/lib/apiClient'

export default function UsersPage() {
  const router = useRouter()
  const [users, setUsers] = useState([])

  useEffect(() => {
    // Check auth using centralized utility
    if (!isAuthenticated()) {
      router.push('/admin')
      return
    }

    // Fetch users
    fetchUsers()
  }, [])

  const fetchUsers = async () => {
    try {
      const result = await apiGet('/users')
      if (result.success && result.data) {
        setUsers(result.data)
      }
    } catch (error) {
      console.error('Error fetching users:', error)
    }
  }

  const deleteUser = async (id: string) => {
    try {
      const result = await apiDelete(`/users/${id}`)
      if (result.success) {
        fetchUsers()
      }
    } catch (error) {
      console.error('Error deleting user:', error)
    }
  }

  return <div>...</div>
}
```

**Benefits:**
- ✅ No hardcoded URLs
- ✅ No manual token handling
- ✅ Cleaner code
- ✅ Better error handling
- ✅ Type-safe

---

## ✅ Testing Checklist

After migration, test:

- [ ] Login works
- [ ] User data displays correctly
- [ ] Token is included in API requests
- [ ] Protected routes redirect when not authenticated
- [ ] Logout clears all data
- [ ] Page refresh maintains login state
- [ ] Invalid localStorage data doesn't crash app

---

## 🆘 Troubleshooting

### Issue: "Authentication required. Please log in."
**Cause:** Token not found in localStorage  
**Solution:** User needs to log in again

### Issue: API requests fail with 401
**Cause:** Token expired or invalid  
**Solution:** Clear auth data and redirect to login
```typescript
import { clearAdminAuth } from '@/lib/auth'

clearAdminAuth()
router.push('/admin')
```

### Issue: TypeScript errors after migration
**Cause:** Missing type imports  
**Solution:** Import types from auth utilities
```typescript
import { type AdminUser } from '@/lib/auth'
```

---

## 📚 Related Documentation

- **Auth Utilities Guide**: `AUTH_UTILITIES_GUIDE.md`
- **Fix Summary**: `FIX_SUMMARY.md`
- **API Client**: `src/lib/apiClient.ts`
- **Auth Utilities**: `src/lib/auth.ts`

---

## 🚀 Quick Migration Script

Use this regex pattern to find files that need migration:

```bash
# Find files with localStorage.getItem
grep -r "localStorage.getItem" frontend/src/app/admin

# Find files with JSON.parse(localStorage
grep -r "JSON.parse.*localStorage" frontend/src
```

---

## ✨ Summary

**Migration Steps:**
1. Import auth utilities
2. Replace `localStorage.getItem('adminUser')` with `getAdminUser()`
3. Replace `localStorage.getItem('adminToken')` with `getAdminToken()`
4. Replace auth checks with `isAuthenticated()`
5. (Optional but recommended) Replace fetch calls with API client

**Benefits:**
- ✅ No more crashes
- ✅ No more hardcoding
- ✅ Type-safe
- ✅ Cleaner code
- ✅ Easier maintenance

**Need help?** Check `AUTH_UTILITIES_GUIDE.md` for detailed examples!
