mirror of
https://github.com/kremalicious/blog.git
synced 2024-12-22 17:23:50 +01:00
put web3 donation on page, kick out modal
This commit is contained in:
parent
eb892807eb
commit
e5adbb68c5
@ -5,6 +5,9 @@ if (typeof window.IntersectionObserver === 'undefined') {
|
|||||||
import('intersection-observer')
|
import('intersection-observer')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import wrapPageElementWithLayout from './src/helpers/wrapPageElement'
|
||||||
|
export const wrapPageElement = wrapPageElementWithLayout
|
||||||
|
|
||||||
// Display a message when a service worker updates
|
// Display a message when a service worker updates
|
||||||
// https://www.gatsbyjs.org/docs/add-offline-support-with-a-service-worker/#displaying-a-message-when-a-service-worker-updates
|
// https://www.gatsbyjs.org/docs/add-offline-support-with-a-service-worker/#displaying-a-message-when-a-service-worker-updates
|
||||||
export const onServiceWorkerUpdateReady = () => {
|
export const onServiceWorkerUpdateReady = () => {
|
||||||
|
2
gatsby-ssr.js
Normal file
2
gatsby-ssr.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
import wrapPageElementWithLayout from './src/helpers/wrapPageElement'
|
||||||
|
export const wrapPageElement = wrapPageElementWithLayout
|
@ -1,124 +0,0 @@
|
|||||||
@import 'variables';
|
|
||||||
|
|
||||||
.modal {
|
|
||||||
position: fixed;
|
|
||||||
overflow: auto;
|
|
||||||
-webkit-overflow-scrolling: touch;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
z-index: 9;
|
|
||||||
background: rgba($body-background-color, 0.95);
|
|
||||||
backdrop-filter: blur(5px);
|
|
||||||
animation: fadein 0.3s;
|
|
||||||
padding: $spacer;
|
|
||||||
|
|
||||||
:global(.dark) & {
|
|
||||||
background: rgba($body-background-color--dark, 0.95);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: $screen-sm) {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
justify-content: center;
|
|
||||||
padding-top: 6vh;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.modalContent {
|
|
||||||
outline: 0;
|
|
||||||
background: $body-background-color;
|
|
||||||
position: relative;
|
|
||||||
border-radius: $border-radius;
|
|
||||||
border: 1px solid rgba($brand-grey-light, 0.4);
|
|
||||||
box-shadow: 0 5px 30px rgba($brand-grey-light, 0.2);
|
|
||||||
padding: 0 $spacer / 2 $spacer / 2;
|
|
||||||
max-width: 100%;
|
|
||||||
|
|
||||||
:global(.dark) & {
|
|
||||||
background: $body-background-color--dark;
|
|
||||||
box-shadow: 0 5px 30px rgba(darken($brand-main, 20%), 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: $screen-md) {
|
|
||||||
max-width: $screen-sm;
|
|
||||||
padding: 0 $spacer $spacer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.modalClose {
|
|
||||||
display: block;
|
|
||||||
cursor: pointer;
|
|
||||||
background: transparent;
|
|
||||||
border: 0;
|
|
||||||
appearance: none;
|
|
||||||
padding: 4px;
|
|
||||||
position: absolute;
|
|
||||||
top: $spacer / 4;
|
|
||||||
right: ($spacer/4);
|
|
||||||
outline: 0;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
stroke: $brand-grey-light;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&:focus {
|
|
||||||
svg {
|
|
||||||
stroke: $brand-cyan;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.isModalOpen {
|
|
||||||
// Prevent background scrolling when modal is open
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
// more cross-browser backdrop-filter
|
|
||||||
// body > div:first-child {
|
|
||||||
// transition: filter .85s ease-out;
|
|
||||||
// filter: blur(5px);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
.modalTitle {
|
|
||||||
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, 0.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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import { render } from '@testing-library/react'
|
|
||||||
import Modal from './Modal'
|
|
||||||
import ReactModal from 'react-modal'
|
|
||||||
|
|
||||||
describe('Modal', () => {
|
|
||||||
it('renders without crashing', () => {
|
|
||||||
ReactModal.setAppElement(document.createElement('div'))
|
|
||||||
|
|
||||||
const { rerender } = render(
|
|
||||||
<Modal title="Hello" isOpen handleCloseModal={() => null}>
|
|
||||||
Hello
|
|
||||||
</Modal>
|
|
||||||
)
|
|
||||||
expect(document.querySelector('.ReactModalPortal')).toBeInTheDocument()
|
|
||||||
|
|
||||||
rerender(
|
|
||||||
<Modal isOpen={false} handleCloseModal={() => null}>
|
|
||||||
Hello
|
|
||||||
</Modal>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,38 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import ReactModal from 'react-modal'
|
|
||||||
import Icon from './Icon'
|
|
||||||
import styles from './Modal.module.scss'
|
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'test') ReactModal.setAppElement('#___gatsby')
|
|
||||||
|
|
||||||
export default function Modal({
|
|
||||||
title,
|
|
||||||
isOpen,
|
|
||||||
handleCloseModal,
|
|
||||||
children,
|
|
||||||
...props
|
|
||||||
}: {
|
|
||||||
title?: string
|
|
||||||
isOpen?: boolean
|
|
||||||
handleCloseModal(): void
|
|
||||||
children: any
|
|
||||||
}) {
|
|
||||||
if (!isOpen) return null
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ReactModal
|
|
||||||
overlayClassName={styles.modal}
|
|
||||||
className={styles.modalContent}
|
|
||||||
htmlOpenClassName={styles.isModalOpen}
|
|
||||||
shouldReturnFocusAfterClose={false}
|
|
||||||
isOpen={isOpen}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
{title && <h1 className={styles.modalTitle}>{title}</h1>}
|
|
||||||
{children}
|
|
||||||
<button className={styles.modalClose} onClick={handleCloseModal}>
|
|
||||||
<Icon name="X" />
|
|
||||||
</button>
|
|
||||||
</ReactModal>
|
|
||||||
)
|
|
||||||
}
|
|
@ -5,10 +5,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.code {
|
.code {
|
||||||
margin: 0;
|
margin: 0 auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
padding-right: 2rem;
|
padding-right: 2rem;
|
||||||
|
width: fit-content;
|
||||||
|
|
||||||
code {
|
code {
|
||||||
padding: $spacer / 2;
|
padding: $spacer / 2;
|
||||||
|
@ -24,6 +24,10 @@
|
|||||||
composes: alert;
|
composes: alert;
|
||||||
color: darken($alert-error, 60%);
|
color: darken($alert-error, 60%);
|
||||||
|
|
||||||
|
:global(.dark) & {
|
||||||
|
color: darken($alert-error, 40%);
|
||||||
|
}
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ export const alertMessages = (
|
|||||||
'Web3 detected, but no account. Are you logged into your MetaMask account?',
|
'Web3 detected, but no account. Are you logged into your MetaMask account?',
|
||||||
noCorrectNetwork: `Please connect to <strong>Main</strong> network. You are on <strong>${networkName}</strong> right now.`,
|
noCorrectNetwork: `Please connect to <strong>Main</strong> network. You are on <strong>${networkName}</strong> right now.`,
|
||||||
noWeb3:
|
noWeb3:
|
||||||
'No Web3 detected. Install <a href="https://metamask.io">MetaMask</a>, <a href="https://brave.com">Brave</a>, or <a href="https://github.com/ethereum/mist">Mist</a>.',
|
'No Web3 detected. Install <a href="https://metamask.io">MetaMask</a> or <a href="https://brave.com">Brave</a>.',
|
||||||
transaction: `<a href="https://etherscan.io/tx/${transactionHash}" target="_blank">See your transaction on etherscan.io.</a>`,
|
transaction: `<a href="https://etherscan.io/tx/${transactionHash}" target="_blank">See your transaction on etherscan.io.</a>`,
|
||||||
waitingForUser: 'Waiting for your confirmation',
|
waitingForUser: 'Waiting for your confirmation',
|
||||||
waitingConfirmation: 'Waiting for network confirmation, hang on',
|
waitingConfirmation: 'Waiting for network confirmation, hang on',
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
@import 'variables';
|
@import 'variables';
|
||||||
@import 'mixins';
|
|
||||||
|
|
||||||
.web3 {
|
.web3 {
|
||||||
@include divider;
|
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: $spacer / 2;
|
margin-top: $spacer / 2;
|
||||||
margin-bottom: $spacer;
|
margin-bottom: $spacer;
|
||||||
padding-bottom: $spacer * 1.5;
|
padding-bottom: $spacer;
|
||||||
|
|
||||||
small {
|
small {
|
||||||
color: darken($alert-info, 60%);
|
color: darken($alert-info, 60%);
|
||||||
|
@ -88,7 +88,7 @@ export default class Web3Donation extends PureComponent<
|
|||||||
|
|
||||||
initAccountsPoll() {
|
initAccountsPoll() {
|
||||||
if (!this.interval) {
|
if (!this.interval) {
|
||||||
this.interval = setInterval(this.fetchAccounts, ONE_SECOND)
|
this.interval = setInterval(this.fetchAccounts, ONE_SECOND * 10)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,8 +184,8 @@ export default class Web3Donation extends PureComponent<
|
|||||||
return (
|
return (
|
||||||
<div className={styles.web3}>
|
<div className={styles.web3}>
|
||||||
<header>
|
<header>
|
||||||
<h4>web3</h4>
|
<h4>Web3 Wallet</h4>
|
||||||
<p>Send Ether with MetaMask, Brave, or Mist.</p>
|
<p>Send Ether with MetaMask or Brave.</p>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div className={styles.web3Row}>
|
<div className={styles.web3Row}>
|
||||||
|
@ -1,20 +1,13 @@
|
|||||||
import React, { useState } from 'react'
|
import React from 'react'
|
||||||
|
import { Link } from 'gatsby'
|
||||||
import Container from '../atoms/Container'
|
import Container from '../atoms/Container'
|
||||||
import Icon from '../atoms/Icon'
|
import Icon from '../atoms/Icon'
|
||||||
import Vcard from '../molecules/Vcard'
|
import Vcard from '../molecules/Vcard'
|
||||||
import ThemeSwitch from '../molecules/ThemeSwitch'
|
import ThemeSwitch from '../molecules/ThemeSwitch'
|
||||||
import ModalThanks from './ModalThanks'
|
|
||||||
|
|
||||||
import styles from './Footer.module.scss'
|
|
||||||
import { useSiteMetadata } from '../../hooks/use-site-metadata'
|
import { useSiteMetadata } from '../../hooks/use-site-metadata'
|
||||||
|
import styles from './Footer.module.scss'
|
||||||
|
|
||||||
function Copyright({
|
function Copyright() {
|
||||||
toggleModal,
|
|
||||||
showModal
|
|
||||||
}: {
|
|
||||||
toggleModal(): void
|
|
||||||
showModal: boolean
|
|
||||||
}) {
|
|
||||||
const { name, uri, bitcoin, github } = useSiteMetadata().author
|
const { name, uri, bitcoin, github } = useSiteMetadata().author
|
||||||
const year = new Date().getFullYear()
|
const year = new Date().getFullYear()
|
||||||
|
|
||||||
@ -30,33 +23,23 @@ function Copyright({
|
|||||||
<Icon name="GitHub" />
|
<Icon name="GitHub" />
|
||||||
View source
|
View source
|
||||||
</a>
|
</a>
|
||||||
<button className={styles.btc} onClick={toggleModal}>
|
<Link to="/thanks" className={styles.btc}>
|
||||||
<Icon name="Bitcoin" />
|
<Icon name="Bitcoin" />
|
||||||
<code>{bitcoin}</code>
|
<code>{bitcoin}</code>
|
||||||
</button>
|
</Link>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{showModal && (
|
|
||||||
<ModalThanks isOpen={showModal} handleCloseModal={toggleModal} />
|
|
||||||
)}
|
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Footer() {
|
export default function Footer() {
|
||||||
const [showModal, setShowModal] = useState(false)
|
|
||||||
|
|
||||||
const toggleModal = () => {
|
|
||||||
setShowModal(!showModal)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<footer role="contentinfo" className={styles.footer}>
|
<footer role="contentinfo" className={styles.footer}>
|
||||||
<Container>
|
<Container>
|
||||||
<ThemeSwitch />
|
<ThemeSwitch />
|
||||||
<Vcard />
|
<Vcard />
|
||||||
|
|
||||||
<Copyright showModal={showModal} toggleModal={toggleModal} />
|
<Copyright />
|
||||||
</Container>
|
</Container>
|
||||||
</footer>
|
</footer>
|
||||||
)
|
)
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
import React, { lazy, Suspense } from 'react'
|
|
||||||
import shortid from 'shortid'
|
|
||||||
import { Author } from '../../@types/Site'
|
|
||||||
import { useSiteMetadata } from '../../hooks/use-site-metadata'
|
|
||||||
import Qr from '../atoms/Qr'
|
|
||||||
import Modal from '../atoms/Modal'
|
|
||||||
import styles from './ModalThanks.module.scss'
|
|
||||||
|
|
||||||
const Web3Donation = lazy(() => import('../molecules/Web3Donation'))
|
|
||||||
|
|
||||||
const Coin = ({ address, author }: { address: string; author: Author }) => (
|
|
||||||
<div className={styles.coin}>
|
|
||||||
<Suspense fallback={<div>Loading...</div>}>
|
|
||||||
<Qr title={address} address={(author as any)[address]} />
|
|
||||||
</Suspense>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
|
|
||||||
export default function ModalThanks(props: any) {
|
|
||||||
const { author } = useSiteMetadata()
|
|
||||||
const coins = Object.keys(author).filter(
|
|
||||||
key => key === 'bitcoin' || key === 'ether'
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
{...props}
|
|
||||||
contentLabel="Say thanks with Bitcoin or Ether"
|
|
||||||
title="Say thanks"
|
|
||||||
>
|
|
||||||
<div className={styles.modalThanks}>
|
|
||||||
<Suspense fallback={<div>Loading...</div>}>
|
|
||||||
<Web3Donation address={author.ether} />
|
|
||||||
</Suspense>
|
|
||||||
|
|
||||||
<header>
|
|
||||||
<h4>Any other wallets</h4>
|
|
||||||
<p>Send Bitcoin or Ether from any wallet.</p>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
{coins.map((address: string) => (
|
|
||||||
<Coin key={shortid.generate()} address={address} author={author} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
)
|
|
||||||
}
|
|
8
src/helpers/wrapPageElement.tsx
Normal file
8
src/helpers/wrapPageElement.tsx
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import Layout from '../components/Layout'
|
||||||
|
|
||||||
|
const wrapPageElement = ({ element, props }: { element: any; props: any }) => (
|
||||||
|
<Layout {...props}>{element}</Layout>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default wrapPageElement
|
@ -1,11 +1,18 @@
|
|||||||
@import 'variables';
|
@import 'variables';
|
||||||
|
@import 'mixins';
|
||||||
|
|
||||||
.modalThanks {
|
.buttonBack {
|
||||||
@media (min-width: $screen-sm) {
|
svg {
|
||||||
display: flex;
|
stroke: $brand-grey-light;
|
||||||
justify-content: space-between;
|
display: inline-block;
|
||||||
flex-wrap: wrap;
|
margin-bottom: -0.15rem;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.thanks {
|
||||||
|
@include breakoutviewport;
|
||||||
|
|
||||||
|
min-height: 100vh;
|
||||||
|
|
||||||
h4 {
|
h4 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@ -41,6 +48,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: $spacer * 2;
|
||||||
|
font-size: $font-size-h2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coins {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
@media (min-width: $screen-sm) {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.coin {
|
.coin {
|
||||||
margin-top: $spacer;
|
margin-top: $spacer;
|
||||||
|
|
||||||
@ -49,3 +72,8 @@
|
|||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loading {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
69
src/pages/thanks.tsx
Normal file
69
src/pages/thanks.tsx
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import React, { lazy, Suspense } from 'react'
|
||||||
|
import shortid from 'shortid'
|
||||||
|
import Helmet from 'react-helmet'
|
||||||
|
import { Author } from '../@types/Site'
|
||||||
|
import { useSiteMetadata } from '../hooks/use-site-metadata'
|
||||||
|
import Typekit from '../components/atoms/Typekit'
|
||||||
|
import Qr from '../components/atoms/Qr'
|
||||||
|
import Icon from '../components/atoms/Icon'
|
||||||
|
import styles from './thanks.module.scss'
|
||||||
|
|
||||||
|
const Web3Donation = lazy(() => import('../components/molecules/Web3Donation'))
|
||||||
|
|
||||||
|
const Coin = ({ address, author }: { address: string; author: Author }) => (
|
||||||
|
<div className={styles.coin}>
|
||||||
|
<Qr title={address} address={(author as any)[address]} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
const BackButton = () => (
|
||||||
|
<button
|
||||||
|
className={`link ${styles.buttonBack}`}
|
||||||
|
onClick={() => window.history.back()}
|
||||||
|
>
|
||||||
|
<Icon name="ChevronLeft" /> Go Back
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default function Thanks() {
|
||||||
|
const { author } = useSiteMetadata()
|
||||||
|
const coins = Object.keys(author).filter(
|
||||||
|
key => key === 'bitcoin' || key === 'ether'
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Helmet>
|
||||||
|
<title>Say thanks</title>
|
||||||
|
<meta name="robots" content="noindex,nofollow" />
|
||||||
|
</Helmet>
|
||||||
|
|
||||||
|
<article className={styles.thanks}>
|
||||||
|
<BackButton />
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<h1 className={styles.title}>Say Thanks</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<Suspense fallback={<div className={styles.loading}>Loading...</div>}>
|
||||||
|
<Web3Donation address={author.ether} />
|
||||||
|
|
||||||
|
<div className={styles.coins}>
|
||||||
|
<header>
|
||||||
|
<h4>Any other wallets</h4>
|
||||||
|
<p>Send Bitcoin or Ether from any wallet.</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{coins.map((address: string) => (
|
||||||
|
<Coin
|
||||||
|
key={shortid.generate()}
|
||||||
|
address={address}
|
||||||
|
author={author}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Suspense>
|
||||||
|
</article>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
@ -2,7 +2,6 @@ import React from 'react'
|
|||||||
import { Helmet } from 'react-helmet'
|
import { Helmet } from 'react-helmet'
|
||||||
import { Post } from '../@types/Post'
|
import { Post } from '../@types/Post'
|
||||||
import SEO from '../components/atoms/SEO'
|
import SEO from '../components/atoms/SEO'
|
||||||
import Layout from '../components/Layout'
|
|
||||||
import styles from './Page.module.scss'
|
import styles from './Page.module.scss'
|
||||||
|
|
||||||
export default function Page({
|
export default function Page({
|
||||||
@ -23,10 +22,8 @@ export default function Page({
|
|||||||
<Helmet title={title} />
|
<Helmet title={title} />
|
||||||
<SEO slug={location.pathname} postSEO post={post} />
|
<SEO slug={location.pathname} postSEO post={post} />
|
||||||
|
|
||||||
<Layout location={location}>
|
<h1 className={styles.pageTitle}>{title}</h1>
|
||||||
<h1 className={styles.pageTitle}>{title}</h1>
|
{section ? <section className={section}>{children}</section> : children}
|
||||||
{section ? <section className={section}>{children}</section> : children}
|
|
||||||
</Layout>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import React, { useState } from 'react'
|
import React, { useState } from 'react'
|
||||||
import ModalThanks from '../../components/organisms/ModalThanks'
|
|
||||||
import { useSiteMetadata } from '../../hooks/use-site-metadata'
|
import { useSiteMetadata } from '../../hooks/use-site-metadata'
|
||||||
import styles from './PostActions.module.scss'
|
import styles from './PostActions.module.scss'
|
||||||
import Icon from '../../components/atoms/Icon'
|
import Icon from '../../components/atoms/Icon'
|
||||||
@ -38,13 +37,8 @@ export default function PostActions({
|
|||||||
githubLink: string
|
githubLink: string
|
||||||
}) {
|
}) {
|
||||||
const { siteUrl } = useSiteMetadata()
|
const { siteUrl } = useSiteMetadata()
|
||||||
const [showModal, setShowModal] = useState(false)
|
|
||||||
const urlTwitter = `https://twitter.com/intent/tweet?text=@kremalicious&url=${siteUrl}${slug}`
|
const urlTwitter = `https://twitter.com/intent/tweet?text=@kremalicious&url=${siteUrl}${slug}`
|
||||||
|
|
||||||
const toggleModal = () => {
|
|
||||||
setShowModal(!showModal)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<aside className={styles.actions}>
|
<aside className={styles.actions}>
|
||||||
<Action
|
<Action
|
||||||
@ -55,17 +49,13 @@ export default function PostActions({
|
|||||||
<Action
|
<Action
|
||||||
title="Found something useful?"
|
title="Found something useful?"
|
||||||
text="Say thanks with Bitcoin or Ether"
|
text="Say thanks with Bitcoin or Ether"
|
||||||
onClick={toggleModal}
|
url="/thanks"
|
||||||
/>
|
/>
|
||||||
<Action
|
<Action
|
||||||
title="Edit on GitHub"
|
title="Edit on GitHub"
|
||||||
text="Contribute to this post on GitHub"
|
text="Contribute to this post on GitHub"
|
||||||
url={githubLink}
|
url={githubLink}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{showModal && (
|
|
||||||
<ModalThanks isOpen={showModal} handleCloseModal={toggleModal} />
|
|
||||||
)}
|
|
||||||
</aside>
|
</aside>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ import React from 'react'
|
|||||||
import { Helmet } from 'react-helmet'
|
import { Helmet } from 'react-helmet'
|
||||||
import { graphql } from 'gatsby'
|
import { graphql } from 'gatsby'
|
||||||
import { Post as PostMetadata } from '../../@types/Post'
|
import { Post as PostMetadata } from '../../@types/Post'
|
||||||
import Layout from '../../components/Layout'
|
|
||||||
import Exif from '../../components/atoms/Exif'
|
import Exif from '../../components/atoms/Exif'
|
||||||
import SEO from '../../components/atoms/SEO'
|
import SEO from '../../components/atoms/SEO'
|
||||||
import RelatedPosts from '../../components/molecules/RelatedPosts'
|
import RelatedPosts from '../../components/molecules/RelatedPosts'
|
||||||
@ -18,11 +17,9 @@ import { Image } from '../../components/atoms/Image'
|
|||||||
|
|
||||||
export default function Post({
|
export default function Post({
|
||||||
data,
|
data,
|
||||||
location,
|
|
||||||
pageContext: { next, prev }
|
pageContext: { next, prev }
|
||||||
}: {
|
}: {
|
||||||
data: { post: PostMetadata }
|
data: { post: PostMetadata }
|
||||||
location: Location
|
|
||||||
pageContext: {
|
pageContext: {
|
||||||
next: { title: string; slug: string }
|
next: { title: string; slug: string }
|
||||||
prev: { title: string; slug: string }
|
prev: { title: string; slug: string }
|
||||||
@ -40,36 +37,34 @@ export default function Post({
|
|||||||
|
|
||||||
<SEO slug={slug} post={post} postSEO />
|
<SEO slug={slug} post={post} postSEO />
|
||||||
|
|
||||||
<Layout location={location}>
|
<article className={styles.hentry}>
|
||||||
<article className={styles.hentry}>
|
<header>
|
||||||
<header>
|
<PostTitle type={type} linkurl={linkurl} title={title} />
|
||||||
<PostTitle type={type} linkurl={linkurl} title={title} />
|
{type === 'post' && <PostLead post={post} />}
|
||||||
{type === 'post' && <PostLead post={post} />}
|
</header>
|
||||||
</header>
|
|
||||||
|
|
||||||
{type === 'photo' && <PostContent post={post} />}
|
{type === 'photo' && <PostContent post={post} />}
|
||||||
{image && (
|
{image && (
|
||||||
<Image
|
<Image
|
||||||
fluid={image.childImageSharp.fluid}
|
fluid={image.childImageSharp.fluid}
|
||||||
alt={title}
|
alt={title}
|
||||||
original={image.childImageSharp.original}
|
original={image.childImageSharp.original}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{type === 'photo' && image && image.fields && (
|
{type === 'photo' && image && image.fields && (
|
||||||
<Exif exif={image.fields.exif} />
|
<Exif exif={image.fields.exif} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{type !== 'photo' && <PostContent post={post} />}
|
{type !== 'photo' && <PostContent post={post} />}
|
||||||
|
|
||||||
{type === 'link' && <PostLinkActions slug={slug} linkurl={linkurl} />}
|
{type === 'link' && <PostLinkActions slug={slug} linkurl={linkurl} />}
|
||||||
<PostActions slug={slug} githubLink={githubLink} />
|
<PostActions slug={slug} githubLink={githubLink} />
|
||||||
<PostMeta post={post} />
|
<PostMeta post={post} />
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<RelatedPosts photos={type === 'photo'} tags={tags} />
|
<RelatedPosts photos={type === 'photo'} tags={tags} />
|
||||||
|
|
||||||
<PrevNext prev={prev} next={next} />
|
<PrevNext prev={prev} next={next} />
|
||||||
</Layout>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Link, graphql } from 'gatsby'
|
import { Link, graphql } from 'gatsby'
|
||||||
import { Post } from '../@types/Post'
|
import { Post } from '../@types/Post'
|
||||||
import Layout from '../components/Layout'
|
|
||||||
import Pagination from '../components/molecules/Pagination'
|
import Pagination from '../components/molecules/Pagination'
|
||||||
import Featured from '../components/molecules/Featured'
|
import Featured from '../components/molecules/Featured'
|
||||||
import PostTitle from './Post/PostTitle'
|
import PostTitle from './Post/PostTitle'
|
||||||
@ -69,7 +68,7 @@ export default function Posts({
|
|||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout location={location}>
|
<>
|
||||||
<SEO />
|
<SEO />
|
||||||
{location.pathname === '/' && <Featured />}
|
{location.pathname === '/' && <Featured />}
|
||||||
{tag && (
|
{tag && (
|
||||||
@ -85,7 +84,7 @@ export default function Posts({
|
|||||||
)}
|
)}
|
||||||
{PostsList}
|
{PostsList}
|
||||||
{numPages > 1 && <Pagination pageContext={pageContext} />}
|
{numPages > 1 && <Pagination pageContext={pageContext} />}
|
||||||
</Layout>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user