Implemented a simple page to view the currently registered users
This commit is contained in:
@@ -110,13 +110,20 @@ export default function FillBlanks({id, allowRepetition, prompt, solutions, text
|
|||||||
setCurrentBlankId(undefined);
|
setCurrentBlankId(undefined);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<span className="text-lg font-medium text-center px-48">{prompt}</span>
|
<span className="text-lg font-medium text-center px-48">
|
||||||
|
{prompt.split("\\n").map((line, index) => (
|
||||||
|
<Fragment key={index}>
|
||||||
|
{line}
|
||||||
|
<br />
|
||||||
|
</Fragment>
|
||||||
|
))}
|
||||||
|
</span>
|
||||||
<span>
|
<span>
|
||||||
{text.split("\n").map((line) => (
|
{text.split("\\n").map((line, index) => (
|
||||||
<>
|
<Fragment key={index}>
|
||||||
{renderLines(line)}
|
{renderLines(line)}
|
||||||
<br />
|
<br />
|
||||||
</>
|
</Fragment>
|
||||||
))}
|
))}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ export default function WriteBlanks({id, prompt, maxWords, solutions, text, onNe
|
|||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<span className="text-lg font-medium text-center px-48">{prompt}</span>
|
<span className="text-lg font-medium text-center px-48">{prompt}</span>
|
||||||
<span>
|
<span>
|
||||||
{text.split("\n").map((line) => (
|
{text.split("\\n").map((line) => (
|
||||||
<>
|
<>
|
||||||
{renderLines(line)}
|
{renderLines(line)}
|
||||||
<br />
|
<br />
|
||||||
|
|||||||
@@ -35,10 +35,9 @@ export default function Navbar({profilePicture}: Props) {
|
|||||||
</label>
|
</label>
|
||||||
<ul tabIndex={0} className="mt-3 p-2 shadow menu menu-compact dropdown-content bg-base-100 rounded-box w-52">
|
<ul tabIndex={0} className="mt-3 p-2 shadow menu menu-compact dropdown-content bg-base-100 rounded-box w-52">
|
||||||
<li>
|
<li>
|
||||||
<a className="justify-between">
|
<Link href="/profile" className="justify-between">
|
||||||
Profile
|
Profile
|
||||||
<span className="badge">New</span>
|
</Link>
|
||||||
</a>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a>Settings</a>
|
<a>Settings</a>
|
||||||
|
|||||||
@@ -17,9 +17,7 @@ export default function ProfileCard({user, className}: Props) {
|
|||||||
<img src={user.profilePicture} alt="Profile picture" className="rounded-full" />
|
<img src={user.profilePicture} alt="Profile picture" className="rounded-full" />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col justify-center">
|
<div className="flex flex-col justify-center">
|
||||||
<span className="text-neutral-600 font-bold text-2xl">
|
<span className="text-neutral-600 font-bold text-2xl">{user.name}</span>
|
||||||
{user.name.first} {user.name.last}
|
|
||||||
</span>
|
|
||||||
<LevelLabel experience={user.experience} />
|
<LevelLabel experience={user.experience} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export default function FillBlanksSolutions({prompt, solutions, text, userSoluti
|
|||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<span className="text-lg font-medium text-center px-48">{prompt}</span>
|
<span className="text-lg font-medium text-center px-48">{prompt}</span>
|
||||||
<span>
|
<span>
|
||||||
{text.split("\n").map((line) => (
|
{text.split("\\n").map((line) => (
|
||||||
<>
|
<>
|
||||||
{renderLines(line)}
|
{renderLines(line)}
|
||||||
<br />
|
<br />
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ export default function WriteBlanksSolutions({
|
|||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<span className="text-lg font-medium text-center px-48">{prompt}</span>
|
<span className="text-lg font-medium text-center px-48">{prompt}</span>
|
||||||
<span>
|
<span>
|
||||||
{text.split("\n").map((line) => (
|
{text.split("\\n").map((line) => (
|
||||||
<>
|
<>
|
||||||
{renderLines(line)}
|
{renderLines(line)}
|
||||||
<br />
|
<br />
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import {infoButtonStyle} from "@/constants/buttonStyles";
|
|||||||
import {Dialog, Transition} from "@headlessui/react";
|
import {Dialog, Transition} from "@headlessui/react";
|
||||||
import {renderExercise} from "@/components/Exercises";
|
import {renderExercise} from "@/components/Exercises";
|
||||||
import {renderSolution} from "@/components/Solutions";
|
import {renderSolution} from "@/components/Solutions";
|
||||||
|
import {Panel} from "primereact/panel";
|
||||||
|
import {Steps} from "primereact/steps";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
exam: ReadingExam;
|
exam: ReadingExam;
|
||||||
@@ -45,7 +47,7 @@ function TextModal({isOpen, title, content, onClose}: {isOpen: boolean; title: s
|
|||||||
</Dialog.Title>
|
</Dialog.Title>
|
||||||
<div className="mt-2 overflow-auto">
|
<div className="mt-2 overflow-auto">
|
||||||
<p className="text-sm text-gray-500">
|
<p className="text-sm text-gray-500">
|
||||||
{content.split("\n").map((line, index) => (
|
{content.split("\\n").map((line, index) => (
|
||||||
<Fragment key={index}>
|
<Fragment key={index}>
|
||||||
{line}
|
{line}
|
||||||
<br />
|
<br />
|
||||||
@@ -115,17 +117,13 @@ export default function Reading({exam, showSolutions = false, onFinish}: Props)
|
|||||||
</span>
|
</span>
|
||||||
<span className="self-end text-sm">You will be allowed to read the text while doing the exercises</span>
|
<span className="self-end text-sm">You will be allowed to read the text while doing the exercises</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="bg-gray-300 rounded-xl p-4 flex flex-col gap-4 items-center w-full overflow-auto">
|
<Panel header={exam.text.title}>
|
||||||
<span className="text-xl font-semibold">{exam.text.title}</span>
|
<p>
|
||||||
<span>
|
{exam.text.content.split("\\n").map((line, index) => (
|
||||||
{exam.text.content.split("\n").map((line, index) => (
|
<p key={index}>{line}</p>
|
||||||
<Fragment key={index}>
|
|
||||||
<span>{line}</span>
|
|
||||||
<br />
|
|
||||||
</Fragment>
|
|
||||||
))}
|
))}
|
||||||
</span>
|
</p>
|
||||||
</div>
|
</Panel>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export default function Writing({exam, showSolutions = false, onFinish}: Props)
|
|||||||
<div className="flex flex-col max-w-2xl gap-2">
|
<div className="flex flex-col max-w-2xl gap-2">
|
||||||
<span>{exam.text.info}</span>
|
<span>{exam.text.info}</span>
|
||||||
<span className="font-bold ml-8">
|
<span className="font-bold ml-8">
|
||||||
{exam.text.prompt.split("\n").map((line, index) => (
|
{exam.text.prompt.split("\\n").map((line, index) => (
|
||||||
<Fragment key={index}>
|
<Fragment key={index}>
|
||||||
<span>{line}</span>
|
<span>{line}</span>
|
||||||
<br />
|
<br />
|
||||||
|
|||||||
19
src/hooks/useUsers.tsx
Normal file
19
src/hooks/useUsers.tsx
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import {User} from "@/interfaces/user";
|
||||||
|
import axios from "axios";
|
||||||
|
import {useEffect, useState} from "react";
|
||||||
|
|
||||||
|
export default function useUsers() {
|
||||||
|
const [users, setUsers] = useState<User[]>([]);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [isError, setIsError] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setIsLoading(true);
|
||||||
|
axios
|
||||||
|
.get<User[]>("/api/users/list")
|
||||||
|
.then((response) => setUsers(response.data))
|
||||||
|
.finally(() => setIsLoading(false));
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return {users, isLoading, isError};
|
||||||
|
}
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
export interface User {
|
export interface User {
|
||||||
email: string;
|
email: string;
|
||||||
name: Name;
|
name: string;
|
||||||
profilePicture: string;
|
profilePicture: string;
|
||||||
id: string;
|
id: string;
|
||||||
experience: number;
|
experience: number;
|
||||||
|
type: Type;
|
||||||
}
|
}
|
||||||
interface Name {
|
|
||||||
first: string;
|
export type Type = "student" | "teacher" | "admin" | "owner" | "developer";
|
||||||
last: string;
|
|
||||||
}
|
|
||||||
|
|||||||
26
src/pages/api/users/list.ts
Normal file
26
src/pages/api/users/list.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
|
||||||
|
import type {NextApiRequest, NextApiResponse} from "next";
|
||||||
|
import {app} from "@/firebase";
|
||||||
|
import {getFirestore, collection, getDocs} from "firebase/firestore";
|
||||||
|
import {withIronSessionApiRoute} from "iron-session/next";
|
||||||
|
import {sessionOptions} from "@/lib/session";
|
||||||
|
|
||||||
|
const db = getFirestore(app);
|
||||||
|
|
||||||
|
export default withIronSessionApiRoute(handler, sessionOptions);
|
||||||
|
|
||||||
|
async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
|
if (!req.session.user) {
|
||||||
|
res.status(401).json({ok: false});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const snapshot = await getDocs(collection(db, "users"));
|
||||||
|
|
||||||
|
res.status(200).json(
|
||||||
|
snapshot.docs.map((doc) => ({
|
||||||
|
id: doc.id,
|
||||||
|
...doc.data(),
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -133,7 +133,7 @@ export default function Page({user}: {user: User}) {
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<link rel="icon" href="/favicon.ico" />
|
<link rel="icon" href="/favicon.ico" />
|
||||||
</Head>
|
</Head>
|
||||||
<main className="w-full h-screen flex flex-col items-center bg-neutral-100 text-black">
|
<main className="w-full h-screen flex flex-col items-center bg-white text-black">
|
||||||
<ToastContainer />
|
<ToastContainer />
|
||||||
<Navbar profilePicture={user.profilePicture} />
|
<Navbar profilePicture={user.profilePicture} />
|
||||||
{renderScreen()}
|
{renderScreen()}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import Head from "next/head";
|
|||||||
import useUser from "@/hooks/useUser";
|
import useUser from "@/hooks/useUser";
|
||||||
import {InputText} from "primereact/inputtext";
|
import {InputText} from "primereact/inputtext";
|
||||||
import {Button} from "primereact/button";
|
import {Button} from "primereact/button";
|
||||||
|
import {Password} from "primereact/password";
|
||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
const [email, setEmail] = useState("");
|
const [email, setEmail] = useState("");
|
||||||
@@ -65,10 +66,11 @@ export default function Login() {
|
|||||||
<span className="p-inputgroup-addon">
|
<span className="p-inputgroup-addon">
|
||||||
<i className="pi pi-star"></i>
|
<i className="pi pi-star"></i>
|
||||||
</span>
|
</span>
|
||||||
<InputText
|
<Password
|
||||||
placeholder="Password..."
|
placeholder="Password..."
|
||||||
type="password"
|
type="password"
|
||||||
required
|
required
|
||||||
|
feedback={false}
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
onChange={(e) => setPassword(e.target.value)}
|
onChange={(e) => setPassword(e.target.value)}
|
||||||
autoComplete="current-password"
|
autoComplete="current-password"
|
||||||
|
|||||||
49
src/pages/profile.tsx
Normal file
49
src/pages/profile.tsx
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import {withIronSessionSsr} from "iron-session/next";
|
||||||
|
import {sessionOptions} from "@/lib/session";
|
||||||
|
import {User} from "@/interfaces/user";
|
||||||
|
import Head from "next/head";
|
||||||
|
import Navbar from "@/components/Navbar";
|
||||||
|
import {Avatar} from "primereact/avatar";
|
||||||
|
|
||||||
|
export const getServerSideProps = withIronSessionSsr(({req, res}) => {
|
||||||
|
const user = req.session.user;
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
res.setHeader("location", "/login");
|
||||||
|
res.statusCode = 302;
|
||||||
|
res.end();
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
user: null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
props: {user: req.session.user},
|
||||||
|
};
|
||||||
|
}, sessionOptions);
|
||||||
|
|
||||||
|
export default function Profile({user}: {user: User}) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Head>
|
||||||
|
<title>IELTS GPT | Profile</title>
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="A training platform for the IELTS exam provided by the Muscat Training Institute and developed by eCrop."
|
||||||
|
/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
</Head>
|
||||||
|
<main className="w-full h-screen flex flex-col items-center bg-neutral-100">
|
||||||
|
<Navbar profilePicture={user.profilePicture} />
|
||||||
|
<div className="w-full h-full flex flex-col items-center justify-center p-4 relative">
|
||||||
|
<section className="bg-white drop-shadow-xl p-4 rounded-xl w-96 flex flex-col items-center">
|
||||||
|
<Avatar image={user.profilePicture} size="xlarge" shape="circle" />
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
103
src/pages/users.tsx
Normal file
103
src/pages/users.tsx
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
import {withIronSessionSsr} from "iron-session/next";
|
||||||
|
import {sessionOptions} from "@/lib/session";
|
||||||
|
import {Type, User} from "@/interfaces/user";
|
||||||
|
import Head from "next/head";
|
||||||
|
import Navbar from "@/components/Navbar";
|
||||||
|
import {Avatar} from "primereact/avatar";
|
||||||
|
import {useEffect, useState} from "react";
|
||||||
|
import {FilterMatchMode, FilterOperator} from "primereact/api";
|
||||||
|
import useUsers from "@/hooks/useUsers";
|
||||||
|
import {DataTable} from "primereact/datatable";
|
||||||
|
import {Column} from "primereact/column";
|
||||||
|
import _ from "lodash";
|
||||||
|
import {levelCalculator} from "@/resources/level";
|
||||||
|
import {Dropdown} from "primereact/dropdown";
|
||||||
|
|
||||||
|
export const getServerSideProps = withIronSessionSsr(({req, res}) => {
|
||||||
|
const user = req.session.user;
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
res.setHeader("location", "/login");
|
||||||
|
res.statusCode = 302;
|
||||||
|
res.end();
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
user: null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
props: {user: req.session.user},
|
||||||
|
};
|
||||||
|
}, sessionOptions);
|
||||||
|
|
||||||
|
export default function Users({user}: {user: User}) {
|
||||||
|
const {users, isLoading} = useUsers();
|
||||||
|
const [filters] = useState({
|
||||||
|
name: {value: null, matchMode: FilterMatchMode.CONTAINS},
|
||||||
|
type: {value: null, matchMode: FilterMatchMode.EQUALS},
|
||||||
|
});
|
||||||
|
|
||||||
|
const userTypes: Type[] = ["admin", "developer", "owner", "student", "teacher"];
|
||||||
|
|
||||||
|
const typeRowFilterTemplate = (options: any) => {
|
||||||
|
return (
|
||||||
|
<Dropdown
|
||||||
|
value={options.value}
|
||||||
|
options={userTypes.map((x) => _.capitalize(x))}
|
||||||
|
onChange={(e) => options.filterApplyCallback(e.value)}
|
||||||
|
placeholder="Select One"
|
||||||
|
className="p-column-filter"
|
||||||
|
showClear
|
||||||
|
style={{minWidth: "12rem"}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Head>
|
||||||
|
<title>IELTS GPT | Profile</title>
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="A training platform for the IELTS exam provided by the Muscat Training Institute and developed by eCrop."
|
||||||
|
/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
</Head>
|
||||||
|
<main className="w-full h-screen flex flex-col items-center bg-neutral-100">
|
||||||
|
<Navbar profilePicture={user.profilePicture} />
|
||||||
|
<div className="w-full h-full flex flex-col items-center justify-center p-4 relative">
|
||||||
|
<DataTable
|
||||||
|
dataKey="id"
|
||||||
|
filters={filters}
|
||||||
|
filterDisplay="row"
|
||||||
|
className="w-full h-full"
|
||||||
|
loading={isLoading}
|
||||||
|
value={users}
|
||||||
|
removableSort
|
||||||
|
stripedRows
|
||||||
|
paginator
|
||||||
|
rows={5}
|
||||||
|
rowsPerPageOptions={[5, 10, 25, 50]}
|
||||||
|
tableStyle={{minWidth: "50rem"}}>
|
||||||
|
<Column field="id" sortable header="ID" />
|
||||||
|
<Column field="name" sortable header="Name" filter filterPlaceholder="Search by name" />
|
||||||
|
<Column field="experience" sortable header="Experience" />
|
||||||
|
<Column field="experience" sortable header="Level" body={(data: User) => levelCalculator(data.experience).currentLevel} />
|
||||||
|
<Column
|
||||||
|
field="type"
|
||||||
|
showFilterMenu={false}
|
||||||
|
filter
|
||||||
|
filterElement={typeRowFilterTemplate}
|
||||||
|
sortable
|
||||||
|
header="Type"
|
||||||
|
body={(data: User) => _.capitalize(data.type)}
|
||||||
|
/>
|
||||||
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
201
src/resources/permissions.ts
Normal file
201
src/resources/permissions.ts
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
import {Type, User} from "@/interfaces/user";
|
||||||
|
|
||||||
|
interface Permissions {
|
||||||
|
createUser: {[key in Type]: boolean};
|
||||||
|
deleteUser: {[key in Type]: boolean};
|
||||||
|
manageUser: {[key in Type]: boolean};
|
||||||
|
viewUsers: {[key in Type]: boolean};
|
||||||
|
viewStats: boolean;
|
||||||
|
viewUserStats: boolean;
|
||||||
|
viewClassStats: boolean;
|
||||||
|
createClass: boolean;
|
||||||
|
manageClass: boolean;
|
||||||
|
deleteClass: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const permissions: {[key in Type]: Permissions} = {
|
||||||
|
student: {
|
||||||
|
createUser: {
|
||||||
|
admin: false,
|
||||||
|
developer: false,
|
||||||
|
owner: false,
|
||||||
|
student: false,
|
||||||
|
teacher: false,
|
||||||
|
},
|
||||||
|
deleteUser: {
|
||||||
|
admin: false,
|
||||||
|
developer: false,
|
||||||
|
owner: false,
|
||||||
|
student: false,
|
||||||
|
teacher: false,
|
||||||
|
},
|
||||||
|
manageUser: {
|
||||||
|
admin: false,
|
||||||
|
developer: false,
|
||||||
|
owner: false,
|
||||||
|
student: false,
|
||||||
|
teacher: false,
|
||||||
|
},
|
||||||
|
viewUsers: {
|
||||||
|
admin: false,
|
||||||
|
developer: false,
|
||||||
|
owner: false,
|
||||||
|
student: false,
|
||||||
|
teacher: false,
|
||||||
|
},
|
||||||
|
createClass: false,
|
||||||
|
deleteClass: false,
|
||||||
|
manageClass: false,
|
||||||
|
viewStats: true,
|
||||||
|
viewUserStats: false,
|
||||||
|
viewClassStats: false,
|
||||||
|
},
|
||||||
|
teacher: {
|
||||||
|
createUser: {
|
||||||
|
admin: false,
|
||||||
|
developer: false,
|
||||||
|
owner: false,
|
||||||
|
student: true,
|
||||||
|
teacher: false,
|
||||||
|
},
|
||||||
|
deleteUser: {
|
||||||
|
admin: false,
|
||||||
|
developer: false,
|
||||||
|
owner: false,
|
||||||
|
student: true,
|
||||||
|
teacher: false,
|
||||||
|
},
|
||||||
|
manageUser: {
|
||||||
|
admin: false,
|
||||||
|
developer: false,
|
||||||
|
owner: false,
|
||||||
|
student: true,
|
||||||
|
teacher: false,
|
||||||
|
},
|
||||||
|
viewUsers: {
|
||||||
|
admin: false,
|
||||||
|
developer: false,
|
||||||
|
owner: false,
|
||||||
|
student: true,
|
||||||
|
teacher: false,
|
||||||
|
},
|
||||||
|
createClass: true,
|
||||||
|
deleteClass: true,
|
||||||
|
manageClass: true,
|
||||||
|
viewStats: true,
|
||||||
|
viewUserStats: true,
|
||||||
|
viewClassStats: true,
|
||||||
|
},
|
||||||
|
admin: {
|
||||||
|
createUser: {
|
||||||
|
admin: false,
|
||||||
|
developer: false,
|
||||||
|
owner: false,
|
||||||
|
student: true,
|
||||||
|
teacher: true,
|
||||||
|
},
|
||||||
|
deleteUser: {
|
||||||
|
admin: false,
|
||||||
|
developer: false,
|
||||||
|
owner: false,
|
||||||
|
student: true,
|
||||||
|
teacher: true,
|
||||||
|
},
|
||||||
|
manageUser: {
|
||||||
|
admin: false,
|
||||||
|
developer: false,
|
||||||
|
owner: false,
|
||||||
|
student: true,
|
||||||
|
teacher: true,
|
||||||
|
},
|
||||||
|
viewUsers: {
|
||||||
|
admin: false,
|
||||||
|
developer: false,
|
||||||
|
owner: false,
|
||||||
|
student: true,
|
||||||
|
teacher: true,
|
||||||
|
},
|
||||||
|
createClass: true,
|
||||||
|
deleteClass: true,
|
||||||
|
manageClass: true,
|
||||||
|
viewStats: true,
|
||||||
|
viewUserStats: true,
|
||||||
|
viewClassStats: true,
|
||||||
|
},
|
||||||
|
owner: {
|
||||||
|
createUser: {
|
||||||
|
admin: true,
|
||||||
|
developer: false,
|
||||||
|
owner: false,
|
||||||
|
student: true,
|
||||||
|
teacher: true,
|
||||||
|
},
|
||||||
|
deleteUser: {
|
||||||
|
admin: true,
|
||||||
|
developer: false,
|
||||||
|
owner: false,
|
||||||
|
student: true,
|
||||||
|
teacher: true,
|
||||||
|
},
|
||||||
|
manageUser: {
|
||||||
|
admin: true,
|
||||||
|
developer: false,
|
||||||
|
owner: false,
|
||||||
|
student: true,
|
||||||
|
teacher: true,
|
||||||
|
},
|
||||||
|
viewUsers: {
|
||||||
|
admin: true,
|
||||||
|
developer: false,
|
||||||
|
owner: false,
|
||||||
|
student: true,
|
||||||
|
teacher: true,
|
||||||
|
},
|
||||||
|
createClass: true,
|
||||||
|
deleteClass: true,
|
||||||
|
manageClass: true,
|
||||||
|
viewStats: true,
|
||||||
|
viewUserStats: true,
|
||||||
|
viewClassStats: true,
|
||||||
|
},
|
||||||
|
developer: {
|
||||||
|
createUser: {
|
||||||
|
admin: true,
|
||||||
|
developer: true,
|
||||||
|
owner: true,
|
||||||
|
student: true,
|
||||||
|
teacher: true,
|
||||||
|
},
|
||||||
|
deleteUser: {
|
||||||
|
admin: true,
|
||||||
|
developer: true,
|
||||||
|
owner: true,
|
||||||
|
student: true,
|
||||||
|
teacher: true,
|
||||||
|
},
|
||||||
|
manageUser: {
|
||||||
|
admin: true,
|
||||||
|
developer: true,
|
||||||
|
owner: true,
|
||||||
|
student: true,
|
||||||
|
teacher: true,
|
||||||
|
},
|
||||||
|
viewUsers: {
|
||||||
|
admin: true,
|
||||||
|
developer: true,
|
||||||
|
owner: true,
|
||||||
|
student: true,
|
||||||
|
teacher: true,
|
||||||
|
},
|
||||||
|
createClass: true,
|
||||||
|
deleteClass: true,
|
||||||
|
manageClass: true,
|
||||||
|
viewStats: true,
|
||||||
|
viewUserStats: true,
|
||||||
|
viewClassStats: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function getPermissions(user: User) {
|
||||||
|
return permissions[user.type];
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user