diff --git a/src/actions/auth.js b/src/actions/auth.js index 6e8a85bd37bed86ce3d6f8f371c37413a1d221c6..a480dba7a94dc0b614d822fb046b9d84a2f2ca3e 100644 --- a/src/actions/auth.js +++ b/src/actions/auth.js @@ -9,17 +9,35 @@ export const getUserData = () => ( const { id, join_date: joinDate, + full_name: fullName, nick, motivation_about: motivationAbout, motivation_profession: motivationProfession, motivation_exercise: motivationExercise, signed, groups, + role, } = user.data; + let permission; + switch (role) { + case 'Applicant': + permission=1; + break; + case 'Student': + permission=2; + break; + case 'Staff': + permission=3; + break; + default: + permission=0; + break; + } + dispatch({ type: GET_USERDATA, payload: { - id, joinDate, nick, motivationAbout, motivationProfession, motivationExercise, signed, groups, + id, fullName, joinDate, nick, motivationAbout, motivationProfession, motivationExercise, signed, groups, role, permission }, }); } catch (e) { diff --git a/src/actions/notes.js b/src/actions/notes.js index 04362abded024bf05f5e633f1948309eca9e4ca6..4737c1f411186ebe3133de36ea78a62f3c2f311e 100644 --- a/src/actions/notes.js +++ b/src/actions/notes.js @@ -4,6 +4,7 @@ import { WRITE_NOTE, ADD_EVENT_NOTE, CLEAR_WRITE, + DELETE_NOTE, } from './types'; export const getNotesByEvent = id => ( @@ -29,7 +30,7 @@ export const postEventNote = ({ eventid, userid, note }) => ( try { const response = await axios.post('/api/v1/notes/', { event: eventid ? eventid : '', - profile: userid ? eventid : '', + profile: userid ? userid : '', note, }); if (response.data.id) { @@ -49,3 +50,21 @@ export const clearWrite = () => ( dispatch({ type: CLEAR_WRITE }); } ); + +export const deleteNote = note => ( + async (dispatch) => { + try { + const response = await axios.delete(`/api/v1/notes/${note.id}/`); + if (!response.data.id) { + alert('Sikeres tĂśrlĂŠs!'); + dispatch({ + type: DELETE_NOTE, + payload: note, + }); + } else { + alert('A tĂśrlĂŠs nem sikerĂźlt!'); + } + } catch (e) { + console.log(e); + } + }); diff --git a/src/actions/statistics.js b/src/actions/statistics.js index 591057d0af5189e5f734fbc87a04a6dbfc5b8c9e..1f92b1e2e54fe6001ef4d8722dc34e18136a9acb 100644 --- a/src/actions/statistics.js +++ b/src/actions/statistics.js @@ -7,13 +7,20 @@ import { WRITE_EVENT, ADD_EVENT, DELETE_EVENT, - GET_TRAINEE_BY_ID, + GET_PROFILES, + GET_SELECTED_PROFILE, + SET_STATUS, + ABSENT_CHANGE, + CHANGE_NO, + EDIT_EVENT, + WRITE_EDITED_EVENT, + SELECT_EVENT_FOR_EDIT, } from './types'; -export const getEvents = () => ( +export const getStaffEvents = () => ( async (dispatch) => { try { - const response = await axios.get('/api/v1/events/'); + const response = await axios.get('/api/v1/staff_events/'); dispatch({ type: GET_EVENTS, payload: response.data, @@ -24,12 +31,12 @@ export const getEvents = () => ( } ); -export const getEventById = id => ( +export const getStudentEvents = () => ( async (dispatch) => { try { - const response = await axios.get(`/api/v1/events/${id}`); + const response = await axios.get('/api/v1/student_events/'); dispatch({ - type: GET_EVENT_BY_ID, + type: GET_EVENTS, payload: response.data, }); } catch (e) { @@ -38,12 +45,12 @@ export const getEventById = id => ( } ); -export const getTraineeById = id => ( +export const getEventById = id => ( async (dispatch) => { try { - const response = await axios.get(`/api/v1/profiles/${id}`); + const response = await axios.get(`/api/v1/staff_events/${id}`); dispatch({ - type: GET_TRAINEE_BY_ID, + type: GET_EVENT_BY_ID, payload: response.data, }); } catch (e) { @@ -55,7 +62,7 @@ export const getTraineeById = id => ( export const getTrainees = () => ( async (dispatch) => { try { - const response = await axios.get('/api/v1/profiles/'); + const response = await axios.get('/api/v1/profiles/', { params: { role: 'Student' } }); dispatch({ type: GET_TRAINEES, payload: response.data, @@ -66,16 +73,28 @@ export const getTrainees = () => ( } ); -export const visitorChange = ({ id }) => { - return (dispatch => (dispatch({ type: VISITOR_CHANGE, payload: id }))); +export const visitorChange = ({ id, value }) => { + switch (value){ + case 'Visitor': + return (dispatch => (dispatch({ type: VISITOR_CHANGE, payload: id }))); + case 'Absent': + return (dispatch => (dispatch({ type: ABSENT_CHANGE, payload: id }))); + case 'No': + return (dispatch => (dispatch({ type: CHANGE_NO, payload: id }))); + default: + } }; -export const submitVisitors = ({ id, visitors }) => ( +export const submitVisitors = ({ id, visitors, absent }) => ( async () => { try { - const response = await axios.patch(`/api/v1/events/${id}/`, { - visitors + const response = await axios.patch(`/api/v1/staff_events/${id}/`, { + visitors, + absent, }); + if (response.data.id) { + alert('Sikeres mentĂŠs!'); + } } catch (e) { console.log(e); } @@ -88,19 +107,50 @@ export const writeEvent = ({ target: { name, value } }) => ( } ); +export const selectEventForEdit = editEvent => ( + (dispatch) => { + dispatch({ type: SELECT_EVENT_FOR_EDIT, payload: editEvent }); + } +); -export const eventDate = (name, value) => ( +export const writeEditEvent = ({ target: { name, value } }) => ( (dispatch) => { - dispatch({ type: WRITE_EVENT, payload: value, target: name }); + dispatch({ type: WRITE_EDITED_EVENT, payload: value, target: name }); + } +); + +export const editEvent = ({ id, name, description, date }) => ( + async (dispatch) => { + try { + const response = await axios.patch(`/api/v1/staff_events/${id}/`, { + name, + description, + date, + }); + if (response.data.id) { + alert('Sikeres mentĂŠs!'); + dispatch({ + type: EDIT_EVENT, + payload: response.data, + + }); + } else { + alert('MentĂŠs nem sikerĂźlt!'); + } + } catch (e) { + console.log(e); + } } ); -export const addEvent = ({ name, date }) => ( +export const addEvent = ({ name, date, description }) => ( async (dispatch) => { try { - const response = await axios.post('/api/v1/events/', { + const response = await axios.post('/api/v1/staff_events/', { name, date, + description, + absent: [], }); if (response.data.id) { alert('Sikeres mentĂŠs!'); @@ -120,7 +170,7 @@ export const addEvent = ({ name, date }) => ( export const deleteEvent = event => ( async (dispatch) => { try { - const response = await axios.delete(`/api/v1/events/${event.id}/`); + const response = await axios.delete(`/api/v1/staff_events/${event.id}/`); if (!response.data.id) { alert('Sikeres tĂśrlĂŠs!'); dispatch({ @@ -134,3 +184,49 @@ export const deleteEvent = event => ( console.log(e); } }); + +export const getProfiles = () => ( + async (dispatch) => { + try { + const response = await axios.get('/api/v1/profiles/'); + dispatch({ + type: GET_PROFILES, + payload: response.data, + }); + } catch (e) { + console.log(e); + } + } +); + +export const setStatus = (id, status) => ( + async (dispatch) => { + try { + const response = await axios.patch(`/api/v1/profiles/${id}/`, { + role: status, + }); + if (response.data.id) { + dispatch({ + type: SET_STATUS, + payload: response.data, + }); + } + } catch (e) { + console.log(e); + } + } +); + +export const getSelectedProfile = id => ( + async (dispatch) => { + try { + const response = await axios.get(`/api/v1/profiles/${id}/`); + dispatch({ + type: GET_SELECTED_PROFILE, + payload: response.data, + }); + } catch (e) { + console.log(e); + } + } +); diff --git a/src/actions/types.js b/src/actions/types.js index d98b3229726dabb3b7c5c7963d0306224437ee61..1922943890a4a208430bab2dd0de83e9c8e989e0 100644 --- a/src/actions/types.js +++ b/src/actions/types.js @@ -15,14 +15,23 @@ export const GET_EVENTS = 'get_events'; export const GET_EVENT_BY_ID = 'get_event_by_id'; export const GET_TRAINEES = 'get_trainees'; -export const GET_TRAINEE_BY_ID = 'get_trainee_by_id'; export const VISITOR_CHANGE = 'visitor_change'; +export const ABSENT_CHANGE = 'absent_change'; +export const CHANGE_NO = 'change_no'; export const GET_NOTES_BY_EVENT = 'get_notes_by_event'; export const WRITE_EVENT = 'write_event'; +export const WRITE_EDITED_EVENT = 'write_selected_event'; export const ADD_EVENT = 'add_event'; +export const SELECT_EVENT_FOR_EDIT = 'select_event_for_edit'; +export const EDIT_EVENT = 'edit_event'; export const DELETE_EVENT = 'delete_event'; 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 GET_PROFILES = 'get_profiles'; +export const SET_STATUS = 'set_status'; +export const GET_SELECTED_PROFILE = 'get_selected_profile'; diff --git a/src/components/Header.js b/src/components/Header.js index e84ddf4c3401303828a2e11712467f1d0d9a5c0b..a8ee7e3ae3a1ad2f9154b1b6748d388ca2b36167 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -12,39 +12,55 @@ import { connect } from 'react-redux'; import { getUserData } from '../actions'; import KSZKlogo from './images/kszk_logo.svg'; - const menuItems = [ { text: 'FĹoldal', to: '/home', prefix: <Image size='mini' src={KSZKlogo} style={{ marginRight: '1.5em' }} />, + permissionLevel: 0, }, { text: 'HĂrek', to: '/news', prefix: '', + permissionLevel: 0, }, { text: 'KĂśreink', to: '/groups', prefix: '', + permissionLevel: 0, }, { text: 'Ătemterv', to: '/schedule', prefix: '', + permissionLevel: 1, }, { text: 'Statisztika', to: '/statistics', prefix: '', + permissionLevel: 3, + }, + { + text: 'JelentkezĂŠsek', + to: '/applications', + prefix: '', + permissionLevel: 3, }, ] const FixedMenu = ({ user }) => ( <Menu fixed='top' size='large' pointing> <Container> - {menuItems.map( (item, i) => <Menu.Item key={i} as={Link} to={item.to}>{item.text}</Menu.Item>)} + {menuItems.map((item, i) => + (user.permission >= item.permissionLevel || + (item.permissionLevel === 0) + ? + <Menu.Item key={i} as={Link} to={item.to}>{item.text}</Menu.Item> + : + null))} <Menu.Menu position='right'> <Menu.Item className='item'> @@ -82,6 +98,8 @@ class Header extends Component { this.setState({ visible: true }); } + + render() { const { visible } = this.state; @@ -97,11 +115,12 @@ class Header extends Component { <Container> <Menu inverted secondary size='large'> - {menuItems.map( - (item, i) => ( + {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> - ) - )} + : + null))} <Menu.Item position='right'> { diff --git a/src/components/Main.js b/src/components/Main.js index 8f917c698f0801312f9870b569a30b4a5b83a1d1..b9a90787a4da001d8d3855c54cf0230037bcb02c 100644 --- a/src/components/Main.js +++ b/src/components/Main.js @@ -9,7 +9,9 @@ import Profile from './pages/Profile'; import Statistics from './pages/Statistics'; import Groups from './pages/Groups'; import News from './pages/News'; +import Applications from './pages/Applications'; import EventDetail from './pages/EventDetail'; +import ApplicantProfile from './pages/ApplicantProfile'; const Main = () => ( <Switch> @@ -22,6 +24,8 @@ const Main = () => ( <Route path='/statistics' component={Statistics} /> <Route path='/groups' component={Groups} /> <Route path='/events/:id' component={EventDetail} /> + <Route path='/applications' component={Applications} /> + <Route path='/applicant/:id' component={ApplicantProfile} /> <Route component={NotFound} /> </Switch> ); diff --git a/src/components/forms/AddEventForm.js b/src/components/forms/AddEventForm.js index af8c4b12e8b0d88922a815fb5884b66077178e65..22b4016f42da3e2bdc3cc8609bf7f41939f83fe0 100644 --- a/src/components/forms/AddEventForm.js +++ b/src/components/forms/AddEventForm.js @@ -1,8 +1,9 @@ import React, { Component } from 'react'; -import { Modal, Button, Form, Input, TextArea, Icon } from 'semantic-ui-react'; +import { Modal, Button, Form, Input, Icon } from 'semantic-ui-react'; import { connect } from 'react-redux'; import { DateTimeInput } from 'semantic-ui-calendar-react'; -import { writeEvent, eventDate, addEvent } from '../../actions/statistics' +import { writeEvent, addEvent } from '../../actions/statistics' +import { clearWrite } from '../../actions/news' class AddEventForm extends Component { constructor(props) { @@ -20,11 +21,11 @@ class AddEventForm extends Component { if (this.state.hasOwnProperty(name)) { this.setState({ [name]: value }); } - this.props.eventDate(name, value) + this.props.writeEvent({ target: {name, value} }); } render() { - const { name, date } = this.props.newEvent; + const { name, date, description } = this.props.newEvent; return ( <Modal open={this.state.showModal} @@ -39,7 +40,7 @@ class AddEventForm extends Component { <Modal.Header>Ăj alkalom:</Modal.Header> <Modal.Content style={{ - paddingTop: '50px', + paddingTop: '20px', }} > <Form> @@ -50,16 +51,23 @@ class AddEventForm extends Component { onChange={e => this.props.writeEvent(e)} value={name} style={{ - marginBottom: '50px', + marginBottom: '20px', }} - placeholder='Title' + placeholder='NĂŠv' + /> + <Form.TextArea + name='description' + label='LeĂrĂĄs:' + placeholder='RĂśvid leĂrĂĄs' + value={description} + onChange={e => this.props.writeEvent(e)} /> <DateTimeInput name="date" label="DĂĄtum:" dateFormat='YYYY-MM-DD' - placeholder="Date" - value={this.state.date} + placeholder="DĂĄtum" + value={date} iconPosition="left" onChange={this.handleChange} /> @@ -69,10 +77,11 @@ class AddEventForm extends Component { <Button inverted color='red' - onClick={() => { this.setState({ showModal: false }); }} + onClick={() => { this.setState({ showModal: false }); + this.props.clearWrite();}} > <Icon name='remove' /> - Cancel + MĂŠgse </Button> <Button inverted @@ -80,9 +89,10 @@ class AddEventForm extends Component { onClick={() => { this.props.addEvent(this.props.newEvent); this.setState({ showModal: false, date: '' }); + this.props.clearWrite(); }} > - <Icon name='checkmark' /> Add + <Icon name='checkmark' /> HozzĂĄad </Button> </Modal.Actions> </Modal> @@ -92,4 +102,4 @@ class AddEventForm extends Component { const mapStateToProps = ({ events: { newEvent } }) => ({ newEvent }); -export default connect(mapStateToProps, { writeEvent, addEvent, eventDate })(AddEventForm); +export default connect(mapStateToProps, { writeEvent, addEvent, clearWrite })(AddEventForm); diff --git a/src/components/forms/AddNewsForm.js b/src/components/forms/AddNewsForm.js index 0a1103249b65a530a58aa6f899a60a736d7ace9a..24deefa957e9f4cd515baca9deeb28b26a5a3be7 100644 --- a/src/components/forms/AddNewsForm.js +++ b/src/components/forms/AddNewsForm.js @@ -31,19 +31,19 @@ class AddNewsForm extends Component { <Form> <Form.Field control={Input} - label='Title' + label='CĂm' name='title' onChange={e => this.props.writeNews(e)} value={title} - placeholder='Title' + placeholder='CĂm' /> <Form.Field control={TextArea} - label='Text' + label='SzĂśveg' name='text' onChange={e => this.props.writeNews(e)} value={text} - placeholder='Tell us what you want...' + placeholder='SzĂśveg' /> </Form> </Modal.Content> @@ -54,7 +54,7 @@ class AddNewsForm extends Component { onClick={() => { this.setState({ showModal: false }); }} > <Icon name='remove' /> - Cancel + MĂŠgse </Button> <Button inverted @@ -65,7 +65,7 @@ class AddNewsForm extends Component { this.props.clearWrite(); }} > - <Icon name='checkmark' /> Add + <Icon name='checkmark' /> HozzĂĄad </Button> </Modal.Actions> </Modal> diff --git a/src/components/forms/ConfirmModal.js b/src/components/forms/ConfirmModal.js new file mode 100644 index 0000000000000000000000000000000000000000..4e196ff1d2703afa7f82e5a6a60d8ce5f43032ba --- /dev/null +++ b/src/components/forms/ConfirmModal.js @@ -0,0 +1,60 @@ +import React, { Component } from 'react'; +import { Button, Header, Icon, Modal } from 'semantic-ui-react'; + +class ConfirmModal extends Component { + constructor(props) { + super(props); + this.state = { + showModal: false, + }; + } + + close = () => this.setState({ showModal: false }) + + open = () => this.setState({ showModal: true}) + + render() { + const { button, text, onAccept } = this.props; + const open = this.state.showModal; + return ( + <Modal + open={open} + closeOnDimmerClick + trigger={button} + onOpen={this.open} + onClose={this.close} + size='small' + basic + > + <Header icon='question' content='MegerĹsĂtĂŠs' /> + <Modal.Content> + <p> + Biztos hogy {text}? + </p> + </Modal.Content> + <Modal.Actions> + <Button + basic + color='red' + inverted + onClick={() => this.close()} + > + <Icon name='remove' /> Nem + </Button> + <Button + color='green' + inverted + onClick={() => { onAccept(); + this.close(); + } + } + > + <Icon name='checkmark' /> Igen + </Button> + </Modal.Actions> + </Modal> + ); + } +} + +export default ConfirmModal; diff --git a/src/components/forms/EditEventForm.js b/src/components/forms/EditEventForm.js new file mode 100644 index 0000000000000000000000000000000000000000..fd50446b7a47901767cb89964d956fe6ef19874e --- /dev/null +++ b/src/components/forms/EditEventForm.js @@ -0,0 +1,112 @@ +import React, { Component } from 'react'; +import { Modal, Button, Form, Input, Icon } from 'semantic-ui-react'; +import { connect } from 'react-redux'; +import moment from 'moment'; +import { DateTimeInput } from 'semantic-ui-calendar-react'; +import { + writeEditEvent, + editEvent, +} from '../../actions/statistics' +import { clearWrite } from '../../actions/news' + +class EditEventForm extends Component { + constructor(props) { + super(props); + this.state = { + showModal: false, + date: '', + }; + } + + // Handling change in redux action creator throws an exception + // Temporal solotion using the components state to display, instead redux state + handleChange = (event, {name, value}) => { + if (this.state.hasOwnProperty(name)) { + this.setState({ [name]: value }); + } + this.props.writeEditEvent({target: {name: name, value: value}}) + } + + render() { + const { name, date, description } = this.props.editedEvent; + return ( + <Modal + open={this.state.showModal} + trigger={ + <Button + compact + onClick={() => { this.props.onClick(); + this.setState({ showModal: true }); }} + size='mini' + > + Szerkeszt + </Button> + } + > + <Modal.Header>Alkalom szerkesztĂŠse:</Modal.Header> + <Modal.Content + style={{ + paddingTop: '20px', + }} + > + <Form> + <Form.Field + control={Input} + label='NĂŠv' + name='name' + onChange={e => this.props.writeEditEvent(e)} + value={name} + style={{ + marginBottom: '20px', + }} + placeholder='NĂŠv' + /> + <Form.TextArea + name='description' + label='LeĂrĂĄs:' + placeholder='RĂśvid leĂrĂĄs' + value={description} + onChange={e => this.props.writeEditEvent(e)} + /> + <DateTimeInput + name="date" + label="DĂĄtum:" + dateFormat='YYYY-MM-DD' + placeholder="DĂĄtum" + value={moment(date).format('YYYY-MM-DD hh:mm')} + iconPosition="left" + onChange={this.handleChange} + /> + </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' + onClick={() => { + this.props.editEvent(this.props.editedEvent); + this.setState({ showModal: false, date: '' }); + this.props.clearWrite(); + }} + > + <Icon name='checkmark' /> Szerkeszt + </Button> + </Modal.Actions> + </Modal> + ); + } +} + +const mapStateToProps = ({ events: { editedEvent } }) => ({ editedEvent }); + +export default connect(mapStateToProps, { writeEditEvent, editEvent, clearWrite })(EditEventForm); diff --git a/src/components/forms/EditNewsForm.js b/src/components/forms/EditNewsForm.js index 7107e8d947e76d4fbbbc69cf448baf3f631b2e42..da1944bf92a0d9a8b75dbfc328f7cf9b8ff76424 100644 --- a/src/components/forms/EditNewsForm.js +++ b/src/components/forms/EditNewsForm.js @@ -25,7 +25,7 @@ class EditNewsForm extends Component { onClick={() => { this.setState({ showModal: true }); }} size='mini' > - Edit + Szerkeszt </Button> } > @@ -34,19 +34,19 @@ class EditNewsForm extends Component { <Form> <Form.Field control={Input} - label='Title' + label='CĂm' name='title' onChange={e => this.props.writeNews(e)} value={title} - placeholder='Title' + placeholder='CĂm' /> <Form.Field control={TextArea} - label='Text' + label='SzĂśveg' name='text' onChange={e => this.props.writeNews(e)} value={text} - placeholder='Tell us what you want...' + placeholder='SzĂśveg' /> </Form> </Modal.Content> @@ -56,7 +56,7 @@ class EditNewsForm extends Component { color='red' onClick={() => { this.setState({ showModal: false }); }} > - <Icon name='remove' /> Cancel + <Icon name='remove' /> MĂŠgse </Button> <Button inverted @@ -69,7 +69,7 @@ class EditNewsForm extends Component { this.props.clearWrite(); }} > - <Icon name='checkmark' /> Edit + <Icon name='checkmark' /> Szerkeszt </Button> </Modal.Actions> </Modal> diff --git a/src/components/pages/ApplicantProfile.js b/src/components/pages/ApplicantProfile.js new file mode 100644 index 0000000000000000000000000000000000000000..535617c75f03d53c51b485bdf0578051c346a6df --- /dev/null +++ b/src/components/pages/ApplicantProfile.js @@ -0,0 +1,95 @@ +import React, { Component } from 'react'; +import { Container, Header, Item, Button, Label } from 'semantic-ui-react'; +import { connect } from 'react-redux'; +import { getSelectedProfile, setStatus } from '../../actions/statistics'; +import ConfirmModal from '../forms/ConfirmModal'; + +class ApplicantProfile extends Component { + componentWillMount() { + this.props.getSelectedProfile(this.props.match.params.id); + } + + render() { + const { id, signed, role, full_name, nick, motivation_about, motivation_exercise, motivation_profession } + = this.props.selectedProfile; + return ( + <Container style={{ padding: '60px' }}> + <Item> + <Item.Content> + <Container textAlign='center'> + <Header as='h2'>{full_name}</Header> + <Item.Meta>{nick}</Item.Meta> + </Container> + <Item.Description> + <Container textAlign='justified' style={{ padding: '30px' }}> + <Header as='h3'>MagamrĂłl, eddigi tevĂŠkenysĂŠgem:</Header> + <p>{motivation_about}</p> + <Header as='h3'>Szakmai motivĂĄciĂł:</Header> + <p>{motivation_profession}</p> + <Header as='h3'>Feladatok megoldĂĄsa:</Header> + <p>{motivation_exercise}</p> + </Container> + <Container textAlign='center' style={{ padding: '20px' }}> + <Header as='h3'>StĂĄtusz:</Header> + { signed ? + <div> + { role === 'Student' ? + <Label color='green' size='huge'>Elfogadva</Label> + : + null + } + { role === 'Staff' ? + <Label color='blue' size='huge'>Staff</Label> + : + null + } + { role === 'Applicant' ? + <Label color='orange' size='huge'>Jelentkezett</Label> + : + null + } + { role === 'Denied' ? + <Label color='red' size='huge'>ElutasĂtva</Label> + : + null + } + </div> + : + <Label color='red' size='huge'>Nem jelentkezett</Label> + } + </Container> + </Item.Description> + </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={ + <Button + color='red' + >JelentkezĂŠs elutasĂtĂĄsa + </Button>} + text='elutasĂtod a jelentkezĂŠst' + onAccept={() => this.props.setStatus(id, 'Denied')} + /> + </Container> + : + null + } + </Container> + ); + } +} + +const mapStateToProps = ({ trainees: { selectedProfile } }) => ({ selectedProfile }); + +export default connect(mapStateToProps, { getSelectedProfile, setStatus })(ApplicantProfile); diff --git a/src/components/pages/Applications.js b/src/components/pages/Applications.js new file mode 100644 index 0000000000000000000000000000000000000000..68e6ce9ca2521880986e17a23f95da35bb155aec --- /dev/null +++ b/src/components/pages/Applications.js @@ -0,0 +1,99 @@ +import React, { Component } from 'react'; +import { Link } from 'react-router-dom'; +import { Container, Table, Label, Button } from 'semantic-ui-react'; +import { connect } from 'react-redux'; +import { getProfiles, setStatus } from '../../actions/statistics'; +import ConfirmModal from '../forms/ConfirmModal'; + +class Applications extends Component { + componentWillMount() { + this.props.getProfiles(); + } + + renderApplicants() { + return this.props.profiles.map((profile) => + { return ( + <Table.Row> + <Table.Cell> + <Link to={`applicant/${profile.id}`}> + {profile.full_name} + </Link> + </Table.Cell> + { profile.signed ? + <Table.Cell textAlign='center'> + { profile.role === 'Student' ? + <Label color='green'>Elfogadva</Label> + : + null + } + { profile.role === 'Staff' ? + <Label color='blue'>Staff</Label> + : + null + } + { profile.role === 'Applicant' ? + <Label color='orange'>Jelentkezett</Label> + : + null + } + { profile.role === 'Denied' ? + <Label color='red'>ElutasĂtva</Label> + : + null + } + </Table.Cell> + : + <Table.Cell textAlign='center'> + { profile.role === 'Staff' ? + <Label color='blue'>Staff</Label> + : + <Label color='red'>Nem jelentkezett</Label> + } + </Table.Cell> + } + <Table.Cell> + <ConfirmModal + button = {<Button + color='blue' + size='tiny' + > + Staff jog adĂĄs + </Button>} + text='staff jogot adsz neki' + onAccept={() => this.props.setStatus(profile.id, 'Staff')} + /> + </Table.Cell> + </Table.Row> + ); + }); + } + + render() { + return ( + <Container + textAlign='center' + style={{ + padding: '80px' + }} + > + <Table color='blue' celled selectable compact> + <Table.Header> + <Table.Row> + <Table.HeaderCell>Jelentkezettek</Table.HeaderCell> + <Table.HeaderCell textAlign='center'>JelentkezĂŠs stĂĄtusza:</Table.HeaderCell> + <Table.HeaderCell /> + </Table.Row> + </Table.Header> + + <Table.Body> + {this.renderApplicants()} + </Table.Body> + </Table> + </Container> + ); + } +} + +const mapStateToProps = ({ trainees: { profiles }, user }) => ({ profiles, user }); + +export default connect(mapStateToProps, { getProfiles, setStatus })(Applications); diff --git a/src/components/pages/CommentModal.js b/src/components/pages/CommentModal.js new file mode 100644 index 0000000000000000000000000000000000000000..eeba0feeb2628c848cdb518bd7b6ad3a07c37978 --- /dev/null +++ b/src/components/pages/CommentModal.js @@ -0,0 +1,58 @@ +import React, { Component } from 'react'; +import { connect } from 'react-redux'; +import { Button, Comment, Modal } from 'semantic-ui-react'; +import { deleteNote } from '../../actions/notes'; +import ConfirmModal from '../forms/ConfirmModal'; + +class CommentModal extends Component { + renderComments() { + const { notes, user } = this.props; + return notes.map((note) => { + return ( + <Comment key={note.id}> + <Comment.Content> + <Comment.Author>{note.created_by_name}</Comment.Author> + <Comment.Text> + {note.note} + </Comment.Text> + { note.created_by_name === user.fullName ? + <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.Content> + </Comment> + ); + }); + } + render() { + return ( + <Modal + closeIcon + trigger={ + <Button icon='comment alternate outline' /> + } + > + <Modal.Header>MegjegyzĂŠsek:</Modal.Header> + <Modal.Content> + {this.renderComments()} + </Modal.Content> + </Modal> + ); + } +} + +const mapStateToProps = ({ user }) => ({ user }); + +export default connect(mapStateToProps, { deleteNote })(CommentModal); diff --git a/src/components/pages/EventDetail.js b/src/components/pages/EventDetail.js index 685697d0259b8fc4a10255e4ac59988948c0b584..fc748e5e90b481b71b1463bba924661d794e160b 100644 --- a/src/components/pages/EventDetail.js +++ b/src/components/pages/EventDetail.js @@ -7,14 +7,13 @@ import { Form, Header, Table, - Icon, - Checkbox, - Popup, } from 'semantic-ui-react'; import { connect } from 'react-redux'; import moment from 'moment'; import { getEventById, getTrainees, visitorChange, submitVisitors } from '../../actions/statistics'; -import { getNotesByEvent, writeNote, clearWrite, postEventNote } from '../../actions/notes'; +import { getNotesByEvent, writeNote, clearWrite, postEventNote, deleteNote } from '../../actions/notes'; +import TraineeTableRow from './TraineeTableRow'; +import ConfirmModal from '../forms/ConfirmModal'; class EventDetail extends Component { constructor(props) { @@ -32,61 +31,30 @@ class EventDetail extends Component { renderTrainees() { + const event = this.props.selectedEvent; return this.props.trainees.map((item) => { - const isVisitor = this.props.selectedEvent.visitors.includes(item.id); + const notes = this.props.eventNotes.filter(note => note.profile === item.id); return ( - <Table.Row> - <Table.Cell> - {item.full_name} - </Table.Cell> - {!this.state.edit ? - <Table.Cell textAlign='center'> - { - isVisitor ? - <Icon color='green' name='checkmark' /> - : - <Icon color='red' name='cancel' /> - } - </Table.Cell> - : - <Table.Cell textAlign='center'> - <Checkbox - defaultChecked={isVisitor ? true : false} - onChange={() => this.props.visitorChange(item)} - /> - </Table.Cell> - } - <Table.Cell> - <Popup - trigger={<Button icon='add' />} - content={this.props.eventNotes.map((note) => { - if (note.profile === item.id) { - return ( - <Comment.Content> - <Comment.Author>{note.created_by_name}</Comment.Author> - <Comment.Text> - {note.note} - </Comment.Text> - </Comment.Content> - ); - } - return (''); - }) - } - basic - /> - </Table.Cell> - </Table.Row> + <TraineeTableRow + selectedEvent={event} + notes={notes} + trainee={item} + edit={this.state.edit} + /> ); }); } renderEvent() { - const { name, date } = this.props.selectedEvent; + const { name, date, description } = this.props.selectedEvent; return ( <Item> <Item.Header as='h2'>{name}</Item.Header> <Item.Header as='h3'>DĂĄtum: {moment(date).format('LL')}</Item.Header> + <Container textAlign='justified'> + <Item.Header as='h3'>LeĂrĂĄs</Item.Header> + <Item.Content>{description}</Item.Content> + </Container> </Item> ); } @@ -106,6 +74,19 @@ 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)} + /> </Comment>); } return ''; @@ -116,7 +97,11 @@ class EventDetail extends Component { const event = this.props.selectedEvent; const note = this.props.actualNote; return ( - <Container> + <Container + style={{ + padding: '80px' + }} + > <Container textAlign='center'> { this.props.selectedEvent && this.props.trainees ? this.renderEvent() @@ -124,11 +109,6 @@ class EventDetail extends Component { '' } </Container> - <Container - style={{ - padding: '80px', - }} - > <Table celled centered> <Table.Header> <Table.Row> @@ -138,8 +118,7 @@ class EventDetail extends Component { </Table.Row> </Table.Header> <Table.Body> - { this.props.trainees && - this.props.selectedEvent ? + { this.props.selectedEvent ? this.renderTrainees() : '' @@ -149,7 +128,7 @@ class EventDetail extends Component { <Button onClick={() => this.setState({ edit: true })} > - Edit + Szerkeszt </Button> { this.state.edit ? <Button @@ -158,7 +137,7 @@ class EventDetail extends Component { this.props.submitVisitors(this.props.selectedEvent); } } - >Save + >MentĂŠs </Button> : '' @@ -191,7 +170,6 @@ class EventDetail extends Component { /> </Form> </Comment.Group> - </Container> </Container> ); } @@ -212,4 +190,5 @@ export default connect(mapStateToProps, { writeNote, clearWrite, postEventNote, + deleteNote, })(EventDetail); diff --git a/src/components/pages/Events.js b/src/components/pages/Events.js index ea287f7faa6ff66b0220f53c1cef391cdfd478b9..d5b6d30b8b3eb9f69ac2c3df9059accaa4feb5ee 100644 --- a/src/components/pages/Events.js +++ b/src/components/pages/Events.js @@ -3,12 +3,14 @@ import moment from 'moment'; import { Link } from 'react-router-dom'; import { Container, Table, Button } from 'semantic-ui-react'; import { connect } from 'react-redux'; -import { getEvents, deleteEvent } from '../../actions/statistics'; +import { getStaffEvents, deleteEvent, selectEventForEdit } from '../../actions/statistics'; import AddEventForm from '../forms/AddEventForm'; +import EditEventForm from '../forms/EditEventForm'; +import ConfirmModal from '../forms/ConfirmModal'; class Events extends Component { componentWillMount() { - this.props.getEvents(); + this.props.getStaffEvents(); } renderEvents() { @@ -23,14 +25,20 @@ class Events extends Component { <Table.Cell>{moment(event.date).format('LL')}</Table.Cell> <Table.Cell>{event.visitor_number}</Table.Cell> <Table.Cell> - <Button - onClick={() => this.props.deleteEvent(event)} - color='red' - compact - size='small' - > - Delete - </Button> + <ConfirmModal + text={`tĂśrĂślni akarod a kĂśvetkezĹ alkalmat:${event.name}`} + button={ + <Button + compact + color='red' + size='mini' + > + TĂśrlĂŠs + </Button> + } + onAccept={() => this.props.deleteEvent(event)} + /> + <EditEventForm onClick={() => this.props.selectEventForEdit(event)} /> </Table.Cell> </Table.Row> ); @@ -62,4 +70,4 @@ class Events extends Component { const mapStateToProps = ({ events: { events }, user }) => ({ events, user }); -export default connect(mapStateToProps, { getEvents, deleteEvent })(Events); +export default connect(mapStateToProps, { getStaffEvents, selectEventForEdit, deleteEvent })(Events); diff --git a/src/components/pages/News.js b/src/components/pages/News.js index d1d7bff2d388d7cf4f9791a0fc3076b10bd405fb..a94b43df4dcd785b8a6ee65a86db449d3da8bf33 100644 --- a/src/components/pages/News.js +++ b/src/components/pages/News.js @@ -2,6 +2,7 @@ import React, { Component } from 'react'; import { Container, Segment, Item, Button, Grid } from 'semantic-ui-react'; import { connect } from 'react-redux'; import moment from 'moment'; +import ConfirmModal from '../forms/ConfirmModal'; import AddNewsForm from '../forms/AddNewsForm'; import EditNewsForm from '../forms/EditNewsForm'; @@ -19,46 +20,41 @@ class News extends Component { return this.props.news.map(item => ( <Item key={item.id}> <Item.Content> - <Item.Header - style={{ fontSize: '2em', width: '100%' }} - > - <Grid> - <Grid.Column floated='center' width={12}> - {item.title} - </Grid.Column> - <Grid.Column floated='right' width={4}> - <EditNewsForm - onClick={() => this.props.setSelectedNews(item)} - /> - <Button - compact - color='red' - size='mini' - onClick={() => this.props.deleteNews(item)} - > - Delete - </Button> - </Grid.Column> - </Grid> - </Item.Header> - <Item.Description className='news-text' style={{ fontSize: '1.33em' }}> - {this.renderMultiLine(item.text)} - </Item.Description> - <Item.Extra> - <Grid> - <Grid.Row className='news-extra'> - <Grid.Column floated='left' width={10}> - <p> KĂŠszĂźlt: {moment(item.created_at).format('LLLL')} </p> - <p> Szerkesztve: {moment(item.updated_at).format('LLLL')}</p> + <Container text textAlign='left'> + <Item.Header + style={{ fontSize: '2em', width: '100%' }} + > + <Grid> + <Grid.Column floated='left' width={8}> + {item.title} </Grid.Column> - <Grid.Column floated='right' width={5}> - <p> Ărta: <strong>{item.author_name}</strong></p> - {/* TODO get the edited by name */} - <p> Szerkesztette: {item.author_name}</p> - </Grid.Column> - </Grid.Row> - </Grid> - </Item.Extra> + { this.props.user.role === 'Staff' ? + <Grid.Column floated='right' width={4}> + <EditNewsForm + onClick={() => this.props.setSelectedNews(item)} + /> + <ConfirmModal + text={`tĂśrĂślni akarod a kĂśvetkezĹ hĂrt: ${item.title}`} + button={ + <Button + compact + color='red' + size='mini' + > + TĂśrlĂŠs + </Button> + } + onAccept={() => this.props.deleteNews(item)} + /> + </Grid.Column> + : null } + </Grid> + </Item.Header> + <Item.Meta style={{ fontSize: '0.75em', fontStyle: 'italic' }}>KĂśzzĂŠtĂŠve: {moment(item.created_at).format('LLLL')}</Item.Meta> + <Item.Description className='news-text' style={{ fontSize: '1em' }}> + {this.renderMultiLine(item.text)} + </Item.Description> + </Container> </Item.Content> </Item> )); @@ -76,7 +72,10 @@ class News extends Component { <Segment style={{ padding: '3em 3em' }} vertical> {/* { this.props.user.is_superuser ? <AddNewsForm /> : ''} */} <Container text textAlign='center'> - <AddNewsForm /> + {this.props.user.role === 'Staff' ? + <AddNewsForm /> + : + null} <Item.Group divided> {this.renderNews()} </Item.Group> diff --git a/src/components/pages/Schedule.js b/src/components/pages/Schedule.js index d6a6ac619ed242e3c78a0af5d41896f4c227df90..1b7e66eda96f72edf024bb86160b8e911110b3d9 100644 --- a/src/components/pages/Schedule.js +++ b/src/components/pages/Schedule.js @@ -1,26 +1,79 @@ import React, { Component } from 'react'; -import { Container, Header, Segment } from 'semantic-ui-react'; +import { Container, Accordion, Icon, Grid } from 'semantic-ui-react'; +import { connect } from 'react-redux'; +import moment from 'moment'; +import { getStudentEvents } from '../../actions/statistics'; + +class Schedule extends Component { + state = { activeIndex: 0 } + + componentWillMount() { + this.props.getStudentEvents(); + } + + handleClick = (e, titleProps) => { + const { index } = titleProps + const { activeIndex } = this.state + const newIndex = activeIndex === index ? -1 : index + + this.setState({ activeIndex: newIndex }) + } -export default class Schedule extends Component { render() { - return ( + const { activeIndex } = this.state + + const events = this.props.events; + const panels = events.map(event => ( <div> - <Segment inverted textAlign='center' vertical> - <Container> - <Header - as='h1' - content='Ătemterv - Hamarosan' - inverted - style={{ - fontSize: '3em', - fontWeight: 'normal', - marginBottom: 0, - marginTop: '0.5em', - }} - /> - </Container> - </Segment> - </div> + <Accordion.Title + active={activeIndex === event.id} + index={event.id} + onClick={this.handleClick} + > + <h3> + <Grid> + <Grid.Column floated='left' width={5} textAlign='left'> + <Icon name='angle right' color='blue' />{event.name} + </Grid.Column> + <Grid.Column floated='right' width={8} textAlign='right'> + {moment(event.date).locale('hu').format('LLLL')} + </Grid.Column> + </Grid> + </h3> + </Accordion.Title> + <Accordion.Content active={activeIndex === event.id}> + <Container text textAlign='left'> + <p> + {event.description} + </p> + </Container> + </Accordion.Content> + </div> + )); + + return ( + <Container + textAlign='center' + style={{ + padding: '60px' + }} + > + <h2>KĂŠpzĂŠs alkalmak:</h2> + <Accordion + fluid + styled + defaultActiveIndex={-1} + panels={panels} + > + {panels} + </Accordion> + <h2>TĂĄbor:</h2> + </Container> ); } } + + +const mapStateToProps = ({ events: { events }, user }) => ({ events, user }); + +export default connect(mapStateToProps, { getStudentEvents })(Schedule); diff --git a/src/components/pages/TraineeTableRow.js b/src/components/pages/TraineeTableRow.js new file mode 100644 index 0000000000000000000000000000000000000000..34e58c3c4ac541fded95a5663c55875f3047e0d2 --- /dev/null +++ b/src/components/pages/TraineeTableRow.js @@ -0,0 +1,135 @@ +import React, { Component } from 'react'; +import { + Comment, + Table, + Icon, + Popup, + Grid, + Button, + Form, +} from 'semantic-ui-react'; +import { connect } from 'react-redux'; +import { visitorChange } from '../../actions/statistics'; +import { writeNote, clearWrite, postEventNote, deleteNote } from '../../actions/notes'; +import CommentModal from './CommentModal' + +class TraineeTableRow extends Component { + constructor(props) { + super(props); + this.state = { + note: '', + } + } + + handleWrite = (e) => { + this.setState({ ...this.state, note: e.target.value }); + } + + clearWrite = () => { + this.setState({ ...this.state, note: '' }); + } + + render() { + const { trainee, edit, selectedEvent, notes } = this.props; + const isVisitor = selectedEvent.visitors.includes(trainee.id); + const isAbsent = selectedEvent.absent.includes(trainee.id); + return ( + <Table.Row key={trainee.id}> + <Table.Cell> + {trainee.full_name} + </Table.Cell> + {!edit ? + <Table.Cell textAlign='center'> + { + isVisitor ? + <Icon color='green' name='checkmark' /> + : + isAbsent ? + <Icon color='orange' name='minus' /> + : + <Icon color='red' name='cancel' /> + } + </Table.Cell> + : + <Table.Cell textAlign='center'> + <Button + compact + icon={<Icon color='green' name='checkmark' />} + color={isVisitor ? 'blue' : 'lightgrey'} + onClick={() => this.props.visitorChange({ id: trainee.id, value: 'Visitor' })} + /> + <Button + compact + icon={<Icon color='orange' name='minus' />} + color={isAbsent ? 'blue' : 'lightgrey'} + onClick={() => this.props.visitorChange({ id: trainee.id, value: 'Absent' })} + /> + <Button + compact + icon={<Icon color='red' name='cancel' />} + color={!isVisitor && !isAbsent ? 'blue' : 'lightgrey'} + onClick={() => this.props.visitorChange({ id: trainee.id, value: 'No' })} + /> + </Table.Cell> + } + <Table.Cell> + <Grid> + <Grid.Row> + <Grid.Column floated='left' width={8} textAlign='left'> + + {notes.length > 0 ? + <Comment> + <Comment.Content> + <Comment.Author>{notes[0].created_by_name}</Comment.Author> + <Comment.Text> + {notes[0].note.length > 50 ? notes[0].note.slice(0, 50).concat('...') + : + notes[0].note } + </Comment.Text> + </Comment.Content> + </Comment> + : + null + } + </Grid.Column> + <Grid.Column floated='right' width={4} textAlign='right'> + {notes.length > 0 ? + <CommentModal notes={notes} /> + : + null} + <Popup + trigger={<Button icon='plus' onClick={this.triggerAdd}/>} + on='click' + position='bottom left' + content={ + <Form reply> + <Form.TextArea + value={this.state.note} + onChange={e => this.handleWrite(e)} + /> + <Button + onClick={() => { + this.props.postEventNote({ eventid:selectedEvent.id, + userid: trainee.id, + note: this.state.note }); + this.clearWrite(); + } + } + content='MegjegyzĂŠs hozzĂĄadĂĄsa' + labelPosition='left' + icon='edit' + primary + /> + </Form> + } + /> + </Grid.Column> + </Grid.Row> + </Grid> + </Table.Cell> + </Table.Row> + ); + } +} + +export default connect(() => ({}), { writeNote, clearWrite, postEventNote, visitorChange, deleteNote })(TraineeTableRow) diff --git a/src/components/pages/Trainees.js b/src/components/pages/Trainees.js index b8b3c5dd28b45f27c8661f70e534d8e08e9a84dc..e49cc33900e5f54780cff2cd80c38f9db6da2bd3 100644 --- a/src/components/pages/Trainees.js +++ b/src/components/pages/Trainees.js @@ -1,12 +1,12 @@ import React, { Component } from 'react'; import { Container, Table, Icon } from 'semantic-ui-react'; import { connect } from 'react-redux'; -import { getTrainees, getEvents } from '../../actions/statistics'; +import { getTrainees, getStaffEvents } from '../../actions/statistics'; class Trainees extends Component { componentWillMount() { this.props.getTrainees(); - this.props.getEvents(); + this.props.getStaffEvents(); } renderVisitedStatus(trainee) { @@ -19,7 +19,11 @@ class Trainees extends Component { } return ( <Table.Cell textAlign='center'> - <Icon color='red' name='cancel' /> + { event.absent.includes(trainee.id) ? + <Icon color='orange' name='minus' /> + : + <Icon color='red' name='cancel' /> + } </Table.Cell>); })); } @@ -66,4 +70,4 @@ class Trainees extends Component { const mapStateToProps = ({ trainees: { trainees }, events: { events }, user }) => ({ trainees, events, user }); -export default connect(mapStateToProps, { getTrainees, getEvents })(Trainees); +export default connect(mapStateToProps, { getTrainees, getStaffEvents })(Trainees); diff --git a/src/reducers/EventReducer.js b/src/reducers/EventReducer.js index 0766ddda7af07dc775f6b45087b8ccbd5b9b7ea8..72a976407b8a514e31953543163f3cb92b6a1665 100644 --- a/src/reducers/EventReducer.js +++ b/src/reducers/EventReducer.js @@ -5,9 +5,15 @@ import { WRITE_EVENT, ADD_EVENT, DELETE_EVENT, + CLEAR_WRITE, + ABSENT_CHANGE, + CHANGE_NO, + SELECT_EVENT_FOR_EDIT, + EDIT_EVENT, + WRITE_EDITED_EVENT, } from '../actions/types'; -const INITIAL_STATE = { newEvent: {} }; +const INITIAL_STATE = { events: [], newEvent: {}, editedEvent: {} }; export default (state = INITIAL_STATE, action) => { switch (action.type) { @@ -16,16 +22,13 @@ export default (state = INITIAL_STATE, action) => { case GET_EVENT_BY_ID: return { ...state, selectedEvent: action.payload }; case VISITOR_CHANGE: - const index = state.selectedEvent.visitors.indexOf(action.payload); - if (index !== -1) { - state.selectedEvent.visitors.splice(index, 1); - return { - ...state, - selectedEvent: { - ...state.selectedEvent, - visitors: state.selectedEvent.visitors, - }, - }; + if (state.selectedEvent.visitors.includes(action.payload)) { + // Benne van nem kell megvĂĄltoztatni + return { ...state } + } + if (state.selectedEvent.absent.indexOf(action.payload) > -1) { + // Ha az absentbe van ki kell venni + state.selectedEvent.absent.splice(state.selectedEvent.absent.indexOf(action.payload), 1); } state.selectedEvent.visitors.push(action.payload) return { @@ -33,6 +36,39 @@ export default (state = INITIAL_STATE, action) => { selectedEvent: { ...state.selectedEvent, visitors: state.selectedEvent.visitors, + absent: state.selectedEvent.absent, + }, + }; + case ABSENT_CHANGE: + if (state.selectedEvent.absent.includes(action.payload)) { + return { ...state }; + } + if (state.selectedEvent.visitors.indexOf(action.payload) > -1) { + state.selectedEvent.visitors.splice(state.selectedEvent.visitors.indexOf(action.payload), 1); + } + state.selectedEvent.absent.push(action.payload); + return { + ...state, + selectedEvent: { + ...state.selectedEvent, + visitors: state.selectedEvent.visitors, + absent: state.selectedEvent.absent, + }, + }; + case CHANGE_NO: + if (state.selectedEvent.visitors.indexOf(action.payload) > -1) { + state.selectedEvent.visitors.splice(state.selectedEvent.visitors.indexOf(action.payload), 1); + } + if (state.selectedEvent.absent.indexOf(action.payload) > -1) { + // Ha az absentbe van ki kell venni + state.selectedEvent.absent.splice(state.selectedEvent.absent.indexOf(action.payload), 1); + } + return { + ...state, + selectedEvent: { + ...state.selectedEvent, + visitors: state.selectedEvent.visitors, + absent: state.selectedEvent.absent, }, }; case WRITE_EVENT: @@ -42,6 +78,16 @@ export default (state = INITIAL_STATE, action) => { case DELETE_EVENT: state.events.splice(state.events.indexOf(action.payload), 1); return { ...state, events: [...state.events] }; + case SELECT_EVENT_FOR_EDIT: + return { ...state, editedEvent: action.payload } + case WRITE_EDITED_EVENT: + return { ...state, editedEvent: { ...state.editedEvent, [action.target]: action.payload } }; + case EDIT_EVENT: + const index = state.events.findIndex(item => item.id === action.payload.id); + state.events.splice(index, 1, action.payload); + return { ...state, events: [...state.events] }; + case CLEAR_WRITE: + return { ...state, newEvent: {}, editedEvent: {} }; default: return state; } diff --git a/src/reducers/NoteReducer.js b/src/reducers/NoteReducer.js index 90e4c8db7dba6f73a721b4eec4bbb8d51d3b5101..37caf2f13db724e0a386e7158fab0b5ae103bded 100644 --- a/src/reducers/NoteReducer.js +++ b/src/reducers/NoteReducer.js @@ -3,6 +3,7 @@ import { WRITE_NOTE, ADD_EVENT_NOTE, CLEAR_WRITE, + DELETE_NOTE, } from '../actions/types'; const INITIAL_STATE = { eventNotes: [], actualNote: {} }; @@ -17,6 +18,9 @@ export default (state = INITIAL_STATE, action) => { return { ...state, eventNotes: [...state.eventNotes, 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] }; default: return state; } diff --git a/src/reducers/TraineeReducer.js b/src/reducers/TraineeReducer.js index f7fa38e0d7e2645d76da834af90dc272cee159ef..526cd7ace95c4e1b758d31e7e81d84242e46a927 100644 --- a/src/reducers/TraineeReducer.js +++ b/src/reducers/TraineeReducer.js @@ -1,13 +1,22 @@ -import { GET_TRAINEES, GET_TRAINEE_BY_ID } from '../actions/types'; +import { GET_TRAINEES, GET_PROFILES, GET_SELECTED_PROFILE, SET_STATUS } from '../actions/types'; -const INITIAL_STATE = {}; +const INITIAL_STATE = { profiles: [], selectedProfile: {} }; export default (state = INITIAL_STATE, action) => { switch (action.type) { case GET_TRAINEES: return { ...state, trainees: [...action.payload] }; - case GET_TRAINEE_BY_ID: - return { ...state, selectedTrainee: action.payload }; + case GET_PROFILES: + return { ...state, profiles: [...action.payload] }; + case GET_SELECTED_PROFILE: + return { ...state, selectedProfile: action.payload }; + case SET_STATUS: + const index = state.profiles.findIndex(item => item.id === action.payload.id); + state.profiles.splice(index, 1, action.payload); + if (action.payload.id === state.selectedProfile.id) { + return { ...state, profiles: [...state.profiles], selectedProfile: action.payload }; + } + return { ...state, profiles: [...state.profiles] } default: return state; }