diff --git a/src/actions/auth.js b/src/actions/auth.js index a480dba7a94dc0b614d822fb046b9d84a2f2ca3e..44a29921b6019ae93f5cc665743933d7f4934196 100644 --- a/src/actions/auth.js +++ b/src/actions/auth.js @@ -21,16 +21,16 @@ export const getUserData = () => ( let permission; switch (role) { case 'Applicant': - permission=1; + permission = 1; break; case 'Student': - permission=2; + permission = 2; break; case 'Staff': - permission=3; + permission = 3; break; default: - permission=0; + permission = 0; break; } diff --git a/src/actions/homework.js b/src/actions/homework.js index f0a78193b86bdb457af0947f5eab0795adc48ca3..e10c0122d33b8dc83b672abb20666e40b081b996 100644 --- a/src/actions/homework.js +++ b/src/actions/homework.js @@ -2,7 +2,10 @@ import axios from './session'; import { GET_TASKS, GET_SOLUTIONS, ADD_TASK, + DELETE_TASK, WRITE_TASK, + EDIT_TASK, + SELECT_TASK, CLEAR_WRITE, ADD_SOLUTION, WRITE_SOLUTION, @@ -50,13 +53,10 @@ export const addTask = ({ title, text, deadline }) => ( deadline, }); if (response.data.id) { - alert('Sikeres mentĂŠs!'); dispatch({ type: ADD_TASK, payload: response.data, }); - } else { - alert('MentĂŠs nem sikerĂźlt!'); } } catch (e) { console.log(e); @@ -64,6 +64,53 @@ export const addTask = ({ title, text, deadline }) => ( } ); +export const editTask = ({ + id, + title, + text, + deadline, +}) => ( + async (dispatch) => { + try { + const response = await axios.patch(`/api/v1/homework/tasks/${id}/`, { + title, + text, + deadline, + }); + if (response.data.id) { + dispatch({ + type: EDIT_TASK, + payload: response.data, + + }); + } + } catch (e) { + console.log(e); + } + } +); + +export const deleteTask = task => ( + async (dispatch) => { + try { + const response = await axios.delete(`/api/v1/homework/tasks/${task.id}/`); + if (!response.data.id) { + dispatch({ + type: DELETE_TASK, + payload: task, + }); + } + } catch (e) { + console.log(e); + } + }); + +export const setSelectedTask = task => ( + (dispatch) => { + dispatch({ type: SELECT_TASK, payload: task }); + } +); + export const addDocument = ({ name, description, file, solution, }) => ( @@ -104,7 +151,6 @@ export const addSolution = ({ note, }); if (response.data.id) { - console.log(response.data.id) dispatch({ type: ADD_SOLUTION, payload: response.data, @@ -112,7 +158,6 @@ export const addSolution = ({ } const solution = response.data.id; - console.log(solution); const formData = new FormData(); formData.append('name', name); @@ -205,14 +250,11 @@ export const correctSolution = (id, corrected, accepted, note) => ( note, }); if (response.data.id) { - alert('Sikeres mentĂŠs!'); dispatch({ type: CORRECT_SOLUTION, payload: response.data, }); - } else { - alert('MentĂŠs nem sikerĂźlt!'); } } catch (e) { console.log(e); diff --git a/src/actions/types.js b/src/actions/types.js index 8165bb34715ba887134c281c1d3c247be9344b81..b4c41c3e4f04178db0559898df0578f803dd49c1 100644 --- a/src/actions/types.js +++ b/src/actions/types.js @@ -13,7 +13,10 @@ export const SELECT_NEWS = 'select_news'; export const GET_TASKS = 'get_homeworks'; export const ADD_TASK = 'add_task'; +export const DELETE_TASK = 'delete_task'; +export const EDIT_TASK = 'edit_task'; export const WRITE_TASK = 'write_task'; +export const SELECT_TASK = 'select_task'; export const WRITE_SOLUTION = 'write_solution'; export const WRITE_SOLUTION_FILE = 'write_solution_file'; export const WRITE_TASK_DEADLINE = 'write_task_deadline'; diff --git a/src/components/Header.js b/src/components/Header.js index 57006a16c30a71b40171b884dc013a4f84d2db60..c27945d8c282f067cf1535d76aa49b54437864eb 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -55,7 +55,7 @@ const menuItems = [ prefix: '', permissionLevel: 2, }, -] +]; const FixedMenu = ({ user }) => ( <Menu fixed='top' size='large' pointing> @@ -64,7 +64,7 @@ const FixedMenu = ({ user }) => ( (user.permission >= item.permissionLevel || (item.permissionLevel === 0) ? - <Menu.Item key={i} as={Link} to={item.to}>{item.text}</Menu.Item> + <Menu.Item key={i} as={Link} to={item.to}>{item.text}</Menu.Item> : null))} @@ -105,7 +105,6 @@ class Header extends Component { } - render() { const { visible } = this.state; @@ -124,8 +123,8 @@ class Header extends Component { {menuItems.map((item, i) => (this.props.user.permission >= item.permissionLevel || (item.permissionLevel === 0) ? - <Menu.Item key={i} as={Link} to={item.to}>{item.prefix}{item.text}</Menu.Item> - : + <Menu.Item key={i} as={Link} to={item.to}>{item.prefix}{item.text}</Menu.Item> + : null))} <Menu.Item position='right'> diff --git a/src/components/forms/AddSolutionForm.js b/src/components/forms/AddSolutionForm.js index 655a120c95140484950b679196ef580fa444df4f..ce4ec712c5f7094f8d44cb94d4a53de80d459eac 100644 --- a/src/components/forms/AddSolutionForm.js +++ b/src/components/forms/AddSolutionForm.js @@ -2,6 +2,9 @@ import React, { Component } from 'react'; import { Modal, Button, Form, Input, TextArea, Icon, Header } from 'semantic-ui-react'; import { connect } from 'react-redux'; import { addSolution, writeSolution, writeSolutionFile, addDocument, clearWrite } from '../../actions/homework'; +import './Forms.css'; +import ConfirmModal from '../forms/ConfirmModal'; +import { emptyMessage } from '../pages/Homework'; class AddSolutionForm extends Component { constructor(props) { @@ -20,46 +23,53 @@ class AddSolutionForm extends Component { const accepted = false; const sentences = this.props.taskdesc.split('\n'); const note = ''; + const disabledText = 'A hatĂĄridĹ lejĂĄrt, tovĂĄbbi beadĂĄs nem lehetsĂŠges.' return ( <Modal open={this.state.showModal} trigger={ - <Button basic color='blue' onClick={() => { this.setState({ showModal: true }); }}> + <button + id='task' + onClick={() => { this.setState({ showModal: true }); }} + > <Icon name='external' /> {this.props.tasktitle} - </Button> + </button> } > <Modal.Header> - Ăj megoldĂĄs beadĂĄsa a(z) {this.props.tasktitle} nevĹą feladathoz: + {this.props.multiple ? 'MĂĄsik megoldĂĄs' : 'MegoldĂĄs'} beadĂĄsa a(z) {this.props.tasktitle} nevĹą feladathoz: </Modal.Header> <Modal.Content> <Modal.Description style={{ marginBottom: '2em' }}> <Header as='h5'>Feladat leĂrĂĄsa:</Header> {sentences.map(s => (<p>{s}</p>))} </Modal.Description> - <Form> - <Form.Field - control={Input} - label='MegoldĂĄs cĂme:' - name='name' - onChange={e => this.props.writeSolution(e)} - value={name} - placeholder='Adj meg egy cĂmet a beadandĂł megoldĂĄsodnak...' - /> - <Form.Field - control={TextArea} - label='MegoldĂĄs leĂrĂĄsa:' - name='description' - onChange={e => this.props.writeSolution(e)} - value={description} - placeholder='Add meg a megoldĂĄs leĂrĂĄsĂĄt...' - /> - <Form.Field> - <label>FĂĄjl:</label> - <Input type='file' onChange={e => this.props.writeSolutionFile(e)} /> - </Form.Field> - </Form> + {this.props.disabled ? + emptyMessage(disabledText, undefined, undefined, this.props.disabled) : + <Form> + <Form.Field + control={Input} + label='MegoldĂĄs cĂme:' + name='name' + onChange={e => this.props.writeSolution(e)} + value={name} + placeholder='Adj meg egy cĂmet a beadandĂł megoldĂĄsodnak...' + /> + <Form.Field + control={TextArea} + label='MegoldĂĄs leĂrĂĄsa:' + name='description' + onChange={e => this.props.writeSolution(e)} + value={description} + placeholder='Add meg a megoldĂĄs leĂrĂĄsĂĄt...' + /> + <Form.Field> + <label>FĂĄjl:</label> + <Input type='file' onChange={e => this.props.writeSolutionFile(e)} /> + </Form.Field> + </Form> + } </Modal.Content> <Modal.Actions> <Button @@ -67,22 +77,46 @@ class AddSolutionForm extends Component { color='red' onClick={() => { this.setState({ showModal: false }); + this.props.clearWrite(); }} > <Icon name='remove' /> MĂŠgse </Button> - <Button - inverted - color='green' - onClick={() => { - this.props.addSolution({ - task, accepted, corrected, note, name, description, file, - }); - this.setState({ showModal: false }); - }} - > - <Icon name='checkmark' /> BeadĂĄs - </Button> + {this.props.multiple + ? + <ConfirmModal + button={ + <Button disabled={(name === '' || description === '')} inverted color='green'> + <Icon name='checkmark' /> BeadĂĄs + </Button> + } + text='beadod az Ăşj megoldĂĄst, ami felĂźlĂrja az elĹzĹt' + onAccept={() => { + this.props.addSolution({ + task, accepted, corrected, note, name, description, file, + }); + this.setState({ showModal: false }); + this.props.clearWrite(); + } + } + /> + : + <Button + inverted + color='green' + disabled={(name === '' || description === '')} + onClick={() => { + this.props.addSolution({ + task, accepted, corrected, note, name, description, file, + }); + this.setState({ showModal: false }); + this.props.clearWrite(); + } + } + > + <Icon name='checkmark' /> BeadĂĄs + </Button> + } </Modal.Actions> </Modal> ); diff --git a/src/components/forms/AddTaskForm.js b/src/components/forms/AddTaskForm.js index 9c93fde609b24a13ebdf0190a866f445a041b13e..f08b1b351627cd274bf9aba40fa4666bb196b865 100644 --- a/src/components/forms/AddTaskForm.js +++ b/src/components/forms/AddTaskForm.js @@ -2,6 +2,7 @@ import React, { Component } from 'react'; import { Modal, Button, Form, Input, TextArea, Icon } from 'semantic-ui-react'; import { connect } from 'react-redux'; import { DateTimeInput } from 'semantic-ui-calendar-react'; +import moment from 'moment'; import { addTask, writeTask, writeTaskDeadline, clearWrite } from '../../actions/homework'; class AddTaskForm extends Component { @@ -49,7 +50,7 @@ class AddTaskForm extends Component { /> <Form.Field control={DateTimeInput} - label='BeadĂĄsi hatĂĄridĹ:' + label='BeadĂĄsi hatĂĄridĹ (a jelenlegi idĹnĂŠl kĂŠsĹbbi idĹpont):' name='deadline' placeholder='BeadĂĄsi hatĂĄridĹ' iconPosition='left' @@ -75,6 +76,7 @@ class AddTaskForm extends Component { <Button inverted color='green' + disabled={(title === '' || text === '' || deadline === '' || moment().isAfter(deadline))} onClick={() => { this.props.addTask({ title, text, deadline }); this.setState({ showModal: false }); diff --git a/src/components/forms/CorrectSolutionForm.js b/src/components/forms/CorrectSolutionForm.js index 019fb59f7140f2bf5ad716bb4edc16810bfacdce..8c16e82e051cb92e133b6df06a2e5e08aff29454 100644 --- a/src/components/forms/CorrectSolutionForm.js +++ b/src/components/forms/CorrectSolutionForm.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import { Modal, Button, Icon, Checkbox, Form, TextArea, Header } from 'semantic-ui-react'; import { connect } from 'react-redux'; -import { correctSolution, writeSolution, check } from '../../actions/homework'; +import { correctSolution, writeSolution, check, clearWrite } from '../../actions/homework'; class CorrectSolutionForm extends Component { constructor(props) { @@ -13,7 +13,7 @@ class CorrectSolutionForm extends Component { render() { const { - studentName, studentFullName, studentId, taskTitle, taskSolutions, + studentFullName, studentId, taskTitle, taskSolutions, } = this.props; const taskSolutionsProfile = taskSolutions.filter(solution => solution.created_by === studentId); @@ -23,10 +23,14 @@ class CorrectSolutionForm extends Component { document.uploaded_by_name === studentFullName); const relevantDocument = relevantDocuments[relevantDocuments.length - 1]; let fileLink; - if (relevantDocument !== undefined || relevantDocument !== null) { + if (relevantDocument !== undefined && relevantDocument !== null && + relevantDocument.file !== undefined && relevantDocument.file !== null) { fileLink = `/media${relevantDocument.file.split('media')[1]}`; + } else { + fileLink = null; } + const { note } = this.props.correction; return ( <Modal @@ -38,18 +42,22 @@ class CorrectSolutionForm extends Component { style={{ marginRight: '1.5em', marginTop: '1.5em' }} onClick={() => { this.setState({ showModal: true }); }} > - {studentName} + {studentFullName} </Button> } > <Modal.Header> - A(z) {taskTitle} nevĹą feladat {studentName} ĂĄltal beadott megoldĂĄsĂĄnak kijavĂtĂĄsa: + A(z) {taskTitle} nevĹą feladat {studentFullName} ĂĄltal beadott megoldĂĄsĂĄnak kijavĂtĂĄsa: </Modal.Header> <Modal.Content> <Header as='h5'>A megoldĂĄs leĂrĂĄsa:</Header> - {relevantDocument === undefined ? 'Nincs leĂrĂĄs.' : relevantDocument.description.split('\n')} + { (relevantDocument !== undefined && relevantDocument !== null && + relevantDocument.description !== undefined && relevantDocument.description !== null + && relevantDocument.description !== '') + ? relevantDocument.description.split('\n') + : <p>Nincs leĂrĂĄs.</p>} <Header as='h5'>A beadott dokumentum:</Header> - {relevantDocument === undefined ? + {fileLink === null ? <p>Nincs fĂĄjl.</p> : <a href={fileLink}>FĂĄjl letĂśltĂŠse</a>} <Header as='h5'>ElfogadĂĄs/ElutasĂtĂĄs:</Header> @@ -78,6 +86,7 @@ class CorrectSolutionForm extends Component { color='red' onClick={() => { this.setState({ showModal: false }); + this.props.clearWrite(); }} > <Icon name='remove' /> MĂŠgse @@ -93,6 +102,7 @@ class CorrectSolutionForm extends Component { this.props.correction.note, ); this.setState({ showModal: false }); + this.props.clearWrite(); }} > <Icon name='checkmark' /> BeadĂĄs @@ -109,4 +119,5 @@ export default connect(mapStateToProps, { correctSolution, writeSolution, check, + clearWrite, })(CorrectSolutionForm); diff --git a/src/components/forms/EditTaskForm.js b/src/components/forms/EditTaskForm.js new file mode 100644 index 0000000000000000000000000000000000000000..4f7ed08a71d3d58c1bc9d2294ece65fe7ca4d7a2 --- /dev/null +++ b/src/components/forms/EditTaskForm.js @@ -0,0 +1,112 @@ +import React, { Component } from 'react'; +import { Modal, Button, Form, Input, TextArea, Icon } from 'semantic-ui-react'; +import { connect } from 'react-redux'; +import { DateTimeInput } from 'semantic-ui-calendar-react'; +import moment from 'moment'; +import { writeTask, writeTaskDeadline, editTask, clearWrite } from '../../actions/homework'; + +class EditTaskForm extends Component { + constructor(props) { + super(props); + this.state = { + showModal: false, + }; + } + + render() { + const { + id, + title, + text, + deadline, + } = this.props.selectedTask; + return ( + <Modal + open={this.state.showModal} + onOpen={this.props.onClick} + trigger={ + <Button + inverted + style={{ marginRight: '2em' }} + color='orange' + onClick={() => { this.setState({ showModal: true }); }} + > + <Icon name='edit' /> MĂłdosĂtĂĄs + </Button> + } + > + <Modal.Header>A {title} nevĹą feladat mĂłdosĂtĂĄsa:</Modal.Header> + <Modal.Content> + <Form> + <Form.Field + control={Input} + label='CĂm:' + name='title' + onChange={e => this.props.writeTask(e)} + value={title} + placeholder='Add meg a feladat cĂmĂŠt.' + /> + <Form.Field + control={TextArea} + label='LeĂrĂĄs:' + name='text' + onChange={e => this.props.writeTask(e)} + value={text} + placeholder='Add meg a feladat leĂrĂĄsĂĄt...' + /> + <Form.Field + control={DateTimeInput} + label='BeadĂĄsi hatĂĄridĹ (a jelenlegi idĹnĂŠl kĂŠsĹbbi idĹpont):' + name='deadline' + placeholder='BeadĂĄsi hatĂĄridĹ' + iconPosition='left' + dateTimeFormat='YYYY-MM-DDTHH:mm' + onChange={(e, { name, value }) => { + this.props.writeTaskDeadline({ name, value }); + }} + value={deadline} + /> + </Form> + </Modal.Content> + <Modal.Actions> + <Button + inverted + color='red' + onClick={() => { + this.setState({ showModal: false }); + this.props.clearWrite(); + }} + > + <Icon name='remove' /> MĂŠgse + </Button> + <Button + inverted + color='green' + disabled={(title === '' || text === '' || deadline === '' || moment().isAfter(deadline))} + onClick={() => { + this.props.editTask({ + id, + title, + text, + deadline, + }); + this.setState({ showModal: false }); + this.props.clearWrite(); + }} + > + <Icon name='checkmark' /> MĂłdosĂtĂĄs + </Button> + </Modal.Actions> + </Modal> + ); + } +} + +const mapStateToProps = ({ selectedTask, user }) => ({ selectedTask, user }); + +export default connect(mapStateToProps, { + writeTask, + writeTaskDeadline, + editTask, + clearWrite, +})(EditTaskForm); diff --git a/src/components/forms/Forms.css b/src/components/forms/Forms.css new file mode 100644 index 0000000000000000000000000000000000000000..71f6a49afae5722b7ad339167b3c27f6d5569ef7 --- /dev/null +++ b/src/components/forms/Forms.css @@ -0,0 +1,10 @@ +#task { + border: none; + background-color: inherit; + color: teal; +} + +#task:hover { + color: red; + cursor: pointer; +} diff --git a/src/components/forms/SolutionDetailsForm.js b/src/components/forms/SolutionDetailsForm.js index 44857158865443e808c9f317365654119c8d7c45..ea478511ae50ddc7527bdc1b6a6941cff26f2178 100644 --- a/src/components/forms/SolutionDetailsForm.js +++ b/src/components/forms/SolutionDetailsForm.js @@ -1,8 +1,9 @@ import React, { Component } from 'react'; -import { Modal, Button, Header, Icon } from 'semantic-ui-react'; +import { Modal, Button, Header, Icon, Divider } from 'semantic-ui-react'; import { connect } from 'react-redux'; import CorrectSolutionForm from './CorrectSolutionForm'; import { emptyMessage } from '../pages/Homework'; +import './Forms.css'; class SolutionDetailsForm extends Component { constructor(props) { @@ -25,14 +26,16 @@ class SolutionDetailsForm extends Component { const profileSolutions = taskSolutions.filter(solution => solution.created_by === this.props.homeworks.profiles[i].id); - if (profileSolutions.length === 0) { - noSubmitStudents.push(this.props.homeworks.profiles[i]); - } else if (taskSolutions[taskSolutions.length - 1].corrected === false) { - waitForCorrectionStudents.push(this.props.homeworks.profiles[i]); - } else if (taskSolutions[taskSolutions.length - 1].accepted === false) { - noAcceptStudents.push(this.props.homeworks.profiles[i]); - } else { - acceptedStudents.push(this.props.homeworks.profiles[i]); + if (this.props.homeworks.profiles[i].role === 'Student') { + if (profileSolutions.length === 0) { + noSubmitStudents.push(this.props.homeworks.profiles[i]); + } else if (taskSolutions[taskSolutions.length - 1].corrected === false) { + waitForCorrectionStudents.push(this.props.homeworks.profiles[i]); + } else if (taskSolutions[taskSolutions.length - 1].accepted === false) { + noAcceptStudents.push(this.props.homeworks.profiles[i]); + } else { + acceptedStudents.push(this.props.homeworks.profiles[i]); + } } } @@ -42,23 +45,27 @@ class SolutionDetailsForm extends Component { <Modal open={this.state.showModal} trigger={ - <Button basic color='blue' onClick={() => { this.setState({ showModal: true }); }}> + <button id='task' onClick={() => { this.setState({ showModal: true }); }}> <Icon name='external' /> {this.props.tasktitle} - </Button> + </button> } > <Modal.Header> A megoldĂĄsok beadĂĄsĂĄnak ĂĄllapota a(z) {this.props.tasktitle} nevĹą feladatnĂĄl: </Modal.Header> <Modal.Content> + <Header as='h3'>A feladat leĂrĂĄsa:</Header> + {this.props.taskdesc.split('\n').map(s => (<p>{s}</p>))} + <Divider /> <Header as='h3'>Nem ĂŠrkezett mĂŠg megoldĂĄs:</Header> {noSubmitStudents.length === 0 ? emptyMessage(emptyStudentText) : noSubmitStudents.map(student => ( - <Button color='blue' style={{ marginRight: '1.5em', marginTop: '1.5em' }}>{student.nick}</Button> + <Button color='blue' style={{ marginRight: '1.5em', marginTop: '1.5em' }}>{student.full_name}</Button> )) } + <Divider /> <Header as='h3'>JavĂtĂĄsra vĂĄr (A nĂŠvre kattintva kijavĂthatĂł a megoldĂĄs):</Header> {waitForCorrectionStudents.length === 0 ? emptyMessage(emptyStudentText) : @@ -72,18 +79,20 @@ class SolutionDetailsForm extends Component { /> )) } + <Divider /> <Header as='h3'>A megoldĂĄs nem elfogadhatĂł:</Header> {noAcceptStudents.length === 0 ? emptyMessage(emptyStudentText) : noAcceptStudents.map(student => ( - <Button color='red' style={{ marginRight: '1.5em', marginTop: '1.5em' }}>{student.nick}</Button> + <Button color='red' style={{ marginRight: '1.5em', marginTop: '1.5em' }}>{student.full_name}</Button> )) } + <Divider /> <Header as='h3'>Elfogadva:</Header> {acceptedStudents.length === 0 ? emptyMessage(emptyStudentText) : acceptedStudents.map(student => ( - <Button color='green' style={{ marginRight: '1.5em', marginTop: '1.5em' }}>{student.nick}</Button> + <Button color='green' style={{ marginRight: '1.5em', marginTop: '1.5em' }}>{student.full_name}</Button> )) } </Modal.Content> diff --git a/src/components/pages/Homework.js b/src/components/pages/Homework.js index 1bb0cccf452f47585945802a51cc4bd17694fdbb..12f8fac4e7d4110d425cc360fd301691f168a555 100644 --- a/src/components/pages/Homework.js +++ b/src/components/pages/Homework.js @@ -10,10 +10,21 @@ import { } from 'semantic-ui-react'; import { connect } from 'react-redux'; import moment from 'moment'; -import { getTasks, getSolutions, addTask, addDocument, getProfiles, getDocuments } from '../../actions/homework'; +import { + getTasks, + getSolutions, + addTask, + setSelectedTask, + deleteTask, + addDocument, + getProfiles, + getDocuments, +} from '../../actions/homework'; import AddTaskForm from '../forms/AddTaskForm'; import AddSolutionForm from '../forms/AddSolutionForm'; import SolutionDetailsForm from '../forms/SolutionDetailsForm'; +import EditTaskForm from '../forms/EditTaskForm'; +import ConfirmModal from '../forms/ConfirmModal'; const displayTypes = { can_submit: { @@ -43,11 +54,12 @@ const displayTypes = { }, }; -export const emptyMessage = (header, text, marginBottom) => ( +export const emptyMessage = (header, text, marginBottom, warning) => ( <Message style={{ marginBottom }} - icon='info' + icon={warning ? 'warning' : 'info'} info + warning={warning} header={header} content={text} /> @@ -104,7 +116,13 @@ class Homework extends Component { } > <Table.Cell> - <AddSolutionForm taskid={task.id} tasktitle={task.title} taskdesc={task.text} /> + <AddSolutionForm + taskid={task.id} + tasktitle={task.title} + taskdesc={task.text} + multiple={this.getTaskDisplayStyle(task) !== 'can_submit'} + disabled={moment().isAfter(task.deadline)} + /> </Table.Cell> <Table.Cell> {moment(task.deadline).format('YYYY. MM. DD. HH:mm')} @@ -117,6 +135,16 @@ class Homework extends Component { )); } + const deleteButton = ( + <Button + inverted + style={{ marginRight: '2em' }} + color='red' + > + <Icon name='x' /> TĂśrlĂŠs + </Button> + ); + return this.props.homeworks.tasks .filter(task => moment().isBefore(task.deadline) === active) .map(task => ( @@ -139,8 +167,12 @@ class Homework extends Component { {moment(task.deadline).format('YYYY. MM. DD. HH:mm')} </Table.Cell> <Table.Cell> - <Icon name={displayTypes[this.getTaskDisplayStyle(task)].icon} />{' '} - {displayTypes[this.getTaskDisplayStyle(task)].text} + <EditTaskForm onClick={() => this.props.setSelectedTask(task)} /> + <ConfirmModal + button={deleteButton} + text='tĂśrlĂśd a kivĂĄlaszott feladatot a mĂĄr beadott megoldĂĄsokkal egyĂźtt' + onAccept={() => this.props.deleteTask(task)} + /> </Table.Cell> </Table.Row> )); @@ -155,21 +187,44 @@ class Homework extends Component { marginBottom = '3em'; } + if (!staff) { + return ( + <Table color={tableColor} fixed style={{ marginBottom }}> + <Table.Header> + <Table.Row> + <Table.HeaderCell> + <Icon circular name='home' /> + Feladat megnevezĂŠse / beadĂĄsa + </Table.HeaderCell> + <Table.HeaderCell> + <Icon circular name='calendar' /> + BeadĂĄsi hatĂĄridĹ + </Table.HeaderCell> + <Table.HeaderCell> + <Icon circular name='tasks' /> + Ăllapot + </Table.HeaderCell> + </Table.Row> + </Table.Header> + <Table.Body>{this.renderTaskList(active, staff)}</Table.Body> + </Table> + ); + } return ( <Table color={tableColor} fixed style={{ marginBottom }}> <Table.Header> <Table.Row> <Table.HeaderCell> <Icon circular name='home' /> - Feladat megnevezĂŠse + Feladat megnevezĂŠse / BeadĂĄsok ĂĄllapota </Table.HeaderCell> <Table.HeaderCell> <Icon circular name='calendar' /> BeadĂĄsi hatĂĄridĹ </Table.HeaderCell> <Table.HeaderCell> - <Icon circular name='tasks' /> - Ăllapot + <Icon circular name='edit' /> + MĂłdosĂtĂĄs / TĂśrlĂŠs </Table.HeaderCell> </Table.Row> </Table.Header> @@ -186,7 +241,7 @@ class Homework extends Component { let headerText = 'AktĂv feladatok'; if (staff) { - headerText = 'AktĂv feladatok kijavĂtĂĄsa'; + headerText = 'AktĂv feladatok kijavĂtĂĄsa, mĂłdosĂtĂĄsa vagy tĂśrlĂŠse'; } if ( @@ -198,7 +253,7 @@ class Homework extends Component { if (!active) { if (staff) { - headerText = 'LejĂĄrt hatĂĄridejĹą feladatok kijavĂtĂĄsa'; + headerText = 'LejĂĄrt hatĂĄridejĹą feladatok kijavĂtĂĄsa, mĂłdosĂtĂĄsa vagy tĂśrlĂŠse'; } else { headerText = 'LejĂĄrt hatĂĄridejĹą feladatok'; } @@ -214,14 +269,14 @@ class Homework extends Component { dividing content={headerText} style={{ - fontSize: '3em', + fontSize: '2em', fontWeight: 'normal', marginBottom: 0, marginTop: '0.5em', }} /> {empty - ? emptyMessage(emptyHeaderText, emptyText, marginBottom) + ? emptyMessage(emptyHeaderText, emptyText, marginBottom, false) : this.renderHomeworksTable(active, staff)} </Container> </Segment> @@ -244,9 +299,9 @@ class Homework extends Component { <Header as='h1' dividing - content='HĂĄzi feladat hozzĂĄadĂĄsa, mĂłdosĂtĂĄsa vagy tĂśrlĂŠse' + content='Ăj hĂĄzi feladat lĂŠtrehozĂĄsa' style={{ - fontSize: '3em', + fontSize: '2em', fontWeight: 'normal', marginBottom: '0.5em', marginTop: '0.5em', @@ -266,14 +321,16 @@ class Homework extends Component { } } -const mapStateToProps = ({ homeworks, user }) => ({ homeworks, user }); +const mapStateToProps = ({ selectedTask, homeworks, user }) => ({ selectedTask, homeworks, user }); export default connect( mapStateToProps, { getTasks, + setSelectedTask, getSolutions, addTask, + deleteTask, addDocument, getProfiles, getDocuments, diff --git a/src/reducers/CorrectSolutionReducer.js b/src/reducers/CorrectSolutionReducer.js index 0578837592e065317b78ec748ae0044890b9837e..aa118c5ff1a56e67ba16ec85d246387c64282446 100644 --- a/src/reducers/CorrectSolutionReducer.js +++ b/src/reducers/CorrectSolutionReducer.js @@ -1,4 +1,4 @@ -import { WRITE_SOLUTION, CHECK } from '../actions/types'; +import { WRITE_SOLUTION, CHECK, CLEAR_WRITE } from '../actions/types'; const INITIAL_STATE = { accepted: false, @@ -11,6 +11,8 @@ export default (state = INITIAL_STATE, action) => { return { ...state, [action.target]: action.payload }; case CHECK: return { ...state, accepted: !state.accepted }; + case CLEAR_WRITE: + return INITIAL_STATE; default: return state; } diff --git a/src/reducers/EditTaskReducer.js b/src/reducers/EditTaskReducer.js new file mode 100644 index 0000000000000000000000000000000000000000..0dc50e0b3cb23b8225c9a99a2d6c056f74b58bbf --- /dev/null +++ b/src/reducers/EditTaskReducer.js @@ -0,0 +1,18 @@ +import { SELECT_TASK, WRITE_TASK, WRITE_TASK_DEADLINE, CLEAR_WRITE } from '../actions/types'; + +const INITIAL_STATE = { }; + +export default (state = INITIAL_STATE, action) => { + switch (action.type) { + case SELECT_TASK: + return action.payload; + case WRITE_TASK: + return { ...state, [action.target]: action.payload }; + case WRITE_TASK_DEADLINE: + return { ...state, [action.target]: action.payload }; + case CLEAR_WRITE: + return INITIAL_STATE; + default: + return state; + } +}; diff --git a/src/reducers/HomeworksReducer.js b/src/reducers/HomeworksReducer.js index ff11e5aa56a3e7d819bd49fc18a0e5b7287b674f..fa60aee79c8a321ca58f0f869afb330d18613879 100644 --- a/src/reducers/HomeworksReducer.js +++ b/src/reducers/HomeworksReducer.js @@ -1,4 +1,11 @@ -import { GET_TASKS, GET_SOLUTIONS, ADD_TASK, ADD_SOLUTION, GET_PROFILES, GET_DOCUMENTS } from '../actions/types'; +import { GET_TASKS, + GET_SOLUTIONS, + ADD_TASK, + DELETE_TASK, + EDIT_TASK, + ADD_SOLUTION, + GET_PROFILES, + GET_DOCUMENTS } from '../actions/types'; const INITIAL_STATE = { id: 0, @@ -19,6 +26,23 @@ export default (state = INITIAL_STATE, action) => { return { ...state, solutions: [action.payload, ...state.solutions], id: action.payload.id }; case ADD_TASK: return { ...state, tasks: [action.payload, ...state.tasks] }; + case DELETE_TASK: + return { + ...state, + tasks: [...state.tasks.slice(0, state.tasks.indexOf(action.payload)), + ...state.tasks.slice(state.tasks.indexOf(action.payload) + 1)], + }; + case EDIT_TASK: + return { + ...state, + tasks: [...state.tasks.map((task) => { + if (task.id !== action.payload.id) { + return task; + } + return action.payload; + }), + ], + }; case GET_PROFILES: return { ...state, profiles: action.payload }; case GET_DOCUMENTS: diff --git a/src/reducers/index.js b/src/reducers/index.js index ea06aa7bd2cb1eaeb255cc55d6bc1475035b2479..669501cd37fd79f2d045eb338b24d98244997ed1 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -10,12 +10,14 @@ import EventReducer from './EventReducer'; import NoteReducer from './NoteReducer'; import TraineeReducer from './TraineeReducer'; import CorrectSolutionReducer from './CorrectSolutionReducer'; +import EditTaskReducer from './EditTaskReducer'; const rootReducer = combineReducers({ user: UserReducer, news: NewsReducer, newNews: AddNewsReducer, selectedNews: EditNewsReducer, + selectedTask: EditTaskReducer, events: EventReducer, trainees: TraineeReducer, notes: NoteReducer,