Skip to content

Commit

Permalink
ready for review
Browse files Browse the repository at this point in the history
  • Loading branch information
SKairinos committed Aug 2, 2024
1 parent e96c39b commit 94d623f
Show file tree
Hide file tree
Showing 6 changed files with 473 additions and 534 deletions.
16 changes: 9 additions & 7 deletions src/pages/teacherDashboard/TeacherDashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as page from "codeforlife/components/page"
import { type FC, useEffect } from "react"
import { CircularProgress } from "@mui/material"
import { type Parameters } from "codeforlife/utils/router"
import { type SchoolTeacherUser } from "codeforlife/api"
import { useNavigate } from "codeforlife/hooks"
Expand All @@ -17,10 +18,10 @@ import { paths } from "../../router"
export interface TeacherDashboardProps {}

const TeacherDashboard: FC<TeacherDashboardProps> = () => {
const [retrieveUser, { data: user, isError }] = useLazyRetrieveUserQuery()
let [retrieveUser, { data: authUser, isError }] = useLazyRetrieveUserQuery()
const navigate = useNavigate()

const isNonSchoolTeacher = user && !user.teacher?.school
const isNonSchoolTeacher = authUser && !authUser.teacher?.school

useEffect(() => {
if (isNonSchoolTeacher) navigate(paths.teacher.onboarding._)
Expand All @@ -34,21 +35,22 @@ const TeacherDashboard: FC<TeacherDashboardProps> = () => {
return (
<page.Page session={{ userType: "teacher" }}>
{({ user_id }) => {
if (!user) {
if (!authUser) {
retrieveUser(user_id)
return <>Loading...</>
return <CircularProgress />
}

const schoolTeacherUser = user as SchoolTeacherUser<RetrieveUserResult>
const authSchoolTeacherUser =
authUser as SchoolTeacherUser<RetrieveUserResult>

return (
<page.TabBar
header={`Welcome back, ${user.first_name} ${user.last_name}`}
header={`Welcome back, ${authUser.first_name} ${authUser.last_name}`}
originalPath={paths.teacher.dashboard.tab._}
tabs={[
{
label: "Your school",
children: <School user={schoolTeacherUser} />,
children: <School authUser={authSchoolTeacherUser} />,
path: (paths.teacher.dashboard.tab.school.__ as Parameters).tab,
},
// {
Expand Down
107 changes: 49 additions & 58 deletions src/pages/teacherDashboard/school/School.tsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,58 @@
import * as page from "codeforlife/components/page"
import { Button, Stack, Typography } from "@mui/material"
import {
Button,
CircularProgress,
Unstable_Grid2 as Grid,
Stack,
Typography,
} from "@mui/material"
import { useLocation, useNavigate } from "codeforlife/hooks"
import { type FC } from "react"
import { type SchoolTeacherUser } from "codeforlife/api"

import TransferClasses, { type TransferClassesProps } from "./TransferClasses"
import InviteTeacherForm from "./InviteTeacherForm"
import { type RetrieveUserResult } from "../../../api/user"
import TransferClasses from "./TransferClasses"
import { paths } from "../../../router"
import { useRemoveTeacherFromSchoolMutation } from "../../../api/teacher"
import TeacherInvitationTable from "./TeacherInvitationTable"
import TeacherTable from "./TeacherTable"
import UpdateSchoolForm from "./UpdateSchoolForm"
import { useRetrieveSchoolQuery } from "../../../api/school"

export interface SchoolProps {
user: SchoolTeacherUser<RetrieveUserResult>
authUser: SchoolTeacherUser<RetrieveUserResult>
}

const School: FC<SchoolProps> = ({ user }) => {
const { data: school } = useRetrieveSchoolQuery(user.teacher.school)
const { state } = useLocation<{ transferClasses: boolean }>()
const [removeTeacherFromSchool] = useRemoveTeacherFromSchoolMutation()
const navigate = useNavigate()

const { transferClasses } = state || {}
const School: FC<SchoolProps> = ({ authUser }) => {
const { data: school, isError } = useRetrieveSchoolQuery(
authUser.teacher.school,
)
const { state } = useLocation<{
transferClasses: TransferClassesProps["user"]
}>()
const navigate = useNavigate<{
transferClasses?: TransferClassesProps["user"]
}>()

const onLeaveOrganisation = (): void => {
removeTeacherFromSchool(user.id)
.unwrap()
.then(() => {
// if (moveClassData?.classes) {
// navigate(paths.teacher.dashboard.school.leave._, {
// state: moveClassData,
// })
// } else {
// navigate(paths.teacher.onboarding._, {
// state: { leftOrganisation: true },
// })
// }
})
.catch(error => {
console.error(error)
})
if (state?.transferClasses) {
return (
<TransferClasses authUserId={authUser.id} user={state.transferClasses} />
)
}

if (!school) return <>TODO</>
// TODO: handle this better
if (isError) return <>There was an error!</>

if (!school) return <CircularProgress />

return true ? (
<TransferClasses loggedInTeacherId={user.teacher.id} teacherUser={user} />
) : (
return (
<>
<page.Section>
<Typography align="center" variant="h4" marginBottom={0}>
Your school: {school.name}
</Typography>
</page.Section>
<page.Section sx={{ paddingTop: 0 }}>
{user.teacher.is_admin ? (
{authUser.teacher.is_admin ? (
<>
<Typography mb={0}>
As an administrator of your school or club, you can select other
Expand All @@ -77,42 +75,29 @@ const School: FC<SchoolProps> = ({ user }) => {
</Typography>
<Button
onClick={() => {
removeTeacherFromSchool(user.teacher.id)
.unwrap()
.then(() => {
navigate(paths.teacher.onboarding._)
})
.catch(() => {
// TODO: error handling strategy.
alert("Failed to leave school")
})
navigate(".", { state: { transferClasses: authUser } })
}}
>
Leave school or club
</Button>
</Stack>
)}
</page.Section>
{/* <page.Section>
<page.Section>
<Typography variant="h5">
These teachers are already part of your school or club
</Typography>
<TeachersTable
teacherData={data.teacher}
coworkersData={data.coworkers}
sentInvites={data.sentInvites}
setDialog={setDialog}
/>
{isAdmin && (
<TeacherTable authUser={authUser} />
{authUser.teacher.is_admin && (
<Grid container columnSpacing={5}>
<Grid item sm={6}>
<Grid sm={6}>
<Typography mb={0}>
Select &apos;Delete&apos; to delete a teacher from your school
or club. You will be able to move any existing classes assigned
to that teacher to other teachers in your school or club.
</Typography>
</Grid>
<Grid item sm={6}>
<Grid sm={6}>
<Typography fontWeight="bold" color="error" mb={0}>
We strongly recommend that administrators who are using 2FA
ensure there is another administrator who will be able to
Expand All @@ -122,12 +107,18 @@ const School: FC<SchoolProps> = ({ user }) => {
</Grid>
</Grid>
)}
</page.Section> */}
{/* {isAdmin && (
<page.Section gridProps={{ bgcolor: theme.palette.info.main }}>
<UpdateSchoolDetailsForm schoolData={data.school} />
</page.Section>
<page.Section>
<Typography variant="h5">
These teachers are invited to your school but have not joined yet
</Typography>
<TeacherInvitationTable authUser={authUser} />
</page.Section>
{authUser.teacher.is_admin && (
<page.Section boxProps={{ bgcolor: "info.main" }}>
<UpdateSchoolForm school={school} />
</page.Section>
)} */}
)}
</>
)
}
Expand Down
142 changes: 142 additions & 0 deletions src/pages/teacherDashboard/school/TeacherInvitationTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import {
Add as AddIcon,
DeleteOutline as DeleteOutlineIcon,
DoNotDisturb as DoNotDisturbIcon,
EmailOutlined as EmailOutlinedIcon,
} from "@mui/icons-material"
import { Button, Typography } from "@mui/material"
import { type FC } from "react"
import { type SchoolTeacherUser } from "codeforlife/api"
import { TablePagination } from "codeforlife/components"

Check failure on line 10 in src/pages/teacherDashboard/school/TeacherInvitationTable.tsx

View workflow job for this annotation

GitHub Actions / main / test / test-js-code

Module '"codeforlife/components"' has no exported member 'TablePagination'.
import { useNavigate } from "codeforlife/hooks"

import * as table from "../../../components/table"
import {
useDestroySchoolTeacherInvitationMutation,
useLazyListSchoolTeacherInvitationsQuery,
} from "../../../api/schoolTeacherInvitation"
import { type RetrieveUserResult } from "../../../api/user"

export interface TeacherInvitationTableProps {
authUser: SchoolTeacherUser<RetrieveUserResult>
}

const TeacherInvitationTable: FC<TeacherInvitationTableProps> = ({
authUser,
}) => {
const navigate = useNavigate()
const [destroySchoolTeacherInvitation] =
useDestroySchoolTeacherInvitationMutation()

function showNotification(children: string, error: boolean = false) {
navigate(".", {
state: { notifications: [{ props: { children, error } }] },
})
}

return (
<TablePagination
useLazyListQuery={useLazyListSchoolTeacherInvitationsQuery}
>
{schoolTeacherInvitations => (

Check failure on line 41 in src/pages/teacherDashboard/school/TeacherInvitationTable.tsx

View workflow job for this annotation

GitHub Actions / main / test / test-js-code

Parameter 'schoolTeacherInvitations' implicitly has an 'any' type.
<table.Table
className="body"
titles={
authUser.teacher!.is_admin
? ["Name", "Administrator status", "Actions"]
: ["Name", "Administrator status"]
}
>
{schoolTeacherInvitations.map(
({
id,

Check failure on line 52 in src/pages/teacherDashboard/school/TeacherInvitationTable.tsx

View workflow job for this annotation

GitHub Actions / main / test / test-js-code

Binding element 'id' implicitly has an 'any' type.
invited_teacher_first_name,
invited_teacher_last_name,
invited_teacher_is_admin,
invited_teacher_email,
expires_at,
}) => (
<table.Body key={`school-teacher-invitation-${id}`}>
<table.Cell>
<Typography variant="subtitle1">
{invited_teacher_first_name} {invited_teacher_last_name}{" "}
<strong>
({expires_at < new Date() ? "expired" : "pending"})
</strong>
</Typography>
</table.Cell>
<table.Cell
direction="column"
alignItems="flex-start"
justifyContent="flex-start"
>
<Typography variant="subtitle1">
{invited_teacher_is_admin
? "Teacher Administrator"
: "Standard Teacher"}
</Typography>
<Typography variant="subtitle1">
({invited_teacher_email})
</Typography>
</table.Cell>
{authUser.teacher.is_admin && (
<table.Cell justifyContent="center">
{invited_teacher_is_admin ? (
<Button
className="alert"
endIcon={<DoNotDisturbIcon />}
onClick={() => {
alert("TODO: create action of backend for this")
}}
>
Revoke admin
</Button>
) : (
<Button
endIcon={<AddIcon />}
onClick={() => {
alert("TODO: create action of backend for this")
}}
>
Make admin
</Button>
)}
<Button
endIcon={<EmailOutlinedIcon />}
onClick={() => {
alert("TODO: create action of backend for this")
}}
>
Resend invite
</Button>
<Button
className="alert"
endIcon={<DeleteOutlineIcon />}
onClick={() => {
destroySchoolTeacherInvitation(id)
.unwrap()
.then(() => {
showNotification("Invitation successfully deleted.")
})
.catch(() => {
showNotification(
"Failed to delete invitation.",
true,
)
})
}}
>
Delete
</Button>
</table.Cell>
)}
</table.Body>
),
)}
</table.Table>
)}
</TablePagination>
)
}

export default TeacherInvitationTable
Loading

0 comments on commit 94d623f

Please sign in to comment.