diff --git a/package-lock.json b/package-lock.json index 2f3ca7f6..b79f9a9a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2157,6 +2157,23 @@ "indent-string": "^4.0.0" } }, + "airbnb-prop-types": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/airbnb-prop-types/-/airbnb-prop-types-2.15.0.tgz", + "integrity": "sha512-jUh2/hfKsRjNFC4XONQrxo/n/3GG4Tn6Hl0WlFQN5PY9OMC9loSCoAYKnZsWaP8wEfd5xcrPloK0Zg6iS1xwVA==", + "requires": { + "array.prototype.find": "^2.1.0", + "function.prototype.name": "^1.1.1", + "has": "^1.0.3", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object.assign": "^4.1.0", + "object.entries": "^1.1.0", + "prop-types": "^15.7.2", + "prop-types-exact": "^1.2.0", + "react-is": "^16.9.0" + } + }, "ajv": { "version": "6.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", @@ -2277,6 +2294,11 @@ "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" }, + "array-filter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", + "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=" + }, "array-flatten": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", @@ -2310,6 +2332,15 @@ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" }, + "array.prototype.find": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.1.1.tgz", + "integrity": "sha512-mi+MYNJYLTx2eNYy+Yh6raoQacCsNeeMUaspFPh9Y141lFSsWxxB8V9mM2ye+eqiRs917J6/pJ4M9ZPzenWckA==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.4" + } + }, "array.prototype.flat": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", @@ -3325,6 +3356,68 @@ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, + "cheerio": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz", + "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==", + "requires": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.1", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash": "^4.15.0", + "parse5": "^3.0.1" + }, + "dependencies": { + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==" + }, + "dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "requires": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, + "parse5": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", + "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", + "requires": { + "@types/node": "*" + } + } + } + }, "chokidar": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", @@ -4375,6 +4468,11 @@ "path-type": "^3.0.0" } }, + "discontinuous-range": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz", + "integrity": "sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=" + }, "dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", @@ -4698,6 +4796,87 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" }, + "enzyme": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-3.11.0.tgz", + "integrity": "sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw==", + "requires": { + "array.prototype.flat": "^1.2.3", + "cheerio": "^1.0.0-rc.3", + "enzyme-shallow-equal": "^1.0.1", + "function.prototype.name": "^1.1.2", + "has": "^1.0.3", + "html-element-map": "^1.2.0", + "is-boolean-object": "^1.0.1", + "is-callable": "^1.1.5", + "is-number-object": "^1.0.4", + "is-regex": "^1.0.5", + "is-string": "^1.0.5", + "is-subset": "^0.1.1", + "lodash.escape": "^4.0.1", + "lodash.isequal": "^4.5.0", + "object-inspect": "^1.7.0", + "object-is": "^1.0.2", + "object.assign": "^4.1.0", + "object.entries": "^1.1.1", + "object.values": "^1.1.1", + "raf": "^3.4.1", + "rst-selector-parser": "^2.2.3", + "string.prototype.trim": "^1.2.1" + } + }, + "enzyme-adapter-react-16": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.2.tgz", + "integrity": "sha512-SkvDrb8xU3lSxID8Qic9rB8pvevDbLybxPK6D/vW7PrT0s2Cl/zJYuXvsd1EBTz0q4o3iqG3FJhpYz3nUNpM2Q==", + "requires": { + "enzyme-adapter-utils": "^1.13.0", + "enzyme-shallow-equal": "^1.0.1", + "has": "^1.0.3", + "object.assign": "^4.1.0", + "object.values": "^1.1.1", + "prop-types": "^15.7.2", + "react-is": "^16.12.0", + "react-test-renderer": "^16.0.0-0", + "semver": "^5.7.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "enzyme-adapter-utils": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/enzyme-adapter-utils/-/enzyme-adapter-utils-1.13.0.tgz", + "integrity": "sha512-YuEtfQp76Lj5TG1NvtP2eGJnFKogk/zT70fyYHXK2j3v6CtuHqc8YmgH/vaiBfL8K1SgVVbQXtTcgQZFwzTVyQ==", + "requires": { + "airbnb-prop-types": "^2.15.0", + "function.prototype.name": "^1.1.2", + "object.assign": "^4.1.0", + "object.fromentries": "^2.0.2", + "prop-types": "^15.7.2", + "semver": "^5.7.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "enzyme-shallow-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.1.tgz", + "integrity": "sha512-hGA3i1so8OrYOZSM9whlkNmVHOicJpsjgTzC+wn2JMJXhq1oO4kA4bJ5MsfzSIcC71aLDKzJ6gZpIxrqt3QTAQ==", + "requires": { + "has": "^1.0.3", + "object-is": "^1.0.2" + } + }, "errno": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", @@ -5905,11 +6084,26 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "function.prototype.name": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.2.tgz", + "integrity": "sha512-C8A+LlHBJjB2AdcRPorc5JvJ5VUoWlXdEHLOJdCI7kjHEtGTpHQUiqMvCIKUwIsGwZX2jZJy761AXsn356bJQg==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "functions-have-names": "^1.2.0" + } + }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" }, + "functions-have-names": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.1.tgz", + "integrity": "sha512-j48B/ZI7VKs3sgeI2cZp7WXWmZXu7Iq5pl5/vptV5N2mq+DGFuS/ulaDjtaoLpYzuD6u8UgrUKHfgo7fDTSiBA==" + }, "gensync": { "version": "1.0.0-beta.1", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", @@ -6268,6 +6462,14 @@ "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==" }, + "html-element-map": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/html-element-map/-/html-element-map-1.2.0.tgz", + "integrity": "sha512-0uXq8HsuG1v2TmQ8QkIhzbrqeskE4kn52Q18QJ9iAA/SnHoEKXWiUxHQtclRsCFWEUD2So34X+0+pZZu862nnw==", + "requires": { + "array-filter": "^1.0.0" + } + }, "html-encoding-sniffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", @@ -6700,6 +6902,11 @@ "binary-extensions": "^2.0.0" } }, + "is-boolean-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.0.1.tgz", + "integrity": "sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ==" + }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", @@ -6807,6 +7014,11 @@ "kind-of": "^3.0.2" } }, + "is-number-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", + "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==" + }, "is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", @@ -6884,6 +7096,11 @@ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==" }, + "is-subset": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz", + "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=" + }, "is-svg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", @@ -8325,6 +8542,21 @@ "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" }, + "lodash.escape": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz", + "integrity": "sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg=" + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -8756,6 +8988,11 @@ "minimist": "^1.2.5" } }, + "moo": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.1.tgz", + "integrity": "sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w==" + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -8829,6 +9066,25 @@ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" }, + "nearley": { + "version": "2.19.2", + "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.19.2.tgz", + "integrity": "sha512-h6lygT0BWAGErDvoE2LfI+tDeY2+UUrqG5dcBPdCmjnjud9z1wE0P7ljb85iNbE93YA+xJLpoSYGMuUqhnSSSA==", + "requires": { + "commander": "^2.19.0", + "moo": "^0.5.0", + "railroad-diagrams": "^1.0.0", + "randexp": "0.4.6", + "semver": "^5.4.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", @@ -10654,6 +10910,16 @@ "react-is": "^16.8.1" } }, + "prop-types-exact": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/prop-types-exact/-/prop-types-exact-1.2.0.tgz", + "integrity": "sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA==", + "requires": { + "has": "^1.0.3", + "object.assign": "^4.1.0", + "reflect.ownkeys": "^0.2.0" + } + }, "proxy-addr": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", @@ -10763,6 +11029,20 @@ "performance-now": "^2.1.0" } }, + "railroad-diagrams": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz", + "integrity": "sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=" + }, + "randexp": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz", + "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==", + "requires": { + "discontinuous-range": "1.0.0", + "ret": "~0.1.10" + } + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -11140,6 +11420,17 @@ "workbox-webpack-plugin": "4.3.1" } }, + "react-test-renderer": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.13.1.tgz", + "integrity": "sha512-Sn2VRyOK2YJJldOqoh8Tn/lWQ+ZiKhyZTPtaO0Q6yNj+QDbmRkVFap6pZPy3YQk8DScRDfyqm/KxKYP9gCMRiQ==", + "requires": { + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "react-is": "^16.8.6", + "scheduler": "^0.19.1" + } + }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -11242,6 +11533,11 @@ "strip-indent": "^3.0.0" } }, + "reflect.ownkeys": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz", + "integrity": "sha1-dJrO7H8/34tj+SegSAnpDFwLNGA=" + }, "regenerate": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", @@ -11615,6 +11911,15 @@ "inherits": "^2.0.1" } }, + "rst-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz", + "integrity": "sha1-gbIw6i/MYGbInjRy3nlChdmwPZE=", + "requires": { + "lodash.flattendeep": "^4.4.0", + "nearley": "^2.7.10" + } + }, "rsvp": { "version": "4.8.5", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", @@ -12531,6 +12836,16 @@ "side-channel": "^1.0.2" } }, + "string.prototype.trim": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.1.tgz", + "integrity": "sha512-MjGFEeqixw47dAMFMtgUro/I0+wNqZB5GKXGt1fFr24u3TzDXCPu7J9Buppzoe3r/LqkSDLDDJzE15RGWDGAVw==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1" + } + }, "string.prototype.trimend": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.0.tgz", diff --git a/package.json b/package.json index 8b404206..2b70bdb2 100644 --- a/package.json +++ b/package.json @@ -2,12 +2,15 @@ "name": "inspiration-board", "version": "0.1.0", "private": true, + "homepage": "https://dnguye3.github.io/inspiration-board/", "dependencies": { - "axios": "^0.19.2", - "emoji-dictionary": "^1.0.10", "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.3.2", "@testing-library/user-event": "^7.1.2", + "axios": "^0.19.2", + "emoji-dictionary": "^1.0.10", + "enzyme": "^3.11.0", + "enzyme-adapter-react-16": "^1.15.2", "react": "^16.13.1", "react-dom": "^16.13.1", "react-scripts": "3.4.1" @@ -16,6 +19,8 @@ "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", + "predeploy": "npm-run-build", + "deploy": "gh-pages -d build", "eject": "react-scripts eject" }, "eslintConfig": { diff --git a/src/App.js b/src/App.js index 60566602..faf0bb14 100644 --- a/src/App.js +++ b/src/App.js @@ -1,16 +1,19 @@ -import React from 'react'; -import './App.css'; -import Board from './components/Board'; +import React from "react"; +import "./App.css"; +import Board from "./components/Board"; + const App = () => { return (
-

