- Created .gitignore to exclude sensitive files and directories. - Added API documentation in API_DOCUMENTATION.md. - Included deployment instructions in DEPLOYMENT.md. - Established project structure documentation in PROJECT_STRUCTURE.md. - Updated README.md with project status and team information. - Added recommendations and status tracking documents. - Introduced testing guidelines in TESTING.md. - Set up CI workflow in .github/workflows/ci.yml. - Created Dockerfile for backend and frontend setups. - Added various service and utility files for backend functionality. - Implemented frontend components and pages for user interface. - Included mobile app structure and services. - Established scripts for deployment across multiple chains.
125 lines
4.1 KiB
TypeScript
125 lines
4.1 KiB
TypeScript
'use client';
|
|
|
|
import { useRouter } from 'next/navigation';
|
|
import { useEffect, useState } from 'react';
|
|
import Link from 'next/link';
|
|
|
|
export default function AdminLayout({
|
|
children,
|
|
}: {
|
|
children: React.ReactNode;
|
|
}) {
|
|
const router = useRouter();
|
|
const [admin, setAdmin] = useState<any>(null);
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
useEffect(() => {
|
|
const token = localStorage.getItem('admin_token');
|
|
if (!token) {
|
|
router.push('/admin/login');
|
|
return;
|
|
}
|
|
|
|
// Verify token
|
|
fetch('/api/admin/auth/verify', {
|
|
headers: {
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
})
|
|
.then((res) => {
|
|
if (!res.ok) {
|
|
router.push('/admin/login');
|
|
return;
|
|
}
|
|
return res.json();
|
|
})
|
|
.then((data) => {
|
|
if (data) setAdmin(data);
|
|
setLoading(false);
|
|
})
|
|
.catch(() => {
|
|
router.push('/admin/login');
|
|
});
|
|
}, [router]);
|
|
|
|
if (loading) {
|
|
return (
|
|
<div className="min-h-screen flex items-center justify-center">
|
|
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (!admin) return null;
|
|
|
|
return (
|
|
<div className="min-h-screen bg-gray-50">
|
|
<nav className="bg-white shadow-sm border-b">
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div className="flex justify-between h-16">
|
|
<div className="flex">
|
|
<div className="flex-shrink-0 flex items-center">
|
|
<h1 className="text-xl font-bold text-gray-900">ASLE Admin</h1>
|
|
</div>
|
|
<div className="hidden sm:ml-6 sm:flex sm:space-x-8">
|
|
<Link
|
|
href="/admin"
|
|
className="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium"
|
|
>
|
|
Dashboard
|
|
</Link>
|
|
<Link
|
|
href="/admin/users"
|
|
className="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium"
|
|
>
|
|
Users
|
|
</Link>
|
|
<Link
|
|
href="/admin/config"
|
|
className="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium"
|
|
>
|
|
Config
|
|
</Link>
|
|
<Link
|
|
href="/admin/deployments"
|
|
className="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium"
|
|
>
|
|
Deployments
|
|
</Link>
|
|
<Link
|
|
href="/admin/white-label"
|
|
className="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium"
|
|
>
|
|
White-Label
|
|
</Link>
|
|
<Link
|
|
href="/admin/audit"
|
|
className="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium"
|
|
>
|
|
Audit Logs
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
<div className="flex items-center">
|
|
<span className="text-sm text-gray-700 mr-4">{admin.email}</span>
|
|
<button
|
|
onClick={() => {
|
|
localStorage.removeItem('admin_token');
|
|
router.push('/admin/login');
|
|
}}
|
|
className="text-sm text-gray-500 hover:text-gray-700"
|
|
>
|
|
Logout
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
<main className="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
|
|
{children}
|
|
</main>
|
|
</div>
|
|
);
|
|
}
|
|
|