Added permission to codes

This commit is contained in:
Joao Ramos
2024-08-07 10:03:17 +01:00
parent cf91f1812d
commit 0fc2df1070
6 changed files with 97 additions and 67 deletions

View File

@@ -27,6 +27,7 @@ export const permissions = [
"viewCountryManager", "viewCountryManager",
"viewAdmin", "viewAdmin",
"viewGroup", "viewGroup",
"viewCodes",
// edit data // edit data
"editStudent", "editStudent",
"editTeacher", "editTeacher",
@@ -41,8 +42,10 @@ export const permissions = [
"deleteCountryManager", "deleteCountryManager",
"deleteAdmin", "deleteAdmin",
"deleteGroup", "deleteGroup",
// create pages "deleteCodes",
// create options
"createGroup", "createGroup",
"createCodes"
] as const; ] as const;
export type PermissionType = (typeof permissions)[keyof typeof permissions]; export type PermissionType = (typeof permissions)[keyof typeof permissions];

View File

@@ -297,7 +297,12 @@ export default function BatchCodeGenerator({ user }: { user: User }) {
{filesContent.length > 0 ? filesContent[0].name : "Choose a file"} {filesContent.length > 0 ? filesContent[0].name : "Choose a file"}
</Button> </Button>
{user && {user &&
checkAccess(user, ["developer", "admin", "corporate", "mastercorporate"]) && ( checkAccess(user, [
"developer",
"admin",
"corporate",
"mastercorporate",
]) && (
<> <>
<div className="-md:flex-row -md:items-center flex justify-between gap-2 md:flex-col 2xl:flex-row 2xl:items-center"> <div className="-md:flex-row -md:items-center flex justify-between gap-2 md:flex-col 2xl:flex-row 2xl:items-center">
<label className="text-mti-gray-dim text-base font-normal"> <label className="text-mti-gray-dim text-base font-normal">
@@ -352,14 +357,20 @@ export default function BatchCodeGenerator({ user }: { user: User }) {
))} ))}
</select> </select>
)} )}
<Button {checkAccess(
onClick={generateAndInvite} user,
disabled={ ["developer", "admin", "corporate", "mastercorporate"],
infos.length === 0 || (isExpiryDateEnabled ? !expiryDate : false) "createCodes"
} ) && (
> <Button
Generate & Send onClick={generateAndInvite}
</Button> disabled={
infos.length === 0 || (isExpiryDateEnabled ? !expiryDate : false)
}
>
Generate & Send
</Button>
)}
</div> </div>
</> </>
); );

View File

