fix(roles): add fallback and debug for roles API response
- Add console.log to debug roles API response structure - Handle different API response formats (results, items, data fields) - Add fallback to empty array when API fails or returns non-array - Fix roles?.map error by ensuring roles is always an array - Handle backend API not working scenario
This commit is contained in:
parent
d06135824d
commit
37747941ce
|
|
@ -15,10 +15,40 @@ import {
|
|||
} from "./_models";
|
||||
|
||||
export const getRoles = async () => {
|
||||
try {
|
||||
const response = await httpGetRequest<Role[]>(
|
||||
APIUrlGenerator(API_ROUTES.GET_ROLES)
|
||||
);
|
||||
console.log("Roles API Response:", response);
|
||||
console.log("Roles data:", response.data);
|
||||
|
||||
// اگر response.data آرایه نیست، ممکن است در فیلد دیگری باشد
|
||||
if (Array.isArray(response.data)) {
|
||||
return response.data;
|
||||
}
|
||||
|
||||
// بررسی اگر در فیلدهای دیگر باشد
|
||||
if (response.data && typeof response.data === "object") {
|
||||
// چک کن آیا در results یا items یا data هست
|
||||
if (Array.isArray((response.data as any).results)) {
|
||||
return (response.data as any).results;
|
||||
}
|
||||
if (Array.isArray((response.data as any).items)) {
|
||||
return (response.data as any).items;
|
||||
}
|
||||
if (Array.isArray((response.data as any).data)) {
|
||||
return (response.data as any).data;
|
||||
}
|
||||
}
|
||||
|
||||
// fallback: آرایه خالی برگردان
|
||||
console.warn("Roles data is not an array:", response.data);
|
||||
return [];
|
||||
} catch (error) {
|
||||
console.error("Error fetching roles:", error);
|
||||
// اگر backend کار نمیکند، آرایه خالی برگردان
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
export const getRole = async (id: string) => {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { useRoles, useDeleteRole } from "../core/_hooks";
|
|||
import { Button } from "@/components/ui/Button";
|
||||
import { LoadingSpinner } from "@/components/ui/LoadingSpinner";
|
||||
import { Role } from "@/types/auth";
|
||||
import { Trash2, Edit, Plus, Eye, Users } from "lucide-react";
|
||||
import { Trash2, Edit, Plus, Eye, Users, Edit3, Shield } from "lucide-react";
|
||||
import { Modal } from "@/components/ui/Modal";
|
||||
|
||||
const RolesListPage = () => {
|
||||
|
|
@ -88,65 +88,61 @@ const RolesListPage = () => {
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody className="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
|
||||
{roles?.map((role: Role) => (
|
||||
{(roles || []).map((role: Role) => (
|
||||
<tr key={role.id} className="hover:bg-gray-50 dark:hover:bg-gray-700">
|
||||
<td className="px-6 py-4 whitespace-nowrap">
|
||||
<div className="text-sm font-medium text-gray-900 dark:text-gray-100">
|
||||
{role.title}
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-6 py-4">
|
||||
<div className="text-sm text-gray-600 dark:text-gray-300 max-w-xs truncate">
|
||||
<div className="text-sm text-gray-500 dark:text-gray-400">
|
||||
{role.description}
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-6 py-4 whitespace-nowrap">
|
||||
<span className="px-2 py-1 text-xs font-medium bg-blue-100 text-blue-800 rounded-full">
|
||||
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100">
|
||||
{role.permissions?.length || 0} دسترسی
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-600 dark:text-gray-300">
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
|
||||
{new Date(role.created_at).toLocaleDateString('fa-IR')}
|
||||
</td>
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm">
|
||||
<div className="flex items-center gap-2">
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium space-x-2 space-x-reverse">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
onClick={() => handleView(role.id)}
|
||||
className="flex items-center gap-1"
|
||||
className="ml-2"
|
||||
>
|
||||
<Eye className="h-3 w-3" />
|
||||
<Eye className="h-4 w-4 ml-1" />
|
||||
مشاهده
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
variant="primary"
|
||||
onClick={() => handlePermissions(role.id)}
|
||||
className="flex items-center gap-1"
|
||||
>
|
||||
<Users className="h-3 w-3" />
|
||||
دسترسیها
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
onClick={() => handleEdit(role.id)}
|
||||
className="flex items-center gap-1"
|
||||
className="ml-2"
|
||||
>
|
||||
<Edit className="h-3 w-3" />
|
||||
<Edit3 className="h-4 w-4 ml-1" />
|
||||
ویرایش
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
variant="danger"
|
||||
onClick={() => handleDelete(role.id)}
|
||||
className="flex items-center gap-1"
|
||||
onClick={() => handlePermissions(role.id)}
|
||||
className="ml-2"
|
||||
>
|
||||
<Trash2 className="h-3 w-3" />
|
||||
<Users className="h-4 w-4 ml-1" />
|
||||
دسترسیها
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setDeleteRoleId(role.id.toString())}
|
||||
className="text-red-600 hover:text-red-800 dark:text-red-400 dark:hover:text-red-300"
|
||||
>
|
||||
<Trash2 className="h-4 w-4 ml-1" />
|
||||
حذف
|
||||
</Button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
|
|
|
|||
Loading…
Reference in New Issue