diff --git a/.env b/.env index 7b8a211..7d910f1 100644 --- a/.env +++ b/.env @@ -1 +1 @@ -NODE_PATH=src/ +SKIP_PREFLIGHT_CHECK=true \ No newline at end of file diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..bb0aefa --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v12.1.0 diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/.prettierrc @@ -0,0 +1 @@ +{} diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..ec2332e --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "baseUrl": "src" + } +} diff --git a/package.json b/package.json index c0befa1..0fa7028 100644 --- a/package.json +++ b/package.json @@ -1,27 +1,39 @@ { "name": "keihard", - "version": "0.1.0", + "version": "1.0.1", "homepage": "http://keihardroeien.nl", "private": true, "dependencies": { - "i18next": "^11.3.2", - "i18next-browser-languagedetector": "^2.2.0", - "react": "^16.3.2", - "react-dom": "^16.3.2", - "react-i18next": "^7.6.1", - "react-redux": "^5.0.7", - "react-router": "^4.2.0", - "react-router-redux": "^5.0.0-alpha.9", - "react-scripts": "1.1.4", - "redux": "^4.0.0", - "redux-devtools-extension": "^2.13.2", - "redux-saga": "^0.16.0", - "styled-components": "^3.2.6" + "i18next": "^19.4.2", + "i18next-browser-languagedetector": "^4.1.1", + "react": "^16.13.1", + "react-dom": "^16.13.1", + "react-i18next": "^11.3.5", + "react-is": "^16.13.1", + "react-redux": "^7.2.0", + "react-scripts": "^3.4.1", + "redux": "^4.0.5", + "redux-devtools-extension": "^2.13.8", + "redux-saga": "^1.1.3", + "styled-components": "^5.1.0", + "typeface-passion-one": "^0.0.72" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] } } diff --git a/src/components/App.js b/src/components/App.js index 172e8ff..d74845d 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -1,29 +1,27 @@ -import React, { Fragment } from 'react' -import { Route, Switch } from 'react-router' +import React from "react"; -import Translations from 'components/Translations' -import Theme from 'components/Theme' -import { Container } from 'components/lib' -import SponsorModal from 'components/SponsorModal' -import PhotoModal from 'components/PhotoModal' -import HomePage from 'pages/home' +import Translations from "components/Translations"; +import LocaleTracker from "components/LocaleTracker"; +import Theme from "components/Theme"; +import { Container } from "components/lib"; +import SponsorModal from "components/SponsorModal"; +import PhotoModal from "components/PhotoModal"; +import HomePage from "pages/home"; const App = () => ( - - + + - - - + - {[1,2,3,4,5,6].map(n => + {[1, 2, 3, 4, 5, 6].map((n) => ( - )} - - + ))} + + -) +); -export default App +export default App; diff --git a/src/components/Footer.js b/src/components/Footer.js index 3368e8b..75e6e33 100644 --- a/src/components/Footer.js +++ b/src/components/Footer.js @@ -1,23 +1,23 @@ -import React from 'react' -import styled from 'styled-components' -import { translate, Trans } from 'react-i18next' +import React from "react"; +import styled from "styled-components"; +import { withTranslation, Trans } from "react-i18next"; -import { Text, Link, Wrapper, Row, Button } from 'components/lib' -import Waves from 'components/Waves' -import Title from 'components/Title' -import Sponsors from 'components/Sponsors' +import { Text, Link, Wrapper, Row, Button } from "components/lib"; +import Waves from "components/Waves"; +import Title from "components/Title"; +import Sponsors from "components/Sponsors"; -const Footer = styled.footer` +const FooterContainer = styled.footer` position: relative; padding: 4em 0; - background: - linear-gradient(#fff, #f2f2f2 2em); -` + background: linear-gradient(#fff, #f2f2f2 2em); +`; const FooterWaves = styled(Waves)` position: absolute; - left: 0; top: 0; + left: 0; + top: 0; right: 0; width: 100%; @@ -25,38 +25,63 @@ const FooterWaves = styled(Waves)` transform: scale(1, -1); - fill: rgba(255, 255, 255, .4); -` + fill: rgba(255, 255, 255, 0.4); +`; const Languages = styled.div` text-align: center; -` +`; -const Language = Button.extend` - margin: 0 .25em; -` +const Language = styled(Button)` + margin: 0 0.25em; +`; -export default translate('page')(({t, i18n}) => ( - -)) + +); + +export default withTranslation()(Footer); diff --git a/src/components/Header.js b/src/components/Header.js index 6cb72eb..a40aa4d 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -1,40 +1,41 @@ -import React from 'react' -import styled from 'styled-components' +import React from "react"; +import styled from "styled-components"; -import { Link } from 'components/lib' -import Waves from 'components/Waves' +import { Link } from "components/lib"; +import Waves from "components/Waves"; -import headerBg from 'assets/header.jpg' -import kika from 'assets/kika.png' +import headerBg from "assets/header.jpg"; +import kika from "assets/kika.png"; const Header = styled.header` position: relative; height: 40vmin; - background-color: ${props => props.theme.colors.primary}; - background: - linear-gradient(90deg, transparent 75%, rgba(255, 255, 255, .1)), + background-color: ${(props) => props.theme.colors.primary}; + background: linear-gradient(90deg, transparent 75%, rgba(255, 255, 255, 0.1)), linear-gradient(transparent 80%, #fff), url(${headerBg}) no-repeat left 30% top 50% / cover; -` +`; const KiKaImage = styled.img` position: absolute; - right: 2em; top: 2em; + right: 2em; + top: 2em; height: 50%; -` +`; const HeaderWaves = styled(Waves)` position: absolute; left: 0; - right: 0; bottom: 0; + right: 0; + bottom: 0; width: 100%; height: 20%; - fill: rgba(255, 255, 255, .8); -` + fill: rgba(255, 255, 255, 0.8); +`; export default () => (
@@ -43,4 +44,4 @@ export default () => (
-) +); diff --git a/src/components/LocaleTracker.js b/src/components/LocaleTracker.js new file mode 100644 index 0000000..03b1073 --- /dev/null +++ b/src/components/LocaleTracker.js @@ -0,0 +1,8 @@ +import { useTranslation } from "react-i18next"; + +const LocaleTracker = ({ children }) => { + useTranslation(); + return children; +}; + +export default LocaleTracker; diff --git a/src/components/PaymentMethod.js b/src/components/PaymentMethod.js index 629e31d..a122719 100644 --- a/src/components/PaymentMethod.js +++ b/src/components/PaymentMethod.js @@ -1,13 +1,13 @@ -import React from 'react' -import { connect } from 'react-redux' -import styled, { css } from 'styled-components' +import React from "react"; +import { connect } from "react-redux"; +import styled, { css } from "styled-components"; -import * as Pledge from 'ducks/pledge' +import * as Pledge from "ducks/pledge"; -import { Image } from 'components/lib' +import { Image } from "components/lib"; -import paypal from 'assets/icons/paypal.png' -import iban from 'assets/icons/iban.png' +import paypal from "assets/icons/paypal.png"; +import iban from "assets/icons/iban.png"; const Method = styled.div` cursor: pointer; @@ -17,52 +17,53 @@ const Method = styled.div` display: inline-block; width: 3em; height: 3.5em; - padding: .5em; - margin: .5em .5em 0 0; - border-radius: ${props => props.theme.border.radius}; + padding: 0.5em; + margin: 0.5em 0.5em 0 0; + border-radius: ${(props) => props.theme.border.radius}; - ${props => props.selected && css` - background-color: rgba(0, 0, 0, .1); - `} -` + ${(props) => + props.selected && + css` + background-color: rgba(0, 0, 0, 0.1); + `} +`; -const CenterImage = Image.extend` +const CenterImage = styled(Image)` position: absolute; - left: .5em; top: .5em; - right: .5em; bottom: .5em; + left: 0.5em; + top: 0.5em; + right: 0.5em; + bottom: 0.5em; max-width: 2em; max-height: 2.5em; margin: auto; -` +`; const PaymentMethod = ({ image, method, selected, onClick }) => ( -) +); const getImage = (method) => { switch (method) { - case 'PayPal': - return paypal - case 'Bankoverschrijving': - return iban + case "PayPal": + return paypal; + case "Bankoverschrijving": + return iban; default: - return paypal + return paypal; } -} +}; const mapStateToProps = (state, props) => ({ image: getImage(props.method), - selected: state.pledge.payment_method === props.method -}) + selected: state.pledge.payment_method === props.method, +}); const mapDispatchToProps = (dispatch, props) => ({ - onClick: () => dispatch(Pledge.update('payment_method', props.method)) -}) + onClick: () => dispatch(Pledge.update("payment_method", props.method)), +}); -export default connect( - mapStateToProps, - mapDispatchToProps -)(PaymentMethod) +export default connect(mapStateToProps, mapDispatchToProps)(PaymentMethod); diff --git a/src/components/PhotoModal.js b/src/components/PhotoModal.js index 013f07a..549a080 100644 --- a/src/components/PhotoModal.js +++ b/src/components/PhotoModal.js @@ -1,37 +1,44 @@ -import React from 'react' -import styled from 'styled-components' +import React from "react"; +import styled from "styled-components"; -import { Modal } from 'components/lib' +import { Modal } from "components/lib"; -import photo1 from 'assets/photo1.jpg' -import photo2 from 'assets/photo2.jpg' -import photo3 from 'assets/photo3.jpg' -import photo4 from 'assets/photo4.jpg' -import photo5 from 'assets/photo5.jpg' -import photo6 from 'assets/photo6.jpg' +import photo1 from "assets/photo1.jpg"; +import photo2 from "assets/photo2.jpg"; +import photo3 from "assets/photo3.jpg"; +import photo4 from "assets/photo4.jpg"; +import photo5 from "assets/photo5.jpg"; +import photo6 from "assets/photo6.jpg"; const Center = styled.div` text-align: center; -` +`; const Photo = styled.img` max-width: calc(100vw - 4em); max-height: calc(100vh - 4.5em); margin: -2em; - border-radius: ${props => props.theme.border.radius}; -` + border-radius: ${(props) => props.theme.border.radius}; +`; -const getSrc = n => { +const getSrc = (n) => { switch (n) { - case 1: return photo1 - case 2: return photo2 - case 3: return photo3 - case 4: return photo4 - case 5: return photo5 - case 6: return photo6 - default: return null + case 1: + return photo1; + case 2: + return photo2; + case 3: + return photo3; + case 4: + return photo4; + case 5: + return photo5; + case 6: + return photo6; + default: + return null; } -} +}; const PhotoModal = ({ n }) => ( @@ -39,6 +46,6 @@ const PhotoModal = ({ n }) => ( -) +); -export default PhotoModal +export default PhotoModal; diff --git a/src/components/Photos.js b/src/components/Photos.js index 802b3a9..241c8a0 100644 --- a/src/components/Photos.js +++ b/src/components/Photos.js @@ -1,53 +1,71 @@ -import React from 'react' -import styled from 'styled-components' -import { connect } from 'react-redux' -import { opacity } from 'style-utils' +import React from "react"; +import styled from "styled-components"; +import { connect } from "react-redux"; +import { opacity } from "style-utils"; -import * as Modals from 'ducks/modals' +import * as Modals from "ducks/modals"; -import { Text, Row, Column } from 'components/lib' -import SubTitle from 'components/SubTitle' +import { Text, Row, Column } from "components/lib"; +import SubTitle from "components/SubTitle"; -import photo1 from 'assets/photo1.jpg' -import photo2 from 'assets/photo2.jpg' -import photo3 from 'assets/photo3.jpg' -import photo4 from 'assets/photo4.jpg' -import photo5 from 'assets/photo5.jpg' -import photo6 from 'assets/photo6.jpg' +import photo1 from "assets/photo1.jpg"; +import photo2 from "assets/photo2.jpg"; +import photo3 from "assets/photo3.jpg"; +import photo4 from "assets/photo4.jpg"; +import photo5 from "assets/photo5.jpg"; +import photo6 from "assets/photo6.jpg"; const StyledPhoto = styled.div` cursor: pointer; padding-top: 75%; margin-bottom: 1em; - border-radius: ${props => props.theme.border.radius}; + border-radius: ${(props) => props.theme.border.radius}; - box-shadow: 0 .1em .3em ${props => opacity(props.theme.colors.primary, .2)}; + box-shadow: 0 0.1em 0.3em + ${(props) => opacity(props.theme.colors.primary, 0.2)}; - background: url(${props => props.src}) no-repeat center / cover; -` + background: url(${(props) => props.src}) no-repeat center / cover; +`; const mapDispatchToProps = (dispatch, { n }) => ({ - innerRef: el => dispatch(Modals.setOrigin(`photo${n}`, el)), - onClick: () => dispatch(Modals.open(`photo${n}`)) -}) + innerRef: (el) => dispatch(Modals.setOrigin(`photo${n}`, el)), + onClick: () => dispatch(Modals.open(`photo${n}`)), +}); -const Photo = connect( - () => ({}), - mapDispatchToProps, -)(StyledPhoto) +const Photo = connect(() => ({}), mapDispatchToProps)(StyledPhoto); export default () => ( Post mortem - In februari 2018 stapten we voor het eerst de roeiboot in bij studenten roeivereniging Proteus te Delft. Een plek waar we de maanden daarna nog veel uren zouden doorbrengen op de roeimachines en in de boten. Na maanden training op 6 juni was het dan zover, de Ringvaart. Deze dag hebben wij: Daniël, Leon, Sigur, Wouter en natuurlijk onze stuur Suzanne, de 100 kilometers geroeid in 10 uur en 8 minuten. De dag is nu voorbij, maar gelukkig hebben we de foto's nog. + + In februari 2018 stapten we voor het eerst de roeiboot in bij studenten + roeivereniging Proteus te Delft. Een plek waar we de maanden daarna nog + veel uren zouden doorbrengen op de roeimachines en in de boten. Na + maanden training op 6 juni was het dan zover, de Ringvaart. Deze dag + hebben wij: Daniël, Leon, Sigur, Wouter en natuurlijk onze stuur + Suzanne, de 100 kilometers geroeid in 10 uur en 8 minuten. De dag is nu + voorbij, maar gelukkig hebben we de foto's nog. + + + + + + + + + + + + + + + + + + + - - - - - - -) +); diff --git a/src/components/ShareForm.js b/src/components/ShareForm.js index 59dd340..ec37f7b 100644 --- a/src/components/ShareForm.js +++ b/src/components/ShareForm.js @@ -1,17 +1,17 @@ -import React from 'react' -import styled from 'styled-components' +import React from "react"; +import styled from "styled-components"; -import { opacity } from 'style-utils' -import { Column } from 'components/lib' +import { opacity } from "style-utils"; +import { Column } from "components/lib"; const ShareForm = styled.div` margin: 1em 0 4em; text-align: center; -` +`; const Share = styled.a.attrs({ - target: '_blank' + target: "_blank", })` display: inline-block; width: 1.5em; @@ -21,17 +21,18 @@ const Share = styled.a.attrs({ color: transparent; svg { - fill: ${props => opacity(props.theme.colors.text, .2)}; + fill: ${(props) => opacity(props.theme.colors.text, 0.2)}; } &:hover svg { - fill: ${props => opacity(props.theme.colors.text, props.theme.opacity.text)}; + fill: ${(props) => + opacity(props.theme.colors.text, props.theme.opacity.text)}; } -` +`; -const url = encodeURIComponent('http://keihardroeien.nl') -const twitterText = 'Wij gaan Keihard roeien voor KiKa.' -const emailBody = `Wij gaan Keihard roeien voor KiKa: ${url}` +const url = encodeURIComponent("http://keihardroeien.nl"); +const twitterText = "Wij gaan Keihard roeien voor KiKa."; +const emailBody = `Wij gaan Keihard roeien voor KiKa: ${url}`; export default () => ( @@ -39,25 +40,36 @@ export default () => ( facebook icon - + - - - twitter icon - - + + + twitter icon + + mail icon - + -) +); diff --git a/src/components/SponsorForm.js b/src/components/SponsorForm.js index a65e7a7..f975e6c 100644 --- a/src/components/SponsorForm.js +++ b/src/components/SponsorForm.js @@ -1,14 +1,14 @@ -import React from 'react' -import { translate } from 'react-i18next' -import { connect } from 'react-redux' -import styled from 'styled-components' +import React from "react"; +import { withTranslation } from "react-i18next"; +import { connect } from "react-redux"; +import styled from "styled-components"; -import { opacity, media } from 'style-utils' -import { Column, Text, Button } from 'components/lib' +import { opacity, media } from "style-utils"; +import { Column, Text, Button } from "components/lib"; -import * as Modals from 'ducks/modals' +import * as Modals from "ducks/modals"; -import Waves from 'components/Waves' +import Waves from "components/Waves"; const Paper = styled.div` position: relative; @@ -19,38 +19,51 @@ const Paper = styled.div` margin: 3em 0 0; ${media.small`margin: 0 -1em;`} - border: 1px solid ${props => opacity(props.theme.colors.primary, .1)}; - border-radius: ${props => props.theme.border.radius}; - box-shadow: 0 .1em .3em ${props => opacity(props.theme.colors.primary, .2)}; -` + border: 1px solid ${(props) => opacity(props.theme.colors.primary, 0.1)}; + border-radius: ${(props) => props.theme.border.radius}; + box-shadow: 0 .1em .3em ${(props) => + opacity(props.theme.colors.primary, 0.2)}; +`; -const TagValue = Text.extend` +const TagValue = styled(Text)` font-size: 2em; margin: 0; -` +`; -const TagLabel = Text.extend` - font-size: .75em; +const TagLabel = styled(Text)` + font-size: 0.75em; margin-top: 0; -` +`; const FormWaves = styled(Waves)` position: absolute; left: 0; - right: 0; bottom: 0; + right: 0; + bottom: 0; z-index: -1; width: 100%; height: 5em; - fill: ${props => opacity(props.theme.colors.accent, .5)}; -` + fill: ${(props) => opacity(props.theme.colors.accent, 0.5)}; +`; -const SponsorForm = ({ t, amount, shirtAmount, count, days, onRefLoad, onButtonClick }) => ( +const SponsorForm = ({ + t, + amount, + shirtAmount, + count, + days, + onRefLoad, + onButtonClick, +}) => ( €{amount},- - {t`donated`} + + {t`donated`} + + {count} @@ -61,37 +74,45 @@ const SponsorForm = ({ t, amount, shirtAmount, count, days, onRefLoad, onButtonC {t`days`} - {t("remark", { kikaAmount: amount - shirtAmount, shirtAmount })} + + + + {t("remark", { kikaAmount: amount - shirtAmount, shirtAmount })} + + - + -) +); const mapStateToProps = (state, props) => ({ - amount: state.sponsors - .map(s => s.amount) - .reduce((acc, x) => acc + x, 0), + amount: state.sponsors.map((s) => s.amount).reduce((acc, x) => acc + x, 0), shirtAmount: state.sponsors - .filter(s => s.who === 'both') - .map(s => s.amount * 0.2) + .filter((s) => s.who === "both") + .map((s) => s.amount * 0.2) .reduce((acc, x) => Math.ceil(Math.min(acc + x, 120)), 0), count: state.sponsors.length, - days: Math.max(0, Math.ceil(((new Date(2018, 5, 6)).getTime() - Date.now()) / (1000 * 60 * 60 * 24))), -}) + days: Math.max( + 0, + Math.ceil( + (new Date(2018, 5, 6).getTime() - Date.now()) / (1000 * 60 * 60 * 24) + ) + ), +}); const mapDispatchToProps = (dispatch, props) => ({ - onRefLoad: (el) => dispatch(Modals.setOrigin('sponsor', el)), - onButtonClick: () => dispatch(Modals.open('sponsor')) -}) + onRefLoad: (el) => dispatch(Modals.setOrigin("sponsor", el)), + onButtonClick: () => dispatch(Modals.open("sponsor")), +}); -export default translate('form')( - connect( - mapStateToProps, - mapDispatchToProps, - )(SponsorForm) -) +export default withTranslation("form")( + connect(mapStateToProps, mapDispatchToProps)(SponsorForm) +); diff --git a/src/components/SponsorModal.js b/src/components/SponsorModal.js index 5f94c90..034f83f 100644 --- a/src/components/SponsorModal.js +++ b/src/components/SponsorModal.js @@ -1,85 +1,138 @@ -import React from 'react' -import { translate, Trans } from 'react-i18next' -import { connect } from 'react-redux' -import styled from 'styled-components' +import React from "react"; +import { withTranslation, Trans } from "react-i18next"; +import { connect } from "react-redux"; +import styled from "styled-components"; -import * as Pledge from 'ducks/pledge' +import * as Pledge from "ducks/pledge"; -import { Title, Text, Form, InputGroup, Input, Button, Modal } from 'components/lib' -import PaymentMethod from 'components/PaymentMethod' +import { + Title, + Text, + Form, + InputGroup, + Input, + Button, + Modal, +} from "components/lib"; +import PaymentMethod from "components/PaymentMethod"; -const H1 = Title(1).extend` +const H1 = styled(Title(1))` strong { - color: ${props => props.theme.colors.primary}; + color: ${(props) => props.theme.colors.primary}; } -` +`; const Kbd = styled.kbd` - padding: .125em .25em; - border-radius: ${props => props.theme.border.radius}; + padding: 0.125em 0.25em; + border-radius: ${(props) => props.theme.border.radius}; - background-color: rgba(0, 0, 0, .05); -` + background-color: rgba(0, 0, 0, 0.05); +`; -const PaymentMethods = () => (
- - -
) +const PaymentMethods = () => ( +
+ + +
+); const SponsorModal = ({ t, values, update, updateModified, submit }) => (

- Thanks + + Thanks +

- {values.success - ? (values.payment_method === 'Bankoverschrijving' - ? - {t('transfer', { amount: values.amount })} NL48 RABO 0118 539 108 {t`to`} Wouter Raateland {t`stating`} Sponsoring {values.name} {t`confirm`}. - - : {t`success`} 🎉) - :
- - - - - - 0 ? values.amount : ''}`} onChange={updateModified('amount')} /> - - - - - - -
- } + {values.success ? ( + values.payment_method === "Bankoverschrijving" ? ( + + {t("transfer", { amount: values.amount })}{" "} + NL48 RABO 0118 539 108 {t`to`} Wouter Raateland{" "} + {t`stating`} Sponsoring {values.name} {t`confirm`}. + + ) : ( + + {t`success`}{" "} + + 🎉 + + + ) + ) : ( +
+ + + + + + 0 ? values.amount : ""}`} + onChange={updateModified("amount")} + /> + + + + + + +
+ )}
-) +); const mapStateToProps = (state) => ({ values: state.pledge, -}) +}); const mapDispatchToProps = (dispatch) => ({ - update: field => value => dispatch(Pledge.update(field, value)), - updateModified: field => value => dispatch(Pledge.update(field, parseInt(value.substring(1) || 0, 10))), - submit: () => dispatch(Pledge.submit()) -}) + update: (field) => (value) => dispatch(Pledge.update(field, value)), + updateModified: (field) => (value) => + dispatch(Pledge.update(field, parseInt(value.substring(1) || 0, 10))), + submit: () => dispatch(Pledge.submit()), +}); -export default translate('modal')( - connect( - mapStateToProps, - mapDispatchToProps - )(SponsorModal) -) +export default withTranslation("modal")( + connect(mapStateToProps, mapDispatchToProps)(SponsorModal) +); diff --git a/src/components/Sponsors.js b/src/components/Sponsors.js index 59ab94b..5432df5 100644 --- a/src/components/Sponsors.js +++ b/src/components/Sponsors.js @@ -1,13 +1,13 @@ -import React from 'react' -import styled from 'styled-components' +import React from "react"; +import styled from "styled-components"; -import { Text } from 'components/lib' +import { Text } from "components/lib"; -import sponsors from 'assets/sponsors.json' +import sponsors from "assets/sponsors.json"; -const Sponsors = Text.extend` +const Sponsors = styled(Text)` margin: 2em 0; -` +`; // const Sponsor = styled.div` // display: inline-block; @@ -24,16 +24,18 @@ const Sponsors = Text.extend` const Sponsor = styled.strong` display: inline-block; margin-right: 1.5em; - margin-bottom: .5em; -` + margin-bottom: 0.5em; +`; export default () => ( - {sponsors.map(({ name }, i) => - {name} + {sponsors.map( + ({ name }, i) => ( + {name} + ) // // // )} -) +); diff --git a/src/components/SubTitle.js b/src/components/SubTitle.js index 66c7dff..5cae675 100644 --- a/src/components/SubTitle.js +++ b/src/components/SubTitle.js @@ -1,9 +1,10 @@ -import { media } from 'style-utils' -import { Title } from 'components/lib' +import styled from "styled-components"; +import { media } from "style-utils"; +import { Title } from "components/lib"; -export default Title(2).extend` - margin: 1em 0 .5em; +export default styled(Title(2))` + margin: 1em 0 0.5em; font-size: 2.5em; ${media.small`font-size: 1.75em;`} -` +`; diff --git a/src/components/Theme.js b/src/components/Theme.js index 41388d9..e6474e7 100644 --- a/src/components/Theme.js +++ b/src/components/Theme.js @@ -1,38 +1,37 @@ -import React from 'react' -import { ThemeProvider, injectGlobal } from 'styled-components' +import "typeface-passion-one"; +import React from "react"; +import { ThemeProvider, createGlobalStyle } from "styled-components"; const theme = { fonts: { - main: 'roboto, sans-serif', + main: "roboto, sans-serif", titles: `'Passion One', cursive`, }, colors: { - text: '#000', - background: '#fff', - primary: '#52006b', - accent: '#e87511', - success: '#4caf50', - warning: '#ffc107', - error: '#f44336', + text: "#000", + background: "#fff", + primary: "#52006b", + accent: "#e87511", + success: "#4caf50", + warning: "#ffc107", + error: "#f44336", }, opacity: { titles: 0.2, text: 0.55, }, border: { - width: '.125em', - radius: '.25em', + width: ".125em", + radius: ".25em", }, columns: { count: 12, - gap: '.5em', + gap: ".5em", }, lineHeight: 1.5, -} - -injectGlobal` - @import url('https://fonts.googleapis.com/css?family=Passion+One:400,700'); +}; +const GlobalStyle = createGlobalStyle` *, *::before, *::after { box-sizing: border-box; } @@ -46,7 +45,7 @@ injectGlobal` padding: 0; margin: 0; - font-family: ${theme.fonts.main}; + font-family: ${(p) => p.theme.fonts.main}; } input, textarea, select, button { @@ -54,12 +53,15 @@ injectGlobal` } h1, h2, h3, h4, h5, h6 { - font-family: ${theme.fonts.titles} + font-family: ${(p) => p.theme.fonts.titles} } -` +`; -const Theme = (props) => ( - -) +const Theme = ({ children, ...props }) => ( + + + {children} + +); -export default Theme +export default Theme; diff --git a/src/components/Title.js b/src/components/Title.js index 8981c8a..41cbed5 100644 --- a/src/components/Title.js +++ b/src/components/Title.js @@ -1,7 +1,8 @@ -import { media } from 'style-utils' -import { Title } from 'components/lib' +import styled from "styled-components"; +import { media } from "style-utils"; +import { Title } from "components/lib"; -export default Title(1).extend` +export default styled(Title(1))` margin-bottom: 0; font-size: 4em; @@ -9,6 +10,6 @@ export default Title(1).extend` font-weight: 900; strong { - color: ${props => props.theme.colors.primary}; + color: ${(props) => props.theme.colors.primary}; } -` +`; diff --git a/src/components/Translations.js b/src/components/Translations.js index 1940a3f..8816f80 100644 --- a/src/components/Translations.js +++ b/src/components/Translations.js @@ -1,29 +1,25 @@ -import React from 'react' -import i18n from 'i18next' -import { I18nextProvider } from 'react-i18next' -import LanguageDetector from 'i18next-browser-languagedetector' +import React from "react"; +import i18n from "i18next"; +import { I18nextProvider } from "react-i18next"; +import LanguageDetector from "i18next-browser-languagedetector"; -import en from 'lang/en.json' -import nl from 'lang/nl.json' +import en from "lang/en.json"; +import nl from "lang/nl.json"; -i18n - .use(LanguageDetector) - .init({ - fallbackLng: 'nl', - debug: false, +i18n.use(LanguageDetector).init({ + fallbackLng: "nl", + debug: false, - react: { - wait: false, - bindI18n: 'languageChanged loaded', - bindStore: 'added removed', - nsMode: 'default' - }, + react: { + wait: false, + bindI18n: "languageChanged loaded", + bindStore: "added removed", + nsMode: "default", + }, - resources: { en, nl } - }) + resources: { en, nl }, +}); -const Translations = (props) => ( - -) +const Translations = (props) => ; -export default Translations +export default Translations; diff --git a/src/components/Waves.js b/src/components/Waves.js index 0d7a512..d4a59e9 100644 --- a/src/components/Waves.js +++ b/src/components/Waves.js @@ -1,13 +1,13 @@ -import React from 'react' +import React from "react"; -const Waves = ({ part=1, ...props }) => ( - +const Waves = ({ part = 1, ...props }) => ( + -) +); -export default Waves +export default Waves; diff --git a/src/components/lib/Button.js b/src/components/lib/Button.js index 93e2ccd..f5bae01 100644 --- a/src/components/lib/Button.js +++ b/src/components/lib/Button.js @@ -1,41 +1,61 @@ -import styled, { css } from 'styled-components' -import { darken, opacity } from 'style-utils' +import styled, { css } from "styled-components"; +import { darken, opacity } from "style-utils"; const Button = styled.button` - ${props => props.block && css` - display: block; - width: 100%; - `} + ${(props) => + props.block && + css` + display: block; + width: 100%; + `} - border-color: ${props => opacity(props.theme.colors.text, props.theme.opacity.text)}; - border-width: ${props => props.theme.border.width}; - border-radius: ${props => props.theme.border.radius}; + border-color: ${(props) => + opacity(props.theme.colors.text, props.theme.opacity.text)}; + border-width: ${(props) => props.theme.border.width}; + border-radius: ${(props) => props.theme.border.radius}; background: transparent; - ${props => props.primary && css` - border-color: ${props.theme.colors.primary}; - background-color: ${props.theme.colors.primary}; - color: ${props.theme.colors.background}; - `} + ${(props) => + props.primary && + css` + border-color: ${props.theme.colors.primary}; + background-color: ${props.theme.colors.primary}; + color: ${props.theme.colors.background}; + `} - ${props => props.small && css`padding: .25em .125em;`} - ${props => props.medium && css`padding: .5em .25em;`} - ${props => props.large && css`padding: .7em .5em;`} + ${(props) => + props.small && + css` + padding: 0.25em 0.125em; + `} + ${(props) => + props.medium && + css` + padding: 0.5em 0.25em; + `} + ${(props) => + props.large && + css` + padding: 0.7em 0.5em; + `} - ${props => props.disabled - ? css` - opacity: .5; - ` - : css` - &:hover { - cursor: pointer; - ${props => props.primary && css` - border-color: ${darken(props.theme.colors.primary, 10)}; - background-color: ${darken(props.theme.colors.primary, 10)}; + ${(props) => + props.disabled + ? css` + opacity: 0.5; + ` + : css` + &:hover { + cursor: pointer; + ${(props) => + props.primary && + css` + border-color: ${darken(props.theme.colors.primary, 10)}; + background-color: ${darken(props.theme.colors.primary, 10)}; + `} + } `} - } - `} -` +`; -export default Button +export default Button; diff --git a/src/components/lib/Column.js b/src/components/lib/Column.js index 28c6592..316cf29 100644 --- a/src/components/lib/Column.js +++ b/src/components/lib/Column.js @@ -1,17 +1,20 @@ -import styled from 'styled-components' -import { media } from 'style-utils' +import styled from "styled-components"; +import { media } from "style-utils"; const Column = styled.div` display: block; float: left; - padding-left: ${props => props.theme.columns.gap}; - padding-right: ${props => props.theme.columns.gap}; + padding-left: ${(props) => props.theme.columns.gap}; + padding-right: ${(props) => props.theme.columns.gap}; - width: ${props => 100 * props.size / props.theme.columns.count}%; + width: ${(props) => (100 * props.size) / props.theme.columns.count}%; - ${media.small`width: ${props => 100 * props.sSize / props.theme.columns.count}%;`} - ${media.medium`width: ${props => 100 * props.mSize / props.theme.columns.count}%;`} - ${media.large`width: ${props => 100 * props.lSize / props.theme.columns.count}%;`} -` + ${media.small`width: ${(props) => + (100 * props.sSize) / props.theme.columns.count}%;`} + ${media.medium`width: ${(props) => + (100 * props.mSize) / props.theme.columns.count}%;`} + ${media.large`width: ${(props) => + (100 * props.lSize) / props.theme.columns.count}%;`} +`; -export default Column +export default Column; diff --git a/src/components/lib/Container.js b/src/components/lib/Container.js index 6f6a549..fb54445 100644 --- a/src/components/lib/Container.js +++ b/src/components/lib/Container.js @@ -1,32 +1,43 @@ -import React from 'react' -import { connect } from 'react-redux' -import styled, { css } from 'styled-components' -import * as Modals from 'ducks/modals' +import React from "react"; +import { connect } from "react-redux"; +import styled, { css } from "styled-components"; +import * as Modals from "ducks/modals"; const Container = styled.div` transform: translateZ(0); - transition: filter .4s ease-out; + transition: filter 0.4s ease-out; will-change: filter; - ${props => props.overlaid && css` - filter: blur(1em) brightness(90%); - & > * { pointer-events: none; } - `} -` + ${(props) => + props.overlaid && + css` + filter: blur(1em) brightness(90%); + & > * { + pointer-events: none; + } + `} +`; const mapStateToProps = (state) => ({ - overlaid: state.modals.current !== null -}) + overlaid: state.modals.current !== null, +}); const mapDispatchToProps = (dispatch) => ({ - onClick: () => dispatch(Modals.close()) -}) + onClick: () => dispatch(Modals.close()), +}); export default connect( mapStateToProps, mapDispatchToProps -)(({ onClick, children, overlaid, ...props }) => overlaid - ? {children} - : {children} -) +)(({ onClick, children, overlaid, ...props }) => + overlaid ? ( + + {children} + + ) : ( + + {children} + + ) +); diff --git a/src/components/lib/Form.js b/src/components/lib/Form.js index a521c45..70b7f95 100644 --- a/src/components/lib/Form.js +++ b/src/components/lib/Form.js @@ -1,5 +1,5 @@ -import styled from 'styled-components' +import styled from "styled-components"; -const Form = styled.form`` +const Form = styled.form``; -export default Form +export default Form; diff --git a/src/components/lib/Image.js b/src/components/lib/Image.js index 464c8a3..3aea531 100644 --- a/src/components/lib/Image.js +++ b/src/components/lib/Image.js @@ -1,8 +1,8 @@ -import styled from 'styled-components' +import styled from "styled-components"; const Image = styled.img` max-width: 100%; max-height: 100%; -` +`; -export default Image +export default Image; diff --git a/src/components/lib/Input.js b/src/components/lib/Input.js index d41b663..d22fef7 100644 --- a/src/components/lib/Input.js +++ b/src/components/lib/Input.js @@ -1,82 +1,107 @@ -import React from 'react' -import styled, { css } from 'styled-components' -import { opacity } from 'style-utils' +import React from "react"; +import styled, { css } from "styled-components"; +import { opacity } from "style-utils"; const Label = styled.label` display: inline-block; margin-bottom: 1em; vertical-align: top; - ${props => props.block && css` - display: block; - width: 100%; - `} + ${(props) => + props.block && + css` + display: block; + width: 100%; + `} - ${props => !props.block && css` - margin-right: 1em; - `} -` + ${(props) => + !props.block && + css` + margin-right: 1em; + `} +`; const LabelText = styled.span` - font-size: .75em; + font-size: 0.75em; - color: ${props => opacity(props.theme.colors.text, props.theme.opacity.text)}; -` + color: ${(props) => + opacity(props.theme.colors.text, props.theme.opacity.text)}; +`; const Input = styled.input` display: block; - padding: .5em 0; + padding: 0.5em 0; - ${props => props.block && css` - width: 100%; - `} + ${(props) => + props.block && + css` + width: 100%; + `} border: none; - border-bottom-width: ${props => props.theme.border.width}; + border-bottom-width: ${(props) => props.theme.border.width}; border-bottom-style: solid; - border-bottom-color: ${props => props.theme.colors.text}; + border-bottom-color: ${(props) => props.theme.colors.text}; - ${props => props.error && css` - border-bottom-color: ${props.theme.colors.error}; - `} + ${(props) => + props.error && + css` + border-bottom-color: ${props.theme.colors.error}; + `} background-color: transparent; &:focus { outline: none; - border-bottom-color: ${props => props.theme.colors.primary}; + border-bottom-color: ${(props) => props.theme.colors.primary}; } -` +`; const ErrorText = styled.span` - color: ${props => props.theme.colors.error}; -` + color: ${(props) => props.theme.colors.error}; +`; -export default ({ type, label, block, error, component: Component, onChange, ...props }) => { - if (type === 'radio') { - const { value, options } = props +export default ({ + type, + label, + block, + error, + component: Component, + onChange, + ...props +}) => { + if (type === "radio") { + const { value, options } = props; return (
- {options.map(option => ( + {options.map((option) => ( ))}
- ) + ); } else { return ( - ) + ); } -} +}; diff --git a/src/components/lib/InputGroup.js b/src/components/lib/InputGroup.js index 408cebe..4e2e275 100644 --- a/src/components/lib/InputGroup.js +++ b/src/components/lib/InputGroup.js @@ -1,5 +1,5 @@ -import styled from 'styled-components' +import styled from "styled-components"; -const InputGroup = styled.div`` +const InputGroup = styled.div``; -export default InputGroup +export default InputGroup; diff --git a/src/components/lib/Link.js b/src/components/lib/Link.js index d9df080..5056715 100644 --- a/src/components/lib/Link.js +++ b/src/components/lib/Link.js @@ -1,7 +1,7 @@ -import styled from 'styled-components' +import styled from "styled-components"; const Link = styled.a` - color: ${props => props.theme.colors.accent}; -` + color: ${(props) => props.theme.colors.accent}; +`; -export default Link +export default Link; diff --git a/src/components/lib/Modal.js b/src/components/lib/Modal.js index aca3a37..1e8ea12 100644 --- a/src/components/lib/Modal.js +++ b/src/components/lib/Modal.js @@ -1,73 +1,79 @@ -import React from 'react' -import { connect } from 'react-redux' -import { css } from 'styled-components' -import { opacity } from 'style-utils' - -import Wrapper from './Wrapper' - -const ModalContent = Wrapper.extend.attrs({ - style: ({ origin, open }) => origin && !open - ? { - left: `${origin.x + (origin.width / 2)}px`, - top: `${origin.y + (origin.height / 2)}px`, - width: `${origin.width}px`, - maxHeight: `${origin.height}px`, - } - : {} -})` +import React from "react"; +import { connect } from "react-redux"; +import styled, { css } from "styled-components"; +import { opacity } from "style-utils"; + +import Wrapper from "./Wrapper"; + +const ModalContent = styled(Wrapper).attrs(({ origin, open }) => ({ + style: + origin && !open + ? { + left: `${origin.x + origin.width / 2}px`, + top: `${origin.y + origin.height / 2}px`, + width: `${origin.width}px`, + maxHeight: `${origin.height}px`, + } + : {}, +}))` position: fixed; overflow: auto; - overflow-scrolling: touch; + -webkit-overflow-scrolling: touch; padding: 2em; margin: auto; - border-radius: ${props => props.theme.border.radius}; + border-radius: ${(props) => props.theme.border.radius}; - background-color: ${props => props.transparent - ? 'transparent' - : opacity(props.theme.colors.background, .9) - }; + background-color: ${(props) => + props.transparent + ? "transparent" + : opacity(props.theme.colors.background, 0.9)}; transform: translate(-50%, -50%); will-change: left, top, width, maxHeight, opacity; - ${props => props.origin && css` - transition-property: left, top, width, max-height, opacity; - transition-duration: .4s; - transition-timing-function: ease-out; - `} - - ${props => !props.open && css` - pointer-events: none; - - opacity: 0; - `} - - ${props => props.open && css` - left: 50%; top: 50%; - width: calc(100vw - 4em); max-height: calc(100vh - 4em); - - opacity: 1; - `} -` + ${(props) => + props.origin && + css` + transition-property: left, top, width, max-height, opacity; + transition-duration: 0.4s; + transition-timing-function: ease-out; + `} + + ${(props) => + !props.open && + css` + pointer-events: none; + + opacity: 0; + `} + + ${(props) => + props.open && + css` + left: 50%; + top: 50%; + width: calc(100vw - 4em); + max-height: calc(100vh - 4em); + + opacity: 1; + `} +`; const Modal = ({ origin, open, children, ...props }) => ( {children} -) +); -const getOriginRect = el => el && el.getBoundingClientRect - ? el.getBoundingClientRect() - : null +const getOriginRect = (el) => + el && el.getBoundingClientRect ? el.getBoundingClientRect() : null; const mapStateToProps = (state, props) => ({ origin: getOriginRect(state.modals.origin[props.name]), open: state.modals.current === props.name, -}) +}); -export default connect( - mapStateToProps -)(Modal) +export default connect(mapStateToProps)(Modal); diff --git a/src/components/lib/Row.js b/src/components/lib/Row.js index 3c5c69f..a5f33a9 100644 --- a/src/components/lib/Row.js +++ b/src/components/lib/Row.js @@ -1,14 +1,14 @@ -import styled from 'styled-components' +import styled from "styled-components"; const Row = styled.div` - margin-left: -${props => props.theme.columns.gap}; - margin-right: -${props => props.theme.columns.gap}; + margin-left: -${(props) => props.theme.columns.gap}; + margin-right: -${(props) => props.theme.columns.gap}; &:after { - content: ''; + content: ""; display: block; clear: both; } -` +`; -export default Row +export default Row; diff --git a/src/components/lib/Text.js b/src/components/lib/Text.js index c65ecda..84b912e 100644 --- a/src/components/lib/Text.js +++ b/src/components/lib/Text.js @@ -1,15 +1,28 @@ -import styled, { css } from 'styled-components' -import { opacity } from 'style-utils' +import styled, { css } from "styled-components"; +import { opacity } from "style-utils"; const Text = styled.p` - line-height: ${props => props.theme.lineHeight}; - color: ${props => opacity(props.theme.colors.text, props.theme.opacity.text)}; + line-height: ${(props) => props.theme.lineHeight}; + color: ${(props) => + opacity(props.theme.colors.text, props.theme.opacity.text)}; - ${props => props.size && css`font-size: ${props.size}em;`} + ${(props) => + props.size && + css` + font-size: ${props.size}em; + `} - ${props => props.accent && css`color: ${props.theme.colors.accent};`} + ${(props) => + props.accent && + css` + color: ${props.theme.colors.accent}; + `} - ${props => props.center && css`text-align: center;`} -` + ${(props) => + props.center && + css` + text-align: center; + `} +`; -export default Text +export default Text; diff --git a/src/components/lib/Title.js b/src/components/lib/Title.js index d72250b..bd42bb6 100644 --- a/src/components/lib/Title.js +++ b/src/components/lib/Title.js @@ -1,8 +1,9 @@ -import styled from 'styled-components' -import { opacity } from 'style-utils' +import styled from "styled-components"; +import { opacity } from "style-utils"; -const Title = level => styled[`h${level}`]` - color: ${props => opacity(props.theme.colors.text, props.theme.opacity.titles)}; -` +const Title = (level) => styled[`h${level}`]` + color: ${(props) => + opacity(props.theme.colors.text, props.theme.opacity.titles)}; +`; -export default Title +export default Title; diff --git a/src/components/lib/Wrapper.js b/src/components/lib/Wrapper.js index 05f61a0..746e84d 100644 --- a/src/components/lib/Wrapper.js +++ b/src/components/lib/Wrapper.js @@ -1,18 +1,32 @@ -import styled, { css } from 'styled-components' +import styled, { css } from "styled-components"; const Wrapper = styled.div` max-width: 60em; margin-left: auto; margin-right: auto; - ${props => !props.nopadding && css` - padding-left: 2em; - padding-right: 2em; - `} + ${(props) => + !props.nopadding && + css` + padding-left: 2em; + padding-right: 2em; + `} - ${props => props.small && css`max-width: 30em;`} - ${props => props.medium && css`max-width: 45em;`} - ${props => props.xlarge && css`max-width: 75em;`} -` + ${(props) => + props.small && + css` + max-width: 30em; + `} + ${(props) => + props.medium && + css` + max-width: 45em; + `} + ${(props) => + props.xlarge && + css` + max-width: 75em; + `} +`; -export default Wrapper +export default Wrapper; diff --git a/src/components/lib/index.js b/src/components/lib/index.js index 0077a02..1ad6f1d 100644 --- a/src/components/lib/index.js +++ b/src/components/lib/index.js @@ -1,30 +1,48 @@ -import Title from './Title' -import Text from './Text' -import Link from './Link' -import Image from './Image' +import Title from "./Title"; +import Text from "./Text"; +import Link from "./Link"; +import Image from "./Image"; -import Form from './Form' -import InputGroup from './InputGroup' -import Input from './Input' -import Button from './Button' +import Form from "./Form"; +import InputGroup from "./InputGroup"; +import Input from "./Input"; +import Button from "./Button"; -import Wrapper from './Wrapper' -import Row from './Row' -import Column from './Column' +import Wrapper from "./Wrapper"; +import Row from "./Row"; +import Column from "./Column"; -import Container from './Container' -import Modal from './Modal' +import Container from "./Container"; +import Modal from "./Modal"; export { - Title, Text, Link, Image, - Form, InputGroup, Input, Button, - Wrapper, Row, Column, - Container, Modal, -} + Title, + Text, + Link, + Image, + Form, + InputGroup, + Input, + Button, + Wrapper, + Row, + Column, + Container, + Modal, +}; export default { - Title, Text, Link, Image, - Form, InputGroup, Input, Button, - Wrapper, Row, Column, - Container, Modal, -} + Title, + Text, + Link, + Image, + Form, + InputGroup, + Input, + Button, + Wrapper, + Row, + Column, + Container, + Modal, +}; diff --git a/src/ducks/modals.js b/src/ducks/modals.js index 4b22f00..3a4beb7 100644 --- a/src/ducks/modals.js +++ b/src/ducks/modals.js @@ -1,40 +1,44 @@ -import { combineReducers } from 'redux' -import { createReducer } from './util' +import { combineReducers } from "redux"; +import { createReducer } from "./util"; // Action types -export const OPEN = 'modals/OPEN' -export const SET_ORIGIN = 'modals/SET_ORIGIN' +export const OPEN = "modals/OPEN"; +export const SET_ORIGIN = "modals/SET_ORIGIN"; // Action creators export const open = (name) => ({ type: OPEN, - payload: { name } -}) + payload: { name }, +}); export const close = () => ({ type: OPEN, - payload: { name: null } -}) + payload: { name: null }, +}); export const setOrigin = (name, origin) => ({ type: SET_ORIGIN, - payload: { name, origin } -}) + payload: { name, origin }, +}); // Reducers export const current = createReducer(null, { [OPEN]: (state, { name }) => name, -}) - -export const origin = createReducer({}, { - [SET_ORIGIN]: (state, { name, origin }) => ({ - ...state, - [name]: origin - }), -}) +}); + +export const origin = createReducer( + {}, + { + [SET_ORIGIN]: (state, { name, origin }) => ({ + ...state, + [name]: origin, + }), + } +); export const reducer = combineReducers({ - current, origin -}) + current, + origin, +}); -export default reducer +export default reducer; diff --git a/src/ducks/pledge.js b/src/ducks/pledge.js index b1a4d12..f7f9c2a 100644 --- a/src/ducks/pledge.js +++ b/src/ducks/pledge.js @@ -1,36 +1,39 @@ -import { createReducer, createAsyncActionType } from './util' +import { createReducer, createAsyncActionType } from "./util"; // Action types -export const UPDATE = 'pledge/UPDATE' -export const SUBMIT = createAsyncActionType('pledge/SUBMIT') +export const UPDATE = "pledge/UPDATE"; +export const SUBMIT = createAsyncActionType("pledge/SUBMIT"); // Action creators export const update = (field, value) => ({ type: UPDATE, - payload: { [field]: value } -}) + payload: { [field]: value }, +}); export const submit = () => ({ type: SUBMIT.REQUEST, - payload: {} -}) + payload: {}, +}); // Reducers -export const reducer = createReducer({ - name: '', - email: '', - amount: 25, - payment_method: 'PayPal', - who: 'both', -}, { - [UPDATE]: (state, payload) => ({ - ...state, - ...payload - }), - [SUBMIT.SUCCESS]: (state) => ({ - ...state, - success: true - }) -}) +export const reducer = createReducer( + { + name: "", + email: "", + amount: 25, + payment_method: "PayPal", + who: "both", + }, + { + [UPDATE]: (state, payload) => ({ + ...state, + ...payload, + }), + [SUBMIT.SUCCESS]: (state) => ({ + ...state, + success: true, + }), + } +); -export default reducer +export default reducer; diff --git a/src/ducks/root.js b/src/ducks/root.js index c2faad9..cd96c2b 100644 --- a/src/ducks/root.js +++ b/src/ducks/root.js @@ -1,17 +1,15 @@ -import { combineReducers } from 'redux' -import { routerReducer as router } from 'react-router-redux' +import { combineReducers } from "redux"; -import window from './window' -import modals from './modals' -import sponsors from './sponsors' -import pledge from './pledge' +import window from "./window"; +import modals from "./modals"; +import sponsors from "./sponsors"; +import pledge from "./pledge"; export const reducer = combineReducers({ - router, window, modals, sponsors, pledge, -}) +}); -export default reducer +export default reducer; diff --git a/src/ducks/sponsors.js b/src/ducks/sponsors.js index cd161be..fa2d099 100644 --- a/src/ducks/sponsors.js +++ b/src/ducks/sponsors.js @@ -1,12 +1,12 @@ -import { createReducer } from './util' +import { createReducer } from "./util"; -import sponsors from 'assets/sponsors.json' +import sponsors from "assets/sponsors.json"; // Action types // Action creators // Reducers -export const reducer = createReducer(sponsors, {}) +export const reducer = createReducer(sponsors, {}); -export default reducer +export default reducer; diff --git a/src/ducks/util.js b/src/ducks/util.js index fa97988..0bbd457 100644 --- a/src/ducks/util.js +++ b/src/ducks/util.js @@ -1,10 +1,13 @@ -export const createReducer = (initialState, handlers) => - (state = initialState, { type, payload }) => - handlers.hasOwnProperty(type) - ? handlers[type](state, payload) - : state +export const createReducer = (initialState, handlers) => ( + state = initialState, + { type, payload } +) => (handlers.hasOwnProperty(type) ? handlers[type](state, payload) : state); -export const createAsyncActionType = (prefix, steps=['REQUEST', 'SUCCESS', 'FAILURE']) => +export const createAsyncActionType = ( + prefix, + steps = ["REQUEST", "SUCCESS", "FAILURE"] +) => steps.reduce( (acc, suffix) => ({ ...acc, [suffix]: `${prefix}_${suffix}` }), - {}) + {} + ); diff --git a/src/ducks/window.js b/src/ducks/window.js index 8582276..783141c 100644 --- a/src/ducks/window.js +++ b/src/ducks/window.js @@ -1,39 +1,42 @@ -import { createReducer } from './util' +import { createReducer } from "./util"; // Action types -export const RESIZE = 'window/RESIZE' -export const SCROLL = 'window/SCROLL' +export const RESIZE = "window/RESIZE"; +export const SCROLL = "window/SCROLL"; // Action creators export const resize = (width, height) => ({ type: RESIZE, - payload: { width, height } -}) + payload: { width, height }, +}); export const scroll = (scrollLeft, scrollTop) => ({ type: SCROLL, - payload: { scrollLeft, scrollTop } -}) + payload: { scrollLeft, scrollTop }, +}); // Reducers -export const reducer = createReducer({ - width: window.innerWidth, - height: window.innerHeight, - scrollTop: window.scrollX, - scrollLeft: window.scrollY, - prevScrollTop: window.scrollY, -}, { - [RESIZE]: (state, { width, height }) => ({ +export const reducer = createReducer( + { + width: window.innerWidth, + height: window.innerHeight, + scrollTop: window.scrollX, + scrollLeft: window.scrollY, + prevScrollTop: window.scrollY, + }, + { + [RESIZE]: (state, { width, height }) => ({ ...state, - width, height + width, + height, }), - [SCROLL]: (state, { scrollLeft, scrollTop }) => ({ + [SCROLL]: (state, { scrollLeft, scrollTop }) => ({ ...state, - scrollLeft, scrollTop, - prevScrollTop: state.scrollTop === 0 - ? scrollTop - : state.scrollTop, + scrollLeft, + scrollTop, + prevScrollTop: state.scrollTop === 0 ? scrollTop : state.scrollTop, }), -}) + } +); -export default reducer +export default reducer; diff --git a/src/index.js b/src/index.js index 0528b70..117477d 100644 --- a/src/index.js +++ b/src/index.js @@ -1,33 +1,23 @@ -import React from 'react' -import { hydrate, render } from 'react-dom' -import { Provider } from 'react-redux' +import React from "react"; +import { hydrate, render } from "react-dom"; +import { Provider } from "react-redux"; -import createHistory from 'history/createBrowserHistory' -import { ConnectedRouter } from 'react-router-redux' -// import registerServiceWorker from './registerServiceWorker' -import configureStore from './store' +import configureStore from "./store"; -import App from 'components/App' +import App from "components/App"; -const history = createHistory() -const initialState = { - router: { location: history.location } -} -const store = configureStore(initialState, history) +const initialState = {}; +const store = configureStore(initialState); const Root = ( - - - - - -) -const root = document.getElementById('root') + + + +); +const root = document.getElementById("root"); if (root.hasChildNodes()) { - hydrate(Root, root) + hydrate(Root, root); } else { - render(Root, root) + render(Root, root); } - -// registerServiceWorker() diff --git a/src/lang/en.json b/src/lang/en.json index 90f5429..7a3575b 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -12,7 +12,7 @@ "answer3": "Yes! During the approximately 8 to 13 hours we’ll be in the boat, we’d love any and all support. If you’re free on June 6th, you can come bike along with us! Check the biking route on <1><0>parthenon-ey-ringvaartregatta.nl/fietsroute.", "thanks": "<0>Thanks to all our supporters for their contribution", - "further questions": "For questions, email <1><0>wouterraateland@gmail.com" + "further_questions": "For questions, email <1><0>wouterraateland@gmail.com" }, "form": { "donated": "donated", diff --git a/src/lang/nl.json b/src/lang/nl.json index e6bac79..d3ca166 100644 --- a/src/lang/nl.json +++ b/src/lang/nl.json @@ -12,7 +12,7 @@ "answer3": "Zeker! Tijdens de ongeveer 8 tot 13 uur dat we in de boot zitten kunnen we best wat aanmoediging gebruiken! Kan je er bij zijn op 6 juni, dan zouden wij het heel erg waarderen als je een stuk met ons mee fietst. Check de fietsroute op: <1><0>parthenon-ey-ringvaartregatta.nl/fietsroute.", "thanks": "Alle sponsoren <0>bedankt voor jullie bijdrage", - "further questions": "Voor vragen, stuur een email naar <1><0>wouterraateland@gmail.com" + "further_questions": "Voor vragen, stuur een email naar <1><0>wouterraateland@gmail.com" }, "form": { "donated": "gedoneerd", diff --git a/src/pages/home.js b/src/pages/home.js index 1f0b1f4..152deaa 100644 --- a/src/pages/home.js +++ b/src/pages/home.js @@ -1,31 +1,34 @@ -import React from 'react' -import styled from 'styled-components' -import { translate, Trans } from 'react-i18next' +import React from "react"; +import styled from "styled-components"; +import { withTranslation, Trans } from "react-i18next"; -import { Text, Link, Wrapper, Row, Column } from 'components/lib' +import { Text, Link, Wrapper, Row, Column } from "components/lib"; -import Header from 'components/Header' -import Title from 'components/Title' -import SubTitle from 'components/SubTitle' -import SponsorForm from 'components/SponsorForm' -import ShareForm from 'components/ShareForm' -import Photos from 'components/Photos' -import Footer from 'components/Footer' +import Header from "components/Header"; +import Title from "components/Title"; +import SubTitle from "components/SubTitle"; +import SponsorForm from "components/SponsorForm"; +import ShareForm from "components/ShareForm"; +import Photos from "components/Photos"; +import Footer from "components/Footer"; const Page = styled.div` - background-color: ${props => props.theme.colors.background}; -` + background-color: ${(props) => props.theme.colors.background}; +`; -const HomePage = ({t}) => ( +const HomePage = ({ t }) => (
- <Trans i18nKey="title"><strong>hard</strong><strong>KiKa</strong></Trans> + <Trans i18nKey="page:title"> + <strong>hard</strong> + <strong>KiKa</strong> + </Trans> - {t("intro")} + {t("page:intro")} @@ -35,24 +38,57 @@ const HomePage = ({t}) => ( - {t("question1")} + {t("page:question1")} - That’s your choice. If you choose to support both us and KiKa, part* of your donation goes to getting our shirts printed, and the rest goes straight to KiKa. If you choose to support only KiKa, your entire sponsorship goes there. Either way, your name and (company) logo will also be on our shirts. That’s 100 kilometers of exposure! + + That’s your choice. If you choose to support both us and KiKa, + part* of your donation goes to getting our shirts + printed, and the rest goes straight to KiKa. If you choose to + support only KiKa, your entire sponsorship goes there. Either way, + your name and (company) logo will also be on our shirts. That’s + 100 kilometers of exposure! + - *{t("remark")} - {t("question2")} + + * + {t("page:remark")} + + {t("page:question2")} - At 100 kilometers, the Ringvaart is the longest rowing marathon of Europe. The race is open to all kinds of rowers: from competitive rowers with years of experience to “Ringvaartleden” who started rowing this winter (us). For more information, see parthenon-ey-ringvaartregatta.nl. + + At 100 kilometers, the Ringvaart is the longest rowing marathon of + Europe. The race is open to all kinds of rowers: from competitive + rowers with years of experience to “Ringvaartleden” who started + rowing this winter (us). For more information, see{" "} + + parthenon-ey-ringvaartregatta.nl + + . + - {t("question2")} + {t("page:question2")} - Yes! During the approximately 8 to 13 hours we’ll be in the boat, we’d love any and all support. If you’re free on June 6th, you can come bike along with us! Check the biking route on parthenon-ey-ringvaartregatta.nl/fietsroute. + + Yes! During the approximately 8 to 13 hours we’ll be in the boat, + we’d love any and all support. If you’re free on June 6th, you can + come bike along with us! Check the biking route on{" "} + + parthenon-ey-ringvaartregatta.nl/fietsroute + + . +