index.jsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. Copyright (C) 2017 Cloudbase Solutions SRL
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. // @flow
  15. import React from 'react'
  16. import { observer } from 'mobx-react'
  17. import styled, { css } from 'styled-components'
  18. import StyleProps from '../../styleUtils/StyleProps'
  19. import Palette from '../../styleUtils/Palette'
  20. import { navigationMenu } from '../../../config'
  21. import hamburgerImage from './images/hamburger'
  22. import backgroundImage from './images/star-bg.jpg'
  23. const Wrapper = styled.div`
  24. margin-right: 20px;
  25. `
  26. const OpenTopLayer = css`
  27. transform: rotate(45deg) translateX(3px);
  28. width: 19px;
  29. `
  30. const OpenMiddleLayer = css`
  31. transform: rotate(-45deg) translateY(4.5px) translateX(-10.5px);
  32. width: 19px;
  33. `
  34. const Close = css`
  35. transform: rotate(0) translateY(0) translateX(0);
  36. opacity: 1;
  37. `
  38. const OpenBottomLayer = css`
  39. opacity: 0;
  40. `
  41. const Hamburger = styled.div`
  42. cursor: pointer;
  43. #top-layer, #middle-layer, #bottom-layer {
  44. transition: all .4s cubic-bezier(0, 1.4, 1, 1);
  45. }
  46. #top-layer {
  47. ${props => props.open ? OpenTopLayer : Close};
  48. }
  49. #middle-layer {
  50. ${props => props.open ? OpenMiddleLayer : Close};
  51. }
  52. #bottom-layer {
  53. ${props => props.open ? OpenBottomLayer : Close};
  54. }
  55. `
  56. const Menu = styled.div`
  57. position: fixed;
  58. background: url('${backgroundImage}');
  59. top: 64px;
  60. left: ${props => props.open ? 0 : '-224px'};
  61. bottom: 0;
  62. width: 184px;
  63. padding-left: 40px;
  64. padding-top: 60px;
  65. transition: all ${StyleProps.animations.swift};
  66. display: flex;
  67. flex-direction: column;
  68. z-index: 1;
  69. `
  70. const MenuItem = styled.a`
  71. font-size: 18px;
  72. color: white;
  73. margin-bottom: 24px;
  74. cursor: pointer;
  75. text-decoration: none;
  76. &:hover {
  77. color: ${Palette.primary};
  78. }
  79. `
  80. type Props = {}
  81. type State = {
  82. open: boolean,
  83. }
  84. @observer
  85. class SideMenu extends React.Component<Props, State> {
  86. constructor() {
  87. super()
  88. this.state = {
  89. open: false,
  90. }
  91. }
  92. handleHamburgerClick() {
  93. this.setState({ open: !this.state.open })
  94. }
  95. render() {
  96. return (
  97. <Wrapper>
  98. <Hamburger
  99. open={this.state.open}
  100. onClick={() => { this.handleHamburgerClick() }}
  101. dangerouslySetInnerHTML={{ __html: hamburgerImage() }}
  102. data-test-id="sideMenu-toggle"
  103. />
  104. <Menu open={this.state.open} data-test-id="sideMenu-menu">
  105. {navigationMenu.filter(i => i.disabled ? !i.disabled : true).map(item => {
  106. return (
  107. <MenuItem key={item.value} href={`/#/${item.value}`} data-test-id={`sideMenu-item-${item.value}`}>{item.label}</MenuItem>
  108. )
  109. })}
  110. </Menu>
  111. </Wrapper>
  112. )
  113. }
  114. }
  115. export default SideMenu