From cf4af9e0e0e5b39af3a97efaa97535fcc77e48d4 Mon Sep 17 00:00:00 2001 From: Himanshu Kulshrestha Date: Fri, 3 May 2024 00:18:12 +0530 Subject: [PATCH] done --- package-lock.json | 347 ++++++++++++++++++++++++++++++---- package.json | 3 + src/App.js | 43 ++--- src/components/Beer.js | 81 ++++++++ src/components/Beers.css | 43 +++++ src/components/Header.js | 14 ++ src/components/HomePage.css | 92 +++++++++ src/components/HomePage.js | 34 ++++ src/components/NewBeerForm.js | 59 ++++++ src/components/RandomBeer.js | 39 ++++ src/components/SingleBeer.js | 93 +++++++++ 11 files changed, 794 insertions(+), 54 deletions(-) create mode 100644 src/components/Beer.js create mode 100644 src/components/Beers.css create mode 100644 src/components/Header.js create mode 100644 src/components/HomePage.css create mode 100644 src/components/HomePage.js create mode 100644 src/components/NewBeerForm.js create mode 100644 src/components/RandomBeer.js create mode 100644 src/components/SingleBeer.js diff --git a/package-lock.json b/package-lock.json index 3c65e57..350d939 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,9 +11,12 @@ "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "axios": "^1.6.8", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-router-dom": "^6.23.0", "react-scripts": "5.0.1", + "styled-components": "^6.1.9", "web-vitals": "^2.1.4" } }, @@ -2132,6 +2135,24 @@ "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, "node_modules/@eslint/eslintrc": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", @@ -3085,6 +3106,14 @@ } } }, + "node_modules/@remix-run/router": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.0.tgz", + "integrity": "sha512-Quz1KOffeEf/zwkCBM3kBtH4ZoZ+pT3xIXBG4PPW/XFtDP7EGhtTiC2+gpL9GnR7+Qdet5Oa6cYSvwKYg6kN9Q==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -4145,6 +4174,11 @@ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" }, + "node_modules/@types/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw==" + }, "node_modules/@types/testing-library__jest-dom": { "version": "5.14.5", "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.5.tgz", @@ -4951,6 +4985,29 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axios/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -5484,6 +5541,14 @@ "node": ">= 6" } }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -5906,6 +5971,14 @@ "postcss": "^8.4" } }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "engines": { + "node": ">=4" + } + }, "node_modules/css-declaration-sorter": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", @@ -6087,6 +6160,16 @@ "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, "node_modules/css-tree": { "version": "1.0.0-alpha.37", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", @@ -6274,9 +6357,9 @@ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" }, "node_modules/csstype": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -7907,9 +7990,9 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" }, "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "funding": [ { "type": "individual", @@ -11771,9 +11854,15 @@ } }, "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -12394,9 +12483,9 @@ } }, "node_modules/postcss": { - "version": "8.4.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", - "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "funding": [ { "type": "opencollective", @@ -12405,10 +12494,14 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -13669,6 +13762,11 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -13971,6 +14069,36 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.0.tgz", + "integrity": "sha512-wPMZ8S2TuPadH0sF5irFGjkNLIcRvOSaEe7v+JER8508dyJumm6XZB1u5kztlX0RVq6AzRVndzqcUh6sFIauzA==", + "dependencies": { + "@remix-run/router": "1.16.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.0.tgz", + "integrity": "sha512-Q9YaSYvubwgbal2c9DJKfx6hTNoBp3iJDsl+Duva/DwxoJH+OTXkxGpql4iUK2sla/8z4RpjAm6EWx1qUDuopQ==", + "dependencies": { + "@remix-run/router": "1.16.0", + "react-router": "6.23.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/react-scripts": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", @@ -14759,6 +14887,11 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -15133,6 +15266,33 @@ "webpack": "^5.0.0" } }, + "node_modules/styled-components": { + "version": "6.1.9", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.9.tgz", + "integrity": "sha512-aBOqs0uMsYufFXSE4q6cA6Ty1fwZuMk4BJRHfiGSna59F1otnxiDelwhN4fEwmBtIymmF0ZqXHnpSigr2ps9Cg==", + "dependencies": { + "@emotion/is-prop-valid": "1.2.1", + "@emotion/unitless": "0.8.1", + "@types/stylis": "4.2.0", + "css-to-react-native": "3.2.0", + "csstype": "3.1.2", + "postcss": "8.4.31", + "shallowequal": "1.1.0", + "stylis": "4.3.1", + "tslib": "2.5.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0" + } + }, "node_modules/stylehacks": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.0.tgz", @@ -15148,6 +15308,11 @@ "postcss": "^8.2.15" } }, + "node_modules/stylis": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.1.tgz", + "integrity": "sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==" + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -15578,9 +15743,9 @@ } }, "node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" }, "node_modules/tsutils": { "version": "3.21.0", @@ -18147,6 +18312,24 @@ "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==", "requires": {} }, + "@emotion/is-prop-valid": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", + "requires": { + "@emotion/memoize": "^0.8.1" + } + }, + "@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, "@eslint/eslintrc": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", @@ -18835,6 +19018,11 @@ "source-map": "^0.7.3" } }, + "@remix-run/router": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.0.tgz", + "integrity": "sha512-Quz1KOffeEf/zwkCBM3kBtH4ZoZ+pT3xIXBG4PPW/XFtDP7EGhtTiC2+gpL9GnR7+Qdet5Oa6cYSvwKYg6kN9Q==" + }, "@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -19649,6 +19837,11 @@ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" }, + "@types/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw==" + }, "@types/testing-library__jest-dom": { "version": "5.14.5", "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.5.tgz", @@ -20227,6 +20420,28 @@ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.3.tgz", "integrity": "sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w==" }, + "axios": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "requires": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + }, + "dependencies": { + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } + }, "axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -20632,6 +20847,11 @@ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==" }, + "camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==" + }, "caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -20952,6 +21172,11 @@ "postcss-selector-parser": "^6.0.9" } }, + "css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==" + }, "css-declaration-sorter": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", @@ -21059,6 +21284,16 @@ "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" }, + "css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "requires": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, "css-tree": { "version": "1.0.0-alpha.37", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", @@ -21197,9 +21432,9 @@ } }, "csstype": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, "damerau-levenshtein": { "version": "1.0.8", @@ -22414,9 +22649,9 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" }, "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" }, "fork-ts-checker-webpack-plugin": { "version": "6.5.2", @@ -25185,9 +25420,9 @@ } }, "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==" }, "natural-compare": { "version": "1.4.0", @@ -25626,11 +25861,11 @@ } }, "postcss": { - "version": "8.4.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", - "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "requires": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } @@ -26369,6 +26604,11 @@ } } }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -26585,6 +26825,23 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==" }, + "react-router": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.0.tgz", + "integrity": "sha512-wPMZ8S2TuPadH0sF5irFGjkNLIcRvOSaEe7v+JER8508dyJumm6XZB1u5kztlX0RVq6AzRVndzqcUh6sFIauzA==", + "requires": { + "@remix-run/router": "1.16.0" + } + }, + "react-router-dom": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.0.tgz", + "integrity": "sha512-Q9YaSYvubwgbal2c9DJKfx6hTNoBp3iJDsl+Duva/DwxoJH+OTXkxGpql4iUK2sla/8z4RpjAm6EWx1qUDuopQ==", + "requires": { + "@remix-run/router": "1.16.0", + "react-router": "6.23.0" + } + }, "react-scripts": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", @@ -27155,6 +27412,11 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, + "shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -27440,6 +27702,22 @@ "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", "requires": {} }, + "styled-components": { + "version": "6.1.9", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.9.tgz", + "integrity": "sha512-aBOqs0uMsYufFXSE4q6cA6Ty1fwZuMk4BJRHfiGSna59F1otnxiDelwhN4fEwmBtIymmF0ZqXHnpSigr2ps9Cg==", + "requires": { + "@emotion/is-prop-valid": "1.2.1", + "@emotion/unitless": "0.8.1", + "@types/stylis": "4.2.0", + "css-to-react-native": "3.2.0", + "csstype": "3.1.2", + "postcss": "8.4.31", + "shallowequal": "1.1.0", + "stylis": "4.3.1", + "tslib": "2.5.0" + } + }, "stylehacks": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.0.tgz", @@ -27449,6 +27727,11 @@ "postcss-selector-parser": "^6.0.4" } }, + "stylis": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.1.tgz", + "integrity": "sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==" + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -27776,9 +28059,9 @@ } }, "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" }, "tsutils": { "version": "3.21.0", diff --git a/package.json b/package.json index 022d9bf..d3eb554 100644 --- a/package.json +++ b/package.json @@ -6,9 +6,12 @@ "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "axios": "^1.6.8", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-router-dom": "^6.23.0", "react-scripts": "5.0.1", + "styled-components": "^6.1.9", "web-vitals": "^2.1.4" }, "scripts": { diff --git a/src/App.js b/src/App.js index 3784575..bbcd173 100644 --- a/src/App.js +++ b/src/App.js @@ -1,25 +1,24 @@ -import logo from './logo.svg'; -import './App.css'; +import React from 'react'; +import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; +import HomePage from './components/HomePage'; +import Beers from './components/Beer'; +import SingleBeer from './components/SingleBeer'; +import RandomBeer from './components/RandomBeer'; +import NewBeerForm from './components/NewBeerForm'; +// Import other components function App() { - return ( -
-
- logo -

