Add printable attendance sheet to class
This commit is contained in:
parent
68537b824e
commit
bcb8108f4d
|
@ -13,6 +13,7 @@
|
||||||
"react-quill": "^1.3.3",
|
"react-quill": "^1.3.3",
|
||||||
"react-router-dom": "^5.1.2",
|
"react-router-dom": "^5.1.2",
|
||||||
"react-scripts": "3.3.0",
|
"react-scripts": "3.3.0",
|
||||||
|
"react-to-print": "^2.5.1",
|
||||||
"semantic-ui-react": "^0.88.2",
|
"semantic-ui-react": "^0.88.2",
|
||||||
"serialize-javascript": "^2.1.2"
|
"serialize-javascript": "^2.1.2"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
import { BrowserRouter as Router, Switch, Route, Link, useParams, useHistory } from 'react-router-dom';
|
import { BrowserRouter as Router, Switch, Route, Link, useParams, useHistory } from 'react-router-dom';
|
||||||
|
import ReactToPrint from 'react-to-print';
|
||||||
import * as Datetime from 'react-datetime';
|
import * as Datetime from 'react-datetime';
|
||||||
import 'react-datetime/css/react-datetime.css';
|
import 'react-datetime/css/react-datetime.css';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
@ -8,6 +9,62 @@ import { Button, Container, Checkbox, Divider, Dropdown, Form, Grid, Header, Ico
|
||||||
import { BasicTable, staticUrl, requester } from './utils.js';
|
import { BasicTable, staticUrl, requester } from './utils.js';
|
||||||
import { MembersDropdown } from './Members.js';
|
import { MembersDropdown } from './Members.js';
|
||||||
|
|
||||||
|
class AttendanceSheet extends React.Component {
|
||||||
|
render() {
|
||||||
|
const clazz = this.props.clazz;
|
||||||
|
const num = clazz.students.length;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ padding: '3rem' }}>
|
||||||
|
<Header size='medium'>{clazz.course_name} Attendance</Header>
|
||||||
|
<p>
|
||||||
|
{moment.utc(clazz.datetime).local().format('llll')}
|
||||||
|
{num >= 2 ? ', '+num+' students sorted by registration time.' : '.'}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<Grid stackable padded columns={2}>
|
||||||
|
<Grid.Column>
|
||||||
|
<Table collapsing unstackable basic='very'>
|
||||||
|
{clazz.students
|
||||||
|
.filter(x => x.attendance_status !== 'Withdrawn')
|
||||||
|
.slice(0, 15)
|
||||||
|
.map(x =>
|
||||||
|
<Table.Row key={x.id}>
|
||||||
|
<Table.Cell>
|
||||||
|
<Icon name='square outline' size='large' />
|
||||||
|
</Table.Cell>
|
||||||
|
<Table.Cell>
|
||||||
|
{x.student_name}
|
||||||
|
</Table.Cell>
|
||||||
|
</Table.Row>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</Table>
|
||||||
|
</Grid.Column>
|
||||||
|
<Grid.Column>
|
||||||
|
<Table collapsing unstackable basic='very'>
|
||||||
|
{clazz.students
|
||||||
|
.filter(x => x.attendance_status !== 'Withdrawn')
|
||||||
|
.slice(15)
|
||||||
|
.map(x =>
|
||||||
|
<Table.Row key={x.id}>
|
||||||
|
<Table.Cell>
|
||||||
|
<Icon name='square outline' size='large' />
|
||||||
|
</Table.Cell>
|
||||||
|
<Table.Cell>
|
||||||
|
{x.student_name}
|
||||||
|
</Table.Cell>
|
||||||
|
</Table.Row>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</Table>
|
||||||
|
</Grid.Column>
|
||||||
|
</Grid>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function AttendanceRow(props) {
|
function AttendanceRow(props) {
|
||||||
const { student, token, refreshClass } = props;
|
const { student, token, refreshClass } = props;
|
||||||
const [error, setError] = useState(false);
|
const [error, setError] = useState(false);
|
||||||
|
@ -67,6 +124,7 @@ export function InstructorClassAttendance(props) {
|
||||||
const [input, setInput] = useState({});
|
const [input, setInput] = useState({});
|
||||||
const [error, setError] = useState(false);
|
const [error, setError] = useState(false);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
const printRef = useRef();
|
||||||
|
|
||||||
const handleValues = (e, v) => setInput({ ...input, [v.name]: v.value });
|
const handleValues = (e, v) => setInput({ ...input, [v.name]: v.value });
|
||||||
|
|
||||||
|
@ -106,6 +164,16 @@ export function InstructorClassAttendance(props) {
|
||||||
|
|
||||||
<Header size='small'>Mark Attendance</Header>
|
<Header size='small'>Mark Attendance</Header>
|
||||||
|
|
||||||
|
{!!clazz.students.length && <div>
|
||||||
|
<div style={{ display: 'none' }}>
|
||||||
|
<AttendanceSheet clazz={clazz} ref={printRef} />
|
||||||
|
</div>
|
||||||
|
<ReactToPrint
|
||||||
|
trigger={() => <Button>Print Attendance Sheet</Button>}
|
||||||
|
content={() => printRef.current}
|
||||||
|
/>
|
||||||
|
</div>}
|
||||||
|
|
||||||
{clazz.students.length ?
|
{clazz.students.length ?
|
||||||
clazz.students.map(x =>
|
clazz.students.map(x =>
|
||||||
<AttendanceRow key={x.id} student={x} {...props} />
|
<AttendanceRow key={x.id} student={x} {...props} />
|
||||||
|
|
|
@ -8724,6 +8724,13 @@ react-scripts@3.3.0:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents "2.1.2"
|
fsevents "2.1.2"
|
||||||
|
|
||||||
|
react-to-print@^2.5.1:
|
||||||
|
version "2.5.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-to-print/-/react-to-print-2.5.1.tgz#eaaff4248910f179788ab15a593ceb3e07527b8c"
|
||||||
|
integrity sha512-HhuujwTmuGYB+yBq52y1pwiv0aooaLTqksMJ6cGKWy+aT+x6zponitZd54swiAeILndxJ7oO+X1F/93XyfT/JA==
|
||||||
|
dependencies:
|
||||||
|
prop-types "^15.7.2"
|
||||||
|
|
||||||
react@^16.12.0:
|
react@^16.12.0:
|
||||||
version "16.12.0"
|
version "16.12.0"
|
||||||
resolved "https://registry.yarnpkg.com/react/-/react-16.12.0.tgz#0c0a9c6a142429e3614834d5a778e18aa78a0b83"
|
resolved "https://registry.yarnpkg.com/react/-/react-16.12.0.tgz#0c0a9c6a142429e3614834d5a778e18aa78a0b83"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user