12 Commits

Author SHA1 Message Date
Primakov Alexandr Alexandrovich
d4b7d0616e 3.6.1 2024-12-15 17:14:49 +03:00
Primakov Alexandr Alexandrovich
b5bd2e02d7 not create access token if not teacher 2024-12-15 17:03:14 +03:00
Primakov Alexandr Alexandrovich
428b06f920 3.6.0
All checks were successful
platform/bro-js/journal.pl/pipeline/head This commit looks good
2024-12-12 22:59:07 +03:00
Primakov Alexandr Alexandrovich
7d6f2a4ca0 no JSON stringify in attendance 2024-12-12 16:00:49 +03:00
Primakov Alexandr Alexandrovich
2fe7600ef3 fix 2024-12-12 15:20:55 +03:00
Primakov Alexandr Alexandrovich
985b8ef315 stringify 2024-12-12 12:30:56 +03:00
Primakov Alexandr Alexandrovich
956fdec7f5 unknown name if no name 2024-12-12 12:12:19 +03:00
Primakov Alexandr Alexandrovich
d44a511a3d try get student name even better 2024-12-12 12:09:25 +03:00
Primakov Alexandr Alexandrovich
0aebb87210 update get student name in attendance 2024-12-12 11:17:38 +03:00
Primakov Alexandr Alexandrovich
9509f12d73 3.5.1
All checks were successful
platform/bro-js/journal.pl/pipeline/head This commit looks good
2024-11-06 13:04:00 +03:00
Primakov Alexandr Alexandrovich
021031ced7 short lesson name 2024-11-06 13:03:55 +03:00
Primakov Alexandr Alexandrovich
22a9199d9d no attendance link if no nav element 2024-11-06 12:59:24 +03:00
7 changed files with 67 additions and 45 deletions

View File