- Edit src/App.js and save to reload. -

- - Learn React - -
-
- ); -} + return ( + + + }/> + } /> + } /> + } /> + } /> + + + ); + } -export default App; + export default App; \ No newline at end of file diff --git a/src/components/Beer.js b/src/components/Beer.js new file mode 100644 index 0000000..c448f01 --- /dev/null +++ b/src/components/Beer.js @@ -0,0 +1,81 @@ + +import './Beers.css'; +import Header from './Header'; +import React, { useState, useEffect } from 'react'; +import styled from 'styled-components'; + +// Styled components +const Container = styled.div` + padding: 20px; + display: flex; + flex-direction: column; + align-items: center; +`; + +const SearchInput = styled.input` + padding: 10px; + margin: 20px 0; + width: 300px; + font-size: 16px; + border: 2px solid #ccc; + border-radius: 5px; +`; + +const BeerList = styled.div` + display: flex; + flex-direction: column; + width: 100%; + align-items: center; +`; + +const BeerItem = styled.div` + background: #f0f0f0; + border-radius: 8px; + padding: 10px; + margin: 10px 0; + width: 80%; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); +`; + +function Beers() { + const [query, setQuery] = useState(''); + const [beers, setBeers] = useState([]); + + useEffect(() => { + if (query.length > 0) { + fetch(`https://ih-beers-api2.herokuapp.com/beers/search?q=${query}`) + .then(response => response.json()) + .then(data => setBeers(data)) + .catch(error => console.error('Error fetching data: ', error)); + } + }, [query]); + + return ( + +
+ setQuery(e.target.value)} + /> + + {beers.map(beer => ( + +
+

{beer.name}

+

{beer.tagline}

+

Contributed by: {beer.contributed_by}

+ View Details +
+
+ {beer.name} +
+
+ ))} +
+ + ); +} + +export default Beers; \ No newline at end of file diff --git a/src/components/Beers.css b/src/components/Beers.css new file mode 100644 index 0000000..e48e939 --- /dev/null +++ b/src/components/Beers.css @@ -0,0 +1,43 @@ +.beersContainer { + padding: 20px; + } + + .beerItem { + display: flex; + align-items: center; + margin-bottom: 20px; + border: 1px solid #ccc; + padding: 10px; + border-radius: 8px; + } + + .beerImage { + height: 150px; + margin-right: 20px; + border-radius: 4px; + } + + .beerDetails { + flex: 1; + } + + .beerName { + margin: 0 0 10px 0; + } + + .beerTagline { + margin: 0 0 10px 0; + font-style: italic; + } + + .beerContributor { + margin: 0; + } + + .beerLink { + margin-top: 10px; + display: inline-block; + text-decoration: none; + color: #007BFF; + font-weight: bold; + } \ No newline at end of file diff --git a/src/components/Header.js b/src/components/Header.js new file mode 100644 index 0000000..7622dab --- /dev/null +++ b/src/components/Header.js @@ -0,0 +1,14 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; + +function Header() { + return ( +
+ + Home + +
+ ); +} + +export default Header; \ No newline at end of file diff --git a/src/components/HomePage.css b/src/components/HomePage.css new file mode 100644 index 0000000..d98417e --- /dev/null +++ b/src/components/HomePage.css @@ -0,0 +1,92 @@ +.home-container { + display: flex; + flex-direction: column; + justify-content: space-around; + flex-wrap: wrap; + padding: 20px; + gap: 20px; /* Ensures spacing between items */ +} + +.beer-item { + flex: 1 1 300px; /* Flex grow, flex shrink, flex basis */ + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + background-color: #f9f9f9; /* Light grey background */ + border-radius: 8px; /* Rounded corners for the beer items */ + padding: 20px; + box-shadow: 0 2px 5px rgba(0,0,0,0.1); /* Subtle shadow for depth */ +} + +.beer-image { + width: 50vw; + height: auto; + margin-bottom: 10px; +} + +.beer-item p { + margin: 10px 0; + color: #333; /* Dark grey text */ + font-size: 16px; /* Readable font size */ +} + +.beer-item a { + text-decoration: none; + color: #0077cc; /* Link color */ + font-weight: bold; + padding: 10px 20px; + border: 2px solid #0077cc; /* Border matching the text color */ + border-radius: 5px; /* Rounded corners for the link */ + transition: background-color 0.3s, color 0.3s; /* Smooth transition for hover effects */ +} + +.beer-item a:hover { + background-color: #0077cc; /* Background color on hover */ + color: white; /* Text color on hover */ +} + +@media (max-width: 768px) { + .home-container { + flex-direction: column; + align-items: center; + } + + .beer-item { + width: 90%; /* Full width on smaller screens */ + } +} +.NewBeerForm { + display: flex; + flex-direction: column; + align-items: center; + margin: 20px; + padding: 20px; + border: 1px solid #ccc; + border-radius: 8px; + background-color: #f9f9f9; +} + +.NewBeerForm input[type="text"], +.NewBeerForm input[type="number"] { + width: 80%; + padding: 10px; + margin: 10px 0; + border: 1px solid #ddd; + border-radius: 4px; +} + +.NewBeerForm button { + width: 50%; + padding: 10px; + background-color: #4CAF50; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 16px; +} + +.NewBeerForm button:hover { + background-color: #45a049; +} \ No newline at end of file diff --git a/src/components/HomePage.js b/src/components/HomePage.js new file mode 100644 index 0000000..ce26d88 --- /dev/null +++ b/src/components/HomePage.js @@ -0,0 +1,34 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; +import beerImage1 from '../assets/beers.png'; +import beerImage2 from '../assets/new-beer.png'; +import beerImage3 from '../assets/random-beer.png'; +import './HomePage.css'; + +function HomePage() { + return ( +
+
+

Our Beers

+

Explore a wide variety of beers from around the world.

+
+
+ Beer 1 +

Discover our finest selection of craft beers.

+ Explore All Beers +
+
+ Beer 2 +

Feeling adventurous? Try a random beer!

+ Get a Random Beer +
+
+ Beer 3 +

Have a unique recipe? Add your own beer to our collection.

+ Create New Beer +
+
+ ); +} + +export default HomePage; \ No newline at end of file diff --git a/src/components/NewBeerForm.js b/src/components/NewBeerForm.js new file mode 100644 index 0000000..810c87f --- /dev/null +++ b/src/components/NewBeerForm.js @@ -0,0 +1,59 @@ +import React, { useState } from 'react'; +import axios from 'axios'; +import './HomePage.css' +function NewBeerForm() { + const [formData, setFormData] = useState({ + name: '', + tagline: '', + description: '', + first_brewed: '', + brewers_tips: '', + attenuation_level: 0, + contributed_by: '' + }); + + const handleChange = (e) => { + const { name, value } = e.target; + setFormData(prevState => ({ + ...prevState, + [name]: name === 'attenuation_level' ? Number(value) : value + })); + }; + + const handleSubmit = async (e) => { + e.preventDefault(); + try { + const response = await axios.post('https://ih-beers-api2.herokuapp.com/beers/new', formData); + if (response.status === 200) { + alert('New beer successfully saved to database!'); + setFormData({ + name: '', + tagline: '', + description: '', + first_brewed: '', + brewers_tips: '', + attenuation_level: 0, + contributed_by: '' + }); + } + } catch (error) { + alert('Failed to save the beer. Error: ' + error.response.data.message); + } + }; + + return ( +
+

Add a new Beer

+ + + + + + + + +
+ ); +} + +export default NewBeerForm; \ No newline at end of file diff --git a/src/components/RandomBeer.js b/src/components/RandomBeer.js new file mode 100644 index 0000000..1303373 --- /dev/null +++ b/src/components/RandomBeer.js @@ -0,0 +1,39 @@ +import React, { useState, useEffect } from 'react'; +import axios from 'axios'; +import Header from './Header'; +function RandomBeer() { + const [beer, setBeer] = useState(null); + + useEffect(() => { + const fetchRandomBeer = async () => { + try { + const response = await axios.get('https://ih-beers-api2.herokuapp.com/beers/random'); + setBeer(response.data); + } catch (error) { + console.error('Error fetching random beer:', error); + } + }; + + fetchRandomBeer(); + }, []); + + if (!beer) { + return
Loading...
; + } + + return (<> +
+
+ {beer.name} +

{beer.name}

+

{beer.tagline}

+

First Brewed: {beer.first_brewed}

+

Attenuation Level: {beer.attenuation_level}

+

{beer.description}

+

Contributed by: {beer.contributed_by}

+
+ + ); +} + +export default RandomBeer; \ No newline at end of file diff --git a/src/components/SingleBeer.js b/src/components/SingleBeer.js new file mode 100644 index 0000000..57a570d --- /dev/null +++ b/src/components/SingleBeer.js @@ -0,0 +1,93 @@ +import React, { useState, useEffect } from 'react'; +import { useParams } from 'react-router-dom'; +import axios from 'axios'; +import Header from './Header'; +function SingleBeer() { + const [beer, setBeer] = useState(null); + const { beerId } = useParams(); + + useEffect(() => { + const fetchBeer = async () => { + try { + const response = await axios.get(`https://ih-beers-api2.herokuapp.com/beers/${beerId}`); + setBeer(response.data); + } catch (error) { + console.error("Error fetching beer details:", error); + } + }; + + fetchBeer(); + }, [beerId]); + + if (!beer) { + return
Loading...
; + } + + return (<> +
+
+ + {beer.name} +
+

{beer.name}

+

{beer.tagline}

+

First Brewed: {beer.first_brewed}

+

Attenuation Level: {beer.attenuation_level}

+

{beer.description}

+

Contributed by: {beer.contributed_by}

+
+
+ + ); +} + +const styles = { + container: { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + margin: '0', + padding: '20px', + boxShadow: '0 4px 8px rgba(0,0,0,0.1)', + borderRadius: '10px', + backgroundColor: '#fff' + }, + image: { + margin:'10px', + height: '300px', + borderRadius: '10px' + }, + infoContainer: { + textAlign: 'center' + }, + name: { + color: '#003366' + }, + tagline: { + color: '#0077CC' + }, + detail: { + color: '#555', + fontSize: '16px' + }, + description: { + marginTop: '10px', + fontSize: '14px', + color: '#666', + textAlign: 'justify' + }, + contributed: { + fontStyle: 'italic', + fontSize: '12px' + }, + Header: { + display: 'flex', + justifyContent:'space-between', + alignItems: 'center', + width: '100%', + backgroundColor: '#003366', + color: '#fff' + } +}; + +export default SingleBeer; \ No newline at end of file