diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 00000000..19f374ad
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1 @@
+#node_modules
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000..0e878c39
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,20 @@
+# base image
+FROM node:9.6.1
+
+# set working directory
+RUN mkdir /usr/inspiration-board
+WORKDIR /usr/inspiration-board
+
+# add `/usr/src/app/node_modules/.bin` to $PATH
+ENV PATH /usr/inspiration-board/node_modules/.bin:$PATH
+
+# install and cache app dependencies
+COPY . /usr/inspiration-board
+#COPY package.json /usr/src/app/package.json
+
+
+RUN npm install --silent
+RUN npm install react-scripts@1.1.1 -g --silent
+
+# start app
+CMD ["npm", "start"]
diff --git a/package-lock.json b/package-lock.json
index 0d789ea1..1674a795 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,9 +5,9 @@
"requires": true,
"dependencies": {
"@types/node": {
- "version": "10.3.0",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-10.3.0.tgz",
- "integrity": "sha512-hWzNviaVFIr1TqcRA8ou49JaSHp+Rfabmnqg2kNvusKqLhPU0rIsGPUj5WJJ7ld4Bb7qdgLmIhLfCD1qS08IVA==",
+ "version": "10.3.3",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-10.3.3.tgz",
+ "integrity": "sha512-/gwCgiI2e9RzzZTKbl+am3vgNqOt7a9fJ/uxv4SqYKxenoEDNVU3KZEadlpusWhQI0A0dOrZ0T68JYKVjzmgdQ==",
"dev": true
},
"abab": {
@@ -2961,7 +2961,7 @@
"object.values": "1.0.4",
"prop-types": "15.6.1",
"react-reconciler": "0.7.0",
- "react-test-renderer": "16.4.0"
+ "react-test-renderer": "16.4.1"
}
},
"enzyme-adapter-utils": {
@@ -2975,6 +2975,15 @@
"prop-types": "15.6.1"
}
},
+ "enzyme-to-json": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/enzyme-to-json/-/enzyme-to-json-3.3.4.tgz",
+ "integrity": "sha1-Z8YEDpMRgvGDQYry659DIyWKp38=",
+ "dev": true,
+ "requires": {
+ "lodash": "4.17.10"
+ }
+ },
"errno": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
@@ -6085,6 +6094,21 @@
"resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-20.0.3.tgz",
"integrity": "sha1-i8Bw6QQUqhVcEajWTIaaDVxx2lk="
},
+ "jest-mock-axios": {
+ "version": "2.1.11",
+ "resolved": "https://registry.npmjs.org/jest-mock-axios/-/jest-mock-axios-2.1.11.tgz",
+ "integrity": "sha512-rxF13chmHuelAh/rysNQEY4YqmOO94XmBO5Mk2+edFh2dOwe3j/XIRSnY8+m61t1658AU6nGoTh1s7tCgvridg==",
+ "dev": true,
+ "requires": {
+ "jest-mock-promise": "1.0.23"
+ }
+ },
+ "jest-mock-promise": {
+ "version": "1.0.23",
+ "resolved": "https://registry.npmjs.org/jest-mock-promise/-/jest-mock-promise-1.0.23.tgz",
+ "integrity": "sha1-ySH9a1EqxUYJftvPR389QWllfkA=",
+ "dev": true
+ },
"jest-regex-util": {
"version": "20.0.3",
"resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-20.0.3.tgz",
@@ -7399,7 +7423,7 @@
"integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
"dev": true,
"requires": {
- "@types/node": "10.3.0"
+ "@types/node": "10.3.3"
}
},
"parseurl": {
@@ -9005,9 +9029,9 @@
"integrity": "sha512-FlsPxavEyMuR6TjVbSSywovXSEyOg6ZDj5+Z8nbsRl9EkOzAhEIcS+GLoQDC5fz/t9suhUXWmUrOBrgeUvrMxw=="
},
"react-is": {
- "version": "16.4.0",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.4.0.tgz",
- "integrity": "sha512-8ADZg/mBw+t2Fbr5Hm1K64v8q8Q6E+DprV5wQ5A8PSLW6XP0XJFMdUskVEW8efQ5oUgWHn8EYdHEPAMF0Co6hA==",
+ "version": "16.4.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.4.1.tgz",
+ "integrity": "sha512-xpb0PpALlFWNw/q13A+1aHeyJyLYCg0/cCHPUA43zYluZuIPHaHL3k8OBsTgQtxqW0FhyDEMvi8fZ/+7+r4OSQ==",
"dev": true
},
"react-reconciler": {
@@ -9208,15 +9232,15 @@
}
},
"react-test-renderer": {
- "version": "16.4.0",
- "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.4.0.tgz",
- "integrity": "sha512-Seh1t9xFY6TKiV/hRlPzUkqX1xHOiKIMsctfU0cggo1ajsLjoIJFL520LlrxV+4/VIj+clrCeH6s/aVv/vTStg==",
+ "version": "16.4.1",
+ "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.4.1.tgz",
+ "integrity": "sha512-wyyiPxRZOTpKnNIgUBOB6xPLTpIzwcQMIURhZvzUqZzezvHjaGNsDPBhMac5fIY3Jf5NuKxoGvV64zDSOECPPQ==",
"dev": true,
"requires": {
"fbjs": "0.8.16",
"object-assign": "4.1.1",
"prop-types": "15.6.1",
- "react-is": "16.4.0"
+ "react-is": "16.4.1"
}
},
"read-pkg": {
diff --git a/package.json b/package.json
index ba61363d..c6ac3678 100644
--- a/package.json
+++ b/package.json
@@ -20,7 +20,14 @@
"devDependencies": {
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
- "gh-pages": "^1.2.0"
+ "enzyme-to-json": "^3.3.4",
+ "gh-pages": "^1.2.0",
+ "jest-mock-axios": "^2.1.11"
+ },
+ "jest": {
+ "snapshotSerializers": [
+ "enzyme-to-json/serializer"
+ ]
},
"homepage": "http://adagold.github.io/inspiration-board"
}
diff --git a/src/App.css b/src/App.css
index 5db345f2..d9cdf0e1 100644
--- a/src/App.css
+++ b/src/App.css
@@ -5,6 +5,7 @@
body {
font-family: 'Raleway', sans-serif;
+ /*background-color: #92FED5;*/
}
h1, h2 {
diff --git a/src/App.js b/src/App.js
index c4854e15..63390472 100644
--- a/src/App.js
+++ b/src/App.js
@@ -10,8 +10,8 @@ class App extends Component {
Inspiration Board
);
diff --git a/src/components/Board.js b/src/components/Board.js
index 9222fd88..3ee3f545 100644
--- a/src/components/Board.js
+++ b/src/components/Board.js
@@ -5,21 +5,99 @@ import axios from 'axios';
import './Board.css';
import Card from './Card';
import NewCardForm from './NewCardForm';
-import CARD_DATA from '../data/card-data.json';
+// import CARD_DATA from '../data/card-data.json';
class Board extends Component {
- constructor() {
- super();
+ constructor(props) {
+ super(props);
this.state = {
cards: [],
};
}
+ componentDidMount = () => {
+ console.log('Component did mount was called')
+
+ axios.get('https://inspiration-board.herokuapp.com/boards/angelap/cards')
+ .then((response) => {
+ this.setState({ cards: response.data });
+ console.log(response.data)
+ })
+ .catch((error) => {
+ console.log('Error is happening');
+ console.log(error);
+ this.setState({ error: error.message});
+ return error;
+
+ });
+ }
+
+ renderCards = () => {
+ console.log('Rendering cards')
+
+ const cardList = this.state.cards.map((card, index) => {
+ let singleCard = card["card"]
+ return (
+
+ );
+ });
+ return cardList;
+ }
+
+ addCard = (note) => {
+ const cards = this.state.cards;
+ axios.post(`https://inspiration-board.herokuapp.com/boards/angelap/cards/`, note)
+ .then((response) => {
+ note.id = response.data.card.id;
+ cards.push({card: note});
+ console.log(note);
+ this.setState({
+ cards,
+ message: `Successfully Added a new Card`
+ });
+ })
+ .catch((error) => {
+ console.log(error)
+ this.setState({
+ message: error.message,
+ });
+ })
+ }
+
+ deleteCard = (id) => {
+ console.log(id)
+ axios.delete(`https://inspiration-board.herokuapp.com/boards/angelap/cards/${id}`)
+ .then((response) => {
+ this.componentDidMount();
+ console.log(response)
+ })
+ .catch((error) => {
+ console.log('Unable to delete card');
+ console.log(error);
+ this.setState({ error: error.message});
+ return error;
+
+ });
+ }
+
+
+
render() {
return (
- Board
+
+
{this.state.error}
+
{this.state.message}
+
)
}
@@ -27,7 +105,7 @@ class Board extends Component {
}
Board.propTypes = {
-
+ cards: PropTypes.array.isRequired,
};
export default Board;
diff --git a/src/components/Board.test.js b/src/components/Board.test.js
index e69de29b..1862df05 100644
--- a/src/components/Board.test.js
+++ b/src/components/Board.test.js
@@ -0,0 +1,14 @@
+
+import React, { Component } from 'react';
+import {mount, shallow} from 'enzyme';
+import Board from './Board'
+
+describe('Board', () => {
+ test('that it matches an existing snapshot', () => {
+ const wrapper = mount()
+
+ expect(wrapper).toMatchSnapshot();
+
+ wrapper.unmount();
+ });
+});
diff --git a/src/components/Card.css b/src/components/Card.css
index e86d4329..c5283621 100644
--- a/src/components/Card.css
+++ b/src/components/Card.css
@@ -1,5 +1,5 @@
.card {
- background-color: #F4FF81;
+ background-color: #D6CADA;
padding: 1em 0;
margin: 0.5rem;
@@ -44,4 +44,5 @@
.card__delete {
align-self: start;
font-family: 'Permanent Marker', Helvetica, sans-serif;
+ margin-left: 8px;
}
diff --git a/src/components/Card.js b/src/components/Card.js
index 6788cc03..8bf715ed 100644
--- a/src/components/Card.js
+++ b/src/components/Card.js
@@ -5,17 +5,39 @@ import emoji from 'emoji-dictionary';
import './Card.css';
class Card extends Component {
+
+ displayEmoji = () => {
+ if (this.props.emoji) {
+ return emoji.getUnicode(this.props.emoji)
+ }
+ };
+
+ removeCard = (event) => {
+ console.log(event.target.id);
+ event.preventDefault();
+ this.props.deleteCard(this.props.id);
+ }
+
render() {
+ console.log('Rendering a card')
return (
- Card
-
- )
- }
-}
+
+
-Card.propTypes = {
+
{this.props.text}
+
{this.displayEmoji()}
+
+
+ )
+ }
+ }
-};
+ Card.propTypes = {
+ text: PropTypes.string.isRequired,
+ emoji: PropTypes.string,
+ deleteCard: PropTypes.func,
+ id: PropTypes.number.isRequired,
+ };
-export default Card;
+ export default Card;
diff --git a/src/components/Card.test.js b/src/components/Card.test.js
new file mode 100644
index 00000000..e419b17e
--- /dev/null
+++ b/src/components/Card.test.js
@@ -0,0 +1,14 @@
+
+import React, { Component } from 'react';
+import {mount, shallow} from 'enzyme';
+import Card from './Card'
+
+describe('Card', () => {
+ test('that it matches an existing snapshot', () => {
+ const wrapper = shallow()
+
+ expect(wrapper).toMatchSnapshot();
+
+ wrapper.unmount();
+ });
+});
diff --git a/src/components/NewCardForm.js b/src/components/NewCardForm.js
index 47331423..c4b61a61 100644
--- a/src/components/NewCardForm.js
+++ b/src/components/NewCardForm.js
@@ -3,4 +3,80 @@ import PropTypes from 'prop-types';
import emoji from 'emoji-dictionary';
import './NewCardForm.css';
-const EMOJI_LIST = ["", "heart_eyes", "beer", "clap", "sparkling_heart", "heart_eyes_cat", "dog"]
+const EMOJI_LIST = ["", "heart_eyes", "beer", "clap", "sparkling_heart", "heart_eyes_cat", "dog", "joy", "sparkles", "clapping"]
+
+class NewCardForm extends Component {
+ constructor() {
+ super();
+
+ this.state = {
+ text:'',
+ emoji:'',
+ };
+ }
+
+ onFieldChange = (event) => {
+ const fieldName = event.target.name;
+ const fieldValue = event.target.value;
+ const updateState = {};
+ updateState[fieldName] = fieldValue;
+ this.setState(updateState);
+ }
+ //
+ // valid = () => {
+ // return this.state.text.length > 0;
+ // }
+
+ clearForm = () => {
+ this.setState({
+ text: '',
+ emoji: '',
+ })
+ }
+
+ onFormSubmit = (event) => {
+ event.preventDefault();
+ this.props.addCardCallBack(this.state)
+ this.clearForm()
+ }
+
+ render() {
+ return(
+
+ );
+ }
+
+}
+
+NewCardForm.propTypes = {
+ addCardCallBack: PropTypes.func.isRequired,
+}
+
+export default NewCardForm;
diff --git a/src/components/NewCardForm.test.js b/src/components/NewCardForm.test.js
index e69de29b..96ff187e 100644
--- a/src/components/NewCardForm.test.js
+++ b/src/components/NewCardForm.test.js
@@ -0,0 +1,44 @@
+
+import React, { Component } from 'react';
+import {mount, shallow} from 'enzyme';
+import NewCardForm from './NewCardForm'
+
+describe('NewCardForm', () => {
+ test('that it matches an existing snapshot', () => {
+ const wrapper = shallow()
+
+ expect(wrapper).toMatchSnapshot();
+
+ wrapper.unmount();
+ });
+
+ test('When a user enters text in the text field the field is updated', () => {
+ // arrange
+ // shallow mounted the wrapper
+
+ const wrapper = shallow({}} />)
+
+ // find the input field
+
+ let nameField = wrapper.find('input[name="text"]');
+
+ // Act
+ nameField.simulate('change', {
+ target: {
+ name: 'text',
+ value: 'Boomer loves you',
+ },
+ });
+
+ //force the onChange event
+ wrapper.update();
+ nameField = wrapper.find('input[name="text"]');
+
+ //assert
+ expect(nameField.getElement().props.value).toEqual('Boomer loves you');
+ });
+
+
+
+});
diff --git a/src/components/__snapshots__/Board.test.js.snap b/src/components/__snapshots__/Board.test.js.snap
new file mode 100644
index 00000000..2fcbf518
--- /dev/null
+++ b/src/components/__snapshots__/Board.test.js.snap
@@ -0,0 +1,122 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Board that it matches an existing snapshot 1`] = `
+
+
+
+
+
+ Create new card:
+
+
+
+
+
+
+
+
+
+`;
diff --git a/src/components/__snapshots__/Card.test.js.snap b/src/components/__snapshots__/Card.test.js.snap
new file mode 100644
index 00000000..7e8d13e2
--- /dev/null
+++ b/src/components/__snapshots__/Card.test.js.snap
@@ -0,0 +1,203 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Card that it matches an existing snapshot 1`] = `
+ShallowWrapper {
+ "length": 1,
+ Symbol(enzyme.__root__): [Circular],
+ Symbol(enzyme.__unrendered__): ,
+ Symbol(enzyme.__renderer__): Object {
+ "batchedUpdates": [Function],
+ "getNode": [Function],
+ "render": [Function],
+ "simulateEvent": [Function],
+ "unmount": [Function],
+ },
+ Symbol(enzyme.__node__): Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "host",
+ "props": Object {
+ "children": ,
+ "className": "card",
+ },
+ "ref": null,
+ "rendered": Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "host",
+ "props": Object {
+ "children": Array [
+ ,
+ ,
+ ,
+ ],
+ "className": "card__content",
+ },
+ "ref": null,
+ "rendered": Array [
+ Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "host",
+ "props": Object {
+ "children": undefined,
+ "className": "card__content-text",
+ },
+ "ref": null,
+ "rendered": null,
+ "type": "p",
+ },
+ Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "host",
+ "props": Object {
+ "children": undefined,
+ "className": "card__content-emoji",
+ },
+ "ref": null,
+ "rendered": null,
+ "type": "p",
+ },
+ Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "host",
+ "props": Object {
+ "children": "Delete",
+ "className": "card__delete",
+ "onClick": [Function],
+ },
+ "ref": null,
+ "rendered": "Delete",
+ "type": "button",
+ },
+ ],
+ "type": "div",
+ },
+ "type": "div",
+ },
+ Symbol(enzyme.__nodes__): Array [
+ Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "host",
+ "props": Object {
+ "children": ,
+ "className": "card",
+ },
+ "ref": null,
+ "rendered": Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "host",
+ "props": Object {
+ "children": Array [
+ ,
+ ,
+ ,
+ ],
+ "className": "card__content",
+ },
+ "ref": null,
+ "rendered": Array [
+ Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "host",
+ "props": Object {
+ "children": undefined,
+ "className": "card__content-text",
+ },
+ "ref": null,
+ "rendered": null,
+ "type": "p",
+ },
+ Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "host",
+ "props": Object {
+ "children": undefined,
+ "className": "card__content-emoji",
+ },
+ "ref": null,
+ "rendered": null,
+ "type": "p",
+ },
+ Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "host",
+ "props": Object {
+ "children": "Delete",
+ "className": "card__delete",
+ "onClick": [Function],
+ },
+ "ref": null,
+ "rendered": "Delete",
+ "type": "button",
+ },
+ ],
+ "type": "div",
+ },
+ "type": "div",
+ },
+ ],
+ Symbol(enzyme.__options__): Object {
+ "adapter": ReactSixteenAdapter {
+ "options": Object {
+ "enableComponentDidUpdateOnSetState": true,
+ },
+ },
+ },
+}
+`;
diff --git a/src/components/__snapshots__/NewCardForm.test.js.snap b/src/components/__snapshots__/NewCardForm.test.js.snap
new file mode 100644
index 00000000..731f1961
--- /dev/null
+++ b/src/components/__snapshots__/NewCardForm.test.js.snap
@@ -0,0 +1,109 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`NewCardForm that it matches an existing snapshot 1`] = `
+
+
+ Create new card:
+
+
+
+`;
diff --git a/src/data/card-data.json b/src/data/card-data.json
index 1f9793ec..068e019d 100644
--- a/src/data/card-data.json
+++ b/src/data/card-data.json
@@ -6,7 +6,7 @@
},
{
"text": "",
- "Emoji": "heart_eyes"
+ "emoji": "heart_eyes"
},
{
"text": "REST is part of work"