From 33ba55f2f86921fda360f660665cef7c4cf332cb Mon Sep 17 00:00:00 2001 From: Sharyn Date: Thu, 5 Jul 2018 11:59:42 +0200 Subject: [PATCH] Adding page components - page header - page footer - modal - resources - wordcloud - search - interviews list - projects list - topics list --- components/interviewsList/index.js | 50 ++++++++++++++ components/interviewsList/style.scss | 37 +++++++++++ components/modal/index.js | 25 +++++++ components/modal/style.scss | 71 ++++++++++++++++++++ components/pageFooter/index.js | 10 +++ components/pageFooter/style.scss | 8 +++ components/pageHeader/index.js | 14 ++++ components/pageHeader/style.scss | 14 ++++ components/projectsList/index.js | 14 ++++ components/projectsList/style.scss | 25 +++++++ components/resources/index.js | 97 ++++++++++++++++++++++++++++ components/resources/style.scss | 75 +++++++++++++++++++++ components/search/index.js | 45 +++++++++++++ components/search/style.scss | 50 ++++++++++++++ components/topicsList/index.js | 14 ++++ components/topicsList/style.scss | 25 +++++++ components/wordCloud/index.js | 35 ++++++++++ components/wordCloud/style.scss | 33 ++++++++++ pages/index.js | 24 +++++-- 19 files changed, 661 insertions(+), 5 deletions(-) create mode 100644 components/interviewsList/index.js create mode 100644 components/interviewsList/style.scss create mode 100644 components/modal/index.js create mode 100644 components/modal/style.scss create mode 100644 components/pageFooter/index.js create mode 100644 components/pageFooter/style.scss create mode 100644 components/pageHeader/index.js create mode 100644 components/pageHeader/style.scss create mode 100644 components/projectsList/index.js create mode 100644 components/projectsList/style.scss create mode 100644 components/resources/index.js create mode 100644 components/resources/style.scss create mode 100644 components/search/index.js create mode 100644 components/search/style.scss create mode 100644 components/topicsList/index.js create mode 100644 components/topicsList/style.scss create mode 100644 components/wordCloud/index.js create mode 100644 components/wordCloud/style.scss diff --git a/components/interviewsList/index.js b/components/interviewsList/index.js new file mode 100644 index 0000000..415f690 --- /dev/null +++ b/components/interviewsList/index.js @@ -0,0 +1,50 @@ +import React from 'react'; +import Modal from '../../components/modal'; +import Data from '../../data/archives/interviews'; +import './style.scss'; + +class InterviewsList extends React.Component { + constructor(props) { + super(props); + this.state = { isInterviewsListModalOpen: false }; + this.toggleInterviewsListModal = this.toggleInterviewsListModal.bind(this); + } + + toggleInterviewsListModal() { + const { isInterviewsListModalOpen } = this.state; + this.setState({ isInterviewsListModalOpen: !isInterviewsListModalOpen }); + } + + render() { + const { isInterviewsListModalOpen } = this.state; + + return ( +
+
+ Interviews (100) {/* eslint-disable-line */} + View {/* eslint-disable-line */} +
+ + { + ( + +

Interviews

+
    + { + Data.map(interview =>
  • { `${interview.name} ${interview.surname}`}
  • ) + } +
+
+ ) + } +
+
+ ); + } +} + +export default InterviewsList; diff --git a/components/interviewsList/style.scss b/components/interviewsList/style.scss new file mode 100644 index 0000000..2111471 --- /dev/null +++ b/components/interviewsList/style.scss @@ -0,0 +1,37 @@ +@import './assets/styles/global.scss'; + +.mob-interviews-link { + display: flex; + justify-content: space-between; + margin-bottom: calculateRem(24); + + @media (min-width: $desktop) { + display: none; + } + + span { + cursor: pointer; + outline: none; + + &:hover { + text-decoration: underline; + } + } +} + +.interviews-list-wrap .modal { + + @media (min-width: $desktop) { + display: block; + width: calculateRem($desktop-related-interviews-width); + } + + li { + font-size: calculateRem(14); + cursor: pointer; + + &:hover { + text-decoration: underline; + } + } +} diff --git a/components/modal/index.js b/components/modal/index.js new file mode 100644 index 0000000..8165aff --- /dev/null +++ b/components/modal/index.js @@ -0,0 +1,25 @@ +import React from 'react'; +import { PropTypes } from 'prop-types'; +import './style.scss'; + +const Modal = props => ( +
+
+ {props.children} +
x
{/* eslint-disable-line */} +
+
+); + +Modal.propTypes = { + isModalOpen: PropTypes.bool.isRequired, + children: PropTypes.shape({}).isRequired, + closeModal: PropTypes.func.isRequired, + modalOnMobileOnly: PropTypes.bool, +}; + +Modal.defaultProps = { + modalOnMobileOnly: false, +}; + +export default Modal; diff --git a/components/modal/style.scss b/components/modal/style.scss new file mode 100644 index 0000000..a47b121 --- /dev/null +++ b/components/modal/style.scss @@ -0,0 +1,71 @@ +@import './assets/styles/global.scss'; + +.modal { + display: none; + + &.modal-open { + display: block; + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background-color: rgba(0, 0, 0, 0.6); + z-index: 3; + } + + &.modal-on-mobile-only { + + @media (min-width: $desktop) { + background-color: transparent; + height: auto; + + .modal-inner { + position: initial; + padding: 0; + width: auto; + height: auto; + top: inherit; + left: inherit; + } + + .modal-close { + display: none; + } + } + } +} + +.modal-inner { + position: relative; + z-index: 4; + background-color: #fff; + width: 90%; + height: 90%; + top: 5%; + left: 5%; + overflow: auto; + padding: calculateRem(20); + + @media (min-width: $tablet) { + padding-top: calculateRem(60); + } +} + +.modal-close { + position: absolute; + top: calculateRem(12); + right: calculateRem(12); + padding: calculateRem(4); + background-color: #cfcfcf; + text-align: center; + width: calculateRem(32); + height: calculateRem(32); + border-radius: 50%; + cursor: pointer; + outline: none; + + &:hover { + background-color: #c1c1c1; + } +} diff --git a/components/pageFooter/index.js b/components/pageFooter/index.js new file mode 100644 index 0000000..e5239a7 --- /dev/null +++ b/components/pageFooter/index.js @@ -0,0 +1,10 @@ +import React from 'react'; +import './style.scss'; + +export default () => ( +
+
+

Copyright { (new Date()).getFullYear() }

+
+
+); diff --git a/components/pageFooter/style.scss b/components/pageFooter/style.scss new file mode 100644 index 0000000..9e37380 --- /dev/null +++ b/components/pageFooter/style.scss @@ -0,0 +1,8 @@ +@import './assets/styles/global.scss'; + +.page-footer { + background-color: #efefef; + padding: calculateRem(8) 0; + text-align: center; + font-size: calculateRem(12); +} diff --git a/components/pageHeader/index.js b/components/pageHeader/index.js new file mode 100644 index 0000000..97e0d49 --- /dev/null +++ b/components/pageHeader/index.js @@ -0,0 +1,14 @@ +import React from 'react'; +import './style.scss'; + +export default () => ( +
+
+

Ethereum Report

+

+ We’ve interviewed 100+ developers to showcase the biggest opportunities in the + Ethereum ecosystem +

+
+
+); diff --git a/components/pageHeader/style.scss b/components/pageHeader/style.scss new file mode 100644 index 0000000..5616434 --- /dev/null +++ b/components/pageHeader/style.scss @@ -0,0 +1,14 @@ +@import './assets/styles/global.scss'; + +.page-header { + background-color: #efefef; + padding: calculateRem(24) 0; + text-align: center; + margin-bottom: calculateRem(24); + + h1 { + margin-bottom: calculateRem(24); + font-family: $secondary-font; + font-size: calculateRem(36); + } +} diff --git a/components/projectsList/index.js b/components/projectsList/index.js new file mode 100644 index 0000000..4bd29f0 --- /dev/null +++ b/components/projectsList/index.js @@ -0,0 +1,14 @@ +import React from 'react'; +import Data from '../../data/archives/projects'; +import './style.scss'; + +export default () => ( +
+

Projects

+ +
+); diff --git a/components/projectsList/style.scss b/components/projectsList/style.scss new file mode 100644 index 0000000..9e4270b --- /dev/null +++ b/components/projectsList/style.scss @@ -0,0 +1,25 @@ +@import './assets/styles/global.scss'; + +.projects-list { + margin-bottom: calculateRem(24); + + ul { + display: flex; + flex-wrap: wrap; + } + + li { + font-size: calculateRem(14); + padding: 0 calculateRem(8) calculateRem(8) 0; + cursor: pointer; + + span { + background-color: rgba(0, 0, 0, 0.1); + padding: calculateRem(4) calculateRem(12); + + &:hover { + background-color: rgba(0, 0, 0, 0.3); + } + } + } +} diff --git a/components/resources/index.js b/components/resources/index.js new file mode 100644 index 0000000..80d93b5 --- /dev/null +++ b/components/resources/index.js @@ -0,0 +1,97 @@ +import React from 'react'; +import Parser from 'html-react-parser'; +import Slider from 'react-slick'; +import Modal from '../../components/modal'; +import WordCloud from '../../components/wordCloud'; +import Data from '../../data/resources/wordclouds'; +import './style.scss'; + +class Resources extends React.Component { + constructor(props) { + super(props); + this.state = { + isWordCloudModalOpen: false, + activeSlide: 1, + }; + this.toggleWordCloudModal = this.toggleWordCloudModal.bind(this); + } + + toggleWordCloudModal(event) { + const { isWordCloudModalOpen } = this.state; + const clickedIndex = event.target.dataset.index; + + this.setState({ + isWordCloudModalOpen: !isWordCloudModalOpen, + activeSlide: clickedIndex, + }); + + this.slider.slickGoTo(clickedIndex); + } + + render() { + const { isWordCloudModalOpen, activeSlide } = this.state; + + const settings = { + infinite: true, + speed: 500, + slidesToShow: 1, + slidesToScroll: 1, + initialSlide: activeSlide, + className: 'resources-content-slider', + arrows: false, + }; + + return ( +
+
+

Resources

+
+ { + Data.map((wordCloud, index) => + ()) + } +
+ + (this.slider = slider)} {...settings}> {/* eslint-disable-line */} + { + Data.map((slide, index, array) => { + const prevItemIndex = index - 1 === -1 ? array.length - 1 : index - 1; + const nextItemIndex = index + 1 === array.length ? 0 : index + 1; + + return ( +
+
+
+
this.slider.slickGoTo(prevItemIndex)}> {/* eslint-disable-line */} + < { array[prevItemIndex].title } +
+

{ slide.title }

+
this.slider.slickGoTo(nextItemIndex)}> {/* eslint-disable-line */} + { array[nextItemIndex].title } > +
+
+
+ { Parser(slide.slideContent) } +
+
+
+ ); + }) + } +
+
+
+
+ ); + } +} + +export default Resources; diff --git a/components/resources/style.scss b/components/resources/style.scss new file mode 100644 index 0000000..42b1572 --- /dev/null +++ b/components/resources/style.scss @@ -0,0 +1,75 @@ +@import './assets/styles/global.scss'; + +.resources-wrap h2 { + text-transform: uppercase; + font-family: $secondary-font; + font-size: calculateRem(36); +} + +.wordclouds-wrap { + margin-bottom: calculateRem(24); + + @media (min-width: $bigMobile) { + display: grid; + grid-template-columns: repeat(2, 1fr); + } +} + +.resources-content-slider { + + @media (min-width: $tablet) { + + .slick-arrow { + top: calculateRem(8); + } + } + + .slide-inner { + text-align: center; + outline: none; + + &:focus, + &:active { + outline: none; + } + } + + .slide-header { + display: flex; + justify-content: space-between; + + @media (min-width: $tablet) { + margin-bottom: calculateRem(24); + } + + h3 { + margin: 0 calculateRem(40); + } + } + + .slide-content { + max-width: calculateRem(1024); + margin: 0 auto; + padding: 0 calculateRem(32); + } + + .slide-arrow { + cursor: pointer; + margin-top: calculateRem(32); + outline: none; + + @media (min-width: $tablet) { + margin-top: 0; + } + + span { + display: none; + + @media (min-width: $tablet) { + display: inline-block; + margin: 0 calculateRem(8); + font-size: calculateRem(12); + } + } + } +} diff --git a/components/search/index.js b/components/search/index.js new file mode 100644 index 0000000..bad7f72 --- /dev/null +++ b/components/search/index.js @@ -0,0 +1,45 @@ +import React from 'react'; +import TopicsList from '../../components/topicsList'; +import ProjectsList from '../../components/projectsList'; +import InterviewsList from '../interviewsList'; +import './style.scss'; + +class Search extends React.Component { + constructor(props) { + super(props); + this.state = { term: '' }; + this.onInputChange = this.onInputChange.bind(this); + } + + onInputChange(event) { + this.setState({ term: event.target.value }); + } + + render() { + return ( +
+
+
+

Browse Archives

+ +
+
+
+ +
+ + +
+
+
+ ); + } +} + +export default Search; diff --git a/components/search/style.scss b/components/search/style.scss new file mode 100644 index 0000000..64247c6 --- /dev/null +++ b/components/search/style.scss @@ -0,0 +1,50 @@ +@import './assets/styles/global.scss'; + +.search-bar { + background-color: #efefef; + margin-bottom: calculateRem(56); + + h3 { + padding: calculateRem(32) 0 0; + text-align: center; + text-transform: uppercase; + font-family: $secondary-font; + font-size: calculateRem(36); + } +} + +.search-input { + width: 100%; + height: calculateRem(48); + border: 5px solid #efefef; + padding: calculateRem(12); + font-size: calculateRem(16); + position: relative; + bottom: calculateRem(-24); + + &:focus, + &:active { + outline: none; + } +} + +.search-results-wrap.container { + margin-bottom: calculateRem(48); + + @media (min-width: $desktop) { + display: flex; + max-width: calculateRem($container-width + $desktop-related-interviews-width*2 + $container-padding*2); + } + + h4 { + margin-bottom: calculateRem(24); + } +} + +.search-results { + + @media (min-width: $desktop) { + width: calculateRem($container-width); + padding: 0 calculateRem($container-padding); + } +} diff --git a/components/topicsList/index.js b/components/topicsList/index.js new file mode 100644 index 0000000..be1604d --- /dev/null +++ b/components/topicsList/index.js @@ -0,0 +1,14 @@ +import React from 'react'; +import Data from '../../data/archives/topics'; +import './style.scss'; + +export default () => ( +
+

Topics

+ +
+); diff --git a/components/topicsList/style.scss b/components/topicsList/style.scss new file mode 100644 index 0000000..df57169 --- /dev/null +++ b/components/topicsList/style.scss @@ -0,0 +1,25 @@ +@import './assets/styles/global.scss'; + +.topics-list { + margin-bottom: calculateRem(24); + + ul { + display: flex; + flex-wrap: wrap; + } + + li { + font-size: calculateRem(14); + padding: 0 calculateRem(8) calculateRem(8) 0; + cursor: pointer; + + span { + background-color: rgba(0, 0, 0, 0.1); + padding: calculateRem(4) calculateRem(12); + + &:hover { + background-color: rgba(0, 0, 0, 0.3); + } + } + } +} diff --git a/components/wordCloud/index.js b/components/wordCloud/index.js new file mode 100644 index 0000000..735dff4 --- /dev/null +++ b/components/wordCloud/index.js @@ -0,0 +1,35 @@ +import React from 'react'; +import { PropTypes } from 'prop-types'; +import './style.scss'; + +const WordCloud = props => ( + // eslint-disable-next-line +
+

{ props.words.title }

+
+ { props.words.cloud.map(word => ( + + { word.word } + + )) + } +
+
+); + +WordCloud.propTypes = { + index: PropTypes.number.isRequired, + words: PropTypes.shape({ + title: PropTypes.string, + cloud: PropTypes.array, + }).isRequired, + toggleWordCloudModal: PropTypes.func.isRequired, +}; + +export default WordCloud; diff --git a/components/wordCloud/style.scss b/components/wordCloud/style.scss new file mode 100644 index 0000000..7bffd97 --- /dev/null +++ b/components/wordCloud/style.scss @@ -0,0 +1,33 @@ +@import './assets/styles/global.scss'; + +.wordcloud { + text-align: center; + padding: calculateRem(24); + cursor: pointer; + outline: none; + + h3{ + margin-bottom: calculateRem(8); + } + + span { + display: inline-block; + padding: 0 calculateRem(8); + + &.size-1 { + font-size: calculateRem(30); + } + + &.size-2 { + font-size: calculateRem(25); + } + + &.size-3 { + font-size: calculateRem(20); + } + + &.size-4 { + font-size: calculateRem(15); + } + } +} diff --git a/pages/index.js b/pages/index.js index 39a449c..72d94f7 100644 --- a/pages/index.js +++ b/pages/index.js @@ -1,8 +1,22 @@ import React from 'react'; +import PageHeader from '../components/pageHeader'; +import PageFooter from '../components/pageFooter'; +import Resources from '../components/resources'; +import Search from '../components/search'; import '../styles.scss'; -export default () => ( -
-

ETHPrize website
coming soon!

-
-); +class PageWrapper extends React.Component { + + render() { + return ( +
+ + + + +
+ ); + } +} + +export default PageWrapper;