Merge branch 'develop' into feature/exam-generation
This commit is contained in:
@@ -2,6 +2,7 @@ import Button from "@/components/Low/Button";
|
||||
import Checkbox from "@/components/Low/Checkbox";
|
||||
import {PERMISSIONS} from "@/constants/userPermissions";
|
||||
import {Type, User} from "@/interfaces/user";
|
||||
import {USER_TYPE_LABELS} from "@/resources/user";
|
||||
import axios from "axios";
|
||||
import clsx from "clsx";
|
||||
import {capitalize} from "lodash";
|
||||
@@ -17,6 +18,7 @@ export default function BatchCodeGenerator({user}: {user: User}) {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [expiryDate, setExpiryDate] = useState<Date | null>(null);
|
||||
const [isExpiryDateEnabled, setIsExpiryDateEnabled] = useState(true);
|
||||
const [type, setType] = useState<Type>("student");
|
||||
|
||||
const {openFilePicker, filesContent} = useFilePicker({
|
||||
accept: ".txt",
|
||||
@@ -108,37 +110,18 @@ export default function BatchCodeGenerator({user}: {user: User}) {
|
||||
)}
|
||||
<label className="font-normal text-base text-mti-gray-dim">Select the type of user they should be</label>
|
||||
{user && (
|
||||
<div className="grid -md:grid-cols-2 md:grid-cols-1 xl:grid-cols-2 gap-4 place-items-center">
|
||||
<Button
|
||||
className="w-44 2xl:w-48"
|
||||
variant="outline"
|
||||
onClick={() => generateCode("student")}
|
||||
disabled={emails.length === 0 || isLoading || !PERMISSIONS.generateCode.student.includes(user.type)}>
|
||||
Student
|
||||
</Button>
|
||||
<Button
|
||||
className="w-44 2xl:w-48"
|
||||
variant="outline"
|
||||
onClick={() => generateCode("teacher")}
|
||||
disabled={emails.length === 0 || isLoading || !PERMISSIONS.generateCode.teacher.includes(user.type)}>
|
||||
Teacher
|
||||
</Button>
|
||||
<Button
|
||||
className="w-44 2xl:w-48"
|
||||
variant="outline"
|
||||
onClick={() => generateCode("corporate")}
|
||||
disabled={emails.length === 0 || isLoading || !PERMISSIONS.generateCode.corporate.includes(user.type)}>
|
||||
Corporate
|
||||
</Button>
|
||||
<Button
|
||||
className="w-44 2xl:w-48"
|
||||
variant="outline"
|
||||
onClick={() => generateCode("admin")}
|
||||
disabled={emails.length === 0 || isLoading || !PERMISSIONS.generateCode.admin.includes(user.type)}>
|
||||
Admin
|
||||
</Button>
|
||||
</div>
|
||||
<select
|
||||
defaultValue="student"
|
||||
onChange={(e) => setType(e.target.value as typeof user.type)}
|
||||
className="p-6 w-full min-w-[350px] min-h-[70px] flex justify-center text-sm font-normal rounded-full border focus:outline-none cursor-pointer bg-white">
|
||||
{Object.keys(USER_TYPE_LABELS).map((type) => (
|
||||
<option key={type} value={type}>
|
||||
{USER_TYPE_LABELS[type as keyof typeof USER_TYPE_LABELS]}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
)}
|
||||
<Button onClick={() => generateCode(type)}>Generate & Send</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import Button from "@/components/Low/Button";
|
||||
import Checkbox from "@/components/Low/Checkbox";
|
||||
import {PERMISSIONS} from "@/constants/userPermissions";
|
||||
import {Type, User} from "@/interfaces/user";
|
||||
import {USER_TYPE_LABELS} from "@/resources/user";
|
||||
import axios from "axios";
|
||||
import clsx from "clsx";
|
||||
import {capitalize} from "lodash";
|
||||
@@ -15,6 +16,7 @@ export default function CodeGenerator({user}: {user: User}) {
|
||||
const [generatedCode, setGeneratedCode] = useState<string>();
|
||||
const [expiryDate, setExpiryDate] = useState<Date | null>(null);
|
||||
const [isExpiryDateEnabled, setIsExpiryDateEnabled] = useState(true);
|
||||
const [type, setType] = useState<Type>("student");
|
||||
|
||||
useEffect(() => {
|
||||
if (user && (user.type === "corporate" || user.type === "teacher")) {
|
||||
@@ -57,36 +59,16 @@ export default function CodeGenerator({user}: {user: User}) {
|
||||
<div className="flex flex-col gap-4 border p-4 border-mti-gray-platinum rounded-xl">
|
||||
<label className="font-normal text-base text-mti-gray-dim">User Code Generator</label>
|
||||
{user && (
|
||||
<div className="grid -md:grid-cols-2 md:grid-cols-1 place-items-center 2xl:grid-cols-2 gap-4">
|
||||
<Button
|
||||
className="w-44 md:w-48"
|
||||
variant="outline"
|
||||
onClick={() => generateCode("student")}
|
||||
disabled={!PERMISSIONS.generateCode.student.includes(user.type) || (isExpiryDateEnabled && expiryDate === null)}>
|
||||
Student
|
||||
</Button>
|
||||
<Button
|
||||
className="w-44 md:w-48"
|
||||
variant="outline"
|
||||
onClick={() => generateCode("teacher")}
|
||||
disabled={!PERMISSIONS.generateCode.teacher.includes(user.type) || (isExpiryDateEnabled && expiryDate === null)}>
|
||||
Teacher
|
||||
</Button>
|
||||
<Button
|
||||
className="w-44 md:w-48"
|
||||
variant="outline"
|
||||
onClick={() => generateCode("corporate")}
|
||||
disabled={!PERMISSIONS.generateCode.corporate.includes(user.type) || (isExpiryDateEnabled && expiryDate === null)}>
|
||||
Corporate
|
||||
</Button>
|
||||
<Button
|
||||
className="w-44 md:w-48"
|
||||
variant="outline"
|
||||
onClick={() => generateCode("admin")}
|
||||
disabled={!PERMISSIONS.generateCode.admin.includes(user.type) || (isExpiryDateEnabled && expiryDate === null)}>
|
||||
Admin
|
||||
</Button>
|
||||
</div>
|
||||
<select
|
||||
defaultValue="student"
|
||||
onChange={(e) => setType(e.target.value as typeof user.type)}
|
||||
className="p-6 w-full min-w-[350px] min-h-[70px] flex justify-center text-sm font-normal rounded-full border focus:outline-none cursor-pointer bg-white">
|
||||
{Object.keys(USER_TYPE_LABELS).map((type) => (
|
||||
<option key={type} value={type}>
|
||||
{USER_TYPE_LABELS[type as keyof typeof USER_TYPE_LABELS]}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
)}
|
||||
{user && (user.type === "developer" || user.type === "admin") && (
|
||||
<>
|
||||
@@ -111,6 +93,7 @@ export default function CodeGenerator({user}: {user: User}) {
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<Button onClick={() => generateCode(type)}>Generate</Button>
|
||||
<label className="font-normal text-base text-mti-gray-dim">Generated Code:</label>
|
||||
<div
|
||||
className={clsx(
|
||||
|
||||
@@ -16,6 +16,7 @@ import {countries, TCountries} from "countries-list";
|
||||
import countryCodes from "country-codes-list";
|
||||
import Modal from "@/components/Modal";
|
||||
import UserCard from "@/components/UserCard";
|
||||
import {USER_TYPE_LABELS} from "@/resources/user";
|
||||
|
||||
const columnHelper = createColumnHelper<User>();
|
||||
|
||||
@@ -159,7 +160,7 @@ export default function UserList({user, filter}: {user: User; filter?: (user: Us
|
||||
onClick={() => updateAccountType(row.original, "corporate")}
|
||||
className="text-sm !py-2 !px-4"
|
||||
disabled={row.original.type === "corporate" || !PERMISSIONS.generateCode["corporate"].includes(user.type)}>
|
||||
Admin
|
||||
Corporate
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => updateAccountType(row.original, "admin")}
|
||||
@@ -316,7 +317,7 @@ export default function UserList({user, filter}: {user: User; filter?: (user: Us
|
||||
<SorterArrow name="type" />
|
||||
</button>
|
||||
) as any,
|
||||
cell: (info) => capitalize(info.getValue()),
|
||||
cell: (info) => USER_TYPE_LABELS[info.getValue()],
|
||||
}),
|
||||
columnHelper.accessor("subscriptionExpirationDate", {
|
||||
header: (
|
||||
|
||||
@@ -68,8 +68,6 @@ export default function RegisterCorporate({isLoading, setIsLoading, mutateUser,
|
||||
userAmount: companyUsers,
|
||||
},
|
||||
referralAgent,
|
||||
allowedUserAmount: companyUsers,
|
||||
monthlyDuration: subscriptionDuration,
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
|
||||
@@ -67,6 +67,7 @@ async function registerIndividual(req: NextApiRequest, res: NextApiResponse) {
|
||||
type: codeData.type,
|
||||
subscriptionExpirationDate: codeData.expiryDate,
|
||||
registrationDate: new Date(),
|
||||
status: code ? "active" : "paymentDue",
|
||||
};
|
||||
|
||||
await setDoc(doc(db, "users", userId), user);
|
||||
|
||||
@@ -26,6 +26,7 @@ import StudentDashboard from "@/dashboards/Student";
|
||||
import AdminDashboard from "@/dashboards/Admin";
|
||||
import CorporateDashboard from "@/dashboards/Corporate";
|
||||
import TeacherDashboard from "@/dashboards/Teacher";
|
||||
import AgentDashboard from "@/dashboards/Agent";
|
||||
|
||||
export const getServerSideProps = withIronSessionSsr(({req, res}) => {
|
||||
const user = req.session.user;
|
||||
@@ -166,6 +167,7 @@ export default function Home() {
|
||||
{user.type === "student" && <StudentDashboard user={user} />}
|
||||
{user.type === "teacher" && <TeacherDashboard user={user} />}
|
||||
{user.type === "corporate" && <CorporateDashboard user={user} />}
|
||||
{user.type === "agent" && <AgentDashboard user={user} />}
|
||||
{user.type === "admin" && <AdminDashboard user={user} />}
|
||||
{user.type === "developer" && <AdminDashboard user={user} />}
|
||||
</Layout>
|
||||
|
||||
@@ -50,7 +50,7 @@ export default function Admin() {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Management Panel | EnCoach</title>
|
||||
<title>Settings Panel | EnCoach</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="A training platform for the IELTS exam provided by the Muscat Training Institute and developed by eCrop."
|
||||
Reference in New Issue
Block a user