@@ -130,47 +130,48 @@ export default function CodeGenerator({ user }: { user: User }) {
))} ))}
</select> </select>
)} )}
{user && {user && checkAccess(user, ["developer", "admin", "corporate", "mastercorporate"]) && (
checkAccess(user, ["developer", "admin", "corporate"]) && ( <>
<> <div className="-md:flex-row -md:items-center flex justify-between gap-2 md:flex-col 2xl:flex-row 2xl:items-center">
<div className="-md:flex-row -md:items-center flex justify-between gap-2 md:flex-col 2xl:flex-row 2xl:items-center"> <label className="text-mti-gray-dim text-base font-normal">
<label className="text-mti-gray-dim text-base font-normal"> Expiry Date
Expiry Date </label>
</label> <Checkbox
<Checkbox isChecked={isExpiryDateEnabled}
isChecked={isExpiryDateEnabled} onChange={setIsExpiryDateEnabled}
onChange={setIsExpiryDateEnabled} disabled={!!user.subscriptionExpirationDate}
disabled={!!user.subscriptionExpirationDate} >
> Enabled
Enabled </Checkbox>
</Checkbox> </div>
</div> {isExpiryDateEnabled && (
{isExpiryDateEnabled && ( <ReactDatePicker
<ReactDatePicker className={clsx(
className={clsx( "flex min-h-[70px] w-full cursor-pointer justify-center rounded-full border p-6 text-sm font-normal focus:outline-none",
"flex min-h-[70px] w-full cursor-pointer justify-center rounded-full border p-6 text-sm font-normal focus:outline-none", "hover:border-mti-purple tooltip",
"hover:border-mti-purple tooltip", "transition duration-300 ease-in-out"
"transition duration-300 ease-in-out" )}
)} filterDate={(date) =>
filterDate={(date) => moment(date).isAfter(new Date()) &&
moment(date).isAfter(new Date()) && (user.subscriptionExpirationDate
(user.subscriptionExpirationDate ? moment(date).isBefore(user.subscriptionExpirationDate)
? moment(date).isBefore(user.subscriptionExpirationDate) : true)
: true) }
} dateFormat="dd/MM/yyyy"
dateFormat="dd/MM/yyyy" selected={expiryDate}
selected={expiryDate} onChange={(date) => setExpiryDate(date)}
onChange={(date) => setExpiryDate(date)} />
/> )}
)} </>
</> )}
)} {checkAccess(user, ["developer", "admin", "corporate", "mastercorporate"], 'createCodes') && (
<Button <Button
onClick={() => generateCode(type)} onClick={() => generateCode(type)}
disabled={isExpiryDateEnabled ? !expiryDate : false} disabled={isExpiryDateEnabled ? !expiryDate : false}
> >
Generate Generate
</Button> </Button>
)}
<label className="font-normal text-base text-mti-gray-dim"> <label className="font-normal text-base text-mti-gray-dim">
Generated Code: Generated Code:
</label> </label>

View File

