Skip to content

Instantly share code, notes, and snippets.

@jhyland87
Last active September 19, 2017 18:37
Show Gist options
  • Save jhyland87/052f4c8a465b1a3d2fb66a0b2be83f66 to your computer and use it in GitHub Desktop.
Save jhyland87/052f4c8a465b1a3d2fb66a0b2be83f66 to your computer and use it in GitHub Desktop.
ReactJS Widget Component
'use strict'
import React, { Component } from 'react'
import _ from 'lodash'
import ReactBootstrap, {
Button, ButtonGroup, DropdownButton, ButtonToolbar, OverlayTrigger, Tooltip, Popover,
MenuItem, Nav, NavItem, Breadcrumb, PageHeader, Table, Panel,
ListGroup, ListGroupItem, Jumbotron, Grid, Row, Col, Alert, Glyphicon,
} from 'react-bootstrap'
import PropTypes from 'prop-types'
import * as U from './helpers/utils'
var metadata = require( './config/metadata.json' )
/**
*
* @classdesc Component to generate Stat widgets displayed using ReactBootstrap.Col
* @example
* <Stat
* title = "Todays Visits"
* color = "blue-grey"
* value = "123"
* desc = "Better than last week (70.1%)"
* icon = "globe"
* progress = ""
* type = "number"
* link = "http://foo.com/?stat=visits"
* interval = "3000" />
*/
class Stat extends Component {
/**
* Creates a new Stat widget that auto updates at a specified interval
*/
constructor(props) {
super(props)
var defaultedProps = _.defaultsDeep( _.cloneDeep( props ), metadata.defaults.stats.props )
this.state = {...props}
if ( ! this.state.interval )
this.state.interval = 1000
var c = _.get( props.color, 'ok', _.defaultTo( metadata.defaults.theme.colors.bg, 'blue' ))
if ( ! this.state.color )
this.state.color = metadata.defaults.theme.colors.bg
// Date object for 1 hour ago
//var dateA = new Date( new Date().getTime() - (60 * 60 * 1000) )
if ( _.isEmpty( props.color ) )
this.state.color = _.get( metadata.defaults.theme.colors, 'bg', 'blue' )
else if ( _.isArray( props.color ) )
this.state.color = props.color[0]
else if ( _.isObject( props.color ) )
this.state.color = Object.values( props.color )[0]
else if ( _.isString( props.color ) )
this.state.color = props.color
}
/**
* @description Method triggered when a component is initially instantiated
* @summary Sets the initial values of the component states
* @access private
* @event {event:Component~getInitialState} Executed when this component is first instantiated
* @see https://facebook.github.io/react/docs/react-without-es6.html#setting-the-initial-state
* @returns {Object} Object containing info regarding this components state and events
* @property {number} initDate Epoch date for time this object was initially instantiated
* @property {number} secondsElapsed Seconds since this objects initial instantiation
* @property {number} lastUpdate Epoch date for time this object was last updated (Initially set to initDate epoch)
* @property {number} updates Number of updates (not checks) performed on this object
* @property {number} lastCheck Epoch date for time this object was last checked (Initially set to initDate epoch)
* @property {number} checks Number of checks this object has iterated over
*/
getInitialState() {
return {
initDate : U.epoch(),
secondsElapsed : 0,
lastUpdate : U.epoch(),
updates : 0,
lastCheck : U.epoch(),
checks : 0
}
}
/**
*
* @description Executed repeatidly via the setInterval function initated via componentDidMount
* @summary Increments this.state.checks; Updates lastCheck to the current timestamp in epoch format
* @access private
* @inner
* @event {event:Component~componentDidMount} Executed when this component is successfully mounted
* @property {number} this.state.checks Number of checks perormed
* @property {number} this.state.lastCheck Epoch timestamp for last check
*/
checkStat(){
this.setState({
checks : ( _.isNil(this.state.checks) ? 0 : this.state.checks+1 ),
lastCheck : U.epoch()
})
}
/**
* @description Once the component is initiated, this sets the setInterval function loop
* @summary Initiates iterator
* @access private
* @inner
* @event {event:Component~componentDidMount} Invoked immediately after a component is mounted
* @see https://facebook.github.io/react/docs/react-component.html#componentdidmount
*/
componentDidMount() {
this.intervalLoop = setInterval(() => {
this.checkStat.apply( this )
}, this.state.interval )
}
/**
* @description Terminates the Stat updates by clearing the interval object this.intervalLoop
* @summary Terminates iterator
* @access private
* @inner
* @event {event:Component~componentWillUnmount} Invoked immediately before a component is unmounted and destroyed
* @see https://facebook.github.io/react/docs/react-component.html#componentwillunmount
*/
componentWillUnmount() {
clearInterval( this.intervalLoop )
}
/**
* @description Method executed whenever component is rendered
* @summary Creates a new ReactBootstrap.Col object using properties/content in the Stat JSX element
* @access private
* @inner
* @see https://facebook.github.io/react/docs/react-component.html#render
* @returns {module:ReactBootstrap.Col}
*/
render() {
return (
<Col md={3} sm={6}>
<div className={"widget widget-stats bg-" + this.state.color}>
<div className="stats-icon stats-icon-lg">
<i className={"fa fa-fw fa-" + this.state.icon}></i>
</div>
<div className="stats-title">{this.state.title}</div>
<div className="stats-number">{this.state.value}</div>
<div className="stats-progress progress">
<div className="progress-bar" style={{width: '70.1%'}}></div>
</div>
<div className="stats-desc">{this.state.desc}</div>
<div className="stats-desc">checks: {this.state.checks}</div>
<div className="stats-desc">lastCheck: {this.state.lastCheck}</div>
<div className="stats-link">
<a href="javascript:;">View Detail <i className="fa fa-arrow-circle-o-right"></i></a>
</div>
</div>
</Col>
)
}
}
Stat.propTypes = {
title: PropTypes.string,
value: PropTypes.number
}
export { Stat }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment