From c129ec038852b5e83dd18e8225f8598321d9e339 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Chif=20Gerg=C5=91?= <chifgeri97@gmail.com>
Date: Thu, 7 Feb 2019 20:30:36 +0100
Subject: [PATCH] Add Comment section to Applicant profile, create some action
 to handle the creation and get the notes by profile

---
 src/actions/notes.js                     |  34 +++++-
 src/actions/types.js                     |   2 +
 src/components/pages/ApplicantProfile.js | 131 +++++++++++++++++++----
 src/components/pages/EventDetail.js      |  38 ++++---
 src/components/pages/TraineeTableRow.js  |   6 +-
 src/reducers/NoteReducer.js              |  11 +-
 6 files changed, 174 insertions(+), 48 deletions(-)

diff --git a/src/actions/notes.js b/src/actions/notes.js
index 4737c1f..09e353d 100644
--- a/src/actions/notes.js
+++ b/src/actions/notes.js
@@ -5,6 +5,8 @@ import {
   ADD_EVENT_NOTE,
   CLEAR_WRITE,
   DELETE_NOTE,
+  GET_NOTES_BY_PROFILE,
+  ADD_PROFILE_NOTE,
 } from './types';
 
 export const getNotesByEvent = id => (
@@ -21,11 +23,25 @@ export const getNotesByEvent = id => (
   }
 );
 
+export const getNotesByProfile = id => (
+  async (dispatch) => {
+    try {
+      const response = await axios.get('/api/v1/notes/', { params: { profileID: id } });
+      dispatch({
+        type: GET_NOTES_BY_PROFILE,
+        payload: response.data,
+      });
+    } catch (e) {
+      console.log(e);
+    }
+  }
+);
+
 export const writeNote = (event) => {
   return (dispatch => (dispatch({ type: WRITE_NOTE, payload: event.target.value })));
 };
 
