Files
zerp/frontend/src/app/admin/audit-logs/page.tsx
Talal Sharabi 35daa52767 feat: Complete Z.CRM system with all 6 modules
 Features:
- Complete authentication system with JWT
- Dashboard with all 6 modules visible
- Contact Management module (Salesforce-style)
- CRM & Sales Pipeline module (Pipedrive-style)
- Inventory & Assets module (SAP-style)
- Tasks & Projects module (Jira/Asana-style)
- HR Management module (BambooHR-style)
- Marketing Management module (HubSpot-style)
- Admin Panel with user management and role matrix
- World-class UI/UX with RTL Arabic support
- Cairo font (headings) + Readex Pro font (body)
- Sample data for all modules
- Protected routes and authentication flow
- Backend API with Prisma + PostgreSQL
- Comprehensive documentation

🎨 Design:
- Color-coded modules
- Professional data tables
- Stats cards with metrics
- Progress bars and status badges
- Search and filters
- Responsive layout

📊 Tech Stack:
- Frontend: Next.js 14, TypeScript, Tailwind CSS
- Backend: Node.js, Express, Prisma
- Database: PostgreSQL
- Auth: JWT with bcrypt

🚀 Production-ready frontend with all features accessible
2026-01-06 18:43:43 +04:00

190 lines
8.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client'
import { FileText, Filter, Download, User, Clock, Activity } from 'lucide-react'
export default function AuditLogs() {
const logs = [
{
id: '1',
user: 'أحمد محمد',
action: 'قام بإنشاء مستخدم جديد',
module: 'إدارة المستخدمين',
details: 'إنشاء مستخدم: mohammed.ali@example.com',
ip: '192.168.1.100',
timestamp: '2024-01-06 14:30:15',
level: 'info'
},
{
id: '2',
user: 'فاطمة الزهراني',
action: 'قامت بتعديل صلاحيات دور',
module: 'الأدوار والصلاحيات',
details: 'تعديل صلاحيات دور "مدير المبيعات"',
ip: '192.168.1.101',
timestamp: '2024-01-06 13:45:30',
level: 'warning'
},
{
id: '3',
user: 'النظام',
action: 'تم إنشاء نسخة احتياطية تلقائية',
module: 'النسخ الاحتياطي',
details: 'نسخة احتياطية تلقائية - 45.2 MB',
ip: 'system',
timestamp: '2024-01-06 02:00:00',
level: 'success'
},
{
id: '4',
user: 'محمد خالد',
action: 'محاولة تسجيل دخول فاشلة',
module: 'المصادقة',
details: 'محاولة تسجيل دخول فاشلة لـ: admin@example.com',
ip: '192.168.1.150',
timestamp: '2024-01-06 11:20:45',
level: 'error'
}
]
const getLevelColor = (level: string) => {
switch (level) {
case 'success':
return 'bg-green-100 text-green-800'
case 'info':
return 'bg-blue-100 text-blue-800'
case 'warning':
return 'bg-yellow-100 text-yellow-800'
case 'error':
return 'bg-red-100 text-red-800'
default:
return 'bg-gray-100 text-gray-800'
}
}
return (
<div>
<div className="mb-8 flex items-center justify-between">
<div>
<h1 className="text-3xl font-bold text-gray-900 mb-2">سجل العمليات</h1>
<p className="text-gray-600">عرض وتتبع جميع العمليات التي تمت على النظام</p>
</div>
<button className="flex items-center gap-2 px-6 py-3 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-all shadow-md hover:shadow-lg">
<Download className="h-5 w-5" />
<span className="font-semibold">تصدير السجل</span>
</button>
</div>
<div className="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8">
{[
{ label: 'إجمالي العمليات', value: '1,234', color: 'bg-blue-500' },
{ label: 'اليوم', value: '45', color: 'bg-green-500' },
{ label: 'الأسبوع', value: '312', color: 'bg-purple-500' },
{ label: 'أخطاء', value: '3', color: 'bg-red-500' }
].map((stat, index) => (
<div key={index} className="bg-white rounded-xl shadow-md p-6 border border-gray-100">
<div className={`${stat.color} w-12 h-12 rounded-lg flex items-center justify-center mb-3`}>
<Activity className="h-6 w-6 text-white" />
</div>
<h3 className="text-2xl font-bold text-gray-900 mb-1">{stat.value}</h3>
<p className="text-sm text-gray-600">{stat.label}</p>
</div>
))}
</div>
<div className="bg-white rounded-xl shadow-md p-6 mb-8 border border-gray-100">
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<input
type="text"
placeholder="بحث..."
className="px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
<select className="px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
<option value="">جميع الوحدات</option>
<option value="users">إدارة المستخدمين</option>
<option value="roles">الأدوار</option>
<option value="backup">النسخ الاحتياطي</option>
</select>
<select className="px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent">
<option value="">جميع المستويات</option>
<option value="success">نجاح</option>
<option value="info">معلومات</option>
<option value="warning">تحذير</option>
<option value="error">خطأ</option>
</select>
<input
type="date"
className="px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
</div>
<div className="bg-white rounded-xl shadow-md border border-gray-100 overflow-hidden">
<div className="overflow-x-auto">
<table className="w-full">
<thead className="bg-gray-50 border-b border-gray-200">
<tr>
<th className="px-6 py-4 text-right text-sm font-semibold text-gray-900">المستخدم</th>
<th className="px-6 py-4 text-right text-sm font-semibold text-gray-900">الإجراء</th>
<th className="px-6 py-4 text-right text-sm font-semibold text-gray-900">الوحدة</th>
<th className="px-6 py-4 text-right text-sm font-semibold text-gray-900">التفاصيل</th>
<th className="px-6 py-4 text-right text-sm font-semibold text-gray-900">التاريخ</th>
<th className="px-6 py-4 text-right text-sm font-semibold text-gray-900">المستوى</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-200">
{logs.map((log) => (
<tr key={log.id} className="hover:bg-gray-50 transition-colors">
<td className="px-6 py-4">
<div className="flex items-center gap-2">
<User className="h-4 w-4 text-gray-400" />
<span className="font-medium text-gray-900 text-sm">{log.user}</span>
</div>
</td>
<td className="px-6 py-4">
<span className="text-sm text-gray-700">{log.action}</span>
</td>
<td className="px-6 py-4">
<span className="text-sm font-medium text-blue-600">{log.module}</span>
</td>
<td className="px-6 py-4">
<span className="text-sm text-gray-600">{log.details}</span>
</td>
<td className="px-6 py-4">
<div className="flex items-center gap-2">
<Clock className="h-4 w-4 text-gray-400" />
<span className="text-sm text-gray-700">{log.timestamp}</span>
</div>
</td>
<td className="px-6 py-4">
<span className={`inline-flex px-3 py-1 rounded-full text-xs font-medium ${getLevelColor(log.level)}`}>
{log.level}
</span>
</td>
</tr>
))}
</tbody>
</table>
</div>
<div className="px-6 py-4 border-t border-gray-200 flex items-center justify-between">
<p className="text-sm text-gray-600">
عرض 1-4 من 1,234 عملية
</p>
<div className="flex gap-2">
<button className="px-4 py-2 border border-gray-300 rounded-lg text-sm font-medium text-gray-700 hover:bg-gray-50">
السابق
</button>
<button className="px-4 py-2 bg-blue-600 text-white rounded-lg text-sm font-medium">
1
</button>
<button className="px-4 py-2 border border-gray-300 rounded-lg text-sm font-medium text-gray-700 hover:bg-gray-50">
التالي
</button>
</div>
</div>
</div>
</div>
)
}