Inspiration Board

+

+ Inspiration Board +

); diff --git a/src/components/Board.css b/src/components/Board.css index ba21589d..7b7840b6 100644 --- a/src/components/Board.css +++ b/src/components/Board.css @@ -1,6 +1,11 @@ .board { display: flex; flex-wrap: wrap; + /* centers board */ + margin-left: auto; + margin-right: auto; + align-items: center; + justify-content: center; } .validation-errors-display { diff --git a/src/components/Board.js b/src/components/Board.js index 698faaaa..84c5d552 100644 --- a/src/components/Board.js +++ b/src/components/Board.js @@ -1,21 +1,78 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import axios from 'axios'; +import React, { useState, useEffect } from "react"; +import PropTypes from "prop-types"; +import axios from "axios"; -import './Board.css'; -import Card from './Card'; -import NewCardForm from './NewCardForm'; -import CARD_DATA from '../data/card-data.json'; +import "./Board.css"; +import Card from "./Card"; +import NewCardForm from "./NewCardForm"; + +const Board = ({ url }) => { + const [cardList, setCardList] = useState([]); + const [errorMessage, setErrorMessage] = useState(null); + + const loadCards = () => { + axios + .get(url) + .then((response) => { + const apiCardList = response.data; + let cardCollection = apiCardList.map((item) => { + return ( + + ); + }); + setCardList(cardCollection); + }) + .catch((error) => { + const errorMessage = error.message; + setErrorMessage(errorMessage); + console.log(errorMessage); + }); + }; + + useEffect(() => {loadCards();}, []); + + const deleteCard = (id) => { + axios.delete(`https://inspiration-board.herokuapp.com/cards/${id}`) + .then((response) => { + loadCards(); + }) + .catch((error) => { + setErrorMessage(`Unable to delete card ${id}`); + }); + // } + }; + + const postCard = (cardObject) => { + axios + .post( + `https://inspiration-board.herokuapp.com/boards/Hala&Diana/cards`, + cardObject) + .then((response) => { + loadCards(); + }) + .catch((error) => { + setErrorMessage(`Unable to post card`); + }); + }; -const Board = () => { return ( -
- Board -
- ) +
+
+ {cardList} +
+
+ + ); }; -Board.propTypes = { +Board.propTypes = { + url: PropTypes.string }; export default Board; diff --git a/src/components/Board.test.js b/src/components/Board.test.js index e69de29b..14864ce4 100644 --- a/src/components/Board.test.js +++ b/src/components/Board.test.js @@ -0,0 +1,43 @@ +import React from 'react'; +import { render, cleanup } from '@testing-library/react' +import Board from './Board'; +import NewCardForm from './NewCardForm'; + +describe ('Board', () => { + // test('renders one card of off the Board', () => { + // const { getByText } = render(); + // const linkElement = getByText(/nap/i); + // expect(linkElement).toBeInTheDocument(); + // }); + + test('will render the NewCardForm properly', () => { + // Arrange-Act + const { asFragment } = render( + { }} + /> + ); + + // Assert + expect(asFragment()).toMatchSnapshot(); + }); +}) + + + + + + + + + + + + + + + + + + + diff --git a/src/components/Card.css b/src/components/Card.css index e86d4329..8346c24c 100644 --- a/src/components/Card.css +++ b/src/components/Card.css @@ -1,5 +1,24 @@ +.card__color-red { + background-color: #E75335; +} + +.card__color-yellow { + background-color: #FFD81B; +} + +.card__color-green { + background-color: #DCDA47; +} + +.card__color-blue { + background-color: #7CA5D1; +} + +.card__color-pink { + background-color: #DB73A4; +} + .card { - background-color: #F4FF81; padding: 1em 0; margin: 0.5rem; @@ -8,8 +27,6 @@ min-width: 225px; flex-basis: 18%; - border-radius: 5px; - display: grid; grid-template-columns: 1fr 5fr 1fr; align-items: center; @@ -17,6 +34,7 @@ .card__content { grid-column-start: 2; + font-family: 'Permanent Marker', Helvetica, sans-serif; display: flex; flex-direction: column; @@ -44,4 +62,109 @@ .card__delete { align-self: start; font-family: 'Permanent Marker', Helvetica, sans-serif; + background-color: black; + border: 1px solid black; + color: white; +} + +.card__delete:hover { + background-color: white; + border: 1px solid white; + color: black; +} + + +/* input text styling */ +/* source: https://codepen.io/chrisoncode/pen/IdGKH */ +/* form starting stylings ------------------------------- */ +.group { + position:relative; + margin-bottom:45px; +} +input { + font-size:18px; + padding:10px 10px 10px 5px; + display:block; + width:300px; + border:none; + border-bottom:1px solid #333; +} +input:focus { outline:none; } + +/* LABEL ======================================= */ +label { + color:#999; + font-size:18px; + font-weight:normal; + position:absolute; + pointer-events:none; + left:5px; + top:10px; + transition:0.2s ease all; + -moz-transition:0.2s ease all; + -webkit-transition:0.2s ease all; +} + +/* active state */ +input:focus ~ label, input:valid ~ label { + top:-20px; + font-size:14px; + color:#5264AE; +} + +/* BOTTOM BARS ================================= */ +.bar { position:relative; display:block; width:300px; } +.bar:before, .bar:after { + content:''; + height:2px; + width:0; + bottom:1px; + position:absolute; + background:#5264AE; + transition:0.2s ease all; + -moz-transition:0.2s ease all; + -webkit-transition:0.2s ease all; +} +.bar:before { + left:50%; +} +.bar:after { + right:50%; +} + +/* active state */ +input:focus ~ .bar:before, input:focus ~ .bar:after { + width:50%; +} + +/* HIGHLIGHTER ================================== */ +.highlight { + position:absolute; + height:60%; + width:100px; + top:25%; + left:0; + pointer-events:none; + opacity:0.5; +} + +/* active state */ +input:focus ~ .highlight { + -webkit-animation:inputHighlighter 0.3s ease; + -moz-animation:inputHighlighter 0.3s ease; + animation:inputHighlighter 0.3s ease; +} + +/* ANIMATIONS ================ */ +@-webkit-keyframes inputHighlighter { + from { background:#ffff88; } + to { width:0; background:transparent; } +} +@-moz-keyframes inputHighlighter { + from { background:#ffff88; } + to { width:0; background:transparent; } } +@keyframes inputHighlighter { + from { background:#ffff88; } + to { width:0; background:transparent; } +} \ No newline at end of file diff --git a/src/components/Card.js b/src/components/Card.js index 51a33966..018cb6c2 100644 --- a/src/components/Card.js +++ b/src/components/Card.js @@ -1,19 +1,35 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import emoji from 'emoji-dictionary'; +import React from "react"; +import PropTypes from "prop-types"; +import "./Card.css"; +import emojis from "emoji-dictionary"; -import './Card.css'; +const Card = ({ emoji, id, text, deleteCardCallback }) => { + // source to randomize a set of colors: https://stackoverflow.com/questions/27799125/random-color-on-different-divs/27799274 + let postItNoteColors = ["card__color-yellow", "card__color-red", "card__color-green", "card__color-blue", "card__color-pink"] -const Card = () => { return ( -
- Card +
+

{text}

+ + {emojis.getUnicode(`${emoji}`)} + +
- ) -} + ); +}; Card.propTypes = { - + id: PropTypes.number, + text: PropTypes.string, + emoji: PropTypes.string, + deleteCardCallback: PropTypes.func, }; export default Card; diff --git a/src/components/NewCardForm.css b/src/components/NewCardForm.css index d11b9ad4..965764c3 100644 --- a/src/components/NewCardForm.css +++ b/src/components/NewCardForm.css @@ -1,9 +1,11 @@ -/* The Modal (background) */ - .new-card-form { width: 50%; margin: auto; padding-bottom: 4rem; + margin-left: auto; + margin-right: auto; + align-items: center; + justify-content: center; } .new-card-form__header { @@ -14,27 +16,117 @@ .new-card-form__form { font-size: 1.5em; display: grid; - grid-template-columns: [labels] auto [controls] 1fr; + grid-template-columns: auto auto auto; grid-auto-flow: row; - grid-gap: .8em; -} - -.new-card-form__form-label { - grid-column: labels; - grid-row: auto; + grid-gap: 0.8em; } -.new-card-form__form-select, .new-card-form__form-textarea, .new-card-form__form-button { - font-family: 'Raleway', sans-serif; + font-family: "Raleway", sans-serif; font-size: 1.25em; - grid-column: controls; grid-row: auto; } +.new-card-form__form-select { + font-family: "Raleway", sans-serif; + font-size: 0.70em; + /* padding:10px 10px 10px 5px; */ + display:block; + width:200px; + height: auto; + border:none; + grid-row: auto; +} + + .new-card-form__form-button { - background-color: inherit; + background-color: black; border: 1px solid black; font-size: 1em; + font-family: 'Permanent Marker'; + color: white; + display: block; + height: auto; + padding:10px 10px 10px 5px; +} + +.new-card-form__form-button:hover { + background-color: white; + color: black; +} + +/* for "your message text input" */ +/* source: https://codepen.io/chrisoncode/pen/IdGKH */ +/* form starting stylings ------------------------------- */ +.group { + position:relative; + margin-bottom:45px; +} +input { + font-size:18px; + padding:10px 10px 10px 5px; + display:block; + width:300px; + border:none; + border-bottom:1px solid #333; +} +input:focus { outline:none; } + + +/* BOTTOM BARS ================================= */ +.bar { position:relative; display:block; width:300px; } +.bar:before, .bar:after { + content:''; + height:2px; + width:0; + bottom:1px; + position:absolute; + background:#5264AE; + transition:0.2s ease all; + -moz-transition:0.2s ease all; + -webkit-transition:0.2s ease all; +} +.bar:before { + left:50%; +} +.bar:after { + right:50%; +} + +/* active state */ +input:focus ~ .bar:before, input:focus ~ .bar:after { + width:50%; +} + +/* HIGHLIGHTER ================================== */ +.highlight { + position:absolute; + height:60%; + width:100px; + top:25%; + left:0; + pointer-events:none; + opacity:0.5; +} + +/* active state */ +input:focus ~ .highlight { + -webkit-animation:inputHighlighter 0.3s ease; + -moz-animation:inputHighlighter 0.3s ease; + animation:inputHighlighter 0.3s ease; +} + +/* ANIMATIONS ================ */ +@-webkit-keyframes inputHighlighter { + from { background:#ffff88; } + to { width:0; background:transparent; } +} +@-moz-keyframes inputHighlighter { + from { background:#ffff88; } + to { width:0; background:transparent; } } +@keyframes inputHighlighter { + from { background:#ffff88; } + to { width:0; background:transparent; } +} \ No newline at end of file diff --git a/src/components/NewCardForm.js b/src/components/NewCardForm.js index 47331423..70427aba 100644 --- a/src/components/NewCardForm.js +++ b/src/components/NewCardForm.js @@ -1,6 +1,81 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import emoji from 'emoji-dictionary'; -import './NewCardForm.css'; +import React, { useState } from "react"; +import PropTypes from "prop-types"; +import "./NewCardForm.css"; +import emojis from 'emoji-dictionary'; -const EMOJI_LIST = ["", "heart_eyes", "beer", "clap", "sparkling_heart", "heart_eyes_cat", "dog"] + +const EMOJI_LIST = ["", "heart_eyes", "beer", "clap", "sparkling_heart", "dog", "heart_eyes_cat"] + +const NewCardForm = ({addCardCallback}) => { + const [cardFields, setCardFields] = useState({ + text: "", + emoji: "", + }); + + const onInputChange = (event) => { + const newCardFields = { + ...cardFields, + }; + newCardFields[event.target.name] = event.target.value; + setCardFields(newCardFields); + }; + + const onFormSubmit = (event) => { + event.preventDefault(); + + addCardCallback(cardFields); + + setCardFields({ + text: "", + emoji: "", + }); + }; + + return ( +
+

Submit your own card~

+
+ {/* text input */} +
+ + + + +
+ {/* emoji */} + + + {/* submit */} + +
+
+ ); +}; + +NewCardForm.propTypes = { + addCardCallback: PropTypes.func +}; + +export default NewCardForm; diff --git a/src/components/__snapshots__/Board.test.js.snap b/src/components/__snapshots__/Board.test.js.snap new file mode 100644 index 00000000..1c3e95df --- /dev/null +++ b/src/components/__snapshots__/Board.test.js.snap @@ -0,0 +1,130 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Board will render properly 1`] = ` + +
+
+ Submit a card! +
+ + + + + +
+
+`; + +exports[`Board will render the NewCardForm properly 1`] = ` + +
+
+ Submit a card! +
+ + + + + +
+
+`; + +exports[`Board will render the add properly 1`] = ` + +
+
+ Submit a card! +
+ + + + + +
+
+`; diff --git a/src/components/test/Card.test.js b/src/components/test/Card.test.js new file mode 100644 index 00000000..18ca73ae --- /dev/null +++ b/src/components/test/Card.test.js @@ -0,0 +1,50 @@ +import React from 'react'; +import { render, cleanup } from '@testing-library/react' +import Card from '../Card'; + +describe('Card', () => { + test('that it matches the existing snapshot', () => { + // Arrange-Act + const { asFragment } = render( + { }} + /> + ) + // Assert + expect(asFragment()).toMatchSnapshot(); + cleanup(); + }); + + test('The "DeleteCardCallback" prop function is called when the `✨Take This Card✨` button is clicked on', () => { + + // Arrange + // Create a mock callback function + const takeThisCard = jest.fn(); + + // Render card + const container = render( + + ); + + // Act + // Find the Mark Absent Button + const button = container.getByText(/✨ Take this card ✨/i); + + // Trigger a click event + button.click(); + + // Assert + // Verify that the callback function was called + expect(takeThisCard).toHaveBeenCalled(); + }); +}); \ No newline at end of file diff --git a/src/components/test/NewCardForm.test.js b/src/components/test/NewCardForm.test.js new file mode 100644 index 00000000..d75f2bc6 --- /dev/null +++ b/src/components/test/NewCardForm.test.js @@ -0,0 +1,19 @@ +import React from 'react'; +import { render, cleanup, fireEvent, getByTestId } from '@testing-library/react'; +import NewCardForm from '../NewCardForm'; + +describe('NewCardForm', () => { + test('that it matches the existing snapshot', () => { + // Arrange-Act + const { asFragment } = render( + { }} + /> + ); + + // Assert + expect(asFragment()).toMatchSnapshot(); + cleanup(); + }); + +}); \ No newline at end of file diff --git a/src/components/test/__snapshots__/Card.test.js.snap b/src/components/test/__snapshots__/Card.test.js.snap new file mode 100644 index 00000000..a9464bb7 --- /dev/null +++ b/src/components/test/__snapshots__/Card.test.js.snap @@ -0,0 +1,25 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Card that it matches the existing snapshot 1`] = ` + +
+

+ Are you a git repository? Because I would commit to you. +

+ + 🌌 + + +
+
+`; diff --git a/src/components/test/__snapshots__/NewCardForm.test.js.snap b/src/components/test/__snapshots__/NewCardForm.test.js.snap new file mode 100644 index 00000000..94f28f9b --- /dev/null +++ b/src/components/test/__snapshots__/NewCardForm.test.js.snap @@ -0,0 +1,44 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`NewCardForm that it matches the existing snapshot 1`] = ` + +
+
+ Submit a card! +
+ + + + + +
+
+`;