@@ -1,12 +0,0 @@
import type { ConfigFile } from '@rtk-query/codegen-openapi'
const config: ConfigFile = {
schemaFile: 'https://platform.bro-js.ru/jrnl-bh/documentation/json',
apiFile: './src/__data__/api/api.ts',
apiImport: 'api',
outputFile: './src/__data__/api/jrnl.ts',
exportName: 'jrnlApi',
hooks: true,
}
export default config

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "journal.pl",
"version": "3.5.0",
"version": "3.6.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "journal.pl",
"version": "3.5.0",
"version": "3.6.1",
"license": "MIT",
"dependencies": {
"@brojs/cli": "^0.0.4-beta.0",

View File

@@ -1,6 +1,6 @@
{
"name": "journal.pl",
"version": "3.5.0",
"version": "3.6.1",
"description": "bro-js platform journal ui repo",
"main": "./src/index.tsx",
"scripts": {
@@ -19,7 +19,6 @@
"author": "",
"license": "MIT",
"devDependencies": {
"@rtk-query/codegen-openapi": "^1.2.0",
"@typescript-eslint/eslint-plugin": "^7.4.0",
"@typescript-eslint/parser": "^7.4.0",
"eslint": "^8.57.0",

View File

@@ -14,7 +14,7 @@ export default (props) => <App {...props} />;
let rootElement: ReactDOM.Root
export const mount = async (Сomponent, element = document.getElementById('app')) => {
export const mount = async (Component, element = document.getElementById('app')) => {
let user = null;
try {
await keycloak.init({ onLoad: "login-required" });
@@ -26,11 +26,11 @@ export const mount = async (Сomponent, element = document.getElementById('app')
const store = createStore({ user });
rootElement = ReactDOM.createRoot(element);
rootElement.render(<Сomponent store={store} />);
rootElement.render(<Component store={store} />);
if(module.hot) {
module.hot.accept('./app', ()=> {
rootElement.render(<Сomponent store={store} />);
rootElement.render(<Component store={store} />);
})
}
};

View File

@@ -1,11 +1,10 @@
import React, { useMemo } from 'react'
import { useParams } from 'react-router-dom'
import styled from '@emotion/styled'
import { Box, Heading, Tooltip, Text } from '@chakra-ui/react'
import dayjs from 'dayjs'
import { api } from '../../__data__/api/api'
import { PageLoader } from '../../components/page-loader/page-loader'
import { Box, Container, Heading } from '@chakra-ui/react'
import dayjs from 'dayjs'
export const Attendance = () => {
const { courseId } = useParams()
@@ -25,15 +24,18 @@ export const Attendance = () => {
attendance.forEach((lesson) => {
lesson.students.forEach((student) => {
const current = studentsMap.get(student.sub) || {}
studentsMap.set(student.sub, {
...student,
value:
student.family_name && student.given_name
id: student.sub,
value: current.value || (student.family_name && student.given_name
? `${student.family_name} ${student.given_name}`
: student.name || student.email,
: student.name || student.email || student.preferred_username || student.family_name || student.given_name),
})
})
})
const compare = Intl.Collator('ru').compare
const students = [...studentsMap.values()]
@@ -61,7 +63,7 @@ export const Attendance = () => {
<th>Дата</th>
<th>Название занятия</th>
{data.students.map((student) => (
<th key={student.sub}>{student.name}</th>
<th id={student.id || student.sub} key={student.sub}>{student.name || student.value || 'Имя не определено'}</th>
))}
</tr>
</thead>
@@ -69,14 +71,22 @@ export const Attendance = () => {
{attendance.map((lesson, index) => (
<tr key={lesson.name}>
<td>{dayjs(lesson.date).format('DD.MM.YYYY')}</td>
<td>{lesson.name}</td>
<td>{<ShortText text={lesson.name} />}</td>
{data.students.map((st) => {
const wasThere =
lesson.students.findIndex((u) => u.sub === st.sub) !== -1
return <td style={{
textAlign: 'center',
backgroundColor: wasThere ? '#8ef78a' : '#e09797',
}} key={st.sub}>{wasThere ? '+' : '-'}</td>
return (
<td
style={{
textAlign: 'center',
backgroundColor: wasThere ? '#8ef78a' : '#e09797',
}}
key={st.sub}
>
{wasThere ? '+' : '-'}
</td>
)
})}
</tr>
))}
@@ -86,3 +96,17 @@ export const Attendance = () => {
</Box>
)
}
const ShortText = ({ text }: { text: string }) => {
const needShortText = text.length > 20
if (needShortText) {
return (
<Tooltip label="На страницу с лекциями" fontSize="12px" top="16px">
<Text>{text.slice(0, 20)}...</Text>
</Tooltip>
)
}
return text
}

View File

@@ -57,21 +57,27 @@ export const CourseCard = ({ course }: { course: Course }) => {
<CourseDetails populatedCourse={populatedCourse.data} />
)}
<Tooltip label="На страницу с лекциями" fontSize="12px" top="16px">
<Button
leftIcon={<LinkIcon />}
as={ConnectedLink}
variant="outline"
colorScheme="blue"
to={generatePath(
`${getNavigationsValue('journal.main')}${getNavigationsValue('link.journal.attendance')}`,
{ courseId: course.id },
)}
{getNavigationsValue('link.journal.attendance') && (
<Tooltip
label="На страницу с лекциями"
fontSize="12px"
top="16px"
>
<Box mt={3}></Box>
Посещаемость
</Button>
</Tooltip>
<Button
leftIcon={<LinkIcon />}
as={ConnectedLink}
variant="outline"
colorScheme="blue"
to={generatePath(
`${getNavigationsValue('journal.main')}${getNavigationsValue('link.journal.attendance')}`,
{ courseId: course.id },
)}
>
<Box mt={3}></Box>
Посещаемость
</Button>
</Tooltip>
)}
</Stack>
</CardBody>
)}

View File

@@ -24,6 +24,8 @@ import {
StudentList,
BreadcrumbsWrapper,
} from './style'
import { useAppSelector } from '../__data__/store'
import { isTeacher } from '../utils/user'
export function getGravatarURL(email, user) {
if (!email) return void 0
@@ -37,6 +39,8 @@ export function getGravatarURL(email, user) {
const LessonDetail = () => {
const { lessonId, courseId } = useParams()
const canvRef = useRef(null)
const user = useAppSelector((s) => s.user)
const {
isFetching,
data: accessCode,
@@ -45,6 +49,7 @@ const LessonDetail = () => {
} = api.useCreateAccessCodeQuery(
{ lessonId },
{
skip: !isTeacher(user),
pollingInterval:
Number(getConfigValue('journal.polling-interval')) || 3000,
skipPollingIfUnfocused: true,