145 lines
4.9 KiB
TypeScript
145 lines
4.9 KiB
TypeScript
import { A } from "@solidjs/router";
|
|
import { For, Show, type Component } from "solid-js";
|
|
import { getDashboardClassroomsHref } from "../../../lib/routes";
|
|
import type { TeacherClassroomDetailData } from "./dashboard-teacher-classroom-detail.data";
|
|
import styles from "./dashboard-teacher-classrooms.module.scss";
|
|
|
|
type Props = {
|
|
data: TeacherClassroomDetailData;
|
|
};
|
|
|
|
const DashboardTeacherClassroomDetail: Component<Props> = (props) => {
|
|
return (
|
|
<section class={styles.page}>
|
|
<article class={styles.heroCard}>
|
|
<div class={styles.heroCopy}>
|
|
<p class={styles.eyebrow}>Classroom view</p>
|
|
<h1>{props.data.classroom.name}</h1>
|
|
<p>{props.data.classroom.description}</p>
|
|
</div>
|
|
|
|
<div class={styles.heroStats}>
|
|
<For each={props.data.classroom.stats}>
|
|
{(stat) => (
|
|
<div class={styles.statCard}>
|
|
<span>{stat.label}</span>
|
|
<strong>{stat.value}</strong>
|
|
<small>{stat.note}</small>
|
|
</div>
|
|
)}
|
|
</For>
|
|
</div>
|
|
</article>
|
|
|
|
<section class={styles.classroomDetailMetaRow}>
|
|
<span class={styles.codePill}>{props.data.classroom.codeLabel}</span>
|
|
<A href={getDashboardClassroomsHref("teacher")} class={styles.manageLink}>
|
|
Back to classrooms
|
|
</A>
|
|
</section>
|
|
|
|
<section class={styles.classroomDetailLayout}>
|
|
<article class={styles.detailPanel}>
|
|
<div class={styles.detailPanelHeader}>
|
|
<div>
|
|
<p class={styles.eyebrow}>Roster</p>
|
|
<h2>{props.data.students.title}</h2>
|
|
</div>
|
|
<p>{props.data.students.description}</p>
|
|
</div>
|
|
|
|
<Show when={props.data.students.items.length} fallback={<section class={styles.emptyState}>No students are enrolled in this classroom yet.</section>}>
|
|
<div class={styles.studentList}>
|
|
<For each={props.data.students.items}>
|
|
{(student) => (
|
|
<A
|
|
href={student.href}
|
|
class={[
|
|
styles.studentCard,
|
|
student.selected ? styles.studentCardSelected : "",
|
|
student.endangeredRank != null ? styles[`studentCardEndangered${student.endangeredRank}`] : "",
|
|
]
|
|
.filter(Boolean)
|
|
.join(" ")}
|
|
>
|
|
<div class={styles.studentCardHeader}>
|
|
<div class={styles.studentAvatar}>{student.initials}</div>
|
|
<div>
|
|
<h3>{student.name}</h3>
|
|
<p>{student.email}</p>
|
|
</div>
|
|
</div>
|
|
<div class={styles.metaRow}>
|
|
<span>{student.statusLabel}</span>
|
|
<span>{student.redoCountLabel}</span>
|
|
<Show when={student.endangeredRank != null}>
|
|
<span>{student.endangeredRank === 1 ? "Most endangered" : student.endangeredRank === 2 ? "Second most endangered" : "Third most endangered"}</span>
|
|
</Show>
|
|
</div>
|
|
<p class={styles.studentScoreLabel}>{student.combinedScoreLabel}</p>
|
|
<p class={styles.studentNote}>{student.note}</p>
|
|
</A>
|
|
)}
|
|
</For>
|
|
</div>
|
|
</Show>
|
|
</article>
|
|
|
|
<article class={styles.detailPanel}>
|
|
<div class={styles.detailPanelHeader}>
|
|
<div>
|
|
<p class={styles.eyebrow}>Student follow-up</p>
|
|
<h2>{props.data.redoAssignments.title}</h2>
|
|
</div>
|
|
<p>{props.data.redoAssignments.description}</p>
|
|
</div>
|
|
|
|
<article class={styles.selectedStudentCard}>
|
|
<div>
|
|
<strong>{props.data.selectedStudent.name ?? "No student selected"}</strong>
|
|
<p>{props.data.selectedStudent.email ?? props.data.selectedStudent.note}</p>
|
|
</div>
|
|
<small>{props.data.selectedStudent.note}</small>
|
|
</article>
|
|
|
|
<Show
|
|
when={props.data.selectedStudent.id != null && props.data.redoAssignments.items.length > 0}
|
|
fallback={<section class={styles.emptyState}>Select a student to inspect their individual redo assignments. If none appear, this student does not have student-specific redo work yet.</section>}
|
|
>
|
|
<div class={styles.redoAssignmentList}>
|
|
<For each={props.data.redoAssignments.items}>
|
|
{(assignment) => (
|
|
<article class={styles.redoAssignmentCard}>
|
|
<div class={styles.cardHeader}>
|
|
<div>
|
|
<h3>{assignment.title}</h3>
|
|
<p>{assignment.note}</p>
|
|
</div>
|
|
<span class={`${styles.statusPill} ${styles[`statusPill${assignment.statusTone[0].toUpperCase()}${assignment.statusTone.slice(1)}`]}`}>{assignment.statusLabel}</span>
|
|
</div>
|
|
|
|
<div class={styles.metaRow}>
|
|
<span>{assignment.dueLabel}</span>
|
|
<span>{assignment.progressLabel}</span>
|
|
<span>{assignment.nextStepLabel}</span>
|
|
</div>
|
|
|
|
<div class={styles.reviewRow}>
|
|
<strong>{assignment.statusLabel}</strong>
|
|
<A href={assignment.href} class={styles.manageLink}>
|
|
Open review
|
|
</A>
|
|
</div>
|
|
</article>
|
|
)}
|
|
</For>
|
|
</div>
|
|
</Show>
|
|
</article>
|
|
</section>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export default DashboardTeacherClassroomDetail;
|