training.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import theme from '../styles/theme'
  2. import PropTypes from 'prop-types'
  3. import TrainingBlock from './trainingBlock'
  4. function calculateRating (ratings) {
  5. const numberOfRatings = ratings.length
  6. const sumOfRatings = ratings.reduce(
  7. (accumulator, rating) => accumulator + rating.value,
  8. 0
  9. )
  10. return numberOfRatings ? sumOfRatings / numberOfRatings : '-'
  11. }
  12. const Training = props => (
  13. <article>
  14. <h2>{props.title}</h2>
  15. <aside>
  16. <div id='trainingType'>
  17. <span className='caption'>Type: </span>
  18. <span className='data'>{props.type.name}</span>
  19. </div>
  20. <div id='trainingDate'>
  21. <span className='caption'>Date: </span>
  22. <span className='data'>
  23. {new Date(props.trainingDate).toLocaleDateString()}
  24. </span>
  25. </div>
  26. <div id='trainingLocation'>
  27. <span className='caption'>Location: </span>
  28. <span className='data'>{props.location}</span>
  29. </div>
  30. <div id='trainingRegistrations'>
  31. <span className='caption'>Registrations: </span>
  32. <span className='data'> {props.registration.length} </span>
  33. </div>
  34. <div id='trainingAttendance'>
  35. <span className='caption'>Attendance: </span>
  36. <span className='data'>{props.attendance}</span>
  37. </div>
  38. <div id='trainingRatings'>
  39. <span className='caption'>Rating: </span>
  40. <span className='data'>
  41. {calculateRating(props.ratings)} [
  42. <a href=''>{props.ratings.length}</a>] Rate it!
  43. <a href=''>*</a>
  44. <a href=''>*</a>
  45. <a href=''>*</a>
  46. <a href=''>*</a>
  47. <a href=''>*</a>
  48. </span>
  49. </div>
  50. <button>Register now!</button>
  51. </aside>
  52. <section>
  53. <h3>Content</h3>
  54. <ol>
  55. {props.content
  56. .sort(block => block.sequence)
  57. .map(block => (
  58. <TrainingBlock key={block.id} {...block} />
  59. ))}
  60. </ol>
  61. </section>
  62. <style jsx>
  63. {`
  64. article {
  65. display: grid;
  66. grid-template-areas:
  67. 'title title'
  68. 'information placeholder'
  69. 'content content';
  70. grid-template-columns: 1fr 2fr;
  71. background-color: rgba(127, 127, 127, 0.5);
  72. background-image: url('media/man_working_out.jpg');
  73. background-size: auto 400px;
  74. background-repeat: no-repeat;
  75. margin: 2em 0;
  76. }
  77. article > * {
  78. padding: 0.2em 1em;
  79. }
  80. article > h2 {
  81. grid-area: title;
  82. font-weight: 900;
  83. font-size: 120%;
  84. background: ${theme.colors.darkerblue};
  85. color: ${theme.colors.offWhite};
  86. }
  87. aside {
  88. grid-area: information;
  89. background: rgba(0, 127, 0, 0.5);
  90. padding: 1em 2em;
  91. margin: 0 1em;
  92. min-height: 350px;
  93. }
  94. section {
  95. grid-area: content;
  96. padding: 1em 2em;
  97. background: rgba(127, 0, 0, 0.5);
  98. }
  99. span.caption {
  100. display: none;
  101. }
  102. `}
  103. </style>
  104. </article>
  105. )
  106. Training.propTypes = {
  107. title: PropTypes.string.isRequired,
  108. type: PropTypes.shape({
  109. name: PropTypes.string.isRequired,
  110. description: PropTypes.string
  111. })
  112. }
  113. export default Training