Offsidebar.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. import React, { Component } from 'react';
  2. import PropTypes from 'prop-types';
  3. import { connect } from 'react-redux';
  4. import { bindActionCreators } from 'redux';
  5. import * as actions from '../../store/actions/actions';
  6. import { TabContent, TabPane, Nav, NavItem, NavLink } from 'reactstrap';
  7. class Offsidebar extends Component {
  8. state = {
  9. activeTab: 'settings',
  10. offsidebarReady: false
  11. }
  12. componentDidMount() {
  13. // When mounted display the offsidebar
  14. window.requestAnimationFrame(() => this.setState({ offsidebarReady: true }));
  15. }
  16. toggle = tab => {
  17. if (this.state.activeTab !== tab) {
  18. this.setState({
  19. activeTab: tab
  20. });
  21. }
  22. }
  23. handleSettingCheckbox = event => {
  24. this.props.actions.changeSetting(event.target.name, event.target.checked);
  25. }
  26. handleThemeRadio = event => {
  27. this.props.actions.changeTheme(event.target.value);
  28. }
  29. render() {
  30. return (
  31. this.state.offsidebarReady &&
  32. <aside className="offsidebar">
  33. { /* START Off Sidebar (right) */ }
  34. <nav>
  35. <div>
  36. { /* Nav tabs */ }
  37. <Nav tabs justified>
  38. <NavItem>
  39. <NavLink className={ this.state.activeTab === 'settings' ? 'active':'' }
  40. onClick={() => { this.toggle('settings'); }}
  41. >
  42. <em className="icon-equalizer fa-lg"></em>
  43. </NavLink>
  44. </NavItem>
  45. <NavItem>
  46. <NavLink className={ this.state.activeTab === 'chat' ? 'active':'' }
  47. onClick={() => { this.toggle('chat'); }}
  48. >
  49. <em className="icon-user fa-lg"></em>
  50. </NavLink>
  51. </NavItem>
  52. </Nav>
  53. { /* Tab panes */ }
  54. <TabContent activeTab={this.state.activeTab}>
  55. <TabPane tabId="settings">
  56. <h3 className="text-center text-thin mt-4">Settings</h3>
  57. <div className="p-2">
  58. <h4 className="text-muted text-thin">Themes</h4>
  59. <div className="row row-flush mb-2">
  60. <div className="col-3 mb-3">
  61. <div className="setting-color">
  62. <label>
  63. <input type="radio" name="setting-theme" checked={this.props.theme.name === 'theme-a'} value='theme-a' onChange={this.handleThemeRadio} />
  64. <span className="icon-check"></span>
  65. <span className="split">
  66. <span className="color bg-info"></span>
  67. <span className="color bg-info-light"></span>
  68. </span>
  69. <span className="color bg-white"></span>
  70. </label>
  71. </div>
  72. </div>
  73. <div className="col-3 mb-3">
  74. <div className="setting-color">
  75. <label>
  76. <input type="radio" name="setting-theme" checked={this.props.theme.name === 'theme-b'} value='theme-b' onChange={this.handleThemeRadio} />
  77. <span className="icon-check"></span>
  78. <span className="split">
  79. <span className="color bg-green"></span>
  80. <span className="color bg-green-light"></span>
  81. </span>
  82. <span className="color bg-white"></span>
  83. </label>
  84. </div>
  85. </div>
  86. <div className="col-3 mb-3">
  87. <div className="setting-color">
  88. <label>
  89. <input type="radio" name="setting-theme" checked={this.props.theme.name === 'theme-c'} value='theme-c' onChange={this.handleThemeRadio} />
  90. <span className="icon-check"></span>
  91. <span className="split">
  92. <span className="color bg-purple"></span>
  93. <span className="color bg-purple-light"></span>
  94. </span>
  95. <span className="color bg-white"></span>
  96. </label>
  97. </div>
  98. </div>
  99. <div className="col-3 mb-3">
  100. <div className="setting-color">
  101. <label>
  102. <input type="radio" name="setting-theme" checked={this.props.theme.name === 'theme-d'} value='theme-d' onChange={this.handleThemeRadio} />
  103. <span className="icon-check"></span>
  104. <span className="split">
  105. <span className="color bg-danger"></span>
  106. <span className="color bg-danger-light"></span>
  107. </span>
  108. <span className="color bg-white"></span>
  109. </label>
  110. </div>
  111. </div>
  112. <div className="col-3 mb-3">
  113. <div className="setting-color">
  114. <label>
  115. <input type="radio" name="setting-theme" checked={this.props.theme.name === 'theme-e'} value='theme-e' onChange={this.handleThemeRadio} />
  116. <span className="icon-check"></span>
  117. <span className="split">
  118. <span className="color bg-info-dark"></span>
  119. <span className="color bg-info"></span>
  120. </span>
  121. <span className="color bg-gray-dark"></span>
  122. </label>
  123. </div>
  124. </div>
  125. <div className="col-3 mb-3">
  126. <div className="setting-color">
  127. <label>
  128. <input type="radio" name="setting-theme" checked={this.props.theme.name === 'theme-f'} value='theme-f' onChange={this.handleThemeRadio} />
  129. <span className="icon-check"></span>
  130. <span className="split">
  131. <span className="color bg-green-dark"></span>
  132. <span className="color bg-green"></span>
  133. </span>
  134. <span className="color bg-gray-dark"></span>
  135. </label>
  136. </div>
  137. </div>
  138. <div className="col-3 mb-3">
  139. <div className="setting-color">
  140. <label>
  141. <input type="radio" name="setting-theme" checked={this.props.theme.name === 'theme-g'} value='theme-g' onChange={this.handleThemeRadio} />
  142. <span className="icon-check"></span>
  143. <span className="split">
  144. <span className="color bg-purple-dark"></span>
  145. <span className="color bg-purple"></span>
  146. </span>
  147. <span className="color bg-gray-dark"></span>
  148. </label>
  149. </div>
  150. </div>
  151. <div className="col-3 mb-3">
  152. <div className="setting-color">
  153. <label>
  154. <input type="radio" name="setting-theme" checked={this.props.theme.name === 'theme-h'} value='theme-h' onChange={this.handleThemeRadio} />
  155. <span className="icon-check"></span>
  156. <span className="split">
  157. <span className="color bg-danger-dark"></span>
  158. <span className="color bg-danger"></span>
  159. </span>
  160. <span className="color bg-gray-dark"></span>
  161. </label>
  162. </div>
  163. </div>
  164. </div>
  165. </div>
  166. <div className="p-2">
  167. <h4 className="text-muted text-thin">Layout</h4>
  168. <div className="clearfix">
  169. <p className="float-left">Fixed</p>
  170. <div className="float-right">
  171. <label className="switch">
  172. <input id="chk-fixed" type="checkbox" name="isFixed" checked={this.props.settings.isFixed} onChange={this.handleSettingCheckbox}/>
  173. <span></span>
  174. </label>
  175. </div>
  176. </div>
  177. <div className="clearfix">
  178. <p className="float-left">Boxed</p>
  179. <div className="float-right">
  180. <label className="switch">
  181. <input id="chk-boxed" type="checkbox" name="isBoxed" checked={this.props.settings.isBoxed} onChange={this.handleSettingCheckbox}/>
  182. <span></span>
  183. </label>
  184. </div>
  185. </div>
  186. </div>
  187. <div className="p-2">
  188. <h4 className="text-muted text-thin">Aside</h4>
  189. <div className="clearfix">
  190. <p className="float-left">Collapsed</p>
  191. <div className="float-right">
  192. <label className="switch">
  193. <input id="chk-collapsed" type="checkbox" name="isCollapsed" checked={this.props.settings.isCollapsed} onChange={this.handleSettingCheckbox}/>
  194. <span></span>
  195. </label>
  196. </div>
  197. </div>
  198. <div className="clearfix">
  199. <p className="float-left">Collapsed Text</p>
  200. <div className="float-right">
  201. <label className="switch">
  202. <input id="chk-collapsed-text" type="checkbox" name="isCollapsedText" checked={this.props.settings.isCollapsedText} onChange={this.handleSettingCheckbox}/>
  203. <span></span>
  204. </label>
  205. </div>
  206. </div>
  207. <div className="clearfix">
  208. <p className="float-left">Float</p>
  209. <div className="float-right">
  210. <label className="switch">
  211. <input id="chk-float" type="checkbox" name="isFloat" checked={this.props.settings.isFloat} onChange={this.handleSettingCheckbox}/>
  212. <span></span>
  213. </label>
  214. </div>
  215. </div>
  216. <div className="clearfix">
  217. <p className="float-left">Hover</p>
  218. <div className="float-right">
  219. <label className="switch">
  220. <input id="chk-hover" type="checkbox" name="asideHover" checked={this.props.settings.asideHover} onChange={this.handleSettingCheckbox}/>
  221. <span></span>
  222. </label>
  223. </div>
  224. </div>
  225. <div className="clearfix">
  226. <p className="float-left">Show Scrollbar</p>
  227. <div className="float-right">
  228. <label className="switch">
  229. <input id="chk-scrollbar" type="checkbox" name="asideScrollbar" checked={this.props.settings.asideScrollbar} onChange={this.handleSettingCheckbox}/>
  230. <span></span>
  231. </label>
  232. </div>
  233. </div>
  234. </div>
  235. </TabPane>
  236. <TabPane tabId="chat">
  237. <h3 className="text-center text-thin mt-4">Connections</h3>
  238. <div className="list-group">
  239. { /* START list title */ }
  240. <div className="list-group-item border-0">
  241. <small className="text-muted">ONLINE</small>
  242. </div>
  243. { /* END list title */ }
  244. <div className="list-group-item list-group-item-action border-0">
  245. <div className="media">
  246. <img className="align-self-center mr-3 rounded-circle thumb48" src="/static/img/user/05.jpg" alt="User avatar" />
  247. <div className="media-body text-truncate">
  248. <a href="">
  249. <strong>Juan Sims</strong>
  250. </a>
  251. <br/>
  252. <small className="text-muted">Designeer</small>
  253. </div>
  254. <div className="ml-auto">
  255. <span className="circle bg-success circle-lg"></span>
  256. </div>
  257. </div>
  258. </div>
  259. <div className="list-group-item list-group-item-action border-0">
  260. <div className="media">
  261. <img className="align-self-center mr-3 rounded-circle thumb48" src="/static/img/user/06.jpg" alt="User avatar" />
  262. <div className="media-body text-truncate">
  263. <a href="">
  264. <strong>Maureen Jenkins</strong>
  265. </a>
  266. <br/>
  267. <small className="text-muted">Designeer</small>
  268. </div>
  269. <div className="ml-auto">
  270. <span className="circle bg-success circle-lg"></span>
  271. </div>
  272. </div>
  273. </div>
  274. <div className="list-group-item list-group-item-action border-0">
  275. <div className="media">
  276. <img className="align-self-center mr-3 rounded-circle thumb48" src="/static/img/user/07.jpg" alt="User avatar" />
  277. <div className="media-body text-truncate">
  278. <a href="">
  279. <strong>Billie Dunn</strong>
  280. </a>
  281. <br/>
  282. <small className="text-muted">Designeer</small>
  283. </div>
  284. <div className="ml-auto">
  285. <span className="circle bg-danger circle-lg"></span>
  286. </div>
  287. </div>
  288. </div>
  289. <div className="list-group-item list-group-item-action border-0">
  290. <div className="media">
  291. <img className="align-self-center mr-3 rounded-circle thumb48" src="/static/img/user/08.jpg" alt="User avatar" />
  292. <div className="media-body text-truncate">
  293. <a href="">
  294. <strong>Tomothy Roberts</strong>
  295. </a>
  296. <br/>
  297. <small className="text-muted">Designeer</small>
  298. </div>
  299. <div className="ml-auto">
  300. <span className="circle bg-warning circle-lg"></span>
  301. </div>
  302. </div>
  303. </div>
  304. { /* START list title */ }
  305. <div className="list-group-item border-0">
  306. <small className="text-muted">OFFLINE</small>
  307. </div>
  308. { /* END list title */ }
  309. <div className="list-group-item list-group-item-action border-0">
  310. <div className="media">
  311. <img className="align-self-center mr-3 rounded-circle thumb48" src="/static/img/user/09.jpg" alt="User avatar" />
  312. <div className="media-body text-truncate">
  313. <a href="">
  314. <strong>Lawrence Robinson</strong>
  315. </a>
  316. <br/>
  317. <small className="text-muted">Designeer</small>
  318. </div>
  319. <div className="ml-auto">
  320. <span className="circle bg-warning circle-lg"></span>
  321. </div>
  322. </div>
  323. </div>
  324. <div className="list-group-item list-group-item-action border-0">
  325. <div className="media">
  326. <img className="align-self-center mr-3 rounded-circle thumb48" src="/static/img/user/10.jpg" alt="User avatar" />
  327. <div className="media-body text-truncate">
  328. <a href="">
  329. <strong>Tyrone Owens</strong>
  330. </a>
  331. <br/>
  332. <small className="text-muted">Designeer</small>
  333. </div>
  334. <div className="ml-auto">
  335. <span className="circle bg-warning circle-lg"></span>
  336. </div>
  337. </div>
  338. </div>
  339. </div>
  340. <div className="px-3 py-4 text-center">
  341. { /* Optional link to list more users */ }
  342. <a className="btn btn-purple btn-sm" href="" title="See more contacts">
  343. <strong>Load more..</strong>
  344. </a>
  345. </div>
  346. { /* Extra items */ }
  347. <div className="px-3 py-2">
  348. <p>
  349. <small className="text-muted">Tasks completion</small>
  350. </p>
  351. <div className="progress progress-xs m-0">
  352. <div className="progress-bar bg-success" aria-valuenow="80" aria-valuemin="0" aria-valuemax="100" style={{width: '80%'}}>
  353. <span className="sr-only">80% Complete</span>
  354. </div>
  355. </div>
  356. </div>
  357. <div className="px-3 py-2">
  358. <p>
  359. <small className="text-muted">Upload quota</small>
  360. </p>
  361. <div className="progress progress-xs m-0">
  362. <div className="progress-bar bg-warning" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style={{width: '40%'}}>
  363. <span className="sr-only">40% Complete</span>
  364. </div>
  365. </div>
  366. </div>
  367. </TabPane>
  368. </TabContent>
  369. </div>
  370. </nav>
  371. { /* END Off Sidebar (right) */ }
  372. </aside>
  373. );
  374. }
  375. }
  376. Offsidebar.propTypes = {
  377. actions: PropTypes.object,
  378. settings: PropTypes.object,
  379. theme: PropTypes.object
  380. };
  381. const mapStateToProps = state => ({ settings: state.settings, theme: state.theme })
  382. const mapDispatchToProps = dispatch => ({ actions: bindActionCreators(actions, dispatch) })
  383. export default connect(
  384. mapStateToProps,
  385. mapDispatchToProps
  386. )(Offsidebar);