deckhearth/components/AdminProtected.js
Randall Stillwell 79f52b456c fix(lint): clear ESLint baseline in components/
Resolve react-hooks purity, immutability, refs, and set-state-in-effect
violations without behavior changes; align img usage with pages/ disable
pattern for external URLs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 00:45:28 -05:00

104 lines
No EOL
3.2 KiB
JavaScript

import { useEffect, useState } from 'react';
import { useRouter } from 'next/router';
import Layout from './Layout';
export default function AdminProtected({ children }) {
const router = useRouter();
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const [accessDenied, setAccessDenied] = useState(false);
useEffect(() => {
const checkAdminAccess = async () => {
try {
// Get token from localStorage
const token = localStorage.getItem('auth_token');
const headers = {
'Content-Type': 'application/json',
};
// Add authorization header if token exists
if (token) {
headers.Authorization = `Bearer ${token}`;
}
const response = await fetch('/api/auth/verify', { headers });
if (response.ok) {
const userData = await response.json();
if (userData.role === 'admin') {
setUser(userData);
setAccessDenied(false);
} else {
setAccessDenied(true);
}
} else {
setAccessDenied(true);
// Clear invalid token
if (token) {
localStorage.removeItem('auth_token');
}
}
} catch (error) {
console.error('Admin auth check failed:', error);
setAccessDenied(true);
} finally {
setLoading(false);
}
};
checkAdminAccess();
}, []);
if (loading) {
return (
<Layout user={null}>
<div className="flex items-center justify-center min-h-screen">
<div className="text-center">
<div className="animate-spin rounded-full h-32 w-32 border-b-2 mx-auto mb-4" style={{ borderColor: 'var(--text-accent)' }}></div>
<p style={{ color: 'var(--text-secondary)' }}>Checking admin access...</p>
</div>
</div>
</Layout>
);
}
if (accessDenied) {
return (
<Layout user={user}>
<div className="flex items-center justify-center min-h-screen">
<div className="text-center">
<div className="text-6xl mb-4">🚫</div>
<h2 className="text-2xl font-bold mb-2" style={{ color: 'var(--text-primary)' }}>
Access Denied
</h2>
<p className="mb-6" style={{ color: 'var(--text-secondary)' }}>
You need administrator privileges to access this page.
</p>
<div className="space-x-4">
<button
onClick={() => router.push('/login')}
className="px-6 py-3 rounded-xl font-medium gradient-bg-purple text-white hover:shadow-lg transition-all duration-200"
>
Login as Admin
</button>
<button
onClick={() => router.push('/')}
className="px-6 py-3 rounded-xl font-medium border transition-all duration-200"
style={{
borderColor: 'var(--border)',
color: 'var(--text-primary)'
}}
>
Go Home
</button>
</div>
</div>
</div>
</Layout>
);
}
// Support both render prop and children patterns
return typeof children === 'function' ? children(user) : children;
}