instantjob-recruiter-client
Version:
a set of tools for creating an instantjob recruiter react client
85 lines (74 loc) • 1.9 kB
JSX
import React, {Component} from 'react'
import styled, {css} from 'styled-components'
import {connect} from 'react-redux'
import {get_alert} from 'selectors/display'
import {cancelable_timeout} from 'common/cancelable'
import auto_bind from 'common/auto_bind'
import {color, acceleration, desceleration} from 'common/styles'
import {array_from_hash} from 'common/utilities'
const alerts_appearance_time = 5 // seconds
class Alerts extends Component {
render() {
const {alert} = this.props
if (alert) {
return (
<Position>
<Alert key={alert.id} {...alert} />
</Position>
)
}
return null
}
}
class Alert extends Component {
constructor(props) {
super(props)
this.state = {
mounted: false,
}
auto_bind(this)
}
remove_alert() {
setTimeout(this.props.remove, 400)
this.setState({mounted: false})
}
componentDidMount() {
setTimeout(() => this.setState({mounted: true}), 10)
this.visible_timeout = cancelable_timeout(this.remove_alert, alerts_appearance_time * 1000)
}
componentWillUnmount() {
this.visible_timeout.cancel()
}
render() {
const {mounted} = this.state
const {text} = this.props
return (
<Container mounted={mounted}>
{text}
</Container>
)
}
}
export default connect(
(state) => ({
alert: get_alert(state),
}),
)(Alerts)
const Position = styled.div`
position: fixed;
bottom: 0;
left: 0;
right: 0;
display: flex;
justify-content: center;
`
const Container = styled.div`
margin: 0 24px;
padding: 14px 24px;
background-color: ${color('black', 'intense')};
color: white;
border-radius: 2px;
transform: translate(0, ${({mounted}) => mounted ? '0' : '100%'});
transition: transform 400ms ${({mounted}) => mounted ? desceleration : acceleration};
box-shadow: 0 0 3px ${color('black', 'intense')};
`