140 lines
4.0 KiB
TypeScript
140 lines
4.0 KiB
TypeScript
|
import React, { useEffect, useState, useRef, useMemo } from 'react'
|
|||
|
import { useParams, Link } from 'react-router-dom'
|
|||
|
import dayjs from 'dayjs'
|
|||
|
import QRCode from 'qrcode'
|
|||
|
import { getConfigValue, getNavigationsValue } from '@ijl/cli'
|
|||
|
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink } from '@chakra-ui/react'
|
|||
|
|
|||
|
import {
|
|||
|
MainWrapper,
|
|||
|
StartWrapper,
|
|||
|
QRCanvas,
|
|||
|
LessonItem,
|
|||
|
Lessonname,
|
|||
|
AddMissedButton,
|
|||
|
Wrapper,
|
|||
|
UnorderList,
|
|||
|
} from './style'
|
|||
|
import { api } from '../__data__/api/api'
|
|||
|
import { User } from '../__data__/model'
|
|||
|
|
|||
|
const LessonDetail = () => {
|
|||
|
const { lessonId, courseId } = useParams()
|
|||
|
const canvRef = useRef(null)
|
|||
|
const [lesson, setLesson] = useState(null)
|
|||
|
const {
|
|||
|
isFetching,
|
|||
|
isLoading,
|
|||
|
data: accessCode,
|
|||
|
error,
|
|||
|
isSuccess,
|
|||
|
} = api.useCreateAccessCodeQuery(
|
|||
|
{ lessonId },
|
|||
|
{
|
|||
|
pollingInterval:
|
|||
|
Number(getConfigValue('journal.polling-interval')) || 3000,
|
|||
|
skipPollingIfUnfocused: true,
|
|||
|
},
|
|||
|
)
|
|||
|
const AllStudents = api.useCourseAllStudentsQuery(courseId)
|
|||
|
const [manualAdd, manualAddRqst] = api.useManualAddStudentMutation()
|
|||
|
const userUrl = useMemo(
|
|||
|
() => `${location.origin}/journal/u/${lessonId}/${accessCode?.body?._id}`,
|
|||
|
[accessCode, lessonId],
|
|||
|
)
|
|||
|
useEffect(() => {
|
|||
|
if (!isFetching && isSuccess) {
|
|||
|
QRCode.toCanvas(
|
|||
|
canvRef.current,
|
|||
|
userUrl,
|
|||
|
{ width: 600 },
|
|||
|
function (error) {
|
|||
|
if (error) console.error(error)
|
|||
|
console.log('success!')
|
|||
|
},
|
|||
|
)
|
|||
|
}
|
|||
|
}, [isFetching, isSuccess])
|
|||
|
|
|||
|
const studentsArr = useMemo(() => {
|
|||
|
let allStudents: (User & { present?: boolean })[] = [
|
|||
|
...(AllStudents.data?.body || []),
|
|||
|
].map((st) => ({ ...st, present: false }))
|
|||
|
let presentStudents: (User & { present?: boolean })[] = [
|
|||
|
...(accessCode?.body.lesson.students || []),
|
|||
|
]
|
|||
|
|
|||
|
while (allStudents.length && presentStudents.length) {
|
|||
|
const student = presentStudents.pop()
|
|||
|
|
|||
|
const present = allStudents.find((st) => st.sub === student.sub)
|
|||
|
|
|||
|
if (present) {
|
|||
|
present.present = true
|
|||
|
} else {
|
|||
|
allStudents.push({ ...student, present: true })
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return allStudents
|
|||
|
}, [accessCode?.body, AllStudents.data])
|
|||
|
|
|||
|
return (
|
|||
|
<MainWrapper>
|
|||
|
<StartWrapper>
|
|||
|
<Breadcrumb>
|
|||
|
<BreadcrumbItem>
|
|||
|
<Link as={BreadcrumbLink} to={getNavigationsValue('journal.main')}>
|
|||
|
Журнал
|
|||
|
</Link>
|
|||
|
</BreadcrumbItem>
|
|||
|
|
|||
|
<BreadcrumbItem>
|
|||
|
<Link
|
|||
|
as={BreadcrumbLink}
|
|||
|
to={`${getNavigationsValue('journal.main')}/lessons-list/${courseId}`}
|
|||
|
>
|
|||
|
Курс
|
|||
|
</Link>
|
|||
|
</BreadcrumbItem>
|
|||
|
|
|||
|
<BreadcrumbItem isCurrentPage>
|
|||
|
<BreadcrumbLink href="#">Лекция</BreadcrumbLink>
|
|||
|
</BreadcrumbItem>
|
|||
|
</Breadcrumb>
|
|||
|
|
|||
|
<h1 style={{ width: '70%' }} >Тема занятия - {accessCode?.body?.lesson?.name}</h1>
|
|||
|
<span style={{ display: 'flex' }}>
|
|||
|
{dayjs(accessCode?.body?.lesson?.date).format('DD MMMM YYYYг.')}{' '}
|
|||
|
Отмечено - {accessCode?.body?.lesson?.students?.length}{' '}
|
|||
|
{AllStudents.isSuccess ? `/ ${AllStudents?.data?.body?.length}` : ''}{' '}
|
|||
|
человек
|
|||
|
</span>
|
|||
|
<Wrapper>
|
|||
|
<a href={userUrl}>
|
|||
|
<QRCanvas ref={canvRef} />
|
|||
|
</a>
|
|||
|
<UnorderList>
|
|||
|
{studentsArr.map((student) => (
|
|||
|
<LessonItem key={student.sub} warn={!student.present}>
|
|||
|
<Lessonname>
|
|||
|
{student.name || student.preferred_username}{' '}
|
|||
|
{!student.present && (
|
|||
|
<AddMissedButton
|
|||
|
onClick={() => manualAdd({ lessonId, user: student })}
|
|||
|
>
|
|||
|
add
|
|||
|
</AddMissedButton>
|
|||
|
)}
|
|||
|
</Lessonname>
|
|||
|
</LessonItem>
|
|||
|
))}
|
|||
|
</UnorderList>
|
|||
|
</Wrapper>
|
|||
|
</StartWrapper>
|
|||
|
</MainWrapper>
|
|||
|
)
|
|||
|
}
|
|||
|
|
|||
|
export default LessonDetail
|