-export const postEventNote = ({ eventid, userid, note }) => (
+export const postNote = ({ eventid, userid, note }) => (
   async (dispatch) => {
     try {
       const response = await axios.post('/api/v1/notes/', {
@@ -35,10 +51,18 @@ export const postEventNote = ({ eventid, userid, note }) => (
       });
       if (response.data.id) {
         alert('Sikeres mentĂŠs!');
-        dispatch({
-          type: ADD_EVENT_NOTE,
-          payload: response.data,
-        });
+        if (eventid) {
+          dispatch({
+            type: ADD_EVENT_NOTE,
+            payload: response.data,
+          });
+        }
+        if (userid) {
+          dispatch({
+            type: ADD_PROFILE_NOTE,
+            payload: response.data,
+          });
+        }
       }
     } catch (e) {
       console.log(e);
diff --git a/src/actions/types.js b/src/actions/types.js
index 8608715..8d2c125 100644
--- a/src/actions/types.js
+++ b/src/actions/types.js
@@ -47,6 +47,8 @@ export const WRITE_NOTE = 'write_note';
 export const CLEAR_NOTE = 'clear_note';
 export const ADD_EVENT_NOTE = 'add_note';
 export const DELETE_NOTE = 'delete_note';
+export const ADD_PROFILE_NOTE = 'add_profile_note';
+export const GET_NOTES_BY_PROFILE = 'get_notes_by_profile';
 
 export const GET_PROFILES = 'get_profiles';
 export const SET_STATUS = 'set_status';
diff --git a/src/components/pages/ApplicantProfile.js b/src/components/pages/ApplicantProfile.js
index a8595aa..3db7dc4 100644
--- a/src/components/pages/ApplicantProfile.js
+++ b/src/components/pages/ApplicantProfile.js
@@ -1,9 +1,21 @@
 import React, { Component } from 'react';
-import { Container, Header, Item, Button, Label, List } from 'semantic-ui-react';
+import {
+  Container,
+  Header,
+  Item,
+  Button,
+  Label,
+  List,
+  Form,
+  Comment,
+} from 'semantic-ui-react';
 import { connect } from 'react-redux';
 import { getSelectedProfile, setStatus } from '../../actions/statistics';
+import { getNotesByProfile, writeNote, clearWrite, postNote, deleteNote } from '../../actions/notes';
 import ConfirmModal from '../forms/ConfirmModal';
 
+import moment from 'moment';
+
 const options = [
   { key: 'DT', text: 'DevTeam' },
   { key: 'NET', text: 'NETeam' },
@@ -15,6 +27,7 @@ const options = [
 class ApplicantProfile extends Component {
   componentWillMount() {
     this.props.getSelectedProfile(this.props.match.params.id);
+    this.props.getNotesByProfile(this.props.match.params.id);
   }
 
   renderGroups() {
@@ -29,7 +42,45 @@ class ApplicantProfile extends Component {
     ));
   }
 
+  renderComments() {
+    const notes = this.props.profileNotes;
+    return notes.map((note) => {
+      if (!note.event) {
+        return (
+          <Comment>
+            <Comment.Content>
+              <Comment.Author>{note.created_by_name}</Comment.Author>
+              <Comment.Metadata>
+                {moment(note.created_at).format('LL')}
+              </Comment.Metadata>
+              <Comment.Text>
+                {note.note}
+              </Comment.Text>
+            </Comment.Content>
+            { this.props.user.fullName === note.created_by_name ?
+              <ConfirmModal
+                text='tĂśrĂślni akarod a megjegyzĂŠst'
+                button={
+                  <Button
+                    compact
+                    color='red'
+                    size='mini'
+                  >
+                    Delete
+                  </Button>
+                }
+                onAccept={() => this.props.deleteNote(note)}
+              />
+            :
+            null }
+          </Comment>);
+      }
+      return '';
+    });
+  }
+
   render() {
+    const note = this.props.actualNote;
     const { id, signed, groups, role, full_name, nick, motivation_about, motivation_exercise, motivation_profession }
     = this.props.selectedProfile;
     return (
@@ -90,25 +141,51 @@ class ApplicantProfile extends Component {
           </Item.Content>
         </Item>
         { signed && role !== 'Staff' ?
-          <Container textAlign='center'>
-            <ConfirmModal
-              button={
-                <Button
-                  color='green'
-                >JelentkezĂŠs elfogadĂĄsa
-                </Button>}
-              text='elfogadod a jelentkezĂŠst'
-              onAccept={() => this.props.setStatus(id, 'Student')}
-            />
-            <ConfirmModal
-              button={
+          <Container>
+            <Container textAlign='center'>
+              <ConfirmModal
+                button={
+                  <Button
+                    color='green'
+                  >JelentkezĂŠs elfogadĂĄsa
+                  </Button>}
+                text='elfogadod a jelentkezĂŠst'
+                onAccept={() => this.props.setStatus(id, 'Student')}
+              />
+              <ConfirmModal
+                button={
+                  <Button
+                    color='red'
+                  >JelentkezĂŠs elutasĂ­tĂĄsa
+                  </Button>}
+                text='elutasĂ­tod a jelentkezĂŠst'
+                onAccept={() => this.props.setStatus(id, 'Denied')}
+              />
+            </Container>
+            <Comment.Group>
+              <Header dividing>
+                MegjegyzĂŠsek
+              </Header>
+              {this.renderComments()}
+              <Form reply>
+                <Form.TextArea
+                  value={note.note}
+                  onChange={e => this.props.writeNote(e)}
+                />
                 <Button
-                  color='red'
-                >JelentkezĂŠs elutasĂ­tĂĄsa
-                </Button>}
-              text='elutasĂ­tod a jelentkezĂŠst'
-              onAccept={() => this.props.setStatus(id, 'Denied')}
-            />
+                  onClick={() => {
+                                  this.props.postNote({ userid: id,
+                                                        note: note.note });
+                                  this.props.clearWrite();
+                                }
+                          }
+                  content='MegjegyzĂŠs hozzĂĄadĂĄsa'
+                  labelPosition='left'
+                  icon='edit'
+                  primary
+                />
+              </Form>
+            </Comment.Group>
           </Container>
           :
           null
@@ -118,6 +195,18 @@ class ApplicantProfile extends Component {
   }
 }
 
-const mapStateToProps = ({ trainees: { selectedProfile } }) => ({ selectedProfile });
+const mapStateToProps = ({
+  user,
+  trainees: { selectedProfile },
+  notes: { profileNotes, actualNote }
+}) => ({ user, selectedProfile, profileNotes, actualNote });
 
-export default connect(mapStateToProps, { getSelectedProfile, setStatus })(ApplicantProfile);
+export default connect(mapStateToProps, {
+  getSelectedProfile,
+  setStatus,
+  postNote,
+  getNotesByProfile,
+  writeNote,
+  deleteNote,
+  clearWrite,
+})(ApplicantProfile);
diff --git a/src/components/pages/EventDetail.js b/src/components/pages/EventDetail.js
index 3584835..3bb8a36 100644
--- a/src/components/pages/EventDetail.js
+++ b/src/components/pages/EventDetail.js
@@ -11,7 +11,7 @@ import {
 import { connect } from 'react-redux';
 import moment from 'moment';
 import { getEventById, getTrainees, visitorChange, submitVisitors } from '../../actions/statistics';
-import { getNotesByEvent, writeNote, clearWrite, postEventNote, deleteNote } from '../../actions/notes';
+import { getNotesByEvent, writeNote, clearWrite, postNote, deleteNote } from '../../actions/notes';
 import TraineeTableRow from './TraineeTableRow';
 import ConfirmModal from '../forms/ConfirmModal';
 
@@ -74,19 +74,22 @@ class EventDetail extends Component {
                 {note.note}
               </Comment.Text>
             </Comment.Content>
-            <ConfirmModal
-              text='tĂśrĂślni akarod a megjegyzĂŠst'
-              button={
-                <Button
-                  compact
-                  color='red'
-                  size='mini'
-                >
-                  Delete
-                </Button>
-              }
-              onAccept={() => this.props.deleteNote(note)}
-            />
+            { this.props.user.fullName === note.created_by_name ?
+              <ConfirmModal
+                text='tĂśrĂślni akarod a megjegyzĂŠst'
+                button={
+                  <Button
+                    compact
+                    color='red'
+                    size='mini'
+                  >
+                    Delete
+                  </Button>
+                }
+                onAccept={() => this.props.deleteNote(note)}
+              />
+            :
+            null }
           </Comment>);
       }
       return '';
@@ -162,7 +165,7 @@ class EventDetail extends Component {
               />
               <Button
                 onClick={() => {
-                                this.props.postEventNote({ eventid: event.id,
+                                this.props.postNote({ eventid: event.id,
                                                           note: note.note });
                                 this.props.clearWrite();
                               }
@@ -180,10 +183,11 @@ class EventDetail extends Component {
 }
 
 const mapStateToProps = ({
+  user,
   notes: { eventNotes, actualNote },
   events: { selectedEvent },
   trainees: { trainees }
-}) => ({ eventNotes, selectedEvent, trainees, actualNote });
+}) => ({ user, eventNotes, selectedEvent, trainees, actualNote });
 
 export default connect(mapStateToProps, {
   getEventById,
@@ -193,6 +197,6 @@ export default connect(mapStateToProps, {
   submitVisitors,
   writeNote,
   clearWrite,
-  postEventNote,
+  postNote,
   deleteNote,
 })(EventDetail);
diff --git a/src/components/pages/TraineeTableRow.js b/src/components/pages/TraineeTableRow.js
index 215ef8e..18a5b0e 100644
--- a/src/components/pages/TraineeTableRow.js
+++ b/src/components/pages/TraineeTableRow.js
@@ -10,7 +10,7 @@ import {
 } from 'semantic-ui-react';
 import { connect } from 'react-redux';
 import { visitorChange } from '../../actions/statistics';
-import { writeNote, clearWrite, postEventNote, deleteNote } from '../../actions/notes';
+import { writeNote, clearWrite, postNote, deleteNote } from '../../actions/notes';
 import CommentModal from './CommentModal'
 
 class TraineeTableRow extends Component {
@@ -109,7 +109,7 @@ class TraineeTableRow extends Component {
                       />
                       <Button
                         onClick={() => {
-                                        this.props.postEventNote({ eventid:selectedEvent.id,
+                                        this.props.postNote({ eventid:selectedEvent.id,
                                                                   userid: trainee.id,
                                                                   note: this.state.note });
                                         this.clearWrite();
@@ -132,4 +132,4 @@ class TraineeTableRow extends Component {
   }
 }
 
-export default connect(() => ({}), { writeNote, clearWrite, postEventNote, visitorChange, deleteNote })(TraineeTableRow)
+export default connect(() => ({}), { writeNote, clearWrite, postNote, visitorChange, deleteNote })(TraineeTableRow)
diff --git a/src/reducers/NoteReducer.js b/src/reducers/NoteReducer.js
index 37caf2f..6873040 100644
--- a/src/reducers/NoteReducer.js
+++ b/src/reducers/NoteReducer.js
@@ -4,23 +4,30 @@ import {
   ADD_EVENT_NOTE,
   CLEAR_WRITE,
   DELETE_NOTE,
+  GET_NOTES_BY_PROFILE,
+  ADD_PROFILE_NOTE,
 } from '../actions/types';
 
-const INITIAL_STATE = { eventNotes: [], actualNote: {} };
+const INITIAL_STATE = { eventNotes: [], actualNote: {}, profileNotes: [] };
 
 export default (state = INITIAL_STATE, action) => {
   switch (action.type) {
     case GET_NOTES_BY_EVENT:
       return { ...state, eventNotes: action.payload };
+    case GET_NOTES_BY_PROFILE:
+      return { ...state, profileNotes: action.payload };
     case WRITE_NOTE:
       return { ...state, actualNote: { ...state.actualNote, note: action.payload } };
     case ADD_EVENT_NOTE:
       return { ...state, eventNotes: [...state.eventNotes, action.payload] };
+    case ADD_PROFILE_NOTE:
+      return { ...state, profileNotes: [...state.profileNotes, action.payload] };
     case CLEAR_WRITE:
       return { ...state, actualNote: { note: '' } };
     case DELETE_NOTE:
       state.eventNotes.splice(state.eventNotes.indexOf(action.payload), 1);
-      return { ...state, eventNotes: [...state.eventNotes] };
+      state.profileNotes.splice(state.profileNotes.indexOf(action.payload), 1);
+      return { ...state, eventNotes: [...state.eventNotes], profileNotes: [...state.profileNotes] };
     default:
       return state;
   }
-- 
GitLab