🐛 fix(headerComponent): reformat code to improve readability and consistency

🔨 refactor(AdminPage/index.tsx): reorganize imports and remove unused imports for better code organization and maintainability
🐛 fix(AdminPage/index.tsx): fix import statement for Header component to resolve import error
🚀 feat(AdminPage/index.tsx): add support for filtering user list based on input value to improve user experience

🔨 refactor(AdminPage/index.tsx): clean up code formatting and indentation for improved readability
🐛 fix(AdminPage/index.tsx): fix missing closing tags and correct JSX syntax errors
✨ feat(AdminPage/index.tsx): add support for user management actions such as filtering, adding, editing, and deleting users
📝 chore(AdminPage/index.tsx): update comments and remove unused code for better code organization

🎨 style: refactor user management UI to improve readability and maintainability
🔧 chore: update user management UI to use UserManagementModal and ConfirmationModal components for edit and delete functionality respectively

🐛 fix(PageComponent/index.tsx): fix formatting of proOptions object to improve readability and maintain consistency
This commit is contained in:
Gabriel Luiz Freitas Almeida 2023-08-30 14:49:03 -03:00
commit f9e3d0f57b
3 changed files with 253 additions and 248 deletions

View file

@ -33,14 +33,14 @@ export default function Header(): JSX.Element {
)} )}
{!autoLogin && location.pathname !== `/flow/${tabId}` && ( {!autoLogin && location.pathname !== `/flow/${tabId}` && (
<a <a
onClick={() => { onClick={() => {
logout(); logout();
navigate("/login"); navigate("/login");
}} }}
className="text-sm font-medium text-muted-foreground transition-colors hover:text-primary cursor-pointer mx-5" className="mx-5 cursor-pointer text-sm font-medium text-muted-foreground transition-colors hover:text-primary"
> >
Sign out Sign out
</a> </a>
)} )}
{location.pathname === "/admin" && ( {location.pathname === "/admin" && (
@ -48,7 +48,7 @@ export default function Header(): JSX.Element {
onClick={() => { onClick={() => {
navigate("/"); navigate("/");
}} }}
className="text-sm font-medium text-muted-foreground transition-colors hover:text-primary cursor-pointer" className="cursor-pointer text-sm font-medium text-muted-foreground transition-colors hover:text-primary"
> >
Home Home
</a> </a>
@ -59,11 +59,11 @@ export default function Header(): JSX.Element {
location.pathname !== "/admin" && location.pathname !== "/admin" &&
location.pathname !== `/flow/${tabId}` && ( location.pathname !== `/flow/${tabId}` && (
<a <a
className="text-sm font-medium text-muted-foreground transition-colors hover:text-primary cursor-pointer" className="cursor-pointer text-sm font-medium text-muted-foreground transition-colors hover:text-primary"
onClick={() => navigate("/admin")} onClick={() => navigate("/admin")}
> >
Admin page Admin page
</a> </a>
)} )}
</div> </div>
<div className="round-button-div"> <div className="round-button-div">

View file

@ -4,6 +4,7 @@ import { useContext, useEffect, useRef, useState } from "react";
import PaginatorComponent from "../../components/PaginatorComponent"; import PaginatorComponent from "../../components/PaginatorComponent";
import ShadTooltip from "../../components/ShadTooltipComponent"; import ShadTooltip from "../../components/ShadTooltipComponent";
import IconComponent from "../../components/genericIconComponent"; import IconComponent from "../../components/genericIconComponent";
import Header from "../../components/headerComponent";
import { Button } from "../../components/ui/button"; import { Button } from "../../components/ui/button";
import { Checkbox } from "../../components/ui/checkbox"; import { Checkbox } from "../../components/ui/checkbox";
import { Input } from "../../components/ui/input"; import { Input } from "../../components/ui/input";
@ -25,9 +26,8 @@ import {
} from "../../controllers/API"; } from "../../controllers/API";
import ConfirmationModal from "../../modals/ConfirmationModal"; import ConfirmationModal from "../../modals/ConfirmationModal";
import UserManagementModal from "../../modals/UserManagementModal"; import UserManagementModal from "../../modals/UserManagementModal";
import { UserInputType } from "../../types/components";
import Header from "../../components/headerComponent";
import { Users } from "../../types/api"; import { Users } from "../../types/api";
import { UserInputType } from "../../types/components";
export default function AdminPage() { export default function AdminPage() {
const [inputValue, setInputValue] = useState(""); const [inputValue, setInputValue] = useState("");
@ -89,7 +89,7 @@ export default function AdminPage() {
if (input === "") { if (input === "") {
setFilterUserList(userList.current); setFilterUserList(userList.current);
} else { } else {
const filteredList = userList.current.filter((user:Users) => const filteredList = userList.current.filter((user: Users) =>
user.username.toLowerCase().includes(input.toLowerCase()) user.username.toLowerCase().includes(input.toLowerCase())
); );
setFilterUserList(filteredList); setFilterUserList(filteredList);
@ -183,249 +183,254 @@ export default function AdminPage() {
return ( return (
<> <>
<div className="flex flex-col"> <div className="flex flex-col">
<Header /> <Header />
{userData && ( {userData && (
<div className="main-page-panel"> <div className="main-page-panel">
<div className="m-auto flex h-full flex-row justify-center"> <div className="m-auto flex h-full flex-row justify-center">
<div className="basis-5/6"> <div className="basis-5/6">
<div className="m-auto flex h-full flex-col space-y-8 p-8 "> <div className="m-auto flex h-full flex-col space-y-8 p-8 ">
<div className="flex items-center justify-between space-y-2"> <div className="flex items-center justify-between space-y-2">
<div> <div>
<h2 className="text-2xl font-bold tracking-tight"> <h2 className="text-2xl font-bold tracking-tight">
Welcome back! Welcome back!
</h2> </h2>
<p className="text-muted-foreground"> <p className="text-muted-foreground">
Navigate through this section to efficiently oversee all Navigate through this section to efficiently oversee all
application users. From here, you can seamlessly manage application users. From here, you can seamlessly manage
user accounts. user accounts.
</p> </p>
</div>
<div className="flex items-center space-x-2"></div>
</div> </div>
<div className="flex items-center space-x-2"></div>
</div>
{userList.current.length === 0 && !loadingUsers && ( {userList.current.length === 0 && !loadingUsers && (
<>
<div className="flex items-center justify-between">
<h2>There's no users registered :)</h2>
</div>
</>
)}
<> <>
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h2>There's no users registered :)</h2> <div className="flex flex-1 items-center space-x-2">
</div> <Input
</> value={inputValue}
)} placeholder="Filter users..."
<> className="h-8 w-[150px] lg:w-[250px]"
<div className="flex items-center justify-between"> onChange={(e) => handleFilterUsers(e.target.value)}
<div className="flex flex-1 items-center space-x-2"> />
<Input {inputValue.length > 0 && (
value={inputValue} <Button
placeholder="Filter users..." onClick={() => {
className="h-8 w-[150px] lg:w-[250px]" setInputValue("");
onChange={(e) => handleFilterUsers(e.target.value)} setFilterUserList(userList.current);
/> }}
{inputValue.length > 0 && ( variant="ghost"
<Button className="h-8 px-2 lg:px-3"
onClick={() => { >
setInputValue(""); Reset
setFilterUserList(userList.current); <X className="ml-2 h-4 w-4" />
</Button>
)}
</div>
<div>
<UserManagementModal
title="New User"
titleHeader={"Add a new user"}
cancelText="Cancel"
confirmationText="Save"
icon={"UserPlus2"}
onConfirm={(index, user) => {
handleNewUser(user);
}} }}
variant="ghost"
className="h-8 px-2 lg:px-3"
> >
Reset <Button>New User</Button>
<X className="ml-2 h-4 w-4" /> </UserManagementModal>
</Button> </div>
)}
</div> </div>
<div> {loadingUsers && (
<UserManagementModal <div>
title="New User" <strong>Loading...</strong>
titleHeader={"Add a new user"} </div>
cancelText="Cancel" )}
confirmationText="Save" <div
icon={"UserPlus2"} className={
onConfirm={(index, user) => { "max-h-[26rem] min-h-[26rem] overflow-scroll overflow-x-hidden rounded-md border-2 bg-muted custom-scroll" +
handleNewUser(user); (loadingUsers ? " border-0" : "")
}} }
> >
<Button>New User</Button> <Table className={"table-fixed bg-muted outline-1"}>
</UserManagementModal> <TableHeader
</div> className={
</div> loadingUsers
{loadingUsers && ( ? "hidden"
<div> : "table-fixed bg-muted outline-1"
<strong>Loading...</strong> }
</div> >
)} <TableRow>
<div <TableHead className="h-10">Id</TableHead>
className={ <TableHead className="h-10">Username</TableHead>
"max-h-[26rem] min-h-[26rem] overflow-scroll overflow-x-hidden rounded-md border-2 bg-muted custom-scroll" + <TableHead className="h-10">Active</TableHead>
(loadingUsers ? " border-0" : "") <TableHead className="h-10">Superuser</TableHead>
} <TableHead className="h-10">Created At</TableHead>
> <TableHead className="h-10">Updated At</TableHead>
<Table className={"table-fixed bg-muted outline-1"}> <TableHead className="h-10 w-[100px] text-right"></TableHead>
<TableHeader </TableRow>
className={ </TableHeader>
loadingUsers {!loadingUsers && (
? "hidden" <TableBody>
: "table-fixed bg-muted outline-1" {filterUserList.map(
} (user: UserInputType, index) => (
> <TableRow key={index}>
<TableRow> <TableCell className="truncate py-2 font-medium">
<TableHead className="h-10">Id</TableHead> <ShadTooltip content={user.id}>
<TableHead className="h-10">Username</TableHead> <span className="cursor-default">
<TableHead className="h-10">Active</TableHead> {user.id}
<TableHead className="h-10">Superuser</TableHead> </span>
<TableHead className="h-10">Created At</TableHead>
<TableHead className="h-10">Updated At</TableHead>
<TableHead className="h-10 w-[100px] text-right"></TableHead>
</TableRow>
</TableHeader>
{!loadingUsers && (
<TableBody>
{filterUserList.map((user:UserInputType, index) => (
<TableRow key={index}>
<TableCell className="truncate py-2 font-medium">
<ShadTooltip content={user.id}>
<span className="cursor-default">
{user.id}
</span>
</ShadTooltip>
</TableCell>
<TableCell className="truncate py-2">
<ShadTooltip content={user.username}>
<span className="cursor-default">
{user.username}
</span>
</ShadTooltip>
</TableCell>
<TableCell className="relative left-5 truncate py-2 text-align-last-left">
<ConfirmationModal
title="Edit"
titleHeader={`${user.username}`}
modalContentTitle="Attention!"
modalContent="Are you completely confident about the changes you are making to this user?"
cancelText="Cancel"
confirmationText="Confirm"
icon={"UserCog2"}
data={user}
index={index}
onConfirm={(index, user) => {
handleDisableUser(
user.is_active,
user.id,
user
);
}}
>
<Checkbox
id="is_active"
checked={user.is_active}
/>
</ConfirmationModal>
</TableCell>
<TableCell className="relative left-5 truncate py-2 text-align-last-left">
<ConfirmationModal
title="Edit"
titleHeader={`${user.username}`}
modalContentTitle="Attention!"
modalContent="Are you completely confident about the changes you are making to this user?"
cancelText="Cancel"
confirmationText="Confirm"
icon={"UserCog2"}
data={user}
index={index}
onConfirm={(index, user) => {
handleSuperUserEdit(
user.is_superuser,
user.id,
user
);
}}
>
<Checkbox
id="is_superuser"
checked={user.is_superuser}
/>
</ConfirmationModal>
</TableCell>
<TableCell className="truncate py-2 ">
{
new Date(user.create_at!)
.toISOString()
.split("T")[0]
}
</TableCell>
<TableCell className="truncate py-2">
{
new Date(user.updated_at!)
.toISOString()
.split("T")[0]
}
</TableCell>
<TableCell className="flex w-[100px] py-2 text-right">
<div className="flex">
<UserManagementModal
title="Edit"
titleHeader={`${user.id}`}
cancelText="Cancel"
confirmationText="Save"
icon={"UserPlus2"}
data={user}
index={index}
onConfirm={(index, editUser) => {
handleEditUser(user.id, editUser);
}}
>
<ShadTooltip content="Edit" side="top">
<IconComponent
name="Pencil"
className="h-4 w-4 cursor-pointer"
/>
</ShadTooltip> </ShadTooltip>
</UserManagementModal> </TableCell>
<TableCell className="truncate py-2">
<ConfirmationModal <ShadTooltip content={user.username}>
title="Delete" <span className="cursor-default">
titleHeader="Delete User" {user.username}
modalContentTitle="Attention!" </span>
modalContent="Are you sure you want to delete this user? This action cannot be undone."
cancelText="Cancel"
confirmationText="Delete"
icon={"UserMinus2"}
data={user}
index={index}
onConfirm={(index, user) => {
handleDeleteUser(user);
}}
>
<ShadTooltip content="Delete" side="top">
<IconComponent
name="Trash2"
className="ml-2 h-4 w-4 cursor-pointer"
/>
</ShadTooltip> </ShadTooltip>
</ConfirmationModal> </TableCell>
</div> <TableCell className="relative left-5 truncate py-2 text-align-last-left">
</TableCell> <ConfirmationModal
</TableRow> title="Edit"
))} titleHeader={`${user.username}`}
</TableBody> modalContentTitle="Attention!"
)} modalContent="Are you completely confident about the changes you are making to this user?"
</Table> cancelText="Cancel"
</div> confirmationText="Confirm"
icon={"UserCog2"}
data={user}
index={index}
onConfirm={(index, user) => {
handleDisableUser(
user.is_active,
user.id,
user
);
}}
>
<Checkbox
id="is_active"
checked={user.is_active}
/>
</ConfirmationModal>
</TableCell>
<TableCell className="relative left-5 truncate py-2 text-align-last-left">
<ConfirmationModal
title="Edit"
titleHeader={`${user.username}`}
modalContentTitle="Attention!"
modalContent="Are you completely confident about the changes you are making to this user?"
cancelText="Cancel"
confirmationText="Confirm"
icon={"UserCog2"}
data={user}
index={index}
onConfirm={(index, user) => {
handleSuperUserEdit(
user.is_superuser,
user.id,
user
);
}}
>
<Checkbox
id="is_superuser"
checked={user.is_superuser}
/>
</ConfirmationModal>
</TableCell>
<TableCell className="truncate py-2 ">
{
new Date(user.create_at!)
.toISOString()
.split("T")[0]
}
</TableCell>
<TableCell className="truncate py-2">
{
new Date(user.updated_at!)
.toISOString()
.split("T")[0]
}
</TableCell>
<TableCell className="flex w-[100px] py-2 text-right">
<div className="flex">
<UserManagementModal
title="Edit"
titleHeader={`${user.id}`}
cancelText="Cancel"
confirmationText="Save"
icon={"UserPlus2"}
data={user}
index={index}
onConfirm={(index, editUser) => {
handleEditUser(user.id, editUser);
}}
>
<ShadTooltip content="Edit" side="top">
<IconComponent
name="Pencil"
className="h-4 w-4 cursor-pointer"
/>
</ShadTooltip>
</UserManagementModal>
<PaginatorComponent <ConfirmationModal
pageIndex={index} title="Delete"
pageSize={size} titleHeader="Delete User"
totalRowsCount={totalRowsCount} modalContentTitle="Attention!"
paginate={(pageIndex, pageSize) => { modalContent="Are you sure you want to delete this user? This action cannot be undone."
handleChangePagination(pageSize, pageIndex); cancelText="Cancel"
}} confirmationText="Delete"
></PaginatorComponent> icon={"UserMinus2"}
</> data={user}
index={index}
onConfirm={(index, user) => {
handleDeleteUser(user);
}}
>
<ShadTooltip
content="Delete"
side="top"
>
<IconComponent
name="Trash2"
className="ml-2 h-4 w-4 cursor-pointer"
/>
</ShadTooltip>
</ConfirmationModal>
</div>
</TableCell>
</TableRow>
)
)}
</TableBody>
)}
</Table>
</div>
<PaginatorComponent
pageIndex={index}
pageSize={size}
totalRowsCount={totalRowsCount}
paginate={(pageIndex, pageSize) => {
handleChangePagination(pageSize, pageIndex);
}}
></PaginatorComponent>
</>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> )}
)}
</div> </div>
</> </>
); );

View file

@ -431,7 +431,7 @@ export default function Page({
zoomOnScroll={!view} zoomOnScroll={!view}
zoomOnPinch={!view} zoomOnPinch={!view}
panOnDrag={!view} panOnDrag={!view}
proOptions={{hideAttribution: true}} proOptions={{ hideAttribution: true }}
> >
<Background className="" /> <Background className="" />
{!view && ( {!view && (