Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 55 additions & 18 deletions apps/src/templates/studentSnapshot/header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,39 @@ import {Student} from '../../progress/progressTypes';

import styles from './header.module.scss';

/**
* Helper function to find the previous and next items in an array based
* on the selected item.
* @param items - Array of items to search through
* @param selectedItem - The currently selected item
* @param getId - Function to extract the ID from an item for comparison
* @returns Object containing currentIndex, previous, and next items
*/
function findNavigationItems<T>(
items: T[] | null | undefined,
selectedItem: T | null | undefined,
getId: (item: T) => number | string
): {
currentIndex: number;
previous: T | null;
next: T | null;
} {
let currentIndex = -1;
let previous: T | null = null;
let next: T | null = null;

if (items && Array.isArray(items) && selectedItem) {
currentIndex = items.findIndex(item => getId(item) === getId(selectedItem));
previous = currentIndex > 0 ? items[currentIndex - 1] : null;
next =
currentIndex >= 0 && currentIndex < items.length - 1
? items[currentIndex + 1]
: null;
}

return {currentIndex, previous, next};
}

interface HeaderProps {
lessons: LessonOption[];
selectedLessonId: number | null;
Expand All @@ -39,20 +72,11 @@ const Header: React.FC<HeaderProps> = ({
lessons?.find(lesson => lesson.id === selectedLessonId) || null;

// Find next and previous lessons based on position
let currentLessonIndex = -1;
let previousLesson = null;
let nextLesson = null;
if (lessons && Array.isArray(lessons) && selectedLesson) {
currentLessonIndex = lessons.findIndex(
lesson => lesson.id === selectedLesson.id
);
previousLesson =
currentLessonIndex > 0 ? lessons[currentLessonIndex - 1] : null;
nextLesson =
currentLessonIndex >= 0 && currentLessonIndex < lessons.length - 1
? lessons[currentLessonIndex + 1]
: null;
}
const {previous: previousLesson, next: nextLesson} = findNavigationItems(
lessons,
selectedLesson,
lesson => lesson.id
);

const showStudentsByOptions = [
{value: 'lastName', text: 'Last Name'},
Expand All @@ -71,16 +95,27 @@ const Header: React.FC<HeaderProps> = ({
}
};

const {selectedStudents} = useAppSelector(state => state.teacherSections);

// Find next and previous students based on position
const {previous: previousStudent, next: nextStudent} = findNavigationItems(
selectedStudents,
selectedStudent,
student => student.id
);

const handlePreviousStudent = () => {
alert('Previous student clicked!');
if (previousStudent) {
setSelectedStudentId(previousStudent.id);
}
};

const handleNextStudent = () => {
alert('Next student clicked!');
if (nextStudent) {
setSelectedStudentId(nextStudent.id);
}
};
Comment on lines 107 to 117
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new navigation logic in handlePreviousStudent and handleNextStudent lacks test coverage. Since other components in the studentSnapshot directory have comprehensive tests (e.g., StudentRubricWidgetTest.tsx), this component should also have tests covering: (1) clicking previous/next buttons updates the selected student, (2) buttons are disabled at the boundaries (first/last student), (3) navigation works correctly with selectedStudents array changes.

Copilot uses AI. Check for mistakes.

const {selectedStudents} = useAppSelector(state => state.teacherSections);

React.useEffect(() => {
if (selectedStudents.length > 0 && selectedStudent === undefined) {
setSelectedStudentId(selectedStudents[0].id);
Expand Down Expand Up @@ -161,11 +196,13 @@ const Header: React.FC<HeaderProps> = ({
onClick={handlePreviousStudent}
color="gray"
type="secondary"
disabled={!previousStudent || !selectedStudents?.length}
/>
<Button
className={styles.button}
text="Next student >"
onClick={handleNextStudent}
disabled={!nextStudent || !selectedStudents?.length}
/>
</div>
</div>
Expand Down