Skip to content

Commit

Permalink
Renders flash messages and allows to delete them
Browse files Browse the repository at this point in the history
  • Loading branch information
Remchi committed Jul 12, 2016
1 parent 8429656 commit a753e5e
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 2 deletions.
9 changes: 8 additions & 1 deletion client/actions/flashMessages.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { ADD_FLASH_MESSAGE } from './types';
import { ADD_FLASH_MESSAGE, DELETE_FLASH_MESSAGE } from './types';

export function addFlashMessage(message) {
return {
type: ADD_FLASH_MESSAGE,
message
}
}

export function deleteFlashMessage(id) {
return {
type: DELETE_FLASH_MESSAGE,
id
}
}
1 change: 1 addition & 0 deletions client/actions/types.js
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export const ADD_FLASH_MESSAGE = 'ADD_FLASH_MESSAGE';
export const DELETE_FLASH_MESSAGE = 'DELETE_FLASH_MESSAGE';
2 changes: 2 additions & 0 deletions client/components/App.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import React from 'react';
import NavigationBar from './NavigationBar';
import FlashMessagesList from './flash/FlashMessagesList';

class App extends React.Component {
render() {
return (
<div className="container">
<NavigationBar />
<FlashMessagesList />
{this.props.children}
</div>
);
Expand Down
33 changes: 33 additions & 0 deletions client/components/flash/FlashMessage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import classnames from 'classnames';

class FlashMessage extends React.Component {
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
}

onClick() {
this.props.deleteFlashMessage(this.props.message.id);
}

render() {
const { id, type, text } = this.props.message;
return (
<div className={classnames('alert', {
'alert-success': type === 'success',
'alert-danger': type === 'error'
})}>
<button onClick={this.onClick} className="close"><span>&times;</span></button>
{text}
</div>
);
}
}

FlashMessage.propTypes = {
message: React.PropTypes.object.isRequired,
deleteFlashMessage: React.PropTypes.func.isRequired
}

export default FlashMessage;
28 changes: 28 additions & 0 deletions client/components/flash/FlashMessagesList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import FlashMessage from './FlashMessage';
import { connect } from 'react-redux';
import { deleteFlashMessage } from '../../actions/flashMessages';

class FlashMessagesList extends React.Component {
render() {
const messages = this.props.messages.map(message =>
<FlashMessage key={message.id} message={message} deleteFlashMessage={this.props.deleteFlashMessage} />
);
return (
<div>{messages}</div>
);
}
}

FlashMessagesList.propTypes = {
messages: React.PropTypes.array.isRequired,
deleteFlashMessage: React.PropTypes.func.isRequired
}

function mapStateToProps(state) {
return {
messages: state.flashMessages
}
}

export default connect(mapStateToProps, { deleteFlashMessage })(FlashMessagesList);
13 changes: 12 additions & 1 deletion client/reducers/flashMessages.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ADD_FLASH_MESSAGE } from '../actions/types';
import { ADD_FLASH_MESSAGE, DELETE_FLASH_MESSAGE } from '../actions/types';
import shortid from 'shortid';
import findIndex from 'lodash/findIndex';

export default (state = [], action = {}) => {
switch(action.type) {
Expand All @@ -12,6 +13,16 @@ export default (state = [], action = {}) => {
text: action.message.text
}
];
case DELETE_FLASH_MESSAGE:
const index = findIndex(state, { id: action.id });
if (index >= 0) {
return [
...state.slice(0, index),
...state.slice(index + 1)
];
}
return state;

default: return state;
}
}

0 comments on commit a753e5e

Please sign in to comment.