Added the ability to view how many students and teachers an admin has
This commit is contained in:
@@ -24,7 +24,12 @@ const expirationDateColor = (date: Date) => {
|
|||||||
if (today.add(7, "days").isAfter(momentDate)) return "!bg-mti-orange-ultralight border-mti-orange-light";
|
if (today.add(7, "days").isAfter(momentDate)) return "!bg-mti-orange-ultralight border-mti-orange-light";
|
||||||
};
|
};
|
||||||
|
|
||||||
const UserCard = ({onClose, ...user}: User & {onClose: (reload?: boolean) => void}) => {
|
const UserCard = ({
|
||||||
|
onClose,
|
||||||
|
onViewStudents,
|
||||||
|
onViewTeachers,
|
||||||
|
...user
|
||||||
|
}: User & {onClose: (reload?: boolean) => void; onViewStudents?: () => void; onViewTeachers?: () => void}) => {
|
||||||
const [expiryDate, setExpiryDate] = useState<Date | null | undefined>(user.subscriptionExpirationDate);
|
const [expiryDate, setExpiryDate] = useState<Date | null | undefined>(user.subscriptionExpirationDate);
|
||||||
const {stats} = useStats(user.id);
|
const {stats} = useStats(user.id);
|
||||||
|
|
||||||
@@ -215,13 +220,27 @@ const UserCard = ({onClose, ...user}: User & {onClose: (reload?: boolean) => voi
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<div className="flex gap-4 justify-end mt-4 w-full">
|
<div className="flex gap-4 justify-between mt-4 w-full">
|
||||||
<Button className="w-full max-w-[200px]" variant="outline" onClick={onClose}>
|
<div className="self-start flex gap-4 justify-start items-center w-full">
|
||||||
Close
|
{onViewStudents && (
|
||||||
</Button>
|
<Button className="w-full max-w-[200px]" variant="outline" color="rose" onClick={onViewStudents}>
|
||||||
<Button onClick={updateUser} className="w-full max-w-[200px]">
|
View Students
|
||||||
Update
|
</Button>
|
||||||
</Button>
|
)}
|
||||||
|
{onViewTeachers && (
|
||||||
|
<Button className="w-full max-w-[200px]" variant="outline" color="rose" onClick={onViewTeachers}>
|
||||||
|
View Teachers
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="self-end flex gap-4 w-full justify-end">
|
||||||
|
<Button className="w-full max-w-[200px]" variant="outline" onClick={onClose}>
|
||||||
|
Close
|
||||||
|
</Button>
|
||||||
|
<Button onClick={updateUser} className="w-full max-w-[200px]">
|
||||||
|
Update
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -6,9 +6,10 @@ import {User} from "@/interfaces/user";
|
|||||||
import UserList from "@/pages/(admin)/Lists/UserList";
|
import UserList from "@/pages/(admin)/Lists/UserList";
|
||||||
import {dateSorter} from "@/utils";
|
import {dateSorter} from "@/utils";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import {useState} from "react";
|
import {useEffect, useState} from "react";
|
||||||
import {BsArrowLeft, BsGlobeCentralSouthAsia, BsPerson, BsPersonFill, BsPersonFillGear, BsPersonGear, BsPersonLinesFill} from "react-icons/bs";
|
import {BsArrowLeft, BsGlobeCentralSouthAsia, BsPerson, BsPersonFill, BsPersonFillGear, BsPersonGear, BsPersonLinesFill} from "react-icons/bs";
|
||||||
import UserCard from "@/components/UserCard";
|
import UserCard from "@/components/UserCard";
|
||||||
|
import useGroups from "@/hooks/useGroups";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
user: User;
|
user: User;
|
||||||
@@ -17,9 +18,15 @@ interface Props {
|
|||||||
export default function OwnerDashboard({user}: Props) {
|
export default function OwnerDashboard({user}: Props) {
|
||||||
const [page, setPage] = useState("");
|
const [page, setPage] = useState("");
|
||||||
const [selectedUser, setSelectedUser] = useState<User>();
|
const [selectedUser, setSelectedUser] = useState<User>();
|
||||||
|
const [showModal, setShowModal] = useState(false);
|
||||||
|
|
||||||
const {stats} = useStats(user.id);
|
const {stats} = useStats(user.id);
|
||||||
const {users, reload} = useUsers();
|
const {users, reload} = useUsers();
|
||||||
|
const {groups} = useGroups();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setShowModal(!!selectedUser && page === "");
|
||||||
|
}, [selectedUser, page]);
|
||||||
|
|
||||||
const UserDisplay = (displayUser: User) => (
|
const UserDisplay = (displayUser: User) => (
|
||||||
<div
|
<div
|
||||||
@@ -42,10 +49,36 @@ export default function OwnerDashboard({user}: Props) {
|
|||||||
<BsArrowLeft className="text-xl" />
|
<BsArrowLeft className="text-xl" />
|
||||||
<span>Back</span>
|
<span>Back</span>
|
||||||
</div>
|
</div>
|
||||||
<h2 className="text-2xl font-semibold">Students</h2>
|
<h2 className="text-2xl font-semibold">
|
||||||
|
Students (
|
||||||
|
{
|
||||||
|
users.filter(
|
||||||
|
(x) =>
|
||||||
|
x.type === "student" &&
|
||||||
|
(!!selectedUser
|
||||||
|
? groups
|
||||||
|
.filter((g) => g.admin === selectedUser.id)
|
||||||
|
.flatMap((g) => g.participants)
|
||||||
|
.includes(x.id) || false
|
||||||
|
: true),
|
||||||
|
).length
|
||||||
|
}
|
||||||
|
)
|
||||||
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<UserList user={user} filter={(x) => x.type === "student"} />
|
<UserList
|
||||||
|
user={user}
|
||||||
|
filter={(x) =>
|
||||||
|
x.type === "student" &&
|
||||||
|
(!!selectedUser
|
||||||
|
? groups
|
||||||
|
.filter((g) => g.admin === selectedUser.id)
|
||||||
|
.flatMap((g) => g.participants)
|
||||||
|
.includes(x.id) || false
|
||||||
|
: true)
|
||||||
|
}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -58,10 +91,36 @@ export default function OwnerDashboard({user}: Props) {
|
|||||||
<BsArrowLeft className="text-xl" />
|
<BsArrowLeft className="text-xl" />
|
||||||
<span>Back</span>
|
<span>Back</span>
|
||||||
</div>
|
</div>
|
||||||
<h2 className="text-2xl font-semibold">Teachers</h2>
|
<h2 className="text-2xl font-semibold">
|
||||||
|
Teachers (
|
||||||
|
{
|
||||||
|
users.filter(
|
||||||
|
(x) =>
|
||||||
|
x.type === "teacher" &&
|
||||||
|
(!!selectedUser
|
||||||
|
? groups
|
||||||
|
.filter((g) => g.admin === selectedUser.id)
|
||||||
|
.flatMap((g) => g.participants)
|
||||||
|
.includes(x.id) || false
|
||||||
|
: true),
|
||||||
|
).length
|
||||||
|
}
|
||||||
|
)
|
||||||
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<UserList user={user} filter={(x) => x.type === "teacher"} />
|
<UserList
|
||||||
|
user={user}
|
||||||
|
filter={(x) =>
|
||||||
|
x.type === "teacher" &&
|
||||||
|
(!!selectedUser
|
||||||
|
? groups
|
||||||
|
.filter((g) => g.admin === selectedUser.id)
|
||||||
|
.flatMap((g) => g.participants)
|
||||||
|
.includes(x.id) || false
|
||||||
|
: true)
|
||||||
|
}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -74,7 +133,7 @@ export default function OwnerDashboard({user}: Props) {
|
|||||||
<BsArrowLeft className="text-xl" />
|
<BsArrowLeft className="text-xl" />
|
||||||
<span>Back</span>
|
<span>Back</span>
|
||||||
</div>
|
</div>
|
||||||
<h2 className="text-2xl font-semibold">Corporate</h2>
|
<h2 className="text-2xl font-semibold">Corporate ({users.filter((x) => x.type === "admin").length})</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<UserList user={user} filter={(x) => x.type === "admin"} />
|
<UserList user={user} filter={(x) => x.type === "admin"} />
|
||||||
@@ -90,7 +149,10 @@ export default function OwnerDashboard({user}: Props) {
|
|||||||
<BsArrowLeft className="text-xl" />
|
<BsArrowLeft className="text-xl" />
|
||||||
<span>Back</span>
|
<span>Back</span>
|
||||||
</div>
|
</div>
|
||||||
<h2 className="text-2xl font-semibold">Inactive Students</h2>
|
<h2 className="text-2xl font-semibold">
|
||||||
|
Inactive Students (
|
||||||
|
{users.filter((x) => x.type === "student" && (x.isDisabled || moment().isAfter(x.subscriptionExpirationDate))).length})
|
||||||
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<UserList user={user} filter={(x) => x.type === "student" && (x.isDisabled || moment().isAfter(x.subscriptionExpirationDate))} />
|
<UserList user={user} filter={(x) => x.type === "student" && (x.isDisabled || moment().isAfter(x.subscriptionExpirationDate))} />
|
||||||
@@ -106,7 +168,10 @@ export default function OwnerDashboard({user}: Props) {
|
|||||||
<BsArrowLeft className="text-xl" />
|
<BsArrowLeft className="text-xl" />
|
||||||
<span>Back</span>
|
<span>Back</span>
|
||||||
</div>
|
</div>
|
||||||
<h2 className="text-2xl font-semibold">Inactive Corporate</h2>
|
<h2 className="text-2xl font-semibold">
|
||||||
|
Inactive Corporate (
|
||||||
|
{users.filter((x) => x.type === "admin" && (x.isDisabled || moment().isAfter(x.subscriptionExpirationDate))).length})
|
||||||
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<UserList user={user} filter={(x) => x.type === "admin" && (x.isDisabled || moment().isAfter(x.subscriptionExpirationDate))} />
|
<UserList user={user} filter={(x) => x.type === "admin" && (x.isDisabled || moment().isAfter(x.subscriptionExpirationDate))} />
|
||||||
@@ -260,7 +325,7 @@ export default function OwnerDashboard({user}: Props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Modal isOpen={!!selectedUser} onClose={() => setSelectedUser(undefined)}>
|
<Modal isOpen={showModal} onClose={() => setSelectedUser(undefined)}>
|
||||||
<>
|
<>
|
||||||
{selectedUser && (
|
{selectedUser && (
|
||||||
<div className="w-full flex flex-col gap-8">
|
<div className="w-full flex flex-col gap-8">
|
||||||
@@ -269,6 +334,10 @@ export default function OwnerDashboard({user}: Props) {
|
|||||||
setSelectedUser(undefined);
|
setSelectedUser(undefined);
|
||||||
if (shouldReload) reload();
|
if (shouldReload) reload();
|
||||||
}}
|
}}
|
||||||
|
onViewStudents={
|
||||||
|
selectedUser.type === "admin" || selectedUser.type === "teacher" ? () => setPage("students") : undefined
|
||||||
|
}
|
||||||
|
onViewTeachers={selectedUser.type === "admin" ? () => setPage("teachers") : undefined}
|
||||||
{...selectedUser}
|
{...selectedUser}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -14,11 +14,14 @@ export interface User {
|
|||||||
bio: string;
|
bio: string;
|
||||||
isVerified: boolean;
|
isVerified: boolean;
|
||||||
demographicInformation?: DemographicInformation;
|
demographicInformation?: DemographicInformation;
|
||||||
|
companyInformation?: CompanyInformation;
|
||||||
subscriptionExpirationDate?: null | Date;
|
subscriptionExpirationDate?: null | Date;
|
||||||
isDisabled?: boolean;
|
isDisabled?: boolean;
|
||||||
registrationDate?: Date;
|
registrationDate?: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CompanyInformation {}
|
||||||
|
|
||||||
export interface DemographicInformation {
|
export interface DemographicInformation {
|
||||||
country: string;
|
country: string;
|
||||||
phone: string;
|
phone: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user