2024-03-01 12:49:55 +03:00
|
|
|
|
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'
|
2024-03-31 18:07:28 +03:00
|
|
|
|
import {
|
|
|
|
|
Box,
|
|
|
|
|
Breadcrumb,
|
|
|
|
|
BreadcrumbItem,
|
|
|
|
|
BreadcrumbLink,
|
|
|
|
|
Container,
|
|
|
|
|
HStack,
|
|
|
|
|
VStack,
|
|
|
|
|
Heading,
|
|
|
|
|
} from '@chakra-ui/react'
|
2024-03-01 12:49:55 +03:00
|
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
QRCanvas,
|
|
|
|
|
LessonItem,
|
|
|
|
|
Lessonname,
|
|
|
|
|
AddMissedButton,
|
|
|
|
|
UnorderList,
|
2024-04-01 17:42:30 +03:00
|
|
|
|
BreadcrumbsWrapper,
|
2024-03-01 12:49:55 +03:00
|
|
|
|
} 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 (
|
2024-04-01 17:42:30 +03:00
|
|
|
|
<>
|
|
|
|
|
<BreadcrumbsWrapper>
|
2024-03-01 12:49:55 +03:00
|
|
|
|
<Breadcrumb>
|
|
|
|
|
<BreadcrumbItem>
|
2024-03-28 18:59:16 +03:00
|
|
|
|
<BreadcrumbLink as={Link} to={getNavigationsValue('journal.main')}>
|
2024-03-01 12:49:55 +03:00
|
|
|
|
Журнал
|
2024-03-28 18:59:16 +03:00
|
|
|
|
</BreadcrumbLink>
|
2024-03-01 12:49:55 +03:00
|
|
|
|
</BreadcrumbItem>
|
|
|
|
|
|
|
|
|
|
<BreadcrumbItem>
|
2024-03-28 18:59:16 +03:00
|
|
|
|
<BreadcrumbLink
|
|
|
|
|
as={Link}
|
2024-03-01 12:49:55 +03:00
|
|
|
|
to={`${getNavigationsValue('journal.main')}/lessons-list/${courseId}`}
|
|
|
|
|
>
|
|
|
|
|
Курс
|
2024-03-28 18:59:16 +03:00
|
|
|
|
</BreadcrumbLink>
|
2024-03-01 12:49:55 +03:00
|
|
|
|
</BreadcrumbItem>
|
|
|
|
|
|
|
|
|
|
<BreadcrumbItem isCurrentPage>
|
|
|
|
|
<BreadcrumbLink href="#">Лекция</BreadcrumbLink>
|
|
|
|
|
</BreadcrumbItem>
|
|
|
|
|
</Breadcrumb>
|
2024-04-01 17:42:30 +03:00
|
|
|
|
</BreadcrumbsWrapper>
|
|
|
|
|
<Container maxW="container.xl" centerContent px="200">
|
|
|
|
|
<VStack align="left">
|
|
|
|
|
<Heading as="h3" mt="4" mb="3">
|
|
|
|
|
Тема занятия:
|
|
|
|
|
</Heading>
|
|
|
|
|
<Box as="span">{accessCode?.body?.lesson?.name}</Box>
|
|
|
|
|
<Box as="span">
|
|
|
|
|
{dayjs(accessCode?.body?.lesson?.date).format('DD MMMM YYYYг.')}{' '}
|
|
|
|
|
Отмечено - {accessCode?.body?.lesson?.students?.length}{' '}
|
|
|
|
|
{AllStudents.isSuccess
|
|
|
|
|
? `/ ${AllStudents?.data?.body?.length}`
|
|
|
|
|
: ''}{' '}
|
|
|
|
|
человек
|
|
|
|
|
</Box>
|
|
|
|
|
</VStack>
|
|
|
|
|
<HStack spacing="8">
|
|
|
|
|
<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>
|
|
|
|
|
</HStack>
|
|
|
|
|
</Container>
|
|
|
|
|
</>
|
2024-03-01 12:49:55 +03:00
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default LessonDetail
|