@@ -19,6 +19,7 @@ import { BsTrash } from "react-icons/bs";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import ReactDatePicker from "react-datepicker"; import ReactDatePicker from "react-datepicker";
import clsx from "clsx"; import clsx from "clsx";
import { checkAccess } from "@/utils/permissions";
const columnHelper = createColumnHelper<Code>(); const columnHelper = createColumnHelper<Code>();
@@ -147,6 +148,12 @@ export default function CodeList({ user }: { user: User }) {
.finally(reload); .finally(reload);
}; };
const allowedToDelete = checkAccess(
user,
["developer", "admin", "corporate", "mastercorporate"],
"deleteCodes"
);
const defaultColumns = [ const defaultColumns = [
columnHelper.accessor("code", { columnHelper.accessor("code", {
id: "codeCheckbox", id: "codeCheckbox",
@@ -209,7 +216,7 @@ export default function CodeList({ user }: { user: User }) {
cell: ({ row }: { row: { original: Code } }) => { cell: ({ row }: { row: { original: Code } }) => {
return ( return (
<div className="flex gap-4"> <div className="flex gap-4">
{!row.original.userId && ( {allowedToDelete && !row.original.userId && (
<div <div
data-tip="Delete" data-tip="Delete"
className="cursor-pointer tooltip" className="cursor-pointer tooltip"
@@ -308,6 +315,7 @@ export default function CodeList({ user }: { user: User }) {
}} }}
/> />
</div> </div>
{allowedToDelete && (
<div className="flex gap-4 items-center"> <div className="flex gap-4 items-center">
<span>{selectedCodes.length} code(s) selected</span> <span>{selectedCodes.length} code(s) selected</span>
<Button <Button
@@ -320,6 +328,7 @@ export default function CodeList({ user }: { user: User }) {
Delete Delete
</Button> </Button>
</div> </div>
)}
</div> </div>
<table className="rounded-xl bg-mti-purple-ultralight/40 w-full"> <table className="rounded-xl bg-mti-purple-ultralight/40 w-full">
<thead> <thead>

View File

@@ -7,6 +7,7 @@ import ExamList from "./ExamList";
import GroupList from "./GroupList"; import GroupList from "./GroupList";
import PackageList from "./PackageList"; import PackageList from "./PackageList";
import UserList from "./UserList"; import UserList from "./UserList";
import { checkAccess } from "@/utils/permissions";
export default function Lists({ user }: { user: User }) { export default function Lists({ user }: { user: User }) {
return ( return (
@@ -20,13 +21,13 @@ export default function Lists({ user }: { user: User }) {
"transition duration-300 ease-in-out", "transition duration-300 ease-in-out",
selected selected
? "bg-white shadow" ? "bg-white shadow"
: "text-blue-100 hover:bg-white/[0.12] hover:text-mti-purple-dark", : "text-blue-100 hover:bg-white/[0.12] hover:text-mti-purple-dark"
) )
} }
> >
User List User List
</Tab> </Tab>
{user?.type === "developer" && ( {checkAccess(user, ["developer"]) && (
<Tab <Tab
className={({ selected }) => className={({ selected }) =>
clsx( clsx(
@@ -35,7 +36,7 @@ export default function Lists({ user }: { user: User }) {
"transition duration-300 ease-in-out", "transition duration-300 ease-in-out",
selected selected
? "bg-white shadow" ? "bg-white shadow"
: "text-blue-100 hover:bg-white/[0.12] hover:text-mti-purple-dark", : "text-blue-100 hover:bg-white/[0.12] hover:text-mti-purple-dark"
) )
} }
> >
@@ -50,13 +51,13 @@ export default function Lists({ user }: { user: User }) {
"transition duration-300 ease-in-out", "transition duration-300 ease-in-out",
selected selected
? "bg-white shadow" ? "bg-white shadow"
: "text-blue-100 hover:bg-white/[0.12] hover:text-mti-purple-dark", : "text-blue-100 hover:bg-white/[0.12] hover:text-mti-purple-dark"
) )
} }
> >
Group List Group List
</Tab> </Tab>
{user && ["developer", "admin", "corporate"].includes(user.type) && ( {checkAccess(user, ["developer", "admin", "corporate"]) && (
<Tab <Tab
className={({ selected }) => className={({ selected }) =>
clsx( clsx(
@@ -65,14 +66,14 @@ export default function Lists({ user }: { user: User }) {
"transition duration-300 ease-in-out", "transition duration-300 ease-in-out",
selected selected
? "bg-white shadow" ? "bg-white shadow"
: "text-blue-100 hover:bg-white/[0.12] hover:text-mti-purple-dark", : "text-blue-100 hover:bg-white/[0.12] hover:text-mti-purple-dark"
) )
} }
> >
Code List Code List
</Tab> </Tab>
)} )}
{user && ["developer", "admin"].includes(user.type) && ( {checkAccess(user, ["developer", "admin"]) && (
<Tab <Tab
className={({ selected }) => className={({ selected }) =>
clsx( clsx(
@@ -81,14 +82,14 @@ export default function Lists({ user }: { user: User }) {
"transition duration-300 ease-in-out", "transition duration-300 ease-in-out",
selected selected
? "bg-white shadow" ? "bg-white shadow"
: "text-blue-100 hover:bg-white/[0.12] hover:text-mti-purple-dark", : "text-blue-100 hover:bg-white/[0.12] hover:text-mti-purple-dark"
) )
} }
> >
Package List Package List
</Tab> </Tab>
)} )}
{user && ["developer", "admin"].includes(user.type) && ( {checkAccess(user, ["developer", "admin"]) && (
<Tab <Tab
className={({ selected }) => className={({ selected }) =>
clsx( clsx(
@@ -97,7 +98,7 @@ export default function Lists({ user }: { user: User }) {
"transition duration-300 ease-in-out", "transition duration-300 ease-in-out",
selected selected
? "bg-white shadow" ? "bg-white shadow"
: "text-blue-100 hover:bg-white/[0.12] hover:text-mti-purple-dark", : "text-blue-100 hover:bg-white/[0.12] hover:text-mti-purple-dark"
) )
} }
> >
@@ -109,7 +110,7 @@ export default function Lists({ user }: { user: User }) {
<Tab.Panel className="overflow-y-scroll max-h-[600px] rounded-xl scrollbar-hide"> <Tab.Panel className="overflow-y-scroll max-h-[600px] rounded-xl scrollbar-hide">
<UserList user={user} /> <UserList user={user} />
</Tab.Panel> </Tab.Panel>
{user?.type === "developer" && ( {checkAccess(user, ["developer"]) && (
<Tab.Panel className="overflow-y-scroll max-h-[600px] rounded-xl scrollbar-hide"> <Tab.Panel className="overflow-y-scroll max-h-[600px] rounded-xl scrollbar-hide">
<ExamList user={user} /> <ExamList user={user} />
</Tab.Panel> </Tab.Panel>
@@ -117,17 +118,21 @@ export default function Lists({ user }: { user: User }) {
<Tab.Panel className="overflow-y-scroll max-h-[600px] rounded-xl scrollbar-hide"> <Tab.Panel className="overflow-y-scroll max-h-[600px] rounded-xl scrollbar-hide">
<GroupList user={user} /> <GroupList user={user} />
</Tab.Panel> </Tab.Panel>
{user && ["developer", "admin", "corporate"].includes(user.type) && ( {checkAccess(
user,
["developer", "admin", "corporate", "mastercorporate"],
"viewCodes"
) && (
<Tab.Panel className="overflow-y-scroll max-h-[600px] rounded-xl scrollbar-hide"> <Tab.Panel className="overflow-y-scroll max-h-[600px] rounded-xl scrollbar-hide">
<CodeList user={user} /> <CodeList user={user} />
</Tab.Panel> </Tab.Panel>
)} )}
{user && ["developer", "admin"].includes(user.type) && ( {checkAccess(user, ["developer", "admin"]) && (
<Tab.Panel className="overflow-y-scroll max-h-[600px] rounded-xl scrollbar-hide"> <Tab.Panel className="overflow-y-scroll max-h-[600px] rounded-xl scrollbar-hide">
<PackageList user={user} /> <PackageList user={user} />
</Tab.Panel> </Tab.Panel>
)} )}
{user && ["developer", "admin"].includes(user.type) && ( {checkAccess(user, ["developer", "admin"]) && (
<Tab.Panel className="overflow-y-scroll max-h-[600px] rounded-xl scrollbar-hide"> <Tab.Panel className="overflow-y-scroll max-h-[600px] rounded-xl scrollbar-hide">
<DiscountList user={user} /> <DiscountList user={user} />
</Tab.Panel> </Tab.Panel>

View File

@@ -14,6 +14,7 @@ import BatchCodeGenerator from "./(admin)/BatchCodeGenerator";
import {shouldRedirectHome} from "@/utils/navigation.disabled"; import {shouldRedirectHome} from "@/utils/navigation.disabled";
import ExamGenerator from "./(admin)/ExamGenerator"; import ExamGenerator from "./(admin)/ExamGenerator";
import BatchCreateUser from "./(admin)/BatchCreateUser"; import BatchCreateUser from "./(admin)/BatchCreateUser";
import { checkAccess, getTypesOfUser } from "@/utils/permissions";
export const getServerSideProps = withIronSessionSsr(({req, res}) => { export const getServerSideProps = withIronSessionSsr(({req, res}) => {
const user = req.session.user; const user = req.session.user;
@@ -60,7 +61,7 @@ export default function Admin() {
<section className="w-full flex -md:flex-col -xl:gap-2 gap-8 justify-between"> <section className="w-full flex -md:flex-col -xl:gap-2 gap-8 justify-between">
<ExamLoader /> <ExamLoader />
<BatchCreateUser user={user} /> <BatchCreateUser user={user} />
{user.type !== "teacher" && ( {checkAccess(user, getTypesOfUser(["teacher"]), 'viewCodes') && (
<> <>
<CodeGenerator user={user} /> <CodeGenerator user={user} />
<BatchCodeGenerator user={user} /> <BatchCodeGenerator user={user} />