diff --git a/backend/models/user.js b/backend/models/user.js index 5f9c41a9f..6745aaed6 100644 --- a/backend/models/user.js +++ b/backend/models/user.js @@ -10,6 +10,7 @@ const userSchema = new mongoose.Schema({ password: { type: String, required: true }, role: { type: String, required: true, enum: ["admin", "customer"]}, balance: { type: mongoose.Schema.Types.Decimal128, required: false }, + }); userSchema.methods.generateAuthToken = function () { diff --git a/client/package-lock.json b/client/package-lock.json index 1bf2003d1..6acdc0fac 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -8,10 +8,10 @@ "name": "client", "version": "0.1.0", "dependencies": { - "@emotion/react": "^11.10.5", - "@emotion/styled": "^11.10.5", + "@emotion/react": "^11.10.6", + "@emotion/styled": "^11.10.6", "@mui/icons-material": "^5.11.0", - "@mui/material": "^5.11.6", + "@mui/material": "^5.11.10", "@mui/styled-engine": "^5.11.0", "@mui/styled-engine-sc": "^5.11.0", "@testing-library/jest-dom": "^5.16.5", @@ -29,6 +29,8 @@ "react-router-dom": "^6.6.1", "react-scripts": "5.0.1", "react-stars": "^2.2.5", + "react-use-cart": "^1.13.0", + "reactjs-popup": "^2.0.5", "styled-components": "^5.3.6", "sweetalert2": "^11.7.1", "web-vitals": "^2.1.4" @@ -1814,9 +1816,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.7.tgz", - "integrity": "sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz", + "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==", "dependencies": { "regenerator-runtime": "^0.13.11" }, @@ -2275,12 +2277,11 @@ } }, "node_modules/@emotion/babel-plugin": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz", - "integrity": "sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA==", + "version": "11.10.6", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.6.tgz", + "integrity": "sha512-p2dAqtVrkhSa7xz1u/m9eHYdLi+en8NowrmXeF/dKtJpU8lCWli8RUAati7NcSl0afsBott48pdnANuD0wh9QQ==", "dependencies": { "@babel/helper-module-imports": "^7.16.7", - "@babel/plugin-syntax-jsx": "^7.17.12", "@babel/runtime": "^7.18.3", "@emotion/hash": "^0.9.0", "@emotion/memoize": "^0.8.0", @@ -2291,9 +2292,6 @@ "find-root": "^1.1.0", "source-map": "^0.5.7", "stylis": "4.1.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { @@ -2346,12 +2344,12 @@ "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" }, "node_modules/@emotion/react": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.5.tgz", - "integrity": "sha512-TZs6235tCJ/7iF6/rvTaOH4oxQg2gMAcdHemjwLKIjKz4rRuYe1HJ2TQJKnAcRAfOUDdU8XoDadCe1rl72iv8A==", + "version": "11.10.6", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.6.tgz", + "integrity": "sha512-6HT8jBmcSkfzO7mc+N1L9uwvOnlcGoix8Zn7srt+9ga0MjREo6lRpuVX0kzo6Jp6oTqDhREOFsygN6Ew4fEQbw==", "dependencies": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.5", + "@emotion/babel-plugin": "^11.10.6", "@emotion/cache": "^11.10.5", "@emotion/serialize": "^1.1.1", "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", @@ -2360,13 +2358,9 @@ "hoist-non-react-statics": "^3.3.1" }, "peerDependencies": { - "@babel/core": "^7.0.0", "react": ">=16.8.0" }, "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, "@types/react": { "optional": true } @@ -2395,26 +2389,22 @@ "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==" }, "node_modules/@emotion/styled": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.5.tgz", - "integrity": "sha512-8EP6dD7dMkdku2foLoruPCNkRevzdcBaY6q0l0OsbyJK+x8D9HWjX27ARiSIKNF634hY9Zdoedh8bJCiva8yZw==", + "version": "11.10.6", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.6.tgz", + "integrity": "sha512-OXtBzOmDSJo5Q0AFemHCfl+bUueT8BIcPSxu0EGTpGk6DmI5dnhSzQANm1e1ze0YZL7TDyAyy6s/b/zmGOS3Og==", "dependencies": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.5", + "@emotion/babel-plugin": "^11.10.6", "@emotion/is-prop-valid": "^1.2.0", "@emotion/serialize": "^1.1.1", "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", "@emotion/utils": "^1.2.0" }, "peerDependencies": { - "@babel/core": "^7.0.0", "@emotion/react": "^11.0.0-rc.0", "react": ">=16.8.0" }, "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, "@types/react": { "optional": true } @@ -3337,14 +3327,14 @@ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, "node_modules/@mui/base": { - "version": "5.0.0-alpha.115", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.115.tgz", - "integrity": "sha512-OGQ84whT/yNYd6xKCGGS6MxqEfjVjk5esXM7HP6bB2Rim7QICUapxZt4nm8q39fpT08rNDkv3xPVqDDwRdRg1g==", + "version": "5.0.0-alpha.118", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.118.tgz", + "integrity": "sha512-GAEpqhnuHjRaAZLdxFNuOf2GDTp9sUawM46oHZV4VnYPFjXJDkIYFWfIQLONb0nga92OiqS5DD/scGzVKCL0Mw==", "dependencies": { - "@babel/runtime": "^7.20.7", + "@babel/runtime": "^7.20.13", "@emotion/is-prop-valid": "^1.2.0", "@mui/types": "^7.2.3", - "@mui/utils": "^5.11.2", + "@mui/utils": "^5.11.9", "@popperjs/core": "^2.11.6", "clsx": "^1.2.1", "prop-types": "^15.8.1", @@ -3374,9 +3364,9 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.11.6", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.6.tgz", - "integrity": "sha512-lbD3qdafBOf2dlqKhOcVRxaPAujX+9UlPC6v8iMugMeAXe0TCgU3QbGXY3zrJsu6ex64WYDpH4y1+WOOBmWMuA==", + "version": "5.11.9", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.9.tgz", + "integrity": "sha512-YGEtucQ/Nl91VZkzYaLad47Cdui51n/hW+OQm4210g4N3/nZzBxmGeKfubEalf+ShKH4aYDS86XTO6q/TpZnjQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui" @@ -3408,16 +3398,16 @@ } }, "node_modules/@mui/material": { - "version": "5.11.6", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.6.tgz", - "integrity": "sha512-MzkkL5KC2PCkFiv8cLpkzgLUPXSrAtnvJBR0emV7mLVWbkwV3n5832vjBx154B6R032fHjFTziTh7YEb50nK6Q==", - "dependencies": { - "@babel/runtime": "^7.20.7", - "@mui/base": "5.0.0-alpha.115", - "@mui/core-downloads-tracker": "^5.11.6", - "@mui/system": "^5.11.5", + "version": "5.11.10", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.10.tgz", + "integrity": "sha512-hs1WErbiedqlJIZsljgoil908x4NMp8Lfk8di+5c7o809roqKcFTg2+k3z5ucKvs29AXcsdXrDB/kn2K6dGYIw==", + "dependencies": { + "@babel/runtime": "^7.20.13", + "@mui/base": "5.0.0-alpha.118", + "@mui/core-downloads-tracker": "^5.11.9", + "@mui/system": "^5.11.9", "@mui/types": "^7.2.3", - "@mui/utils": "^5.11.2", + "@mui/utils": "^5.11.9", "@types/react-transition-group": "^4.4.5", "clsx": "^1.2.1", "csstype": "^3.1.1", @@ -3457,12 +3447,12 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "node_modules/@mui/private-theming": { - "version": "5.11.2", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.2.tgz", - "integrity": "sha512-qZwMaqRFPwlYmqwVKblKBGKtIjJRAj3nsvX93pOmatsXyorW7N/0IPE/swPgz1VwChXhHO75DwBEx8tB+aRMNg==", + "version": "5.11.9", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.9.tgz", + "integrity": "sha512-XMyVIFGomVCmCm92EvYlgq3zrC9K+J6r7IKl/rBJT2/xVYoRY6uM7jeB+Wxh7kXxnW9Dbqsr2yL3cx6wSD1sAg==", "dependencies": { - "@babel/runtime": "^7.20.7", - "@mui/utils": "^5.11.2", + "@babel/runtime": "^7.20.13", + "@mui/utils": "^5.11.9", "prop-types": "^15.8.1" }, "engines": { @@ -3483,11 +3473,11 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.0.tgz", - "integrity": "sha512-AF06K60Zc58qf0f7X+Y/QjaHaZq16znliLnGc9iVrV/+s8Ln/FCoeNuFvhlCbZZQ5WQcJvcy59zp0nXrklGGPQ==", + "version": "5.11.9", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.9.tgz", + "integrity": "sha512-bkh2CjHKOMy98HyOc8wQXEZvhOmDa/bhxMUekFX5IG0/w4f5HJ8R6+K6nakUUYNEgjOWPYzNPrvGB8EcGbhahQ==", "dependencies": { - "@babel/runtime": "^7.20.6", + "@babel/runtime": "^7.20.13", "@emotion/cache": "^11.10.5", "csstype": "^3.1.1", "prop-types": "^15.8.1" @@ -3539,15 +3529,15 @@ } }, "node_modules/@mui/system": { - "version": "5.11.5", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.5.tgz", - "integrity": "sha512-KNVsJ0sgRRp2XBqhh4wPS5aacteqjwxgiYTVwVnll2fgkgunZKo3DsDiGMrFlCg25ZHA3Ax58txWGE9w58zp0w==", + "version": "5.11.9", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.9.tgz", + "integrity": "sha512-h6uarf+l3FO6l75Nf7yO+qDGrIoa1DM9nAMCUFZQsNCDKOInRzcptnm8M1w/Z3gVetfeeGoIGAYuYKbft6KZZA==", "dependencies": { - "@babel/runtime": "^7.20.7", - "@mui/private-theming": "^5.11.2", - "@mui/styled-engine": "^5.11.0", + "@babel/runtime": "^7.20.13", + "@mui/private-theming": "^5.11.9", + "@mui/styled-engine": "^5.11.9", "@mui/types": "^7.2.3", - "@mui/utils": "^5.11.2", + "@mui/utils": "^5.11.9", "clsx": "^1.2.1", "csstype": "^3.1.1", "prop-types": "^15.8.1" @@ -3591,11 +3581,11 @@ } }, "node_modules/@mui/utils": { - "version": "5.11.2", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.2.tgz", - "integrity": "sha512-AyizuHHlGdAtH5hOOXBW3kriuIwUIKUIgg0P7LzMvzf6jPhoQbENYqY6zJqfoZ7fAWMNNYT8mgN5EftNGzwE2w==", + "version": "5.11.9", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.9.tgz", + "integrity": "sha512-eOJaqzcEs4qEwolcvFAmXGpln+uvouvOS9FUX6Wkrte+4I8rZbjODOBDVNlK+V6/ziTfD4iNKC0G+KfOTApbqg==", "dependencies": { - "@babel/runtime": "^7.20.7", + "@babel/runtime": "^7.20.13", "@types/prop-types": "^15.7.5", "@types/react-is": "^16.7.1 || ^17.0.0", "prop-types": "^15.8.1", @@ -26399,6 +26389,29 @@ "react-dom": ">=16.6.0" } }, + "node_modules/react-use-cart": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/react-use-cart/-/react-use-cart-1.13.0.tgz", + "integrity": "sha512-V3jrNOgBXxTn/RWh1HCEdrQk/jx2xCixdkX1c7Vyl4zxEf9jOuniUnjZSTALO7rQ5226onqmvXxKz1eu0Yz6Iw==", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16" + } + }, + "node_modules/reactjs-popup": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/reactjs-popup/-/reactjs-popup-2.0.5.tgz", + "integrity": "sha512-b5hv9a6aGsHEHXFAgPO5s1Jw1eSkopueyUVxQewGdLgqk2eW0IVXZrPRpHR629YcgIpC2oxtX8OOZ8a7bQJbxA==", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -32403,9 +32416,9 @@ } }, "@babel/runtime": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.7.tgz", - "integrity": "sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz", + "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==", "requires": { "regenerator-runtime": "^0.13.11" } @@ -32681,12 +32694,11 @@ } }, "@emotion/babel-plugin": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz", - "integrity": "sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA==", + "version": "11.10.6", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.6.tgz", + "integrity": "sha512-p2dAqtVrkhSa7xz1u/m9eHYdLi+en8NowrmXeF/dKtJpU8lCWli8RUAati7NcSl0afsBott48pdnANuD0wh9QQ==", "requires": { "@babel/helper-module-imports": "^7.16.7", - "@babel/plugin-syntax-jsx": "^7.17.12", "@babel/runtime": "^7.18.3", "@emotion/hash": "^0.9.0", "@emotion/memoize": "^0.8.0", @@ -32742,12 +32754,12 @@ "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" }, "@emotion/react": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.5.tgz", - "integrity": "sha512-TZs6235tCJ/7iF6/rvTaOH4oxQg2gMAcdHemjwLKIjKz4rRuYe1HJ2TQJKnAcRAfOUDdU8XoDadCe1rl72iv8A==", + "version": "11.10.6", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.6.tgz", + "integrity": "sha512-6HT8jBmcSkfzO7mc+N1L9uwvOnlcGoix8Zn7srt+9ga0MjREo6lRpuVX0kzo6Jp6oTqDhREOFsygN6Ew4fEQbw==", "requires": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.5", + "@emotion/babel-plugin": "^11.10.6", "@emotion/cache": "^11.10.5", "@emotion/serialize": "^1.1.1", "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", @@ -32781,12 +32793,12 @@ "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==" }, "@emotion/styled": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.5.tgz", - "integrity": "sha512-8EP6dD7dMkdku2foLoruPCNkRevzdcBaY6q0l0OsbyJK+x8D9HWjX27ARiSIKNF634hY9Zdoedh8bJCiva8yZw==", + "version": "11.10.6", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.6.tgz", + "integrity": "sha512-OXtBzOmDSJo5Q0AFemHCfl+bUueT8BIcPSxu0EGTpGk6DmI5dnhSzQANm1e1ze0YZL7TDyAyy6s/b/zmGOS3Og==", "requires": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.5", + "@emotion/babel-plugin": "^11.10.6", "@emotion/is-prop-valid": "^1.2.0", "@emotion/serialize": "^1.1.1", "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", @@ -33484,14 +33496,14 @@ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, "@mui/base": { - "version": "5.0.0-alpha.115", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.115.tgz", - "integrity": "sha512-OGQ84whT/yNYd6xKCGGS6MxqEfjVjk5esXM7HP6bB2Rim7QICUapxZt4nm8q39fpT08rNDkv3xPVqDDwRdRg1g==", + "version": "5.0.0-alpha.118", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.118.tgz", + "integrity": "sha512-GAEpqhnuHjRaAZLdxFNuOf2GDTp9sUawM46oHZV4VnYPFjXJDkIYFWfIQLONb0nga92OiqS5DD/scGzVKCL0Mw==", "requires": { - "@babel/runtime": "^7.20.7", + "@babel/runtime": "^7.20.13", "@emotion/is-prop-valid": "^1.2.0", "@mui/types": "^7.2.3", - "@mui/utils": "^5.11.2", + "@mui/utils": "^5.11.9", "@popperjs/core": "^2.11.6", "clsx": "^1.2.1", "prop-types": "^15.8.1", @@ -33506,9 +33518,9 @@ } }, "@mui/core-downloads-tracker": { - "version": "5.11.6", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.6.tgz", - "integrity": "sha512-lbD3qdafBOf2dlqKhOcVRxaPAujX+9UlPC6v8iMugMeAXe0TCgU3QbGXY3zrJsu6ex64WYDpH4y1+WOOBmWMuA==" + "version": "5.11.9", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.9.tgz", + "integrity": "sha512-YGEtucQ/Nl91VZkzYaLad47Cdui51n/hW+OQm4210g4N3/nZzBxmGeKfubEalf+ShKH4aYDS86XTO6q/TpZnjQ==" }, "@mui/icons-material": { "version": "5.11.0", @@ -33519,16 +33531,16 @@ } }, "@mui/material": { - "version": "5.11.6", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.6.tgz", - "integrity": "sha512-MzkkL5KC2PCkFiv8cLpkzgLUPXSrAtnvJBR0emV7mLVWbkwV3n5832vjBx154B6R032fHjFTziTh7YEb50nK6Q==", - "requires": { - "@babel/runtime": "^7.20.7", - "@mui/base": "5.0.0-alpha.115", - "@mui/core-downloads-tracker": "^5.11.6", - "@mui/system": "^5.11.5", + "version": "5.11.10", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.10.tgz", + "integrity": "sha512-hs1WErbiedqlJIZsljgoil908x4NMp8Lfk8di+5c7o809roqKcFTg2+k3z5ucKvs29AXcsdXrDB/kn2K6dGYIw==", + "requires": { + "@babel/runtime": "^7.20.13", + "@mui/base": "5.0.0-alpha.118", + "@mui/core-downloads-tracker": "^5.11.9", + "@mui/system": "^5.11.9", "@mui/types": "^7.2.3", - "@mui/utils": "^5.11.2", + "@mui/utils": "^5.11.9", "@types/react-transition-group": "^4.4.5", "clsx": "^1.2.1", "csstype": "^3.1.1", @@ -33545,21 +33557,21 @@ } }, "@mui/private-theming": { - "version": "5.11.2", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.2.tgz", - "integrity": "sha512-qZwMaqRFPwlYmqwVKblKBGKtIjJRAj3nsvX93pOmatsXyorW7N/0IPE/swPgz1VwChXhHO75DwBEx8tB+aRMNg==", + "version": "5.11.9", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.9.tgz", + "integrity": "sha512-XMyVIFGomVCmCm92EvYlgq3zrC9K+J6r7IKl/rBJT2/xVYoRY6uM7jeB+Wxh7kXxnW9Dbqsr2yL3cx6wSD1sAg==", "requires": { - "@babel/runtime": "^7.20.7", - "@mui/utils": "^5.11.2", + "@babel/runtime": "^7.20.13", + "@mui/utils": "^5.11.9", "prop-types": "^15.8.1" } }, "@mui/styled-engine": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.0.tgz", - "integrity": "sha512-AF06K60Zc58qf0f7X+Y/QjaHaZq16znliLnGc9iVrV/+s8Ln/FCoeNuFvhlCbZZQ5WQcJvcy59zp0nXrklGGPQ==", + "version": "5.11.9", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.9.tgz", + "integrity": "sha512-bkh2CjHKOMy98HyOc8wQXEZvhOmDa/bhxMUekFX5IG0/w4f5HJ8R6+K6nakUUYNEgjOWPYzNPrvGB8EcGbhahQ==", "requires": { - "@babel/runtime": "^7.20.6", + "@babel/runtime": "^7.20.13", "@emotion/cache": "^11.10.5", "csstype": "^3.1.1", "prop-types": "^15.8.1" @@ -33575,15 +33587,15 @@ } }, "@mui/system": { - "version": "5.11.5", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.5.tgz", - "integrity": "sha512-KNVsJ0sgRRp2XBqhh4wPS5aacteqjwxgiYTVwVnll2fgkgunZKo3DsDiGMrFlCg25ZHA3Ax58txWGE9w58zp0w==", + "version": "5.11.9", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.9.tgz", + "integrity": "sha512-h6uarf+l3FO6l75Nf7yO+qDGrIoa1DM9nAMCUFZQsNCDKOInRzcptnm8M1w/Z3gVetfeeGoIGAYuYKbft6KZZA==", "requires": { - "@babel/runtime": "^7.20.7", - "@mui/private-theming": "^5.11.2", - "@mui/styled-engine": "^5.11.0", + "@babel/runtime": "^7.20.13", + "@mui/private-theming": "^5.11.9", + "@mui/styled-engine": "^5.11.9", "@mui/types": "^7.2.3", - "@mui/utils": "^5.11.2", + "@mui/utils": "^5.11.9", "clsx": "^1.2.1", "csstype": "^3.1.1", "prop-types": "^15.8.1" @@ -33596,11 +33608,11 @@ "requires": {} }, "@mui/utils": { - "version": "5.11.2", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.2.tgz", - "integrity": "sha512-AyizuHHlGdAtH5hOOXBW3kriuIwUIKUIgg0P7LzMvzf6jPhoQbENYqY6zJqfoZ7fAWMNNYT8mgN5EftNGzwE2w==", + "version": "5.11.9", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.9.tgz", + "integrity": "sha512-eOJaqzcEs4qEwolcvFAmXGpln+uvouvOS9FUX6Wkrte+4I8rZbjODOBDVNlK+V6/ziTfD4iNKC0G+KfOTApbqg==", "requires": { - "@babel/runtime": "^7.20.7", + "@babel/runtime": "^7.20.13", "@types/prop-types": "^15.7.5", "@types/react-is": "^16.7.1 || ^17.0.0", "prop-types": "^15.8.1", @@ -50712,6 +50724,18 @@ "prop-types": "^15.6.2" } }, + "react-use-cart": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/react-use-cart/-/react-use-cart-1.13.0.tgz", + "integrity": "sha512-V3jrNOgBXxTn/RWh1HCEdrQk/jx2xCixdkX1c7Vyl4zxEf9jOuniUnjZSTALO7rQ5226onqmvXxKz1eu0Yz6Iw==", + "requires": {} + }, + "reactjs-popup": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/reactjs-popup/-/reactjs-popup-2.0.5.tgz", + "integrity": "sha512-b5hv9a6aGsHEHXFAgPO5s1Jw1eSkopueyUVxQewGdLgqk2eW0IVXZrPRpHR629YcgIpC2oxtX8OOZ8a7bQJbxA==", + "requires": {} + }, "read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", diff --git a/client/package.json b/client/package.json index 9c3449b7c..697f36aee 100644 --- a/client/package.json +++ b/client/package.json @@ -3,10 +3,10 @@ "version": "0.1.0", "private": true, "dependencies": { - "@emotion/react": "^11.10.5", - "@emotion/styled": "^11.10.5", + "@emotion/react": "^11.10.6", + "@emotion/styled": "^11.10.6", "@mui/icons-material": "^5.11.0", - "@mui/material": "^5.11.6", + "@mui/material": "^5.11.10", "@mui/styled-engine": "^5.11.0", "@mui/styled-engine-sc": "^5.11.0", "@testing-library/jest-dom": "^5.16.5", @@ -24,6 +24,8 @@ "react-router-dom": "^6.6.1", "react-scripts": "5.0.1", "react-stars": "^2.2.5", + "react-use-cart": "^1.13.0", + "reactjs-popup": "^2.0.5", "styled-components": "^5.3.6", "sweetalert2": "^11.7.1", "web-vitals": "^2.1.4" diff --git a/client/src/App.js b/client/src/App.js index 12fc7874b..d5d83ff79 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -1,6 +1,8 @@ import "./App.css"; import CompleteNavbar from "./components/NavBar"; import { BrowserRouter, Routes } from "react-router-dom"; +import { CartProvider } from "react-use-cart"; +import Main_Cart from "./views/Cart/Cart"; function App() { return ( diff --git a/client/src/components/NavBar/NavBar.jsx b/client/src/components/NavBar/NavBar.jsx index 77d675a30..f08551d9d 100644 --- a/client/src/components/NavBar/NavBar.jsx +++ b/client/src/components/NavBar/NavBar.jsx @@ -1,5 +1,6 @@ import React from "react"; import { useNavigate } from "react-router-dom"; +import { IoMdCart } from "react-icons/io"; const NavBar = ({ user }) => { const navigate = useNavigate(); @@ -10,13 +11,12 @@ const NavBar = ({ user }) => { localStorage.removeItem("userType"); localStorage.removeItem("userID"); window.location.reload(); + navigate("/"); } else { navigate("/login"); } }; - - return (
+

@@ -110,15 +126,15 @@ const Browse = () => {

- - + */}
diff --git a/client/src/views/Cart/Cart.jsx b/client/src/views/Cart/Cart.jsx new file mode 100644 index 000000000..b72c28191 --- /dev/null +++ b/client/src/views/Cart/Cart.jsx @@ -0,0 +1,306 @@ +import { CartProvider, useCart } from "react-use-cart"; +import { React, useState, useEffect } from "react"; +import { Remove, Add } from "@mui/icons-material"; +import { Grid, Chip, Avatar } from "@mui/material"; +import { Button } from "@mui/material"; +import books from "../Books"; +import { useNavigate } from "react-router-dom"; +import axios from "axios"; + +function clear_cart() { + localStorage.setItem("books_cart", JSON.stringify([])); + localStorage.setItem("booksCartNames", JSON.stringify({})); + window.location.reload(false); +} + +function addItem(book) { + var books_cart = JSON.parse(localStorage.getItem("books_cart")); + if (books_cart == null) { + books_cart = []; + } + + var booksCartNames = JSON.parse(localStorage.getItem("booksCartNames")); + if (booksCartNames == null) { + booksCartNames = []; + } + booksCartNames.push(book.title); + + booksCartNames = booksCartNames.reduce(function (prev, cur) { + prev[cur] = (prev[cur] || 0) + 1; + return prev; + }, {}); + + books_cart.push(book); + localStorage.setItem("books_cart", JSON.stringify(books_cart)); + localStorage.setItem("booksCartNames", JSON.stringify(booksCartNames)); + console.log(booksCartNames); +} + +function getBook(books, bookName) { + for (let i = 0; i < books.length; ++i) { + if (books[i].title == bookName) { + return books[i]; + } + } +} + +function round(value, decimals) { + return Number(Math.round(value + "e" + decimals) + "e-" + decimals); +} + +function getKeys(obj) { + var keys = []; + iterate(obj, function (oVal, oKey) { + keys.push(oKey); + }); + return keys; +} +function iterate(iterable, callback) { + for (var key in iterable) { + if ( + key === "length" || + key === "prototype" || + !Object.prototype.hasOwnProperty.call(iterable, key) + ) + continue; + callback(iterable[key], key, iterable); + } +} + +function calculatePrice(books, booksCartNames) { + let finalPrice = 0; + var bookNames = getKeys(booksCartNames); + for (let i = 0; i < bookNames.length; ++i) { + finalPrice = + finalPrice + + booksCartNames[bookNames[i]] * getBook(books, bookNames[i]).price; + } + + return round(finalPrice, 2); +} + +const MainCart = ({ currentUser }) => { + const navigate = useNavigate(); + var booksCartNames = JSON.parse(localStorage.getItem("booksCartNames")); + + const [quantity, setQuantity] = useState(booksCartNames); + function add(booksCartNames, bookName) { + console.log("adding"); + booksCartNames[bookName] = booksCartNames[bookName] + 1; + setQuantity(booksCartNames); + localStorage.setItem("booksCartNames", JSON.stringify(booksCartNames)); + window.location.reload(); + } + + function subtract(booksCartNames, bookName) { + console.log("subing"); + if (quantity[bookName] > 0) { + booksCartNames[bookName] = booksCartNames[bookName] - 1; + setQuantity(booksCartNames); + localStorage.setItem("booksCartNames", JSON.stringify(booksCartNames)); + window.location.reload(); + } + } + + function setZero(booksCartNames, bookName) { + booksCartNames[bookName] = 0; + setQuantity(booksCartNames); + localStorage.setItem("booksCartNames", JSON.stringify(booksCartNames)); + window.location.reload(); + } + + function deleteItem(booksCartNames, bookName) { + delete booksCartNames[bookName]; + setQuantity(booksCartNames); + localStorage.setItem("booksCartNames", JSON.stringify(booksCartNames)); + window.location.reload(); + } + + const getUserData = async () => { + const url = "/api/users/" + currentUser; + const res = await axios.get(url, data); + return res.data; + }; + + const [data, setData] = useState(getUserData); + const [error, setError] = useState(""); + const handleChange = (e) => { + const { name, value } = e.target; + setData({ + ...data, + [name]: value, + }); + }; + + const handleSubmit = async (e) => { + e.preventDefault(); + try { + const url = "/api/users/" + currentUser; + if (data.password === "") { + delete data.password; + } + console.log(data); + const res = await axios.put(url, data); + window.location.reload(); + } catch (error) { + console.log(error); + if (error.response?.status >= 400 && error.response.status <= 500) { + setError(error.response.data.message); + } + } + }; + + function ValidatedUsers(props) { + const [currentUser, setCurrentUser] = useState(""); + const [users, setUsers] = useState([]); + + useEffect(() => { + async function getValidatedUsers() { + const url = "/api/users"; + const res = await axios.get(url); + const users = res.data; + setCurrentUser(props.currentUser); + setUsers(users); + } + getValidatedUsers(); + }, [props.currentUser]); + return users; + } + + function userData(users, currentUser) { + for (let i = 0; i < users.length; ++i) { + if (users[i]._id === currentUser) { + console.log(users[i].balance.$numberDecimal); + return users[i].balance.$numberDecimal; + } + } + } + var allUsers; + var currentBalance; + if (currentUser && currentUser.length !== 0) { + allUsers = ValidatedUsers(currentUser); + currentBalance = userData(allUsers, currentUser); + } + + const availableBalance = () => { + if (currentUser && currentUser.length !== 0) { + var allUsers = ValidatedUsers(currentUser); + return userData(allUsers, currentUser); + } + return 0; + }; + + var puchaseBooks = (currentUser) => { + if (currentUser && currentUser.length !== 0) { + console.log(currentBalance); + if (currentBalance - calculatePrice(books, booksCartNames) >= 0) { + if (currentBalance - calculatePrice(books, booksCartNames) === 0) { + data.balance = "0"; + } else { + data.balance = currentBalance - calculatePrice(books, booksCartNames); + } + console.log(data.balance); + localStorage.setItem("books_cart", JSON.stringify([])); + localStorage.setItem("booksCartNames", JSON.stringify({})); + handleChange(); + } else { + handleChange(); + window.location.reload(); + } + } else { + navigate("/login"); + } + }; + + return ( +
+ + + Available balance: ${availableBalance()} + + +
+
+ {getKeys(booksCartNames).map((bookName) => ( +
+
+ +
+
+

+ {getBook(books, bookName).title} by{" "} + {getBook(books, bookName).author} +

+

+ Price: ${getBook(books, bookName).price} +

+

+ Quantity: {booksCartNames[bookName]} +
+ subtract(booksCartNames, bookName)} + > + + + } + label={ +

{quantity[bookName]}

+ } + clickable + onDelete={() => add(booksCartNames, bookName)} + deleteIcon={} + /> + + +
+

+
+
+ ))} +
+
+ +
+
+

+ Total: ${calculatePrice(books, booksCartNames)} +

+ +
+
+
+ ); +}; + +export default MainCart; diff --git a/client/src/views/Cart/CurrentCart.js b/client/src/views/Cart/CurrentCart.js new file mode 100644 index 000000000..06d52aa4d --- /dev/null +++ b/client/src/views/Cart/CurrentCart.js @@ -0,0 +1,3 @@ +const Items = ["Book1", "Book2"]; + +export default Items; diff --git a/client/src/views/Forums.jsx b/client/src/views/Forums.jsx index acb9ba907..a0545a9ee 100644 --- a/client/src/views/Forums.jsx +++ b/client/src/views/Forums.jsx @@ -8,47 +8,52 @@ export default class Forums extends React.Component { }; // this may be supposed to be async - getForumPosts = async() => { + getForumPosts = async () => { const url = "/api/forums"; axios.get(url).then((res) => { // console.log("The data:", res.data); // const forums = res.data; - this.setState({forums: res.data}); + this.setState({ forums: res.data }); }); }; componentDidMount = () => { this.getForumPosts(); - } + }; // Form Change Method isLoggedIn = () => { const currentUser = this.props.currentUser; return currentUser && currentUser.length !== 0; - } - + }; // Update this to vary based on user log in - render() { return( -
-
-
- Viewing Forums -
-
-
-
-
- {this.state.forums.map((forum) => ( -
-
{forum.post}
-
by: {(forum.uuid)} on date: {forum.date}
-
- ))} + render() { + return ( +
+
+
+ Viewing Forums +
+
+
+
+ {this.state.forums.map((forum) => ( +
+
{forum.post}
+
+ by: {forum.uuid} on date: {forum.date} +
+
+ ))} +
+
-
-
- ) - } - } + + ); + } +} diff --git a/client/src/views/Home.jsx b/client/src/views/Home.jsx index 7c63006b5..e46449602 100644 --- a/client/src/views/Home.jsx +++ b/client/src/views/Home.jsx @@ -6,7 +6,7 @@ const Home = () => { return (
-
+
Welcome
diff --git a/client/src/views/Login.jsx b/client/src/views/Login.jsx index ce5981844..e79a1001f 100644 --- a/client/src/views/Login.jsx +++ b/client/src/views/Login.jsx @@ -48,11 +48,11 @@ const Login = () => {
-
diff --git a/package-lock.json b/package-lock.json index 069bec042..99fe21a07 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,9 +11,13 @@ "dependencies": { "@emailjs/browser": "^3.9.1", "concurrently": "^4.1.2", + "local-storage": "^2.0.0", "nodemon": "^2.0.20", "react-icons": "^4.6.0", "react-native-svg": "^13.6.0", + "react-redux": "^8.0.5", + "react-use-cart": "^1.13.0", + "redux": "^4.2.1", "tailwind-scrollbar": "^2.1.0" }, "devDependencies": { @@ -1884,7 +1888,6 @@ "version": "7.20.6", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", "integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==", - "peer": true, "dependencies": { "regenerator-runtime": "^0.13.11" }, @@ -4675,6 +4678,15 @@ "@types/node": "*" } }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", @@ -4707,12 +4719,37 @@ "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", "dev": true }, + "node_modules/@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + }, + "node_modules/@types/react": { + "version": "18.0.28", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz", + "integrity": "sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" + }, "node_modules/@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, "node_modules/@types/yargs": { "version": "16.0.4", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", @@ -6036,6 +6073,11 @@ "node": ">=4" } }, + "node_modules/csstype": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + }, "node_modules/date-fns": { "version": "1.30.1", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", @@ -7127,6 +7169,19 @@ "node": ">=8" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -11661,6 +11716,11 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/local-storage": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/local-storage/-/local-storage-2.0.0.tgz", + "integrity": "sha512-/0sRoeijw7yr/igbVVygDuq6dlYCmtsuTmmpnweVlVtl/s10pf5BCq8LWBxW/AMyFJ3MhMUuggMZiYlx6qr9tw==" + }, "node_modules/locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -14267,6 +14327,49 @@ "react-native": "*" } }, + "node_modules/react-redux": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz", + "integrity": "sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw==", + "dependencies": { + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", + "hoist-non-react-statics": "^3.3.2", + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^16.8 || ^17.0 || ^18.0", + "@types/react-dom": "^16.8 || ^17.0 || ^18.0", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0", + "react-native": ">=0.59", + "redux": "^4" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-redux/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, "node_modules/react-refresh": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz", @@ -14289,6 +14392,17 @@ "react": "^16.0.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-use-cart": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/react-use-cart/-/react-use-cart-1.13.0.tgz", + "integrity": "sha512-V3jrNOgBXxTn/RWh1HCEdrQk/jx2xCixdkX1c7Vyl4zxEf9jOuniUnjZSTALO7rQ5226onqmvXxKz1eu0Yz6Iw==", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -14379,6 +14493,14 @@ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", "peer": true }, + "node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -14400,8 +14522,7 @@ "node_modules/regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "peer": true + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "node_modules/regenerator-transform": { "version": "0.15.1", @@ -15955,7 +16076,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", - "peer": true, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } @@ -17485,7 +17605,6 @@ "version": "7.20.6", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", "integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==", - "peer": true, "requires": { "regenerator-runtime": "^0.13.11" } @@ -19629,6 +19748,15 @@ "@types/node": "*" } }, + "@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "requires": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "@types/istanbul-lib-coverage": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", @@ -19661,12 +19789,37 @@ "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", "dev": true }, + "@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + }, + "@types/react": { + "version": "18.0.28", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz", + "integrity": "sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==", + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" + }, "@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, "@types/yargs": { "version": "16.0.4", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", @@ -20673,6 +20826,11 @@ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" }, + "csstype": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + }, "date-fns": { "version": "1.30.1", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", @@ -21499,6 +21657,21 @@ "source-map": "^0.7.3" } }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, "hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -24867,6 +25040,11 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "local-storage": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/local-storage/-/local-storage-2.0.0.tgz", + "integrity": "sha512-/0sRoeijw7yr/igbVVygDuq6dlYCmtsuTmmpnweVlVtl/s10pf5BCq8LWBxW/AMyFJ3MhMUuggMZiYlx6qr9tw==" + }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -26841,6 +27019,26 @@ "css-tree": "^1.1.3" } }, + "react-redux": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz", + "integrity": "sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw==", + "requires": { + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", + "hoist-non-react-statics": "^3.3.2", + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, "react-refresh": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz", @@ -26857,6 +27055,12 @@ "react-is": "^16.12.0 || ^17.0.0 || ^18.0.0" } }, + "react-use-cart": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/react-use-cart/-/react-use-cart-1.13.0.tgz", + "integrity": "sha512-V3jrNOgBXxTn/RWh1HCEdrQk/jx2xCixdkX1c7Vyl4zxEf9jOuniUnjZSTALO7rQ5226onqmvXxKz1eu0Yz6Iw==", + "requires": {} + }, "read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -26933,6 +27137,14 @@ } } }, + "redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "requires": { + "@babel/runtime": "^7.9.2" + } + }, "regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -26951,8 +27163,7 @@ "regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "peer": true + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "regenerator-transform": { "version": "0.15.1", @@ -28158,7 +28369,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", - "peer": true, "requires": {} }, "util-deprecate": { diff --git a/package.json b/package.json index 64f3efcc2..027ef7ee5 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,13 @@ "dependencies": { "@emailjs/browser": "^3.9.1", "concurrently": "^4.1.2", + "local-storage": "^2.0.0", "nodemon": "^2.0.20", "react-icons": "^4.6.0", "react-native-svg": "^13.6.0", + "react-redux": "^8.0.5", + "react-use-cart": "^1.13.0", + "redux": "^4.2.1", "tailwind-scrollbar": "^2.1.0" }, "homepage": "https://github.com/SCCapstone/BufferOverload#readme",