Updated permissions to have a key to group them
This commit is contained in:
@@ -1,5 +1,12 @@
|
||||
import React from "react";
|
||||
import { Permission } from "@/interfaces/permissions";
|
||||
import {createColumnHelper, flexRender, getCoreRowModel, useReactTable} from "@tanstack/react-table";
|
||||
import {
|
||||
createColumnHelper,
|
||||
flexRender,
|
||||
getCoreRowModel,
|
||||
useReactTable,
|
||||
Row,
|
||||
} from "@tanstack/react-table";
|
||||
import Link from "next/link";
|
||||
import { convertCamelCaseToReadable } from "@/utils/string";
|
||||
|
||||
@@ -16,7 +23,8 @@ const defaultColumns = [
|
||||
<Link
|
||||
href={`/permissions/${row.original.id}`}
|
||||
key={row.id}
|
||||
className="underline text-mti-purple-light hover:text-mti-purple-dark transition ease-in-out duration-300 cursor-pointer">
|
||||
className="underline text-mti-purple-light hover:text-mti-purple-dark transition ease-in-out duration-300 cursor-pointer"
|
||||
>
|
||||
{convertCamelCaseToReadable(getValue() as string)}
|
||||
</Link>
|
||||
),
|
||||
@@ -29,6 +37,18 @@ export default function PermissionList({permissions}: Props) {
|
||||
columns: defaultColumns,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
});
|
||||
|
||||
const groupedData: { [key: string]: Row<Permission>[] } = table
|
||||
.getRowModel()
|
||||
.rows.reduce((groups: { [key: string]: Row<Permission>[] }, row) => {
|
||||
const parent = row.original.topic;
|
||||
if (!groups[parent]) {
|
||||
groups[parent] = [];
|
||||
}
|
||||
groups[parent].push(row);
|
||||
return groups;
|
||||
}, {});
|
||||
|
||||
return (
|
||||
<div className="w-full">
|
||||
<div className="w-full flex flex-col gap-2">
|
||||
@@ -38,22 +58,45 @@ export default function PermissionList({permissions}: Props) {
|
||||
<tr key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => (
|
||||
<th className="py-4 px-4 text-left" key={header.id}>
|
||||
{header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext()
|
||||
)}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</thead>
|
||||
<tbody className="px-2">
|
||||
{table.getRowModel().rows.map((row) => (
|
||||
<tr className="odd:bg-white even:bg-mti-purple-ultralight/40 rounded-lg py-2" key={row.id}>
|
||||
{Object.keys(groupedData).map((parent) => (
|
||||
<React.Fragment key={parent}>
|
||||
<tr>
|
||||
<td className="px-2 py-2 items-center w-fit">
|
||||
<strong>{parent}</strong>
|
||||
</td>
|
||||
</tr>
|
||||
{groupedData[parent].map((row, i) => (
|
||||
<tr
|
||||
className="odd:bg-white even:bg-mti-purple-ultralight/40 rounded-lg py-2"
|
||||
key={row.id}
|
||||
>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<td className="px-4 py-2 items-center w-fit" key={cell.id}>
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
<td
|
||||
className="px-4 py-2 items-center w-fit"
|
||||
key={cell.id}
|
||||
>
|
||||
{flexRender(
|
||||
cell.column.columnDef.cell,
|
||||
cell.getContext()
|
||||
)}
|
||||
</td>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -1,58 +1,89 @@
|
||||
export const markets = ["au", "br", "de"] as const;
|
||||
export interface PermissionTopic {
|
||||
topic: string;
|
||||
list: string[];
|
||||
}
|
||||
|
||||
export const permissions = [
|
||||
// generate codes are basicly invites
|
||||
"createCodeStudent",
|
||||
"createCodeTeacher",
|
||||
{
|
||||
topic: "Manage Corporate",
|
||||
list: [
|
||||
"viewCorporate",
|
||||
"editCorporate",
|
||||
"deleteCorporate",
|
||||
"createCodeCorporate",
|
||||
],
|
||||
},
|
||||
{
|
||||
topic: "Manage Admin",
|
||||
list: ["viewAdmin", "editAdmin", "deleteAdmin", "createCodeAdmin"],
|
||||
},
|
||||
{
|
||||
topic: "Manage Student",
|
||||
list: ["viewStudent", "editStudent", "deleteStudent", "createCodeStudent"],
|
||||
},
|
||||
{
|
||||
topic: "Manage Teacher",
|
||||
list: ["viewTeacher", "editTeacher", "deleteTeacher", "createCodeTeacher"],
|
||||
},
|
||||
{
|
||||
topic: "Manage Country Manager",
|
||||
list: [
|
||||
"viewCountryManager",
|
||||
"editCountryManager",
|
||||
"deleteCountryManager",
|
||||
"createCodeCountryManager",
|
||||
"createCodeAdmin",
|
||||
// exams
|
||||
],
|
||||
},
|
||||
{
|
||||
topic: "Manage Exams",
|
||||
list: [
|
||||
"createReadingExam",
|
||||
"createListeningExam",
|
||||
"createWritingExam",
|
||||
"createSpeakingExam",
|
||||
"createLevelExam",
|
||||
// view pages
|
||||
],
|
||||
},
|
||||
{
|
||||
topic: "View Pages",
|
||||
list: [
|
||||
"viewExams",
|
||||
"viewExercises",
|
||||
"viewRecords",
|
||||
"viewStats",
|
||||
"viewTickets",
|
||||
"viewPaymentRecords",
|
||||
// view data
|
||||
"viewStudent",
|
||||
"viewTeacher",
|
||||
"viewCorporate",
|
||||
"viewCountryManager",
|
||||
"viewAdmin",
|
||||
"viewGroup",
|
||||
"viewCodes",
|
||||
// edit data
|
||||
"editStudent",
|
||||
"editTeacher",
|
||||
"editCorporate",
|
||||
"editCountryManager",
|
||||
"editAdmin",
|
||||
"editGroup",
|
||||
// delete data
|
||||
"deleteStudent",
|
||||
"deleteTeacher",
|
||||
"deleteCorporate",
|
||||
"deleteCountryManager",
|
||||
"deleteAdmin",
|
||||
"deleteGroup",
|
||||
"deleteCodes",
|
||||
// create options
|
||||
"createGroup",
|
||||
"createCodes",
|
||||
"all",
|
||||
],
|
||||
},
|
||||
{
|
||||
topic: "Manage Group",
|
||||
list: ["viewGroup", "editGroup", "deleteGroup", "createGroup"],
|
||||
},
|
||||
{
|
||||
topic: "Manage Codes",
|
||||
list: ["viewCodes", "deleteCodes", "createCodes"],
|
||||
},
|
||||
{
|
||||
topic: "Others",
|
||||
list: ["all"],
|
||||
},
|
||||
] as const;
|
||||
|
||||
export type PermissionType = (typeof permissions)[keyof typeof permissions];
|
||||
const permissionsList = [
|
||||
...new Set(
|
||||
permissions.reduce(
|
||||
(accm: string[], permission) => [...accm, ...permission.list],
|
||||
[]
|
||||
)
|
||||
),
|
||||
];
|
||||
|
||||
export type PermissionType =
|
||||
(typeof permissionsList)[keyof typeof permissionsList];
|
||||
|
||||
export interface Permission {
|
||||
id: string;
|
||||
type: PermissionType;
|
||||
topic: string;
|
||||
users: string[];
|
||||
}
|
||||
|
||||
@@ -55,9 +55,7 @@ interface Props {
|
||||
}
|
||||
|
||||
export default function Page(props: Props) {
|
||||
|
||||
const { permissions, user } = props;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
|
||||
@@ -16,12 +16,13 @@ import {
|
||||
Permission,
|
||||
PermissionType,
|
||||
permissions,
|
||||
PermissionTopic,
|
||||
} from "@/interfaces/permissions";
|
||||
import { v4 } from "uuid";
|
||||
|
||||
const db = getFirestore(app);
|
||||
|
||||
async function createPermission(type: string) {
|
||||
async function createPermission(topic: string, type: string) {
|
||||
const permData = doc(db, "permissions", v4());
|
||||
const permDoc = await getDoc(permData);
|
||||
if (permDoc.exists()) {
|
||||
@@ -30,9 +31,14 @@ async function createPermission(type: string) {
|
||||
|
||||
await setDoc(permData, {
|
||||
type,
|
||||
topic,
|
||||
users: [],
|
||||
});
|
||||
}
|
||||
interface PermissionsHelperList {
|
||||
topic: string;
|
||||
type: string;
|
||||
}
|
||||
export function getPermissions(userId: string | undefined, docs: Permission[]) {
|
||||
if (!userId) {
|
||||
return [];
|
||||
@@ -52,8 +58,18 @@ export function getPermissions(userId: string | undefined, docs: Permission[]) {
|
||||
}
|
||||
|
||||
export async function bootstrap() {
|
||||
await permissions.forEach(async (type) => {
|
||||
await createPermission(type);
|
||||
await permissions
|
||||
.reduce((accm: PermissionsHelperList[], permissionData) => {
|
||||
return [
|
||||
...accm,
|
||||
...permissionData.list.map((type) => ({
|
||||
topic: permissionData.topic,
|
||||
type,
|
||||
})),
|
||||
];
|
||||
}, [])
|
||||
.forEach(async ({ topic, type }) => {
|
||||
await createPermission(topic, type);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user