journal.pl/src/pages/lesson-details.tsx

169 lines
4.6 KiB
TypeScript
Raw Normal View History

import React, { useEffect, useState, useRef, useMemo } from 'react'
import { useParams, Link } from 'react-router-dom'
import dayjs from 'dayjs'
import QRCode from 'qrcode'
2024-04-03 19:47:18 +03:00
import { sha256 } from 'js-sha256'
2024-08-05 21:56:28 +03:00
import { getConfigValue, getNavigationsValue } from '@brojs/cli'
2024-03-31 18:07:28 +03:00
import {
Box,
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
Container,
VStack,
Heading,
2024-04-03 22:00:17 +03:00
Stack,
2024-03-31 18:07:28 +03:00
} from '@chakra-ui/react'
2024-04-03 22:00:17 +03:00
import { api } from '../__data__/api/api'
import { User } from '../__data__/model'
import { UserCard } from '../components/user-card'
import {
QRCanvas,
2024-04-03 22:00:17 +03:00
StudentList,
BreadcrumbsWrapper,
} from './style'
2024-12-15 17:03:14 +03:00
import { useAppSelector } from '../__data__/store'
import { isTeacher } from '../utils/user'
2024-04-03 19:47:18 +03:00
export function getGravatarURL(email, user) {
if (!email) return void 0
const address = String(email).trim().toLowerCase()
const hash = sha256(address)
// Grab the actual image URL
return `https://www.gravatar.com/avatar/${hash}?d=robohash`
}
const LessonDetail = () => {
const { lessonId, courseId } = useParams()
const canvRef = useRef(null)
2024-12-15 17:03:14 +03:00
const user = useAppSelector((s) => s.user)
const {
isFetching,
data: accessCode,
isSuccess,
2024-04-03 22:00:17 +03:00
refetch,
} = api.useCreateAccessCodeQuery(
{ lessonId },
{
2024-12-15 17:03:14 +03:00
skip: !isTeacher(user),
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],
)
2024-04-03 22:00:17 +03:00
useEffect(() => {
if (manualAddRqst.isSuccess) {
refetch()
}
}, [manualAddRqst.isSuccess])
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 })
}
}
2024-04-03 19:47:18 +03:00
return allStudents.sort((a, b) => (a.present ? -1 : 1))
}, [accessCode?.body, AllStudents.data])
return (
<>
<BreadcrumbsWrapper>
<Breadcrumb>
<BreadcrumbItem>
<BreadcrumbLink as={Link} to={getNavigationsValue('journal.main')}>
Журнал
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbItem>
<BreadcrumbLink
as={Link}
to={`${getNavigationsValue('journal.main')}/lessons-list/${courseId}`}
>
Курс
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbItem isCurrentPage>
<BreadcrumbLink href="#">Лекция</BreadcrumbLink>
</BreadcrumbItem>
</Breadcrumb>
</BreadcrumbsWrapper>
2024-04-03 19:47:18 +03:00
<Container maxW="2280px">
<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>
2024-04-03 22:00:17 +03:00
<Stack spacing="8" sx={{ flexDirection: { sm: 'column', md: 'row' } }}>
<a href={userUrl}>
<QRCanvas ref={canvRef} />
</a>
2024-04-03 22:00:17 +03:00
<StudentList>
2024-12-15 17:20:16 +03:00
{isTeacher(user) && studentsArr.map((student) => (
2024-04-03 22:00:17 +03:00
<UserCard
wrapperAS="li"
key={student.sub}
student={student}
present={student.present}
onAddUser={(user: User) => manualAdd({ lessonId, user })}
/>
))}
2024-04-03 22:00:17 +03:00
</StudentList>
</Stack>
</Container>
</>
)
}
export default LessonDetail