diff --git a/TODO.md b/TODO.md
new file mode 100644
index 0000000..51523ed
--- /dev/null
+++ b/TODO.md
@@ -0,0 +1,25 @@
+- Update to latest React
+- Package a local version of Gatsby with hooks support
+- Switch to SVG emoji heart
+
+```jsx
+import React, { useState } from 'react'
+
+const handleSubmit = (value, mutation) => {
+ return ev => {
+ ev.preventDefault()
+ }
+
+ // use value
+}
+
+function() {
+ const [value, setValue] = useState('')
+
+ return (
+
+ )
+}
+```
diff --git a/client/src/components/canvas.js b/client/src/components/canvas.js
index 8867e55..5a170b7 100644
--- a/client/src/components/canvas.js
+++ b/client/src/components/canvas.js
@@ -49,6 +49,8 @@ export default class Canvas extends Component {
context.clearRect(0, 0, this.canvas.width, this.canvas.height)
}
+ positionInScaledCanvas = points => points.map(point => point / 4)
+
render() {
const { children, render = children } = this.props
const { context } = this.state
@@ -58,6 +60,7 @@ export default class Canvas extends Component {
? render({
...this.state,
clear: this.clear,
+ getPosition: this.positionInScaledCanvas,
})
: null}
diff --git a/client/src/components/footer.js b/client/src/components/footer.js
index b8bfcac..532e618 100644
--- a/client/src/components/footer.js
+++ b/client/src/components/footer.js
@@ -1,16 +1,39 @@
import React from 'react'
import styled from 'react-emotion'
+import { FaGithub } from 'react-icons/fa'
+
+import Link from './outbound-link'
import { position } from '../style'
const Container = styled.footer`
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
box-sizing: border-box;
background-color: #fffaf5;
+ border-top: 2px solid #c51104;
width: 100%;
padding: 1rem 0.5rem;
${position.absolute({ bottom: true })}
`
-export default function Footer({ children }) {
- return {children}
+const GithubIcon = styled(FaGithub)`
+ font-size: 24px;
+`
+
+export default function Footer() {
+ return (
+
+
+
+
+
+ #buildwithgatsby
+
+
+ )
}
diff --git a/client/src/components/heart-canvas.js b/client/src/components/heart-canvas.js
new file mode 100644
index 0000000..2934833
--- /dev/null
+++ b/client/src/components/heart-canvas.js
@@ -0,0 +1,29 @@
+import React from 'react'
+import Canvas from './canvas'
+
+function HeartCanvas() {
+ return (
+
+ )
+}
+
+export default HeartCanvas
diff --git a/client/src/components/heart.js b/client/src/components/heart.js
index 1b3102f..29955ed 100644
--- a/client/src/components/heart.js
+++ b/client/src/components/heart.js
@@ -1,23 +1,28 @@
import React from 'react'
-import styled from 'react-emotion'
+import styled, { css } from 'react-emotion'
import { PULSE_ANIMATION } from '../style'
const Container = styled.span`
display: inline-block;
- animation: 2s infinite ${PULSE_ANIMATION}
- cubic-bezier(0.455, 0.03, 0.515, 0.955);
- transition: 2s ease-in-out;
-
- :hover {
- animation: none;
- }
+ ${props =>
+ props.animate &&
+ css`
+ animation: 2s infinite ${PULSE_ANIMATION}
+ cubic-bezier(0.455, 0.03, 0.515, 0.955);
+ `}
`
-export default function Heart() {
+function Heart({ animate }) {
return (
-
+
❤️
)
}
+
+Heart.defaultProps = {
+ animate: true,
+}
+
+export default Heart
diff --git a/client/src/components/index.js b/client/src/components/index.js
index 3a7f75b..7082875 100644
--- a/client/src/components/index.js
+++ b/client/src/components/index.js
@@ -1,3 +1,6 @@
export { default as Canvas } from './canvas'
export { default as Heart } from './heart'
+export { default as HeartCanvas } from './heart-canvas'
export { default as Footer } from './footer'
+export { default as LoveCanvas } from './love-canvas'
+export { default as OutboundLink } from './outbound-link'
diff --git a/client/src/components/love-canvas.js b/client/src/components/love-canvas.js
new file mode 100644
index 0000000..06237af
--- /dev/null
+++ b/client/src/components/love-canvas.js
@@ -0,0 +1,82 @@
+import React from 'react'
+import styled from 'react-emotion'
+import PropTypes from 'prop-types'
+
+import Canvas from './canvas'
+import Heart from './heart'
+
+const Container = styled.div`
+ font-family: monospace;
+ font-size: 10vw;
+`
+
+const Empty = () => (
+
+ {`{...`}
+
+ {`}`}
+
+)
+
+/*
+ * TODO: implement fill algorithm
+ */
+function Love({ items }) {
+ if (items.length === 0) {
+ return
+ }
+
+ const total = items.reduce((count, item) => {
+ return count + item.count
+ }, 0)
+
+ return (
+