Skip to content

Instantly share code, notes, and snippets.

@igorcaldeira
Last active April 2, 2019 23:06
Show Gist options
  • Save igorcaldeira/2b8e99fa4724ddef8282e0e504dd7205 to your computer and use it in GitHub Desktop.
Save igorcaldeira/2b8e99fa4724ddef8282e0e504dd7205 to your computer and use it in GitHub Desktop.
The relevant parts of a section of code using reactjs that shows part of a message handler component. This component handle various types of messages that appears fixed and above the main menu of a system. It has some rules like show the message only for 3 seconds each and group messages with the same content. Hope you like it!
import React from 'react'
import { translate } from 'react-i18next'
import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import { simpleId } from 'utils/utility'
import * as actions from 'store/messages/messages.useCases'
import './MessageHandler.scss'
import { ReactComponent as IcCheck } from 'assets/icons/message/check.svg'
import { ReactComponent as IcAlert } from 'assets/icons/message/alert.svg'
import { ReactComponent as IcError } from 'assets/icons/message/error.svg'
import { ReactComponent as IcClose } from 'assets/icons/message/close.svg'
const individualRemoveWatcher = (id, remove) => setTimeout(() => remove(id), 3000)
const Icon = ({ type }) => {
switch (type) {
case 'danger': return <IcError />
case 'info': return <IcAlert />
case 'warning': return <IcAlert />
case 'success': return <IcCheck />
default: return null
}
}
const Content = ({ text, type, id, count, remove }) => {
individualRemoveWatcher(id, remove)
return <>
<div className={`message-container message-container--${type}`}>
<Icon { ...{ type } } />
<span className='pl-3'>{ text } <span className='bold'>{ count > 1 ? `(ocorreu ${ count }x)` : ''}</span></span>
<div className='close-container' onClick={() => remove(id)} ><IcClose /></div>
</div>
</>
}
const MessageHandler = props => {
const { messages, removeMessage } = props
return <div className='message-handler'>
{ messages.map(m => <Content key={simpleId()} {...m} remove={removeMessage} />) }
</div>
}
MessageHandler.propTypes = {
messages: PropTypes.array,
removeMessage: PropTypes.func
}
MessageHandler.defaultProps = {
messages: [],
removeMessage: () => {}
}
const mapStateToProps = ({ messages }) => messages
const mapDispatchToProps = dispatch => ({
removeMessage: id => dispatch(actions.removeMessage(id)),
})
export default connect(mapStateToProps, mapDispatchToProps)(translate()(MessageHandler))
.message-handler{
position: fixed;
top: 60px;
left: 0px;
width: 100%;
z-index: 2;
.message-container{
width: 100%;
position: relative;
display: block;
min-height: 60px;
background-color: #363636;
padding: 20px;
color: white;
opacity: 0.9;
svg{ margin-top: 5px; }
.close-container{
float: right;
cursor: pointer;
}
&--success{ background-color: #94c13d; }
&--danger{ background-color: #c61557; }
&--warning{ background-color: #ffcf3d; }
&--info{ background-color: #00c0f3; }
}
}
import { simpleId } from 'utils/utility'
import * as actionTypes from './messages.actionTypes'
const initialState = { messages: [] }
const reset = (state, action) => initialState
const addMessage = (state, action) => {
const messages = state.messages.concat([{
id: simpleId(),
text: action.message.text,
type: action.message.type,
count: 1
}])
messages.map((msg, msgIndex) => messages.map((msgValid, msgValidIndex) => {
if(msg.id !== msgValid.id && msg.text === msgValid.text){
msg.count++
messages.splice(msgValidIndex, 1)
}
}))
return ({ messages })
}
const removeMessage = (state, action) => ({
messages: state.messages.filter(item => item.id !== action.id)
})
const reducer = (state = initialState, action) => {
switch (action.type) {
case actionTypes.RESET: return reset(state, action)
case actionTypes.ADD_MESSAGE: return addMessage(state, action)
case actionTypes.REMOVE_MESSAGE: return removeMessage(state, action)
default: return state
}
}
export default reducer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment