Skip to content

Commit

Permalink
feat(manageUsers): manage users table & role update functionality add
Browse files Browse the repository at this point in the history
  • Loading branch information
NSUWAL123 committed Jan 31, 2025
1 parent cc9d7b8 commit b3d3430
Showing 1 changed file with 152 additions and 0 deletions.
152 changes: 152 additions & 0 deletions src/frontend/src/views/ManageUsers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import React, { useEffect, useState } from 'react';
import DataTable from '@/components/common/DataTable';
import { GetUserListService, UpdateUserRole } from '@/api/User';
import { useAppDispatch, useAppSelector } from '@/types/reduxTypes';
import AssetModules from '@/shared/AssetModules';
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/common/Dropdown';
import { user_roles } from '@/types/enums';
import { CommonActions } from '@/store/slices/CommonSlice';
import Searchbar from '@/components/common/SearchBar';
import useDebouncedInput from '@/hooks/useDebouncedInput';

const VITE_API_URL = import.meta.env.VITE_API_URL;

type roleType = 'READ_ONLY' | 'ADMIN' | 'MAPPER';
const roleLabel = {
READ_ONLY: 'Read Only',
MAPPER: 'Mapper',
ADMIN: 'Admin',
};

const ManageUsers = () => {
const dispatch = useAppDispatch();
const userListLoading = useAppSelector((state) => state.user.userListLoading);
const userList = useAppSelector((state) => state.user.userList);

const updateRole = (id: number, currentRole: roleType, newRole: roleType) => {
if (currentRole === newRole) {
dispatch(CommonActions.SetSnackBar({ duration: 2000, open: true, message: 'Role up-to-date', variant: 'info' }));
return;
}
dispatch(UpdateUserRole(`${VITE_API_URL}/users/${id}`, { role: newRole }));
};

const userDatacolumns = [
{
header: 'Users',
accessorKey: 'username',
cell: ({ row }: any) => {
return (
<div className="fmtm-flex fmtm-items-center fmtm-gap-2">
{!row?.original?.profile_img ? (
<div className="fmtm-w-[1.875rem] fmtm-h-[1.875rem] fmtm-rounded-full fmtm-bg-[#68707F] fmtm-flex fmtm-items-center fmtm-justify-center fmtm-cursor-default">
<p className="fmtm-text-white">{row?.original?.username[0]?.toUpperCase()}</p>
</div>
) : (
<img
src={row?.original?.profile_img}
className="fmtm-w-[1.875rem] fmtm-h-[1.875rem] fmtm-rounded-full"
alt="profile image"
/>
)}
<p>{row?.original?.username}</p>
</div>
);
},
},
{
header: 'User ID',
accessorKey: 'id',
},
{
header: 'Role',
accessorKey: 'role',
},
{
header: 'Last Active',
accessorKey: 'last_login_at',
cell: ({ row }: any) => {
const lastActive = row?.original?.last_login_at ? row?.original?.last_login_at?.split('T')[0] : 'N/A';
return <>{lastActive}</>;
},
},
{
header: ' ',
cell: ({ row }: any) => {
const userId = row?.original?.id;
const currentRole = row?.original?.role;
return (
<>
<DropdownMenu>
<DropdownMenuTrigger className="fmtm-outline-none">
<AssetModules.ManageAccountsOutlinedIcon className="fmtm-cursor-pointer hover:fmtm-text-primaryRed" />
</DropdownMenuTrigger>
<DropdownMenuContent className="fmtm-z-[50] fmtm-bg-white" align="end">
{Object.keys(user_roles)?.map((role) => (
<DropdownMenuItem
key={role}
className="hover:fmtm-bg-red-50 fmtm-duration-200 fmtm-outline-none fmtm-py-1 fmtm-px-4 fmtm-cursor-pointer fmtm-rounded"
onSelect={() => {
updateRole(userId, currentRole as roleType, role as roleType);
}}
>
{roleLabel[role]}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
</>
);
},
},
];

const [filter, setFilter] = useState({ search: '' });

const [pagination, setPagination] = useState({
pageIndex: 0,
pageSize: 2,
});

const [searchTextData, handleChangeData] = useDebouncedInput({
ms: 500,
init: filter.search,
onChange: (debouncedEvent) => setFilter((prev) => ({ ...prev, search: debouncedEvent.target.value })),
});

useEffect(() => {
dispatch(
GetUserListService(`${VITE_API_URL}/users`, {
results_per_page: 2,
page: pagination.pageIndex + 1,
...filter,
}),
);
}, [filter, pagination, filter]);
return (
<div className="fmtm-h-full fmtm-flex fmtm-flex-col">
<div className="fmtm-flex fmtm-items-center fmtm-justify-between">
<h4 className="fmtm-text-[1.25rem] fmtm-font-bold fmtm-text-[#2C3038]">Manage Users</h4>
<Searchbar
value={searchTextData}
onChange={handleChangeData}
wrapperStyle="!fmtm-w-[13rem]"
className="!fmtm-py-0"
placeholder="Search by username"
isSmall
/>
</div>
<p className="fmtm-text-grey-500 fmtm-mb-4">Total number of users: {userList?.pagination?.total}</p>
<DataTable
data={userList || []}
columns={userDatacolumns}
isLoading={userListLoading}
pagination={{ pageIndex: pagination.pageIndex, pageSize: pagination.pageSize }}
setPaginationPage={(page) => setPagination(page)}
tableWrapperClassName="fmtm-flex-1"
/>
</div>
);
};

export default ManageUsers;

0 comments on commit b3d3430

Please sign in to comment.