Files
tabungin/docs/features/admin-auto-redirect.md
dwindown 89f881e7cf feat: reorganize admin settings with tabbed interface and documentation
- Reorganized admin settings into tabbed interface (General, Security, Payment Methods)
- Vertical tabs on desktop, horizontal scrollable on mobile
- Moved Payment Methods from separate menu to Settings tab
- Fixed admin profile reuse and dashboard blocking
- Fixed maintenance mode guard to use AppConfig model
- Added admin auto-redirect after login (admins → /admin, users → /)
- Reorganized documentation into docs/ folder structure
- Created comprehensive README and documentation index
- Added PWA and Web Push notifications to to-do list
2025-10-13 09:28:12 +07:00

5.6 KiB

Admin Auto-Redirect Implementation

COMPLETE: Admins Now Redirect to /admin Automatically

Overview

Modified all authentication flows to automatically redirect admin users to /admin instead of the member dashboard (/).


📝 Changes Made

1. Login Page (/apps/web/src/components/pages/Login.tsx)

Already Implemented

  • Lines 42-46: Checks result.user?.role === 'admin'
  • Redirects admins to /admin
  • Redirects regular users to /
if (result.user?.role === 'admin') {
  navigate('/admin')
} else {
  navigate('/')
}

2. OTP Verification (/apps/web/src/components/pages/OtpVerification.tsx)

Fixed

  • Lines 60-66: Now checks user role after OTP verification
  • Redirects based on role

Before:

await verifyOtp(tempToken, code, method)
navigate('/') // Always went to member dashboard

After:

const result = await verifyOtp(tempToken, code, method)
if (result.user?.role === 'admin') {
  navigate('/admin')
} else {
  navigate('/')
}

3. Auth Callback (Google OAuth) (/apps/web/src/components/pages/AuthCallback.tsx)

Fixed

  • Lines 22-36: Fetches user data to check role
  • Redirects based on role

Before:

localStorage.setItem('token', token)
window.location.href = '/' // Always went to member dashboard

After:

localStorage.setItem('token', token)

// Fetch user to check role
const response = await axios.get(`${API_URL}/api/auth/me`, {
  headers: { Authorization: `Bearer ${token}` }
})

// Redirect based on role
if (response.data.role === 'admin') {
  window.location.href = '/admin'
} else {
  window.location.href = '/'
}

4. Public Route Guard (/apps/web/src/App.tsx)

Fixed

  • Lines 55-58: Prevents logged-in users from accessing login/register
  • Now redirects admins to /admin instead of /

Before:

if (user) {
  return <Navigate to="/" replace /> // Always went to member dashboard
}

After:

if (user) {
  // Redirect based on role
  const redirectTo = user.role === 'admin' ? '/admin' : '/'
  return <Navigate to={redirectTo} replace />
}

🎯 User Flows

Admin Login Flow:

1. Admin goes to /auth/login
2. Enters credentials
3. Clicks "Sign In"
   ↓
4a. If NO OTP required:
    → Redirected to /admin ✅
   
4b. If OTP required:
    → Goes to /auth/otp
    → Enters OTP code
    → Redirected to /admin ✅

Admin Google OAuth Flow:

1. Admin clicks "Continue with Google"
2. Completes Google authentication
3. Redirected to /auth/callback
   ↓
4a. If NO OTP required:
    → Redirected to /admin ✅
   
4b. If OTP required:
    → Goes to /auth/otp
    → Enters OTP code
    → Redirected to /admin ✅

Admin Already Logged In:

1. Admin is already logged in
2. Admin tries to access /auth/login or /auth/register
   ↓
3. PublicRoute guard intercepts
4. Redirected to /admin ✅

Regular User Flows:

All regular users continue to be redirected to / (member dashboard) as before.


📊 Redirect Matrix

Scenario User Type Destination
Login (no OTP) Admin /admin
Login (no OTP) User /
Login → OTP Admin /admin
Login → OTP User /
Google OAuth (no OTP) Admin /admin
Google OAuth (no OTP) User /
Google OAuth → OTP Admin /admin
Google OAuth → OTP User /
Already logged in → /auth/login Admin /admin
Already logged in → /auth/login User /

🧪 Testing Instructions

Test 1: Admin Email Login

1. Go to http://localhost:5174/auth/login
2. Login with admin credentials
3. Verify redirected to /admin ✅

Test 2: Admin Google Login

1. Go to http://localhost:5174/auth/login
2. Click "Continue with Google"
3. Complete Google authentication
4. Verify redirected to /admin ✅

Test 3: Admin with OTP

1. Login as admin (with OTP enabled)
2. Enter OTP code
3. Verify redirected to /admin ✅

Test 4: Admin Already Logged In

1. Login as admin
2. Manually navigate to /auth/login
3. Verify redirected to /admin ✅

Test 5: Regular User Login

1. Login as regular user
2. Verify redirected to / (member dashboard) ✅

📁 Files Modified

  1. /apps/web/src/components/pages/OtpVerification.tsx

    • Added role check after OTP verification
    • Conditional redirect based on role
  2. /apps/web/src/components/pages/AuthCallback.tsx

    • Fetches user data to determine role
    • Conditional redirect based on role
    • Added error handling
  3. /apps/web/src/App.tsx

    • Updated PublicRoute to redirect admins to /admin
    • Regular users still go to /
  4. /apps/web/src/components/pages/Login.tsx

    • Already had role-based redirect (no changes needed)

Verification Checklist

  • Admin email login → /admin
  • Admin Google login → /admin
  • Admin with OTP → /admin
  • Admin already logged in → /admin (when accessing login page)
  • Regular user login → /
  • Regular user with OTP → /
  • Regular user already logged in → / (when accessing login page)

🎉 Summary

All authentication flows now correctly redirect admins to /admin!

  • Email/password login
  • Google OAuth login
  • OTP verification
  • Already logged-in guard
  • No changes to regular user flows

Admins will now land on the admin dashboard immediately after login, providing a better UX and clearer separation between admin and member interfaces.