138 lines
7.1 KiB
TypeScript
138 lines
7.1 KiB
TypeScript
import React, { useState } from 'react';
|
||
import { usePermissions } from '../core/_hooks';
|
||
import { Permission } from '../core/_models';
|
||
import { Shield } from "lucide-react";
|
||
import { TableSkeleton } from '@/components/common/TableSkeleton';
|
||
import { PageHeader } from '@/components/layout/PageHeader';
|
||
import { EmptyState } from '@/components/common/EmptyState';
|
||
import { FiltersSection } from '@/components/common/FiltersSection';
|
||
import { formatDate } from '@/utils/formatters';
|
||
|
||
const PermissionsListPage = () => {
|
||
const [filters, setFilters] = useState({
|
||
search: ''
|
||
});
|
||
|
||
const { data: permissions, isLoading, error } = usePermissions(filters);
|
||
|
||
const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||
setFilters(prev => ({ ...prev, search: e.target.value }));
|
||
};
|
||
|
||
if (error) {
|
||
return (
|
||
<div className="p-6">
|
||
<div className="text-center py-12">
|
||
<p className="text-red-600 dark:text-red-400">خطا در بارگذاری دسترسیها</p>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
return (
|
||
<div className="p-6 space-y-6">
|
||
<PageHeader
|
||
title="لیست دسترسیها"
|
||
subtitle="نمایش دسترسیهای سیستم"
|
||
icon={Shield}
|
||
/>
|
||
|
||
<FiltersSection>
|
||
<div>
|
||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||
جستجو
|
||
</label>
|
||
<input
|
||
type="text"
|
||
placeholder="جستجو در عنوان یا توضیحات..."
|
||
value={filters.search}
|
||
onChange={handleSearchChange}
|
||
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-1 focus:ring-primary-500 dark:bg-gray-700 dark:text-gray-100"
|
||
/>
|
||
</div>
|
||
</FiltersSection>
|
||
|
||
{/* Permissions Table */}
|
||
{isLoading ? (
|
||
<TableSkeleton columns={4} rows={5} />
|
||
) : (permissions || []).length === 0 ? (
|
||
<div className="bg-white dark:bg-gray-800 shadow-sm border border-gray-200 dark:border-gray-700 rounded-lg">
|
||
<EmptyState
|
||
icon={Shield}
|
||
title="هیچ دسترسی یافت نشد"
|
||
description={filters.search
|
||
? "نتیجهای برای جستجوی شما یافت نشد"
|
||
: "دسترسیهای سیستم در اینجا نمایش داده میشوند"
|
||
}
|
||
/>
|
||
</div>
|
||
) : (
|
||
<div className="bg-white dark:bg-gray-800 shadow-sm border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden">
|
||
{/* Desktop Table */}
|
||
<div className="hidden md:block">
|
||
<div className="overflow-x-auto">
|
||
<table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
|
||
<thead className="bg-gray-50 dark:bg-gray-700">
|
||
<tr>
|
||
<th className="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
|
||
عنوان
|
||
</th>
|
||
<th className="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
|
||
توضیحات
|
||
</th>
|
||
<th className="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
|
||
تاریخ ایجاد
|
||
</th>
|
||
<th className="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
|
||
عملیات
|
||
</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody className="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
|
||
{(permissions || []).map((permission: Permission) => (
|
||
<tr key={permission.id} className="hover:bg-gray-50 dark:hover:bg-gray-700">
|
||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
|
||
{permission.title}
|
||
</td>
|
||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
|
||
{permission.description}
|
||
</td>
|
||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
|
||
{formatDate(permission.created_at)}
|
||
</td>
|
||
</tr>
|
||
))}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Mobile Cards */}
|
||
<div className="md:hidden p-4 space-y-4">
|
||
{(permissions || []).map((permission: Permission) => (
|
||
<div key={permission.id} className="border border-gray-200 dark:border-gray-700 rounded-lg p-4">
|
||
<div className="flex justify-between items-start mb-2">
|
||
<div>
|
||
<h3 className="text-sm font-medium text-gray-900 dark:text-gray-100">
|
||
{permission.title}
|
||
</h3>
|
||
<p className="text-sm text-gray-600 dark:text-gray-400">
|
||
{permission.description}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div className="text-xs text-gray-500 dark:text-gray-400">
|
||
تاریخ ایجاد: {formatDate(permission.created_at)}
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default PermissionsListPage;
|