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";
|
} from "./_models";
|
||||||
|
|
||||||
export const getRoles = async () => {
|
export const getRoles = async () => {
|
||||||
|
try {
|
||||||
const response = await httpGetRequest<Role[]>(
|
const response = await httpGetRequest<Role[]>(
|
||||||
APIUrlGenerator(API_ROUTES.GET_ROLES)
|
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;
|
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) => {
|
export const getRole = async (id: string) => {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { useRoles, useDeleteRole } from "../core/_hooks";
|
||||||
import { Button } from "@/components/ui/Button";
|
import { Button } from "@/components/ui/Button";
|
||||||
import { LoadingSpinner } from "@/components/ui/LoadingSpinner";
|
import { LoadingSpinner } from "@/components/ui/LoadingSpinner";
|
||||||
import { Role } from "@/types/auth";
|
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";
|
import { Modal } from "@/components/ui/Modal";
|
||||||
|
|
||||||
const RolesListPage = () => {
|
const RolesListPage = () => {
|
||||||
|
|
@ -88,65 +88,61 @@ const RolesListPage = () => {
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
|
<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">
|
<tr key={role.id} className="hover:bg-gray-50 dark:hover:bg-gray-700">
|
||||||
<td className="px-6 py-4 whitespace-nowrap">
|
<td className="px-6 py-4 whitespace-nowrap">
|
||||||
<div className="text-sm font-medium text-gray-900 dark:text-gray-100">
|
<div className="text-sm font-medium text-gray-900 dark:text-gray-100">
|
||||||
{role.title}
|
{role.title}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
<div className="text-sm text-gray-500 dark:text-gray-400">
|
||||||
<td className="px-6 py-4">
|
|
||||||
<div className="text-sm text-gray-600 dark:text-gray-300 max-w-xs truncate">
|
|
||||||
{role.description}
|
{role.description}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-6 py-4 whitespace-nowrap">
|
<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} دسترسی
|
{role.permissions?.length || 0} دسترسی
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</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')}
|
{new Date(role.created_at).toLocaleDateString('fa-IR')}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-6 py-4 whitespace-nowrap text-sm">
|
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium space-x-2 space-x-reverse">
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<Button
|
<Button
|
||||||
|
variant="outline"
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="secondary"
|
|
||||||
onClick={() => handleView(role.id)}
|
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>
|
||||||
<Button
|
<Button
|
||||||
|
variant="outline"
|
||||||
size="sm"
|
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)}
|
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>
|
||||||
<Button
|
<Button
|
||||||
|
variant="outline"
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="danger"
|
onClick={() => handlePermissions(role.id)}
|
||||||
onClick={() => handleDelete(role.id)}
|
className="ml-2"
|
||||||
className="flex items-center gap-1"
|
|
||||||
>
|
>
|
||||||
<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>
|
</Button>
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue