From 62d98d0c19585c4e2805e9cad42f2deaefb05dae Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Tue, 14 Aug 2018 21:12:30 +0200 Subject: [PATCH] add thank you modal --- package.json | 17 ++-- src/components/Layout.module.scss | 2 +- src/components/atoms/Modal.jsx | 42 ++++++++ src/components/atoms/Modal.module.scss | 98 +++++++++++++++++++ src/components/molecules/ModalThanks.jsx | 60 ++++++++++++ .../molecules/ModalThanks.module.scss | 69 +++++++++++++ src/components/organisms/Footer.jsx | 23 ++++- src/styles/_code.scss | 2 + src/templates/Post.module.scss | 8 ++ 9 files changed, 310 insertions(+), 11 deletions(-) create mode 100644 src/components/atoms/Modal.jsx create mode 100644 src/components/atoms/Modal.module.scss create mode 100644 src/components/molecules/ModalThanks.jsx create mode 100644 src/components/molecules/ModalThanks.module.scss diff --git a/package.json b/package.json index fea44801..54e64bff 100644 --- a/package.json +++ b/package.json @@ -24,14 +24,14 @@ "dependencies": { "clipboard": "^2.0.1", "exif-js": "^2.3.0", - "gatsby": "^2.0.0-beta.98", + "gatsby": "^2.0.0-beta.100", "gatsby-image": "^2.0.0-beta.7", - "gatsby-plugin-catch-links": "^2.0.2-beta.7", + "gatsby-plugin-catch-links": "^2.0.2-beta.8", "gatsby-plugin-matomo": "^0.4.1", "gatsby-plugin-react-helmet": "^3.0.0-beta.4", "gatsby-plugin-sass": "^2.0.0-beta.10", "gatsby-plugin-sharp": "^2.0.0-beta.7", - "gatsby-plugin-sitemap": "^2.0.0-beta.3", + "gatsby-plugin-sitemap": "^2.0.0-beta.4", "gatsby-remark-autolink-headers": "^2.0.0-beta.5", "gatsby-remark-copy-linked-files": "^2.0.0-beta.3", "gatsby-remark-images": "^2.0.1-beta.10", @@ -39,7 +39,7 @@ "gatsby-remark-smartypants": "^2.0.0-beta.3", "gatsby-source-filesystem": "^2.0.1-beta.10", "gatsby-transformer-remark": "^2.1.1-beta.6", - "gatsby-transformer-sharp": "^2.1.1-beta.6", + "gatsby-transformer-sharp": "^2.1.1-beta.7", "gatsby-transformer-yaml": "^2.1.1-beta.3", "graphql": "^0.13.2", "intersection-observer": "^0.5.0", @@ -48,21 +48,24 @@ "prismjs": "^1.15.0", "qrious": "^4.0.2", "react": "^16.4.2", + "react-clipboard.js": "^2.0.0", "react-dom": "^16.4.2", "react-helmet": "^5.2.0", + "react-modal": "^3.5.1", + "react-qr-svg": "^2.1.0", "react-time": "^4.3.0", "slugify": "^1.3.1", "vex-js": "^4.1.0" }, "devDependencies": { - "@svgr/cli": "^2.1.1", + "@svgr/cli": "^2.2.0", "babel-eslint": "^8.2.6", "eslint": "^5.3.0", - "eslint-config-prettier": "^2.9.0", + "eslint-config-prettier": "^2.10.0", "eslint-loader": "^2.1.0", "eslint-plugin-graphql": "^2.1.1", "eslint-plugin-prettier": "^2.6.2", - "eslint-plugin-react": "^7.10.0", + "eslint-plugin-react": "^7.11.0", "prettier": "^1.14.1", "prettier-stylelint": "^0.4.2", "stylelint": "^9.4.0", diff --git a/src/components/Layout.module.scss b/src/components/Layout.module.scss index 2af6f6dd..e691a053 100644 --- a/src/components/Layout.module.scss +++ b/src/components/Layout.module.scss @@ -39,7 +39,7 @@ @include transition; margin-top: $spacer * 2.65; - margin-bottom: $spacer * 20; + margin-bottom: $spacer * 20; // height of footer position: relative; z-index: 2; diff --git a/src/components/atoms/Modal.jsx b/src/components/atoms/Modal.jsx new file mode 100644 index 00000000..69d6ec16 --- /dev/null +++ b/src/components/atoms/Modal.jsx @@ -0,0 +1,42 @@ +import React, { PureComponent } from 'react' +import PropTypes from 'prop-types' +import ReactModal from 'react-modal' + +import styles from './Modal.module.scss' + +ReactModal.setAppElement('#___gatsby') + +class Modal extends PureComponent { + render() { + if (!this.props.isOpen) { + return null + } + + const { children, title, handleCloseModal } = this.props + + return ( + + {title &&

{title}

} + {children} + +
+ ) + } +} + +Modal.propTypes = { + title: PropTypes.string, + isOpen: PropTypes.bool, + handleCloseModal: PropTypes.func.isRequired, + children: PropTypes.node.isRequired +} + +export default Modal diff --git a/src/components/atoms/Modal.module.scss b/src/components/atoms/Modal.module.scss new file mode 100644 index 00000000..d00c65b4 --- /dev/null +++ b/src/components/atoms/Modal.module.scss @@ -0,0 +1,98 @@ +@import 'variables'; + +.modal { + position: fixed; + overflow: auto; + -webkit-overflow-scrolling: touch; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 10; + background: rgba($body-background-color, .9); + backdrop-filter: blur(5px); + animation: fadein .3s; + padding: $spacer / 2; + + @media (min-width: $screen-sm) { + display: flex; + align-items: center; + justify-content: center; + } +} + +.modal__content { + outline: 0; + background: transparent; + position: relative; + border-radius: $border-radius; + border: 1px solid rgba($brand-grey-light, .4); + box-shadow: 0 5px 30px rgba($brand-grey-light, .2); + padding: 0 $spacer / 2 $spacer / 2; + max-width: 100%; + + @media (min-width: $screen-md) { + max-width: $screen-sm; + padding: 0 $spacer $spacer; + } +} + +.modal__close { + display: block; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; + line-height: 1; + font-size: $font-size-large; + padding: 3px; + position: absolute; + top: 0; + right: ($spacer/4); + color: $brand-grey; + font-weight: 500; +} + +// Prevent background scrolling when modal is open +.isModalOpen { + overflow: hidden; +} + +.modal__title { + font-size: $font-size-h4; + margin-top: $spacer / 2; + margin-bottom: $spacer / 2; + margin-left: -($spacer / 2); + margin-right: -($spacer / 2); + border-bottom: 1px solid rgba($brand-grey-light, .4); + padding: 0 $spacer; + padding-bottom: ($spacer/2); + + @media (min-width: $screen-md) { + margin-left: -($spacer); + margin-right: -($spacer); + } +} + +// +// Overlay/content animations +// +@keyframes fadein { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@keyframes fadeout { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} diff --git a/src/components/molecules/ModalThanks.jsx b/src/components/molecules/ModalThanks.jsx new file mode 100644 index 00000000..1a65a027 --- /dev/null +++ b/src/components/molecules/ModalThanks.jsx @@ -0,0 +1,60 @@ +import React from 'react' +import { StaticQuery, graphql } from 'gatsby' +import { QRCode } from 'react-qr-svg' +import Clipboard from 'react-clipboard.js' + +import Modal from '../atoms/Modal' +import IconClipboard from '../svg/Clipboard' +import styles from './ModalThanks.module.scss' + +const ModalThanks = ({ ...props }) => ( + { + const { author } = data.contentYaml + + return ( + +
+ {Object.keys(author).map((address, i) => ( +
+

{address}

+ +
+                  {author[address]}
+                  
+                    
+                  
+                
+
+ ))} +
+
+ ) + }} + /> +) + +export default ModalThanks diff --git a/src/components/molecules/ModalThanks.module.scss b/src/components/molecules/ModalThanks.module.scss new file mode 100644 index 00000000..02155fd3 --- /dev/null +++ b/src/components/molecules/ModalThanks.module.scss @@ -0,0 +1,69 @@ +@import 'variables'; + +.modalThanks { + @media (min-width: $screen-sm) { + display: flex; + justify-content: space-between; + } +} + +.coin { + margin-top: $spacer; + + @media (min-width: $screen-sm) { + width: 48%; + margin-top: 0; + } + + h4 { + font-size: $font-size-large; + margin-top: 0; + margin-bottom: $spacer / 2; + color: $brand-grey; + text-align: center; + } + + > svg { + margin-bottom: $spacer / 2; + } + + pre { + margin: 0; + position: relative; + padding: 0; + padding-right: 2rem; + + code { + padding: $spacer / 2; + font-size: .65rem; + text-align: center; + } + } + + button { + margin: 0; + position: absolute; + right: 0; + top: 0; + bottom: 0; + border: 0; + box-shadow: none; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + background: rgba($brand-grey, .3); + padding: $spacer / 3; + + svg { + width: 1rem; + height: 1rem; + fill: $brand-grey; + transition: .15s ease-out; + } + + &:hover { + svg { + fill: $brand-grey-dimmed; + } + } + } +} diff --git a/src/components/organisms/Footer.jsx b/src/components/organisms/Footer.jsx index a308698f..c610f257 100644 --- a/src/components/organisms/Footer.jsx +++ b/src/components/organisms/Footer.jsx @@ -3,6 +3,8 @@ import { StaticQuery, graphql } from 'gatsby' import Img from 'gatsby-image' import Container from '../atoms/Container' +import ModalThanks from '../molecules/ModalThanks' + import Twitter from '../svg/Twitter' import Github from '../svg/Github' import Facebook from '../svg/Facebook' @@ -16,7 +18,14 @@ class Footer extends PureComponent { constructor(props) { super(props) - this.state = { year: null } + this.state = { + year: null, + showModal: false + } + } + + toggleModal = () => { + this.setState({ showModal: !this.state.showModal }) } componentDidMount() { @@ -46,7 +55,6 @@ class Footer extends PureComponent { } } bitcoin - ether } } } @@ -125,11 +133,20 @@ class Footer extends PureComponent { View source - + {author.bitcoin}

+ + diff --git a/src/styles/_code.scss b/src/styles/_code.scss index 73aa4e42..b0f3a95b 100644 --- a/src/styles/_code.scss +++ b/src/styles/_code.scss @@ -37,6 +37,7 @@ pre { background-color: $code-bg; margin-left: -($spacer); margin-right: -($spacer); + border-radius: $border-radius; // make 'em scrollable overflow: scroll; @@ -59,6 +60,7 @@ pre { overflow-wrap: normal; word-wrap: normal; word-break: normal; + overflow: auto; } } diff --git a/src/templates/Post.module.scss b/src/templates/Post.module.scss index e94dd45f..69b8b26f 100644 --- a/src/templates/Post.module.scss +++ b/src/templates/Post.module.scss @@ -18,6 +18,14 @@ &:first-child { padding-top: 0; } + + &:only-child { + border: 0; + + &::before { + display: none; + } + } } // Post/photo teaser