diff --git a/package-lock.json b/package-lock.json index 5a6f198..ff6936c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "food-saviour", "version": "0.0.0", "dependencies": { + "@anatoliygatt/heart-switch": "^1.0.13", + "@emotion/react": "^11.11.4", + "@emotion/styled": "^11.11.5", "bootstrap": "^5.3.3", "firebase": "^10.12.2", "react": "^18.2.0", @@ -46,11 +49,21 @@ "node": ">=6.0.0" } }, + "node_modules/@anatoliygatt/heart-switch": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/@anatoliygatt/heart-switch/-/heart-switch-1.0.13.tgz", + "integrity": "sha512-Dr3gdbBoMgbVFbtB4pcXSZdy+p3vfbIx9WweQFHVDzWIlDaZAkjywVti/Vz/Jz2BWYUkTcH6aIAb8goxLxaOwA==", + "license": "MIT", + "peerDependencies": { + "@emotion/react": "^11.0.0", + "@emotion/styled": "^11.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/@babel/code-frame": { "version": "7.24.6", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.6.tgz", "integrity": "sha512-ZJhac6FkEd1yhG2AHOmfcXG4ceoLltoCVJjN5XsWN9BifBQr+cHJbWi0h68HZuSORq+3WtJ2z0hwF2NG1b5kcA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/highlight": "^7.24.6", @@ -195,7 +208,6 @@ "version": "7.24.6", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.6.tgz", "integrity": "sha512-a26dmxFJBF62rRO9mmpgrfTLsAuyHk4e1hKTUkD/fcMfynt8gvEKwQPQDVxWhca8dHoDck+55DFt42zV0QMw5g==", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.24.6" @@ -225,9 +237,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.6.tgz", - "integrity": "sha512-MZG/JcWfxybKwsA9N9PmtF2lOSFSEMVCpIRrbxccZFLJPrJciJdG/UhSh5W96GEteJI2ARqm5UAHxISwRDLSNg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", "dev": true, "license": "MIT", "engines": { @@ -261,20 +273,18 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.6.tgz", - "integrity": "sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==", - "dev": true, + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.6.tgz", - "integrity": "sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==", - "dev": true, + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -308,7 +318,6 @@ "version": "7.24.6", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.6.tgz", "integrity": "sha512-2YnuOp4HAk2BsBrJJvYCbItHx0zWscI1C3zgWkz+wDyD9I7GIVrfnLyrR4Y1VR+7p+chAEcrgRQYZAGIKMV7vQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.24.6", @@ -415,20 +424,183 @@ } }, "node_modules/@babel/types": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.6.tgz", - "integrity": "sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==", - "dev": true, + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.6", - "@babel/helper-validator-identifier": "^7.24.6", + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==", + "license": "MIT" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "license": "MIT", + "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==", + "license": "MIT" + }, + "node_modules/@emotion/react": { + "version": "11.11.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", + "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.4.tgz", + "integrity": "sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==", + "license": "MIT" + }, + "node_modules/@emotion/styled": { + "version": "11.11.5", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.5.tgz", + "integrity": "sha512-/ZjjnaNKvuMPxcIiUkf/9SHoG4Q196DRl1w82hQ3WCsjo1IUR8uaGWrC6a87CrYAW0Kb/pK7hk8BnLgLRi9KoQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.2", + "@emotion/serialize": "^1.1.4", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", + "license": "MIT" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==", + "license": "MIT" + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", @@ -2092,6 +2264,12 @@ "undici-types": "~5.26.4" } }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "license": "MIT" + }, "node_modules/@types/prop-types": { "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", @@ -2413,7 +2591,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^1.9.0" @@ -2439,6 +2616,21 @@ "node": ">=8" } }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2525,7 +2717,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -2556,7 +2747,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", @@ -2591,7 +2781,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "license": "MIT", "dependencies": { "color-name": "1.1.3" @@ -2601,7 +2790,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, "license": "MIT" }, "node_modules/concat-map": { @@ -2618,6 +2806,22 @@ "dev": true, "license": "MIT" }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -2722,6 +2926,15 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, "node_modules/es6-object-assign": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", @@ -2780,7 +2993,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.8.0" @@ -3187,6 +3399,12 @@ "node": ">=8" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "license": "MIT" + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -3305,6 +3523,15 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -3425,12 +3652,32 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" } }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, "node_modules/http-parser-js": { "version": "0.5.8", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", @@ -3457,7 +3704,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, "license": "MIT", "dependencies": { "parent-module": "^1.0.0", @@ -3508,6 +3754,27 @@ "loose-envify": "^1.0.0" } }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", + "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -3606,6 +3873,12 @@ "dev": true, "license": "MIT" }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -3657,6 +3930,12 @@ "node": ">= 0.8.0" } }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -3867,7 +4146,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "license": "MIT", "dependencies": { "callsites": "^3.0.0" @@ -3876,6 +4154,24 @@ "node": ">=6" } }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -3906,11 +4202,16 @@ "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3920,7 +4221,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true, "license": "ISC" }, "node_modules/picomatch": { @@ -4212,11 +4512,27 @@ "node": ">=0.10.0" } }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -4385,6 +4701,15 @@ "node": ">=8" } }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", @@ -4434,11 +4759,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "license": "MIT" + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^3.0.0" @@ -4447,6 +4777,18 @@ "node": ">=4" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/sweetalert": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/sweetalert/-/sweetalert-2.1.2.tgz", @@ -4468,7 +4810,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -4820,6 +5161,15 @@ "dev": true, "license": "ISC" }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", diff --git a/package.json b/package.json index 36ef6be..87283d9 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,9 @@ "preview": "vite preview" }, "dependencies": { + "@anatoliygatt/heart-switch": "^1.0.13", + "@emotion/react": "^11.11.4", + "@emotion/styled": "^11.11.5", "bootstrap": "^5.3.3", "firebase": "^10.12.2", "react": "^18.2.0", diff --git a/src/App.tsx b/src/App.tsx index ee053a5..13588d5 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -6,20 +6,23 @@ import { Layout } from "./Layout"; import { RegisterPage } from "./pages/Register"; import { Dashboard } from "./pages/Dashboard"; import { FavoritePage } from "./pages/Favorites"; +import { AuthContextProvider } from "./context/Auth"; function App() { return ( - - - }> - } /> - } /> - } /> - } /> - } /> - - - + + + + }> + } /> + } /> + } /> + } /> + } /> + + + + ); } diff --git a/src/components/Add.tsx b/src/components/Add.tsx index 8f42562..29b4987 100644 --- a/src/components/Add.tsx +++ b/src/components/Add.tsx @@ -5,14 +5,15 @@ import { getDownloadURL, ref, uploadBytes } from "firebase/storage"; import { v4 as uuidv4 } from "uuid"; import { addSuccess, invalidInputWarning } from "../functions/Alert"; import { CrudForm } from "./CrudForm"; +import { useAuth } from "../context/Auth"; interface AddProps { - user: any; getFoodList: Function; setIsAdding: React.Dispatch>; } -export const Add = ({ user, getFoodList, setIsAdding }: AddProps) => { +export const Add = ({ getFoodList, setIsAdding }: AddProps) => { + const user = useAuth().user; const [name, setName] = useState(""); const [price, setPrice] = useState(0); const [image, setImage] = useState(); @@ -34,7 +35,7 @@ export const Add = ({ user, getFoodList, setIsAdding }: AddProps) => { } // Upload image to storage - const imagePath = "images/" + `${user.uid}/` + uuidv4(); + const imagePath = "images/" + `${user?.uid}/` + uuidv4(); const storageRef = ref(storage, imagePath); try { await uploadBytes(storageRef, image); @@ -43,19 +44,19 @@ export const Add = ({ user, getFoodList, setIsAdding }: AddProps) => { } getDownloadURL(storageRef) // Download image url - .then(async (url) => { - const imageURL = url; - await addDoc(collection(db, "food"), { + .then(async (imageURL) => { + const newFood = { name: name, price: price, date: date, post: post, - userId: user.uid, - business: user.displayName, + userId: user?.uid, + business: user?.displayName, imageURL: imageURL, imagePath: imagePath, cuisine: cuisine, - }); + }; + await addDoc(collection(db, "food"), newFood); setIsAdding(false); getFoodList(); addSuccess(name, price); diff --git a/src/components/Cards.tsx b/src/components/Cards.tsx index 997e073..4b06e46 100644 --- a/src/components/Cards.tsx +++ b/src/components/Cards.tsx @@ -1,25 +1,25 @@ import { Badge, Button, Card, Col, Row } from "react-bootstrap"; import { FoodItem } from "../interface/FoodItem"; import { timestampToString } from "../functions/Date"; +import { useAuth } from "../context/Auth"; export const Cards = ({ - user, foodList, updateFood, deleteFood, }: { - user: any; foodList: FoodItem[]; updateFood: Function; deleteFood: Function; }) => { + const user = useAuth().user; return ( <> {foodList && foodList.length > 0 ? ( {foodList.map( (food, index) => - food.userId == user.uid && ( + food.userId == user?.uid && ( (); - const [isConsumer, setIsConsumer] = useState(false); - - const getUser = async () => { - onAuthStateChanged(auth, (user) => { - if (user) { - setUser(user); - if (doc(db, "consumer", user.uid)) { - // Consumer account - setIsConsumer(true); - } - } - }); - }; - - useEffect(() => { - getUser(); - }, []); + const { user, isConsumer } = useAuth(); const Logout = () => { signOut(auth) diff --git a/src/context/Auth.tsx b/src/context/Auth.tsx new file mode 100644 index 0000000..f66bc2e --- /dev/null +++ b/src/context/Auth.tsx @@ -0,0 +1,72 @@ +import { + useContext, + createContext, + useEffect, + useState, + FC, + ReactNode, +} from "react"; +import { onAuthStateChanged, User } from "firebase/auth"; +import { auth, db } from "../config/firebase"; +import { doc, getDoc } from "firebase/firestore"; + +// Define the type for the UserContext +type UserContextType = { + user: User | null; + isConsumer: boolean; +}; + +// Create a context with a default value of null +const AuthContext = createContext(null); + +// AuthContextProvider component to wrap around the app +export const AuthContextProvider: FC<{ children: ReactNode }> = ({ + children, +}) => { + const [user, setUser] = useState(null); + const [isConsumer, setIsConsumer] = useState(false); + + // useEffect to listen for authentication state changes + useEffect(() => { + const unsubscribe = onAuthStateChanged( + auth, + async (currentUser) => { + setUser(currentUser); // Set the current user in state + if (currentUser) { + const docRef = doc(db, "consumer", currentUser.uid); + const docSnap = await getDoc(docRef); + if (docSnap.exists()) { + setIsConsumer(true); + } + } + }, + (error) => { + console.error("Auth state change error: ", error); // Log any errors + } + ); + + // Cleanup subscription on component unmount + return () => { + unsubscribe(); + }; + }, []); + + // Provide the user state to child components + return ( + + {children} + + ); +}; + +// Custom hook to use the AuthContext +export const useAuth = (): UserContextType => { + const context = useContext(AuthContext); + + // Throw an error if the hook is used outside of AuthProvider + if (!context) { + throw new Error("useAuth must be used within an AuthProvider"); + } + + return context; // Return the context value +}; diff --git a/src/pages/Dashboard.tsx b/src/pages/Dashboard.tsx index 8ddc487..0770f63 100644 --- a/src/pages/Dashboard.tsx +++ b/src/pages/Dashboard.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from "react"; -import { auth, db } from "../config/firebase"; +import { db } from "../config/firebase"; import { doc, deleteDoc, getDoc } from "firebase/firestore"; import { Cards } from "../components/Cards"; import { Edit } from "../components/Edit"; @@ -10,9 +10,16 @@ import { FoodItem } from "../interface/FoodItem"; import { deleteSuccess, deleteWarning } from "../functions/Alert"; import { getFoodList } from "../functions/GetFood"; import { Spinner } from "react-bootstrap"; +import { useAuth } from "../context/Auth"; +import { useNavigate } from "react-router-dom"; export function Dashboard() { - const user = auth.currentUser; + const user = useAuth().user; + let navigate = useNavigate(); + if (!user) { + navigate("/login"); + } + const [isAdding, setIsAdding] = useState(false); const [selectedFoodId, setSelectedFoodId] = useState(""); const [isEditing, setIsEditing] = useState(false); @@ -26,8 +33,7 @@ export function Dashboard() { const fetchFoodList = async () => { try { setIsLoading(true); - const updatedFoodList = await getFoodList(); - setFoodList(updatedFoodList); + setFoodList(await getFoodList()); setIsLoading(false); } catch (error) { console.error("Error fetching food items:", error); @@ -109,7 +115,6 @@ export function Dashboard() { /> + )} {isEditing && ( diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index eec5ead..60df58b 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -5,6 +5,7 @@ import { Search } from "../components/Search"; import { FoodItem } from "../interface/FoodItem"; import { timestampToString } from "../functions/Date"; import { getFoodList } from "../functions/GetFood"; +// import { HeartSwitch } from "@anatoliygatt/heart-switch"; export function Home() { const [foodList, setFoodList] = useState([]); @@ -19,8 +20,7 @@ export function Home() { setIsLoading(true); const updatedFoodList = await getFoodList(); const postedFoodList = updatedFoodList.filter((food) => { - // Display posted food items only - return food.post === true; + return food.post === true; // Display posted food items only }); setFoodList(postedFoodList); setIsLoading(false); @@ -88,11 +88,7 @@ export function Home() { {food.name} ${food.price} - - {food.date - ? `Date: ${timestampToString(food.date)}` - : "No Date"} - + Date: ${timestampToString(food.date)} {food.business} + {/* { + handleFavChange(event.target.checked, food.id) + }} + /> */} diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx index 4bc4ef2..b92cd22 100644 --- a/src/pages/Login.tsx +++ b/src/pages/Login.tsx @@ -19,6 +19,7 @@ export const LoginPage = () => { setAuthenticating(true); try { await signInWithEmailAndPassword(auth, email, password); + navigate("/dashboard"); } catch (error) { setAuthenticating(false); setError(getErrorMessage(error)); diff --git a/src/unused/FoodList.tsx b/src/unused/FoodList.tsx new file mode 100644 index 0000000..cd7a7f0 --- /dev/null +++ b/src/unused/FoodList.tsx @@ -0,0 +1,89 @@ +import { + useContext, + createContext, + useEffect, + useState, + FC, + ReactNode, +} from "react"; +import { collection, getDocs, writeBatch } from "firebase/firestore"; +import { db } from "../config/firebase"; +import { FoodItem } from "../interface/FoodItem"; +import { timestampToDate } from "../functions/Date"; + +// Create a context with a default value of null +const FoodContext = createContext([]); + +// FoodContextProvider component to wrap around the app +export const FoodContextProvider: FC<{ children: ReactNode }> = ({ + children, +}) => { + const [foodList, setFoodList] = useState([]); + const [isLoading, setIsLoading] = useState(false); + + // Function to fetch food items from Firestore and update the list + + // useEffect to fetch food list on component mount + useEffect(() => { + const getFoodList = async () => { + try { + setIsLoading(true); + const foodCollectionRef = collection(db, "food"); + const querySnapshot = await getDocs(foodCollectionRef); + + const batch = writeBatch(db); + + querySnapshot.forEach((doc) => { + const foodItem = doc.data() as FoodItem; + + // Check if the food item's date is before the current date + if (foodItem.post && timestampToDate(foodItem.date) < new Date()) { + // Update the document to set post to false in the batch + const foodDocRef = doc.ref; + batch.update(foodDocRef, { post: false }); + } + }); + + // Commit the batch update + await batch.commit(); + + // Fetch the updated data after the batch update + const updatedQuerySnapshot = await getDocs(foodCollectionRef); + const updatedFoodList = updatedQuerySnapshot.docs.map((doc) => ({ + ...doc.data(), + id: doc.id, + })) as FoodItem[]; + + // Update the state with the fetched food list + setFoodList(updatedFoodList); + console.log("called"); + setIsLoading(false); + } catch (error) { + throw error; // Rethrow the error to handle it in the calling component + } + }; + + return () => { + getFoodList(); + }; + }, []); + + // Provide the food list state to child components + return ( + + {!isLoading && children} + + ); +}; + +// Custom hook to use the FoodContext +export const useFoodList = (): FoodItem[] => { + const context = useContext(FoodContext); + + // Throw an error if the hook is used outside of FoodContextProvider + if (context === null) { + throw new Error("useFoodList must be used within a FoodProvider"); + } + + return context; // Return the context value +}; diff --git a/src/unused/context/User.ts b/src/unused/context/User.ts deleted file mode 100644 index 8d78120..0000000 --- a/src/unused/context/User.ts +++ /dev/null @@ -1,6 +0,0 @@ -export type UserContextType = { - user: any | null; -} - - - \ No newline at end of file diff --git a/src/unused/context/UserAuth.tsx b/src/unused/context/UserAuth.tsx deleted file mode 100644 index 3d4e027..0000000 --- a/src/unused/context/UserAuth.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { - useContext, - createContext, - useEffect, - useState, - FC, - ReactNode, -} from "react"; -import { onAuthStateChanged } from "firebase/auth"; -import { auth } from "../../config/firebase"; -import { UserContextType } from "./User"; - -const AuthContext = createContext(null); - -export const AuthContextProvider: FC<{ children: ReactNode }> = ({ - children, -}) => { - const [user, setUser] = useState({}); - - useEffect(() => { - const unsubscribe = onAuthStateChanged(auth, (currentUser) => { - if (currentUser) { - setUser(currentUser); - } - }); - return () => { - unsubscribe(); - }; - }, []); - - return ( - {children} - ); -}; - -export const UserAuth = () => { - const context = useContext(AuthContext); - if (!context) - throw Error("useAuthContext can only be used inside an AuthProvider"); - return context; -};