feat: Add user role filtering to the dashboard with UI tabs and API integration.
This commit is contained in:
@@ -4,6 +4,15 @@ import { useEffect, useState } from 'react';
|
|||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { usersService, User, getErrorMessage } from '@/services';
|
import { usersService, User, getErrorMessage } from '@/services';
|
||||||
|
|
||||||
|
type RoleFilter = 'ALL' | 'ADMIN' | 'USER' | 'AGENT';
|
||||||
|
|
||||||
|
const roleFilters: { label: string; value: RoleFilter }[] = [
|
||||||
|
{ label: 'All Users', value: 'ALL' },
|
||||||
|
{ label: 'Admin', value: 'ADMIN' },
|
||||||
|
{ label: 'Users', value: 'USER' },
|
||||||
|
{ label: 'Agents', value: 'AGENT' },
|
||||||
|
];
|
||||||
|
|
||||||
export default function UsersPage() {
|
export default function UsersPage() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [users, setUsers] = useState<User[]>([]);
|
const [users, setUsers] = useState<User[]>([]);
|
||||||
@@ -11,17 +20,22 @@ export default function UsersPage() {
|
|||||||
const [error, setError] = useState('');
|
const [error, setError] = useState('');
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [totalUsers, setTotalUsers] = useState(0);
|
const [totalUsers, setTotalUsers] = useState(0);
|
||||||
|
const [activeFilter, setActiveFilter] = useState<RoleFilter>('ALL');
|
||||||
const limit = 10;
|
const limit = 10;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchUsers();
|
fetchUsers();
|
||||||
}, [currentPage]);
|
}, [currentPage, activeFilter]);
|
||||||
|
|
||||||
const fetchUsers = async () => {
|
const fetchUsers = async () => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
setError('');
|
setError('');
|
||||||
try {
|
try {
|
||||||
const response = await usersService.getUsers({ page: currentPage, limit });
|
const filters: { page: number; limit: number; role?: string } = { page: currentPage, limit };
|
||||||
|
if (activeFilter !== 'ALL') {
|
||||||
|
filters.role = activeFilter;
|
||||||
|
}
|
||||||
|
const response = await usersService.getUsers(filters);
|
||||||
setUsers(response.users || []);
|
setUsers(response.users || []);
|
||||||
setTotalUsers(response.total || 0);
|
setTotalUsers(response.total || 0);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -35,6 +49,11 @@ export default function UsersPage() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleFilterChange = (filter: RoleFilter) => {
|
||||||
|
setActiveFilter(filter);
|
||||||
|
setCurrentPage(1); // Reset to first page when filter changes
|
||||||
|
};
|
||||||
|
|
||||||
const totalPages = Math.ceil(totalUsers / limit);
|
const totalPages = Math.ceil(totalUsers / limit);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -49,7 +68,22 @@ export default function UsersPage() {
|
|||||||
<div className="bg-white rounded-lg shadow">
|
<div className="bg-white rounded-lg shadow">
|
||||||
<div className="px-6 py-4 border-b border-gray-200">
|
<div className="px-6 py-4 border-b border-gray-200">
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<h2 className="text-lg font-semibold text-gray-900">All Users</h2>
|
{/* Filter Tabs */}
|
||||||
|
<div className="flex space-x-1 bg-gray-100 rounded-lg p-1">
|
||||||
|
{roleFilters.map((filter) => (
|
||||||
|
<button
|
||||||
|
key={filter.value}
|
||||||
|
onClick={() => handleFilterChange(filter.value)}
|
||||||
|
className={`px-4 py-2 text-sm font-medium rounded-md transition-colors ${
|
||||||
|
activeFilter === filter.value
|
||||||
|
? 'bg-white text-gray-900 shadow-sm'
|
||||||
|
: 'text-gray-600 hover:text-gray-900'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{filter.label}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
<button
|
<button
|
||||||
onClick={fetchUsers}
|
onClick={fetchUsers}
|
||||||
className="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium rounded-lg transition-colors flex items-center"
|
className="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium rounded-lg transition-colors flex items-center"
|
||||||
|
|||||||
Reference in New Issue
Block a user