Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat (roles and permission) for team-kimiko #712

Merged
merged 3 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
65 changes: 65 additions & 0 deletions src/components/common/modals/role-creation/index.tsx
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;
Loading