From 68148b7c05299c9220d0ece01098ad0b8d51a0ec Mon Sep 17 00:00:00 2001 From: elvin solano Date: Thu, 18 Nov 2021 15:01:57 -0500 Subject: [PATCH 01/95] adds remaining files --- public/index.html | 2 +- src/components/Container/index.js | 21 +- src/components/Footer/index.js | 2 +- src/components/Mapathon/Details.js | 5 +- src/components/Mapathons/FilterButton.js | 45 +- src/components/Mapathons/InformationDialog.js | 38 + src/components/Mapathons/List.js | 39 +- src/components/Mapathons/index.js | 902 ++++++++++++++---- src/components/Mapathons/messages.js | 114 ++- src/components/Notification/index.js | 4 +- src/components/Spinner/Wrapper.js | 2 - src/components/TopBar/SearchForm.js | 29 +- src/components/TopBar/index.js | 51 +- src/components/TopBar/messages.js | 478 +++++----- src/images/icon-information.png | Bin 0 -> 5326 bytes src/images/mapathon-detail.png | Bin 0 -> 133514 bytes src/images/video-image.png | Bin 0 -> 323330 bytes src/images/video.png | Bin 0 -> 50798 bytes src/styles.js | 17 +- 19 files changed, 1150 insertions(+), 599 deletions(-) create mode 100644 src/components/Mapathons/InformationDialog.js create mode 100644 src/images/icon-information.png create mode 100644 src/images/mapathon-detail.png create mode 100644 src/images/video-image.png create mode 100644 src/images/video.png diff --git a/public/index.html b/public/index.html index ed7be1a0..2263b472 100644 --- a/public/index.html +++ b/public/index.html @@ -24,7 +24,7 @@ padding: 0; width: 100%; - background-color: #FAFAFA; + background-color: #FFF; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; diff --git a/src/components/Container/index.js b/src/components/Container/index.js index 5a13bcf6..e2ed3ed6 100755 --- a/src/components/Container/index.js +++ b/src/components/Container/index.js @@ -9,26 +9,9 @@ const Container = styled.div` justify-content: center; display: flex; - - padding: 2rem 1rem; + padding: 0; + // padding: 2rem 1rem; width: 100%; - - background-color: ${colors.lightestGrey}; - - ${media.tablet` - padding: 2rem 0; - width: 723px; - `}; - - ${media.desktop` - padding: 2rem 0; - width: 933px; - `}; - - ${media.widescreen` - padding: 2rem 0; - width: 1127px; - `}; ` export default Container diff --git a/src/components/Footer/index.js b/src/components/Footer/index.js index 067e4df9..33db7ccf 100644 --- a/src/components/Footer/index.js +++ b/src/components/Footer/index.js @@ -269,7 +269,7 @@ const IconLink = styled.a` display: flex; align-items: center; justify-content: center; - border-radius: 3px; + border-radius: 6px; height: 3rem; margin-right: 2rem; width: 100%; diff --git a/src/components/Mapathon/Details.js b/src/components/Mapathon/Details.js index 3d4a497c..1b882061 100644 --- a/src/components/Mapathon/Details.js +++ b/src/components/Mapathon/Details.js @@ -90,7 +90,7 @@ export default class Details extends React.Component { } render() { - const formatMessage = this.context.intl.formatMessage + const { formatMessage } = this.context.intl let canEditMapathon = false if (this.props.isAuthenticated) { @@ -172,7 +172,8 @@ export default class Details extends React.Component { float disabled={false} onClickHandler={() => - this.props.joinMapathon(this.props.id, this.props.userData.id)} + this.props.joinMapathon(this.props.id, this.props.userData.id) + } > props.float ? `0 3px 5px ${rgba(colors.darkestGrey, 0.4)}` : 'none'}; - height: 3rem; - margin: 0.2rem; - padding-top: 0.8rem; - padding-left: 0.5rem; - padding-right: 0.5rem; - padding-bottom: 0.5rem; - background-color: ${props => props.backgroundColor || colors.primary}; + background-color: #fff; + border: 1px solid ##dededf; cursor: pointer; color: ${props => props.color || colors.darkestGrey}; - font-weight: bold; - text-transform: uppercase; - + min-width: 104px; + font-size: 1rem; + margin-right: 20px; + padding: 0 10px; + &:last-child { + margin-right: 0; + } &:active, &:focus { outline: 2px solid ${colors.secondary}; + background-color: ##6b6b6b; } &:disabled, &[disabled] { opacity: 0.5; } - width: auto; @media only screen and (max-width: 600px) { - width: 48%; - font-size: 10.5px; } @media only screen and (max-width: 359px) { - width: 48%; - font-size: 9.4px; } @media only screen and (max-width: 343px) { - width: 48%; - font-size: 8.4px; } - + // REPLACE + svg { + display: none; + } ` const ButtonContent = styled.div` display: flex; - align-items: left; - justify-content: flex-start; + align-items: center; + justify-content: center; + min-height: 32px; ` const Text = styled.div` - margin: 0 0 0 0.5rem; - @media only screen and (max-width: 600px) { - margin: 0.2rem 0 0 0.4rem; - } + margin: 0; ` class FilterButton extends React.Component { @@ -132,6 +126,7 @@ class FilterButton extends React.Component { this.state.filter > 0 && ( )} + {this.state.type === 'radioButton' && this.state.filter === 0 && ( diff --git a/src/components/Mapathons/InformationDialog.js b/src/components/Mapathons/InformationDialog.js new file mode 100644 index 00000000..45166887 --- /dev/null +++ b/src/components/Mapathons/InformationDialog.js @@ -0,0 +1,38 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { intlShape } from 'react-intl' +import styled from 'styled-components' + +import Icon from '../Icon' +import { colors, media } from '../../styles' + +export default class Modal extends React.Component { + onClose = e => { + this.props.onClose && this.props.onClose(e) + } + + render() { + if (!this.props.show) { + return null + } + return ( + + ) + } +} +Modal.propTypes = { + onClose: PropTypes.func.isRequired, + show: PropTypes.bool.isRequired +} diff --git a/src/components/Mapathons/List.js b/src/components/Mapathons/List.js index 7d79d5f3..84cb88a9 100644 --- a/src/components/Mapathons/List.js +++ b/src/components/Mapathons/List.js @@ -12,7 +12,6 @@ import messages from './messages' const Wrapper = styled.div` flex-grow: 1; width: 100%; - &::after { display: table; clear: both; @@ -22,21 +21,16 @@ const Wrapper = styled.div` const Item = styled(RouterLink)` float: left; - display: flex; - align-items: center; justify-content: center; - border: 1px solid ${colors.grey}; margin-bottom: 1rem; margin-right: 0; border-radius: 3px; width: 100%; height: 10rem; - background-color: white; - text-decoration: none; &:active, @@ -87,11 +81,9 @@ const Item = styled(RouterLink)` const Poster = styled.div` flex-shrink: 0; - border-radius: 3px 0 0 3px; width: 30%; height: 99.9%; - background-image: ${props => `url("${props.image}")`}; background-position: center; background-repeat: no-repeat; @@ -99,7 +91,6 @@ const Poster = styled.div` ${media.desktop` flex-shrink: 1; - border-radius: 3px 3px 0 0; height: 50%; width: 100%; @@ -108,10 +99,8 @@ const Poster = styled.div` const Info = styled.div` display: flex; - flex-direction: column; justify-content: space-between; - height: inherit; padding: 1rem; width: 70%; @@ -125,10 +114,8 @@ const Info = styled.div` const Name = styled.h3` overflow: hidden; - margin: 0 0 1rem 0; width: 100%; - color: ${colors.darkestGrey}; text-overflow: ellipsis; white-space: nowrap; @@ -136,20 +123,18 @@ const Name = styled.h3` const AddressWrapper = styled.div` display: flex; - align-items: center; - margin-bottom: 0.2rem; width: 100%; ` -const Icon = styled(Icn)`flex-shrink: 0;` +const Icon = styled(Icn)` + flex-shrink: 0; +` const AddressText = styled.p` overflow: hidden; - margin: 0 0 0 0.5rem; - color: ${colors.darkestGrey}; font-size: 0.9rem; text-overflow: ellipsis; @@ -158,18 +143,14 @@ const AddressText = styled.p` const DatesWrapper = styled.div` display: flex; - align-items: center; - margin-bottom: 1rem; width: 100%; ` const DatesText = styled.p` overflow: hidden; - margin: 0 0 0 0.5rem; - color: ${colors.darkestGrey}; font-size: 0.9rem; text-overflow: ellipsis; @@ -190,9 +171,7 @@ const ReviewsFill = styled.div` const ReviewsText = styled.p` overflow: hidden; - margin: 0 0 0.5rem 0; - color: ${colors.darkestGrey}; font-size: 0.9rem; font-weight: bold; @@ -201,8 +180,8 @@ const ReviewsText = styled.p` ` const List = (props, context) => { - const formatMessage = context.intl.formatMessage - const formatDate = context.intl.formatDate + const { formatMessage } = context.intl + const { formatDate } = context.intl if (props.mapathons.length === 0) return null @@ -249,9 +228,11 @@ const List = (props, context) => { 1 - ? 100 - : m.reviewsAmount / m.reviewsGoal * 100}%`} + width={`${ + m.reviewsAmount / m.reviewsGoal > 1 + ? 100 + : (m.reviewsAmount / m.reviewsGoal) * 100 + }%`} /> diff --git a/src/components/Mapathons/index.js b/src/components/Mapathons/index.js index 7a594362..e2ddf5ca 100755 --- a/src/components/Mapathons/index.js +++ b/src/components/Mapathons/index.js @@ -1,31 +1,39 @@ -import { array, bool, func, number, object } from "prop-types"; -import React, { Component } from "react"; -import ReactGA from "react-ga"; -import { Helmet } from "react-helmet"; -import { intlShape } from "react-intl"; -import styled from "styled-components"; - -import Button from "../Button"; -import Ctn from "../Container"; -import Footer from "../Footer"; -import Icon from "../Icon"; -import LinkBtn from "../LinkButton"; -import NoResults from "../NoResults"; -import Spinner from "../Spinner"; -import { colors, media } from "../../styles"; -import TabBar from "../../containers/TabBar"; -import TopBar from "../../containers/TopBar"; -import Wrapper from "../Wrapper"; - -import List from "./List"; -import messages from "./messages"; -import FilterButton from "./FilterButton"; -import SelectBox from "../SelectBox"; +import { array, bool, func, number, object } from 'prop-types' +import React, { Component } from 'react' +import ReactGA from 'react-ga' +import { Helmet } from 'react-helmet' +import { intlShape } from 'react-intl' +import styled from 'styled-components' + +import { NoEncryption } from '@material-ui/icons' +import Button from '../Button' +import Ctn from '../Container' +import Footer from '../Footer' +import Icon from '../Icon' +import LinkBtn from '../LinkButton' +import NoResults from '../NoResults' +import Spinner from '../Spinner' +import { colors, fontWeight, media } from '../../styles' +import TabBar from '../../containers/TabBar' +import TopBar from '../../containers/TopBar' +import Wrapper from '../Wrapper' +import CloseBtn from '../CreateReview/CloseBtn' + +import List from './List' +import messages from './messages' +import FilterButton from './FilterButton' +import SelectBox from '../SelectBox' + +import VideoImage from '../../images/video-image.png' +import MapathonImage from '../../images/mapathon-detail.png' +import InformationIcon from '../../images/icon-information.png' +import MobileLanguageDropdown from '../../images/icons/world.png' + +import Modal from './InformationDialog' const Container = styled(Ctn)` justify-content: flex-start; - padding-bottom: 4rem; - padding-top: 1rem; + padding-top: 4rem; margin-left: auto; margin-right: auto; @@ -35,9 +43,142 @@ const Container = styled(Ctn)` `}; ${media.desktop` - padding-bottom: 2rem; + margin-left: auto; + margin-right: auto; + padding-bottom: 2rem; `}; -`; +` + +const TopContainer = styled.div` + width: 100%; + background-color: #fff; +` + +const BottomContainer = styled.div` + width: 100%; + background-color: #f4f4f4; +` + +const InteriorContainer = styled.div` + width: 100%; + margin: 0 auto; + padding: 1rem; + + ${media.tablet` + padding: 2rem 0; + width: 723px; + `}; + + ${media.desktop` + padding: 2rem 0; + width: 933px; + `}; + + ${media.widescreen` + padding: 2rem 0; + width: 1172px; + `}; +` + +const HeroCopy = styled.div` + font-size: 1.25rem; + font-weight: bold; + color: #42454a; + width: 80%; + margin-bottom: 20px; + ${media.tablet` + font-size: 1.2rem; + `}; + + ${media.desktop` + width: 100%; + font-size: 1.9rem; + `}; +` + +const HeroTop = styled.div` + width: 100%; + position: relative; + ${media.tablet` + width: 100%; + `}; + + ${media.desktop` + width: 50%; + padding-right: 10px; + `}; +` + +const HeroBottom = styled.div` + width: 100%; + ${media.tablet` + width: 100%; + `}; + + ${media.desktop` + width: 50%; + `}; +` + +const HeroList = styled.ol` + margin: 0 0 20px; + padding-left: 40px; + clear: both; + list-style: none; +` + +const HeroListItem = styled.li` + display: block; + position: relative; + counter-increment: inst; + padding-bottom: 20px; + ::before { + content: counter(inst); + background: ${props => props.backgroundColor || colors.primary}; + border-radius: 50%; + font-size: 1em; + text-align: center; + font-weight: bold; + left: -40px; + top: 0; + min-height: 32px; + min-width: 32px; + position: absolute; + padding: 5px; + } + &:last-child { + padding: 0; + } +` + +const HeroListCopy = styled.p` + font-size: 1rem; + margin: 0; +` + +const ModalBtn = styled.div` + position: absolute; + top: 0; + right: 0; + + ${media.tablet` + + `}; + + ${media.desktop` + display: none; + `}; +` + +const Flex = styled.div` + ${media.tablet` + + `}; + + ${media.desktop` + display: flex; + `}; +` const Video = styled.iframe` height: 15rem; @@ -51,26 +192,40 @@ const Video = styled.iframe` ${media.desktop` height: 25rem; + display: block; `}; -`; +` + +const Image = styled.img` + width: auto; + margin: 0; +` + +const VideoContainer = styled.img` + display: block; + width: auto; + margin: 0; +` const LinkButton = styled(LinkBtn)` margin-bottom: 1rem; + width: 100%; ${media.tablet` margin-bottom: 2rem; + width: 266px; + `}; + ${media.desktop` + width: 266px; `}; -`; +` const ButtonsWrapper = styled.div` bottom: 5rem; left: 0; position: fixed; - display: flex; - - justify-content: space-around; - + justify-content: center; padding: 0 1rem; width: 100%; @@ -81,17 +236,18 @@ const ButtonsWrapper = styled.div` ${media.desktop` position: static; `}; -`; +` const ButtonContent = styled.div` display: flex; align-items: center; - justify-content: space-between; -`; + justify-content: center; + width: 100%; +` const ButtonContent2 = styled.div` width: 100%; padding: 0; - margin: 0 0 2rem 0; + margin: 0; list-style: none; -ms-box-orient: horizontal; display: -webkit-box; @@ -103,9 +259,175 @@ const ButtonContent2 = styled.div` -webkit-flex-wrap: wrap; flex-wrap: wrap; ${media.desktop` + justify-content: space-between; + `}; +` + +const FilterWrapper = styled.div` + margin: 0 0 2rem 0; + width: fit-content; +` + +const HideOnMobile = styled.div` + display: none; + + ${media.tablet` + + `}; + + ${media.desktop` + display: block; + `}; +` + +// + +const WrapperItem = styled.div` + flex-grow: 1; + width: 100%; + &::after { + display: table; + clear: both; + content: ''; + } +` + +const Item = styled.div` + float: left; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + border: 1px solid ${colors.grey}; + border-radius: 10px; + margin-bottom: 1rem; + margin-right: 0; + width: 100%; + min-height: 10rem; + background-color: white; + text-decoration: none; + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16%); + overflow: hidden; + + &:active, + &:focus { + outline: 2px solid ${colors.secondary}; + } + + &:disabled, + &[disabled] { + opacity: 0.5; + } + + ${media.tablet` + margin-bottom: 2rem; + margin-right: 2rem; + width: calc((100% - 2rem * 1) / 2); + + &:nth-child(2n+2) { + float: right; + margin-right: 0; + } + `}; + + ${media.desktop` + flex-direction: column; + margin-bottom: 2rem; + margin-right: 2rem; + width: calc((100% - 2rem * 3) / 4); + height: 20rem; + + &:nth-child(2n+2) { + float: left; + margin-right: 2rem; + } + + &:nth-child(3n+3) { + float: left; + margin-right: 2rem; + } + + &:nth-child(4n+4) { + float: right; + margin-right: 0; + } + `}; +` + +const Poster = styled.div` + flex-shrink: 0; + width: 100%; + height: 150px; + background-image: ${props => `url("${props.image}")`}; + background-position: top; + background-repeat: no-repeat; + background-size: cover; + + ${media.desktop` + flex-shrink: 1; + width: 100%; + height: 150px; + `}; +` + +const Info = styled.div` + display: flex; + flex-direction: column; justify-content: space-between; + height: inherit; + width: 100%; + padding: 1rem; + + ${media.desktop` + border-radius: 0 0 3px 3px; + height: 50%; + width: 100%; `}; -`; +` + +const Name = styled.h3` + overflow: hidden; + margin: 0 0 1rem 0; + width: 100%; + color: ${colors.darkestGrey}; + text-overflow: ellipsis; + white-space: nowrap; +` + +const AddressWrapper = styled.div` + display: flex; + align-items: center; + margin-bottom: 0.2rem; + width: 100%; +` + +const AddressText = styled.p` + overflow: hidden; + margin: 0 0 0 0.5rem; + color: ${colors.darkestGrey}; + font-size: 0.9rem; + text-overflow: ellipsis; + white-space: nowrap; +` + +const DatesWrapper = styled.div` + display: flex; + align-items: center; + margin-bottom: 1rem; + width: 100%; +` + +const ReviewsText = styled.p` + overflow: hidden; + margin: 0 0 0.5rem 0; + color: ${colors.darkestGrey}; + font-size: 0.9rem; + font-weight: bold; + text-overflow: ellipsis; + white-space: nowrap; +` + +// class Mapathons extends Component { static propTypes = { @@ -119,221 +441,421 @@ class Mapathons extends Component { mapathons: array.isRequired, sendingRequest: bool.isRequired, getMapathons: func.isRequired, - clearState: func.isRequired, - }; + clearState: func.isRequired + } state = { geolocation: this.props.filters.geolocation, gettingGeolocation: false, - }; + show: false + } static contextTypes = { - intl: intlShape, - }; + intl: intlShape + } componentWillMount() { - ReactGA.pageview(window.location.pathname + window.location.search); + ReactGA.pageview(window.location.pathname + window.location.search) } componentDidMount() { - this.props.getMapathons(); + this.props.getMapathons() } componentWillUnmount() { - this.props.clearState(); + this.props.clearState() } - updateGeolocation = (event) => { - const radius = parseInt(event.target.value); + updateGeolocation = event => { + const radius = parseInt(event.target.value) if (radius === 0) { this.setState({ geolocation: { lat: 0, long: 0, - radius: 0, + radius: 0 }, - gettingGeolocation: false, - }); + gettingGeolocation: false + }) this.props.applyFilters({ geolocation: { radius: 0, lat: 0, - long: 0, - }, - }); - return; + long: 0 + } + }) + return } - this.setState({ gettingGeolocation: true, geolocation: { radius } }); + this.setState({ gettingGeolocation: true, geolocation: { radius } }) navigator.geolocation.getCurrentPosition( - (position) => { - const lat = position.coords.latitude; - const long = position.coords.longitude; + position => { + const lat = position.coords.latitude + const long = position.coords.longitude this.setState({ gettingGeolocation: false, geolocation: { radius, lat, - long, - }, - }); + long + } + }) this.props.applyFilters({ geolocation: { - radius: radius, - lat: lat, - long: long, - }, - }); + radius, + lat, + long + } + }) }, () => { this.setState({ geolocation: { lat: -1, long: -1, - radius: radius, + radius }, - gettingGeolocation: false, - }); + gettingGeolocation: false + }) this.props.applyFilters({ geolocation: { - radius: radius, + radius, lat: -1, - long: -1, - }, - }); + long: -1 + } + }) } - ); - }; + ) + } + + showModal = e => { + this.setState({ + show: !this.state.show + }) + } render() { - const { formatMessage } = this.context.intl; + const { formatMessage } = this.context.intl const options = [ - { value: "0", label: formatMessage(messages.allLabel) }, - { value: "10", label: `10 ${formatMessage(messages.milesLabel)}` }, - { value: "25", label: `25 ${formatMessage(messages.milesLabel)}` }, - { value: "50", label: `50 ${formatMessage(messages.milesLabel)}` }, - ]; + { value: '0', label: formatMessage(messages.allLabel) }, + { value: '10', label: `10 ${formatMessage(messages.milesLabel)}` }, + { value: '25', label: `25 ${formatMessage(messages.milesLabel)}` }, + { value: '50', label: `50 ${formatMessage(messages.milesLabel)}` } + ] return ( + + + + {formatMessage(messages.pageLabel)} + + + + + + {formatMessage(messages.listFirstTitle)} + + + + {formatMessage(messages.listFirstCopy)} + + + + + + {formatMessage(messages.listSecondTitle)} + + + + {formatMessage(messages.listSecondCopy)} + + + + + + {formatMessage(messages.listThirdTitle)} + + + + {formatMessage(messages.listThirdCopy)} + + + + + -