import { Box, FormControl, FormLabel, Progress, Skeleton, Stack, Table, TableContainer, Tbody, Td, Text, Th, Thead, Tr, } from '@chakra-ui/react'; import { useQuery } from '@tanstack/react-query'; import { __, sprintf } from '@wordpress/i18n'; import React from 'react'; import StatusBadge from '../../../../../../assets/js/account/common/StatusBadge'; import { accountPageFormLabelStyles } from '../../../../../../assets/js/account/utils/general'; import API from '../../../../../../assets/js/back-end/utils/api'; import { getSiteDate } from '../../../../../../assets/js/back-end/utils/utils'; import { urls } from '../../constants/urls'; import { GroupProgressSchema, MemberCourseProgress } from '../../types/group'; interface Props { groupId: number; } type Standing = { status: 'draft' | 'cancelled' | 'completed' | 'pending'; label: string; }; /** The badge key (its colour) and label for a member's standing in a course. */ export const standing = (row: MemberCourseProgress): Standing => { if (!row.enrollment_status) { return { status: 'draft', label: __('Not enrolled', 'learning-management-system'), }; } if (row.enrollment_status !== 'active') { return { status: 'cancelled', label: __('Inactive', 'learning-management-system'), }; } if (row.progress_status === 'completed') { return { status: 'completed', label: __('Completed', 'learning-management-system'), }; } if (!row.progress_status) { return { status: 'draft', label: __('Not started', 'learning-management-system'), }; } return { status: 'pending', label: __('In progress', 'learning-management-system'), }; }; const countOf = (counts: { completed: number; total: number }) => sprintf( /* translators: 1: completed count, 2: total count */ __('%1$d of %2$d', 'learning-management-system'), counts.completed, counts.total, ); const lastActivity = (row: MemberCourseProgress) => { const date = row.completed_at ?? row.modified_at; return date ? getSiteDate(date) : '—'; }; const GroupProgress: React.FC = ({ groupId }) => { const progressQuery = useQuery({ queryKey: ['groupProgress', groupId], queryFn: () => new API(urls.groups).get(`${groupId}/progress`), }); return ( {__('Member Progress', 'learning-management-system')} {progressQuery.isLoading ? ( ) : progressQuery.isError || !progressQuery.data ? ( {__('Could not load member progress.', 'learning-management-system')} ) : ( )} ); }; const ProgressTables: React.FC = ({ courses, members, }) => { if (courses.length === 0 || members.length === 0) { return ( {courses.length === 0 ? __( 'Progress appears once the group has a course.', 'learning-management-system', ) : __( 'Progress appears once the group has members.', 'learning-management-system', )} ); } return ( {courses.map((course, courseIndex) => ( {courses.length > 1 && ( {course.name} )} {members.map((member) => { const row = member.courses[courseIndex]; const badge = standing(row); return ( ); })}
{__('Member', 'learning-management-system')} {__('Status', 'learning-management-system')} {__('Progress', 'learning-management-system')} {__('Lessons', 'learning-management-system')} {__('Quizzes', 'learning-management-system')} {__('Last activity', 'learning-management-system')}
{member.user?.display_name ?? member.email} {member.user ? member.email : __( 'No account yet', 'learning-management-system', )} {badge.label} {row.percentage}% {countOf(row.lessons)} {countOf(row.quizzes)} {lastActivity(row)}
))}
); }; export default GroupProgress;