From 8834bf40b98ba510021f6f1396f88f7eec3f5c5b Mon Sep 17 00:00:00 2001 From: Bereczki Sandor <bsandor453@gmail.com> Date: Tue, 29 Jan 2019 15:48:58 +0100 Subject: [PATCH] CorrectionForm Added, Previous Corr. Form made into DetailsPanel --- src/actions/homework.js | 100 ++++++++++++++--- src/actions/types.js | 3 + src/components/forms/AddSolutionForm.js | 10 +- src/components/forms/CorrectSolutionForm.js | 112 ++++++++++++++++++++ src/components/forms/SolutionDetailsForm.js | 43 ++++---- src/components/pages/Homework.js | 4 +- src/reducers/CorrectSolutionReducer.js | 13 +-- src/reducers/HomeworksReducer.js | 8 +- src/reducers/index.js | 2 + 9 files changed, 240 insertions(+), 55 deletions(-) create mode 100644 src/components/forms/CorrectSolutionForm.js diff --git a/src/actions/homework.js b/src/actions/homework.js index f3aff4e..f0a7819 100644 --- a/src/actions/homework.js +++ b/src/actions/homework.js @@ -8,7 +8,10 @@ import { GET_TASKS, WRITE_SOLUTION, WRITE_SOLUTION_FILE, GET_PROFILES, - ADD_DOCUMENT } from './types'; + ADD_DOCUMENT, + GET_DOCUMENTS, + CORRECT_SOLUTION, + CHECK } from './types'; export const getTasks = () => ( async (dispatch) => { @@ -61,20 +64,25 @@ export const addTask = ({ title, text, deadline }) => ( } ); -export const addSolution = ({ - task, accepted, corrected, note, +export const addDocument = ({ + name, description, file, solution, }) => ( async (dispatch) => { try { - const response = await axios.post('/api/v1/homework/solutions/', { - task, - accepted, - corrected, - note, - }); + const formData = new FormData(); + formData.append('name', name); + formData.append('description', description); + formData.append('file', file); + formData.append('solution', solution); + const config = { + headers: { + 'content-type': 'multipart/form-data', + }, + }; + const response = await axios.post('/api/v1/documents/', formData, config); if (response.data.id) { dispatch({ - type: ADD_SOLUTION, + type: ADD_DOCUMENT, payload: response.data, }); } @@ -84,11 +92,28 @@ export const addSolution = ({ } ); -export const addDocument = ({ - name, description, file, solution, +export const addSolution = ({ + task, accepted, corrected, note, name, description, file, }) => ( async (dispatch) => { try { + const response = await axios.post('/api/v1/homework/solutions/', { + task, + accepted, + corrected, + note, + }); + if (response.data.id) { + console.log(response.data.id) + dispatch({ + type: ADD_SOLUTION, + payload: response.data, + }); + } + + const solution = response.data.id; + console.log(solution); + const formData = new FormData(); formData.append('name', name); formData.append('description', description); @@ -99,11 +124,11 @@ export const addDocument = ({ 'content-type': 'multipart/form-data', }, }; - const response = await axios.post('/api/v1/documents/', formData, config); - if (response.data.id) { + const responsedoc = await axios.post('/api/v1/documents/', formData, config); + if (responsedoc.data.id) { dispatch({ type: ADD_DOCUMENT, - payload: response.data, + payload: responsedoc.data, }); } } catch (e) { @@ -112,6 +137,21 @@ export const addDocument = ({ } ); +export const getDocuments = (id, solution) => ( + async (dispatch) => { + try { + const response = + await axios.get('/api/v1/documents', { params: { profileID: id, solutionID: solution } }); + dispatch({ + type: GET_DOCUMENTS, + payload: response.data, + }); + } catch (e) { + console.log(e); + } + } +); + export const writeSolution = ({ target: { name, value } }) => ( (dispatch) => { dispatch({ type: WRITE_SOLUTION, payload: value, target: name }); @@ -155,3 +195,33 @@ export const getProfiles = () => ( } } ); + +export const correctSolution = (id, corrected, accepted, note) => ( + async (dispatch) => { + try { + const response = await axios.patch(`/api/v1/homework/solutions/${id}/`, { + corrected, + accepted, + 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); + } + } +); + +export const check = () => ( + (dispatch) => { + dispatch({ type: CHECK }); + } +); diff --git a/src/actions/types.js b/src/actions/types.js index f46175d..eefcfc9 100644 --- a/src/actions/types.js +++ b/src/actions/types.js @@ -20,6 +20,9 @@ export const WRITE_TASK_DEADLINE = 'write_task_deadline'; export const GET_SOLUTIONS = 'get_solutions'; export const ADD_SOLUTION = 'add_solution'; export const ADD_DOCUMENT = 'add_document'; +export const GET_DOCUMENTS = 'get_documents'; +export const CORRECT_SOLUTION = 'correct_solution'; +export const CHECK = 'check'; export const GET_EVENTS = 'get_events'; export const GET_EVENT_BY_ID = 'get_event_by_id'; diff --git a/src/components/forms/AddSolutionForm.js b/src/components/forms/AddSolutionForm.js index 999bf9a..655a120 100644 --- a/src/components/forms/AddSolutionForm.js +++ b/src/components/forms/AddSolutionForm.js @@ -20,11 +20,6 @@ class AddSolutionForm extends Component { const accepted = false; const sentences = this.props.taskdesc.split('\n'); const note = ''; - let solution = 1; - if ((this.props.homeworks.solutions[this.props.homeworks.solutions.length - 1]) - !== undefined) { - solution = (this.props.homeworks.solutions[this.props.homeworks.solutions.length - 1]).id; - } return ( <Modal open={this.state.showModal} @@ -81,11 +76,8 @@ class AddSolutionForm extends Component { color='green' onClick={() => { this.props.addSolution({ - task, accepted, corrected, note, + task, accepted, corrected, note, name, description, file, }); - this.props.addDocument({ - name, description, file, solution, -}); this.setState({ showModal: false }); }} > diff --git a/src/components/forms/CorrectSolutionForm.js b/src/components/forms/CorrectSolutionForm.js new file mode 100644 index 0000000..019fb59 --- /dev/null +++ b/src/components/forms/CorrectSolutionForm.js @@ -0,0 +1,112 @@ +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'; + +class CorrectSolutionForm extends Component { + constructor(props) { + super(props); + this.state = { + showModal: false, + }; + } + + render() { + const { + studentName, studentFullName, studentId, taskTitle, taskSolutions, + } = this.props; + const taskSolutionsProfile = + taskSolutions.filter(solution => solution.created_by === studentId); + const relevantSolution = taskSolutionsProfile[taskSolutionsProfile.length - 1]; + const relevantDocuments = this.props.homeworks.documents.filter(document => + document.solution === relevantSolution.id).filter(document => + document.uploaded_by_name === studentFullName); + const relevantDocument = relevantDocuments[relevantDocuments.length - 1]; + let fileLink; + if (relevantDocument !== undefined || relevantDocument !== null) { + fileLink = `/media${relevantDocument.file.split('media')[1]}`; + } + + const { note } = this.props.correction; + return ( + <Modal + open={this.state.showModal} + trigger={ + <Button + inverted + color='orange' + style={{ marginRight: '1.5em', marginTop: '1.5em' }} + onClick={() => { this.setState({ showModal: true }); }} + > + {studentName} + </Button> + } + > + <Modal.Header> + A(z) {taskTitle} nevű feladat {studentName} á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')} + <Header as='h5'>A beadott dokumentum:</Header> + {relevantDocument === undefined ? + <p>Nincs fájl.</p> : + <a href={fileLink}>Fájl letöltése</a>} + <Header as='h5'>Elfogadás/ElutasÃtás:</Header> + <Button color={this.props.correction.accepted ? 'green' : 'red'} onClick={() => this.props.check()}> + <Checkbox + label={this.props.correction.accepted + ? 'Elfogadható' + : 'Nem elfogadható'} + checked={this.props.correction.accepted} + /> + </Button> + <Header as='h5'>Megjegyzés:</Header> + <Form> + <Form.Field + control={TextArea} + name='note' + onChange={e => this.props.writeSolution(e)} + value={note} + placeholder='Ãrhatsz megjegyzést a megoldásra...' + /> + </Form> + </Modal.Content> + <Modal.Actions> + <Button + inverted + color='red' + onClick={() => { + this.setState({ showModal: false }); + }} + > + <Icon name='remove' /> Mégse + </Button> + <Button + inverted + color='green' + onClick={() => { + this.props.correctSolution( + relevantSolution.id, + true, + this.props.correction.accepted, + this.props.correction.note, + ); + this.setState({ showModal: false }); + }} + > + <Icon name='checkmark' /> Beadás + </Button> + </Modal.Actions> + </Modal> + ); + } +} + +const mapStateToProps = ({ homeworks, correction, user }) => ({ homeworks, correction, user }); + +export default connect(mapStateToProps, { + correctSolution, + writeSolution, + check, +})(CorrectSolutionForm); diff --git a/src/components/forms/SolutionDetailsForm.js b/src/components/forms/SolutionDetailsForm.js index 104a11a..4485715 100644 --- a/src/components/forms/SolutionDetailsForm.js +++ b/src/components/forms/SolutionDetailsForm.js @@ -1,6 +1,7 @@ import React, { Component } from 'react'; import { Modal, Button, Header, Icon } from 'semantic-ui-react'; import { connect } from 'react-redux'; +import CorrectSolutionForm from './CorrectSolutionForm'; import { emptyMessage } from '../pages/Homework'; class SolutionDetailsForm extends Component { @@ -25,13 +26,13 @@ class SolutionDetailsForm extends Component { solution.created_by === this.props.homeworks.profiles[i].id); if (profileSolutions.length === 0) { - noSubmitStudents.push(this.props.homeworks.profiles[i].nick); + noSubmitStudents.push(this.props.homeworks.profiles[i]); } else if (taskSolutions[taskSolutions.length - 1].corrected === false) { - waitForCorrectionStudents.push(this.props.homeworks.profiles[i].nick); + waitForCorrectionStudents.push(this.props.homeworks.profiles[i]); } else if (taskSolutions[taskSolutions.length - 1].accepted === false) { - noAcceptStudents.push(this.props.homeworks.profiles[i].nick); + noAcceptStudents.push(this.props.homeworks.profiles[i]); } else { - acceptedStudents.push(this.props.homeworks.profiles[i].nick); + acceptedStudents.push(this.props.homeworks.profiles[i]); } } @@ -54,49 +55,47 @@ class SolutionDetailsForm extends Component { <Header as='h3'>Nem érkezett még megoldás:</Header> {noSubmitStudents.length === 0 ? emptyMessage(emptyStudentText) : - noSubmitStudents.map(name => ( - <Button color='blue' style={{ marginRight: '1.5em', marginTop: '1.5em' }}>{name}</Button> + noSubmitStudents.map(student => ( + <Button color='blue' style={{ marginRight: '1.5em', marginTop: '1.5em' }}>{student.nick}</Button> )) } <Header as='h3'>JavÃtásra vár (A névre kattintva kijavÃtható a megoldás):</Header> {waitForCorrectionStudents.length === 0 ? emptyMessage(emptyStudentText) : - waitForCorrectionStudents.map(name => ( - <Button inverted color='orange' style={{ marginRight: '1.5em', marginTop: '1.5em' }}>{name}</Button> + waitForCorrectionStudents.map(student => ( + <CorrectSolutionForm + studentName={student.nick} + studentFullName={student.full_name} + studentId={student.id} + taskTitle={this.props.tasktitle} + taskSolutions={taskSolutions} + /> )) } <Header as='h3'>A megoldás nem elfogadható:</Header> {noAcceptStudents.length === 0 ? emptyMessage(emptyStudentText) : - noAcceptStudents.map(name => ( - <Button color='red' style={{ marginRight: '1.5em', marginTop: '1.5em' }}>{name}</Button> + noAcceptStudents.map(student => ( + <Button color='red' style={{ marginRight: '1.5em', marginTop: '1.5em' }}>{student.nick}</Button> )) } <Header as='h3'>Elfogadva:</Header> {acceptedStudents.length === 0 ? emptyMessage(emptyStudentText) : - acceptedStudents.map(name => ( - <Button color='green' style={{ marginRight: '1.5em', marginTop: '1.5em' }}>{name}</Button> + acceptedStudents.map(student => ( + <Button color='green' style={{ marginRight: '1.5em', marginTop: '1.5em' }}>{student.nick}</Button> )) } </Modal.Content> <Modal.Actions> - <Button - inverted - color='red' - onClick={() => { - this.setState({ showModal: false }); - }} - > - <Icon name='remove' /> Mégse - </Button> <Button inverted color='green' onClick={() => { + this.setState({ showModal: false }); }} > - <Icon name='checkmark' /> Beadás + <Icon name='checkmark' /> Kész </Button> </Modal.Actions> </Modal> diff --git a/src/components/pages/Homework.js b/src/components/pages/Homework.js index f171b65..1bb0ccc 100644 --- a/src/components/pages/Homework.js +++ b/src/components/pages/Homework.js @@ -10,7 +10,7 @@ import { } from 'semantic-ui-react'; import { connect } from 'react-redux'; import moment from 'moment'; -import { getTasks, getSolutions, addTask, addDocument, getProfiles } from '../../actions/homework'; +import { getTasks, getSolutions, addTask, addDocument, getProfiles, getDocuments } from '../../actions/homework'; import AddTaskForm from '../forms/AddTaskForm'; import AddSolutionForm from '../forms/AddSolutionForm'; import SolutionDetailsForm from '../forms/SolutionDetailsForm'; @@ -58,6 +58,7 @@ class Homework extends Component { this.props.getTasks(); this.props.getSolutions(this.props.user.id); this.props.getProfiles(); + this.props.getDocuments(); } getTaskDisplayStyle(task) { @@ -275,5 +276,6 @@ export default connect( addTask, addDocument, getProfiles, + getDocuments, }, )(Homework); diff --git a/src/reducers/CorrectSolutionReducer.js b/src/reducers/CorrectSolutionReducer.js index afde07a..0578837 100644 --- a/src/reducers/CorrectSolutionReducer.js +++ b/src/reducers/CorrectSolutionReducer.js @@ -1,15 +1,16 @@ -import { } from '../actions/types'; +import { WRITE_SOLUTION, CHECK } from '../actions/types'; const INITIAL_STATE = { - can_submit: [], - no_submit: [], - wait_correction: [], - no_accept: [], - accepted: [], + accepted: false, + note: '', }; export default (state = INITIAL_STATE, action) => { switch (action.type) { + case WRITE_SOLUTION: + return { ...state, [action.target]: action.payload }; + case CHECK: + return { ...state, accepted: !state.accepted }; default: return state; } diff --git a/src/reducers/HomeworksReducer.js b/src/reducers/HomeworksReducer.js index da7dfd7..ff11e5a 100644 --- a/src/reducers/HomeworksReducer.js +++ b/src/reducers/HomeworksReducer.js @@ -1,9 +1,11 @@ -import { GET_TASKS, GET_SOLUTIONS, ADD_TASK, ADD_SOLUTION, GET_PROFILES } from '../actions/types'; +import { GET_TASKS, GET_SOLUTIONS, ADD_TASK, ADD_SOLUTION, GET_PROFILES, GET_DOCUMENTS } from '../actions/types'; const INITIAL_STATE = { + id: 0, tasks: [], solutions: [], profiles: [], + documents: [], }; @@ -14,11 +16,13 @@ export default (state = INITIAL_STATE, action) => { case GET_SOLUTIONS: return { ...state, solutions: action.payload }; case ADD_SOLUTION: - return { ...state, solutions: [action.payload, ...state.solutions] }; + return { ...state, solutions: [action.payload, ...state.solutions], id: action.payload.id }; case ADD_TASK: return { ...state, tasks: [action.payload, ...state.tasks] }; case GET_PROFILES: return { ...state, profiles: action.payload }; + case GET_DOCUMENTS: + return { ...state, documents: action.payload }; default: return state; } diff --git a/src/reducers/index.js b/src/reducers/index.js index 51225a9..ff180a9 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -9,6 +9,7 @@ import AddSolutionReducer from './AddSolutionReducer'; import EventReducer from './EventReducer'; import TraineeReducer from './TraineeReducer'; import NoteReducer from './NoteReducer'; +import CorrectSolutionReducer from './CorrectSolutionReducer'; const rootReducer = combineReducers({ user: UserReducer, @@ -16,6 +17,7 @@ const rootReducer = combineReducers({ newNews: AddNewsReducer, selectedNews: EditNewsReducer, homeworks: HomeworksReducer, + correction: CorrectSolutionReducer, newTask: AddTaskReducer, newSolution: AddSolutionReducer, events: EventReducer, -- GitLab