Files
danak-admin/src/pages/accessLogs/PermissionLogs.tsx
T
2025-09-02 17:00:37 +03:30

294 lines
12 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.
import React, { useState } from "react";
import {
Shield,
Refresh,
InfoCircle,
TickCircle,
CloseCircle
} from "iconsax-react";
import Button from "../../components/Button";
import Pagination from "../../components/Pagination";
import TitleLine from "../../components/TitleLine";
import PageLoading from "../../components/PageLoading";
import FilterPanel from "./components/FilterPanel";
import AccessLogsTable from "./components/AccessLogsTable";
import LogDetailsModal from "./components/LogDetailsModal";
import { useErrorLogs, useAccessLogDetail } from "./hooks/useAccessLogs";
import { AccessLog } from "./types/AccessLogTypes";
const PermissionLogs: React.FC = () => {
const {
errorLogs,
loading,
error,
total,
filters,
updateFilters,
refetch,
} = useErrorLogs();
const { log: selectedLog, fetchLog, clearLog } = useAccessLogDetail();
const [isDetailsModalOpen, setIsDetailsModalOpen] = useState(false);
const handleViewDetails = async (log: AccessLog) => {
await fetchLog(log.id);
setIsDetailsModalOpen(true);
};
const handleCloseDetailsModal = () => {
setIsDetailsModalOpen(false);
clearLog();
};
const handleSort = (field: string, order: "ASC" | "DESC") => {
updateFilters({ sortBy: field, sortOrder: order });
};
const handlePageChange = (page: number) => {
updateFilters({ page });
};
const resetFilters = () => {
updateFilters({
page: 1,
limit: 20,
sortBy: "createdAt",
sortOrder: "DESC",
operationType: undefined,
userType: undefined,
entityName: "",
entityId: "",
userId: "",
ipAddress: "",
endpoint: "",
httpMethod: undefined,
statusCode: undefined,
startDate: "",
endDate: "",
search: "",
minExecutionTime: undefined,
maxExecutionTime: undefined,
});
};
// Filter permission-related logs (assuming they have specific operation types or endpoints)
const permissionLogs = (errorLogs || []).filter((log: AccessLog) => {
return log.operationType?.includes('permission') ||
log.endpoint?.includes('permission') ||
log.entityName?.includes('role') ||
log.entityName?.includes('permission');
});
// Count permission actions
const permissionStats = permissionLogs.reduce((acc: Record<string, number>, log: AccessLog) => {
const action = log.operationType || 'unknown';
acc[action] = (acc[action] || 0) + 1;
return acc;
}, {} as Record<string, number>);
// Count recent permission changes (last 24 hours)
const recentPermissions = permissionLogs.filter((log: AccessLog) => {
const logDate = new Date(log.createdAt);
const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
return logDate > oneDayAgo;
}).length;
if (error) {
return (
<div className="p-6">
<TitleLine title="لاگ‌های مجوز" />
<div className="bg-red-50 border border-red-200 rounded-lg p-4">
<div className="flex items-center justify-between">
<p className="text-red-800">{error}</p>
<Button
onClick={refetch}
className="bg-red-600 text-white hover:bg-red-700"
>
تلاش مجدد
</Button>
</div>
</div>
</div>
);
}
return (
<div className="p-6 space-y-6">
{/* Header */}
<div className="flex items-center justify-between">
<div>
<TitleLine title="لاگ‌های مجوز" />
<p className="text-gray-600 mt-2">
مشاهده و تحلیل تغییرات مجوزها و نقشهای کاربری
</p>
</div>
<div className="flex items-center gap-3">
<Button
onClick={refetch}
disabled={loading}
className="flex items-center gap-2 border border-gray-300 bg-white text-gray-700 hover:bg-gray-50"
>
<Refresh size={16} className={loading ? "animate-spin" : ""} />
بروزرسانی
</Button>
</div>
</div>
{/* Permission Stats */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-4">
<div className="flex items-center gap-3">
<div className="flex-shrink-0 p-2 bg-blue-100 rounded-lg">
<Shield size={20} className="text-blue-600" />
</div>
<div>
<p className="text-sm font-medium text-gray-600">کل تغییرات مجوز</p>
<p className="text-xl font-bold text-gray-900">
{permissionLogs.length.toLocaleString('fa-IR')}
</p>
</div>
</div>
</div>
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-4">
<div className="flex items-center gap-3">
<div className="flex-shrink-0 p-2 bg-green-100 rounded-lg">
<TickCircle size={20} className="text-green-600" />
</div>
<div>
<p className="text-sm font-medium text-gray-600">مجوزهای اعطا شده</p>
<p className="text-xl font-bold text-gray-900">
{(permissionStats['grant'] || 0).toLocaleString('fa-IR')}
</p>
</div>
</div>
</div>
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-4">
<div className="flex items-center gap-3">
<div className="flex-shrink-0 p-2 bg-red-100 rounded-lg">
<CloseCircle size={20} className="text-red-600" />
</div>
<div>
<p className="text-sm font-medium text-gray-600">مجوزهای لغو شده</p>
<p className="text-xl font-bold text-gray-900">
{(permissionStats['revoke'] || 0).toLocaleString('fa-IR')}
</p>
</div>
</div>
</div>
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-4">
<div className="flex items-center gap-3">
<div className="flex-shrink-0 p-2 bg-yellow-100 rounded-lg">
<InfoCircle size={20} className="text-yellow-600" />
</div>
<div>
<p className="text-sm font-medium text-gray-600">24 ساعت گذشته</p>
<p className="text-xl font-bold text-gray-900">
{recentPermissions.toLocaleString('fa-IR')}
</p>
</div>
</div>
</div>
</div>
{/* Security Alert */}
{recentPermissions > 5 && (
<div className="bg-yellow-50 border border-yellow-200 rounded-lg p-4">
<div className="flex items-center gap-3">
<Shield size={20} className="text-yellow-600" />
<div>
<h3 className="text-sm font-medium text-yellow-900">تغییرات زیاد مجوز</h3>
<p className="text-sm text-yellow-700 mt-1">
{recentPermissions} تغییر مجوز در 24 ساعت گذشته رخ داده است.
لطفاً این تغییرات را بررسی کنید.
</p>
</div>
</div>
</div>
)}
{/* Filter Panel */}
<FilterPanel
filters={filters}
onFiltersChange={updateFilters}
onReset={resetFilters}
loading={loading}
/>
{/* Loading State */}
{loading && <PageLoading />}
{/* Table */}
{!loading && (
<>
<AccessLogsTable
logs={permissionLogs}
loading={loading}
onViewDetails={handleViewDetails}
onSort={handleSort}
sortBy={filters.sortBy}
sortOrder={filters.sortOrder}
/>
{/* Pagination */}
{total > (filters.limit || 20) && (
<div className="flex justify-center">
<Pagination
currentPage={filters.page || 1}
totalPages={Math.ceil(total / (filters.limit || 20))}
onPageChange={handlePageChange}
/>
</div>
)}
</>
)}
{/* Details Modal */}
<LogDetailsModal
log={selectedLog}
isOpen={isDetailsModalOpen}
onClose={handleCloseDetailsModal}
/>
{/* Empty State Info */}
{!loading && (!permissionLogs || permissionLogs.length === 0) && !error && (
<div className="bg-green-50 border border-green-200 rounded-lg p-6">
<div className="flex items-center gap-3">
<InfoCircle size={24} className="text-green-600" />
<div>
<h3 className="text-lg font-medium text-green-900">هیچ تغییر مجوزی یافت نشد</h3>
<p className="text-green-700 mt-1">
در بازه زمانی و فیلترهای انتخاب شده، هیچ تغییر مجوزی ثبت نشده است.
</p>
</div>
</div>
</div>
)}
{/* Permission Analysis Tips */}
{!loading && permissionLogs && permissionLogs.length > 0 && (
<div className="bg-blue-50 border border-blue-200 rounded-lg p-6">
<div className="flex items-start gap-3">
<InfoCircle size={24} className="text-blue-600 flex-shrink-0 mt-0.5" />
<div>
<h3 className="text-lg font-medium text-blue-900 mb-2">راهنمای تحلیل مجوزها</h3>
<div className="text-blue-700 space-y-2">
<p> <strong>تغییرات نقش:</strong> بررسی تغییرات نقشهای کاربری و مجوزهای مربوطه</p>
<p> <strong>دسترسیهای حساس:</strong> نظارت بر دسترسیهای مهم و حساس سیستم</p>
<p> <strong>الگوهای دسترسی:</strong> شناسایی الگوهای غیرعادی در دسترسیها</p>
<p> <strong>زمانبندی:</strong> توجه به زمان تغییرات مجوزها</p>
<p> <strong>کاربران:</strong> شناسایی کاربرانی که تغییرات مجوز زیادی دارند</p>
</div>
</div>
</div>
</div>
)}
</div>
);
};
export default PermissionLogs;