-
Notifications
You must be signed in to change notification settings - Fork 265
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #712 from Justfemi/feat-roles-and-components-kimiko
Feat (roles and permission) for team-kimiko
- Loading branch information
Showing
2 changed files
with
248 additions
and
3 deletions.
There are no files selected for viewing
186 changes: 183 additions & 3 deletions
186
src/app/dashboard/(user-dashboard)/settings/organization/roles-and-permissions/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,185 @@ | ||
const page = () => { | ||
return <div>page</div>; | ||
"use client"; | ||
|
||
import { useState } from "react"; | ||
|
||
import CustomButton from "~/components/common/common-button/common-button"; | ||
import RoleCreationModal from "~/components/common/modals/role-creation"; | ||
|
||
type Role = { | ||
id: number; | ||
name: string; | ||
description: string; | ||
}; | ||
|
||
type Permission = { | ||
name: string; | ||
enabled: boolean; | ||
}; | ||
|
||
const rolesData: Role[] = [ | ||
{ id: 1, name: "Guest", description: "Read-only access" }, | ||
{ id: 2, name: "User", description: "Read, write, update" }, | ||
{ id: 3, name: "Manager", description: "Read, write, approve" }, | ||
{ id: 4, name: "Project Lead", description: "Manage, coordinate, oversee" }, | ||
{ id: 5, name: "Administrator", description: "Full access, control" }, | ||
]; | ||
|
||
const permissionsData: { [key: number]: Permission[] } = { | ||
1: [ | ||
{ name: "Can view transactions", enabled: true }, | ||
{ name: "Can view refunds", enabled: false }, | ||
{ name: "Can log refunds", enabled: true }, | ||
], | ||
2: [ | ||
{ name: "Can view users", enabled: true }, | ||
{ name: "Can create users", enabled: false }, | ||
{ name: "Can edit users", enabled: true }, | ||
{ name: "Can blacklist/whitelist users", enabled: true }, | ||
], | ||
3: [ | ||
{ name: "Can view users", enabled: true }, | ||
{ name: "Can create users", enabled: true }, | ||
{ name: "Can edit users", enabled: false }, | ||
{ name: "Can blacklist/whitelist users", enabled: true }, | ||
], | ||
4: [ | ||
{ name: "Can view transactions", enabled: true }, | ||
{ name: "Can view refunds", enabled: true }, | ||
{ name: "Can log refunds", enabled: true }, | ||
{ name: "Can view users", enabled: true }, | ||
{ name: "Can create users", enabled: true }, | ||
{ name: "Can edit users", enabled: true }, | ||
{ name: "Can blacklist/whitelist users", enabled: true }, | ||
], | ||
5: [ | ||
{ name: "Can view transactions", enabled: true }, | ||
{ name: "Can view refunds", enabled: true }, | ||
{ name: "Can log refunds", enabled: true }, | ||
{ name: "Can view users", enabled: true }, | ||
{ name: "Can create users", enabled: true }, | ||
{ name: "Can edit users", enabled: true }, | ||
{ name: "Can blacklist/whitelist users", enabled: true }, | ||
], | ||
}; | ||
|
||
const RolesAndPermission = () => { | ||
const [selectedRoleId, setSelectedRoleId] = useState<number | undefined>(); | ||
const [permissions, setPermissions] = useState<Permission[]>([]); | ||
const [isModalOpen, setIsModalOpen] = useState(false); | ||
|
||
const handleRoleClick = (roleId: number) => { | ||
setSelectedRoleId(roleId); | ||
setPermissions([...permissionsData[roleId]]); | ||
}; | ||
|
||
const handleToggle = (index: number) => { | ||
setPermissions((previous) => { | ||
const newPermissions = [...previous]; | ||
newPermissions[index].enabled = !newPermissions[index].enabled; | ||
permissionsData[selectedRoleId!] = newPermissions; | ||
return newPermissions; | ||
}); | ||
}; | ||
|
||
const handleModalOpen = () => { | ||
setIsModalOpen(true); | ||
}; | ||
|
||
const handleModalClose = () => { | ||
setIsModalOpen(false); | ||
}; | ||
|
||
return ( | ||
<div className="min-h-screen p-8"> | ||
<div className="flex"> | ||
<div className="w-1/4 pr-6"> | ||
<h2 className="mb-10 text-xl font-medium">Roles</h2> | ||
<ul> | ||
{rolesData.map((role) => ( | ||
<li | ||
key={role.id} | ||
className={`mb-6 cursor-pointer border-b border-[#CBD5E1] p-2 ${ | ||
selectedRoleId === role.id | ||
? "rounded-md bg-orange-500 text-white" | ||
: "bg-white text-[#0a0a0a] hover:bg-[#F1F5F9]" | ||
}`} | ||
onClick={() => handleRoleClick(role.id)} | ||
> | ||
<div className="text-base font-medium">{role.name}</div> | ||
<div | ||
className={`text-xs font-normal ${selectedRoleId === role.id ? "text-white" : "text-[#525252]"}`} | ||
> | ||
{role.description} | ||
</div> | ||
</li> | ||
))} | ||
</ul> | ||
</div> | ||
<div className="w-3/4"> | ||
<div className="flex justify-end"> | ||
<CustomButton | ||
variant="primary" | ||
className="mb-6" | ||
onClick={handleModalOpen} | ||
> | ||
+ Create roles | ||
</CustomButton> | ||
</div> | ||
<div className="border-l border-[#CBD5E1] pl-6"> | ||
<div className="border-b border-[#CBD5E1] pb-4"> | ||
<h2 className="mb-2 text-xl font-semibold text-[#0A0A0A]"> | ||
Permissions | ||
</h2> | ||
<p className="text-xs font-normal text-[#525252]"> | ||
See the list of permissions for this role | ||
</p> | ||
</div> | ||
{selectedRoleId === undefined ? ( | ||
<div className="item-center flex flex-col justify-center py-56"> | ||
<p className="text-center text-sm font-normal text-[#525252]"> | ||
No list to show | ||
</p> | ||
<p className="text-center text-sm font-normal text-[#525252]"> | ||
Click on a role to view permissions | ||
</p> | ||
</div> | ||
) : ( | ||
<div className="mt-6"> | ||
<h3 className="mb-4 font-[#0a0a0a] text-base font-medium"> | ||
Transactions Permission | ||
</h3> | ||
{permissions.map((permission, index) => ( | ||
<div | ||
key={permission.name} | ||
className="mb-6 flex items-center justify-between" | ||
> | ||
<span className="text-sm font-normal text-[#525252]"> | ||
{permission.name} | ||
</span> | ||
<label className="relative inline-flex cursor-pointer items-center"> | ||
<input | ||
type="checkbox" | ||
className="peer sr-only" | ||
checked={permission.enabled} | ||
onChange={() => handleToggle(index)} | ||
/> | ||
<div className="peer h-6 w-11 rounded-full bg-gray-200 after:absolute after:left-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:border after:border-gray-300 after:bg-white after:transition-all after:content-[''] peer-checked:bg-orange-600 peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:ring-4 peer-focus:ring-orange-300 dark:border-gray-600 dark:bg-gray-700 dark:peer-focus:ring-orange-800"></div> | ||
</label> | ||
</div> | ||
))} | ||
<div className="mt-16 flex justify-end"> | ||
<button className="rounded border border-[#E2E8F0] bg-[#F1F5F9] px-4 py-2 text-sm font-medium text-[#0F172A] hover:bg-[#c1c9d2]"> | ||
Save Preferences | ||
</button> | ||
</div> | ||
</div> | ||
)} | ||
</div> | ||
</div> | ||
</div> | ||
<RoleCreationModal show={isModalOpen} onClose={handleModalClose} /> | ||
</div> | ||
); | ||
}; | ||
|
||
export default page; | ||
export default RolesAndPermission; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
"use client"; | ||
|
||
import CustomButton from "~/components/common/common-button/common-button"; | ||
import { | ||
Dialog, | ||
DialogContent, | ||
DialogDescription, | ||
DialogHeader, | ||
DialogTitle, | ||
} from "~/components/ui/dialog"; | ||
|
||
interface ModalProperties { | ||
show: boolean; | ||
onClose: () => void; | ||
} | ||
|
||
const RoleCreationModal: React.FC<ModalProperties> = ({ show, onClose }) => { | ||
return ( | ||
<> | ||
<Dialog open={show} onOpenChange={onClose}> | ||
<DialogContent> | ||
<DialogHeader> | ||
<DialogTitle> | ||
<h2 className="mb-2 text-left text-lg font-semibold text-neutral-dark-2"> | ||
Create Role | ||
</h2> | ||
</DialogTitle> | ||
<DialogDescription> | ||
<p className="text-left text-sm font-normal text-[#475569]"> | ||
Define customized responsibilities for collaborative success. | ||
</p> | ||
<div className="mb-7 mt-6"> | ||
<label className="mb-2 block text-left text-base font-bold text-neutral-dark-2"> | ||
Name of role | ||
</label> | ||
<input | ||
type="text" | ||
placeholder="e.g: IT Staff" | ||
className="w-full rounded-md border border-border px-3 py-2 shadow-sm outline-none focus:border-primary focus:ring-ring md:w-56" | ||
/> | ||
</div> | ||
<div> | ||
<label className="mb-2 block text-left text-base font-bold text-neutral-dark-2"> | ||
Role Descriotion | ||
</label> | ||
<textarea | ||
placeholder="describe role" | ||
className="min-h-20 w-full resize-none rounded-md border border-border px-3 py-2 shadow-sm outline-none focus:border-primary focus:ring-ring" | ||
/> | ||
</div> | ||
<div className="mt-8 flex items-center justify-end gap-4"> | ||
<CustomButton variant="subtle" onClick={onClose}> | ||
Cancel | ||
</CustomButton> | ||
<CustomButton variant="primary">Create Role</CustomButton> | ||
</div> | ||
</DialogDescription> | ||
</DialogHeader> | ||
</DialogContent> | ||
</Dialog> | ||
</> | ||
); | ||
}; | ||
|
||
export default RoleCreationModal; |