diff --git a/package-lock.json b/package-lock.json index f7b13db..0c54c28 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1125,6 +1125,12 @@ "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz", "integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==" }, + "@emotion/hash": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==", + "dev": true + }, "@eslint/eslintrc": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.3.0.tgz", @@ -1729,6 +1735,88 @@ } } }, + "@material-ui/core": { + "version": "4.11.3", + "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.11.3.tgz", + "integrity": "sha512-Adt40rGW6Uds+cAyk3pVgcErpzU/qxc7KBR94jFHBYretU4AtWZltYcNsbeMn9tXL86jjVL1kuGcIHsgLgFGRw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@material-ui/styles": "^4.11.3", + "@material-ui/system": "^4.11.3", + "@material-ui/types": "^5.1.0", + "@material-ui/utils": "^4.11.2", + "@types/react-transition-group": "^4.2.0", + "clsx": "^1.0.4", + "hoist-non-react-statics": "^3.3.2", + "popper.js": "1.16.1-lts", + "prop-types": "^15.7.2", + "react-is": "^16.8.0 || ^17.0.0", + "react-transition-group": "^4.4.0" + } + }, + "@material-ui/icons": { + "version": "4.11.2", + "resolved": "https://registry.npmjs.org/@material-ui/icons/-/icons-4.11.2.tgz", + "integrity": "sha512-fQNsKX2TxBmqIGJCSi3tGTO/gZ+eJgWmMJkgDiOfyNaunNaxcklJQFaFogYcFl0qFuaEz1qaXYXboa/bUXVSOQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@material-ui/styles": { + "version": "4.11.3", + "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.3.tgz", + "integrity": "sha512-HzVzCG+PpgUGMUYEJ2rTEmQYeonGh41BYfILNFb/1ueqma+p1meSdu4RX6NjxYBMhf7k+jgfHFTTz+L1SXL/Zg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@emotion/hash": "^0.8.0", + "@material-ui/types": "^5.1.0", + "@material-ui/utils": "^4.11.2", + "clsx": "^1.0.4", + "csstype": "^2.5.2", + "hoist-non-react-statics": "^3.3.2", + "jss": "^10.5.1", + "jss-plugin-camel-case": "^10.5.1", + "jss-plugin-default-unit": "^10.5.1", + "jss-plugin-global": "^10.5.1", + "jss-plugin-nested": "^10.5.1", + "jss-plugin-props-sort": "^10.5.1", + "jss-plugin-rule-value-function": "^10.5.1", + "jss-plugin-vendor-prefixer": "^10.5.1", + "prop-types": "^15.7.2" + } + }, + "@material-ui/system": { + "version": "4.11.3", + "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.11.3.tgz", + "integrity": "sha512-SY7otguNGol41Mu2Sg6KbBP1ZRFIbFLHGK81y4KYbsV2yIcaEPOmsCK6zwWlp+2yTV3J/VwT6oSBARtGIVdXPw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@material-ui/utils": "^4.11.2", + "csstype": "^2.5.2", + "prop-types": "^15.7.2" + } + }, + "@material-ui/types": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz", + "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==", + "dev": true + }, + "@material-ui/utils": { + "version": "4.11.2", + "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.2.tgz", + "integrity": "sha512-Uul8w38u+PICe2Fg2pDKCaIG7kOyhowZ9vjiC1FsVwPABTW8vPPKfF6OvxRq3IiBaI1faOJmgdvMG7rMJARBhA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "prop-types": "^15.7.2", + "react-is": "^16.8.0 || ^17.0.0" + } + }, "@nodelib/fs.scandir": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", @@ -1788,6 +1876,46 @@ } } }, + "@popperjs/core": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.8.4.tgz", + "integrity": "sha512-h0lY7g36rhjNV8KVHKS3/BEOgfsxu0AiRI8+ry5IFBGEsQFkpjxtcpVc9ndN8zrKUeMZXAWMc7eQMepfgykpxQ==", + "dev": true + }, + "@react-dnd/asap": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-4.0.0.tgz", + "integrity": "sha512-0XhqJSc6pPoNnf8DhdsPHtUhRzZALVzYMTzRwV4VI6DJNJ/5xxfL9OQUwb8IH5/2x7lSf7nAZrnzUD+16VyOVQ==", + "dev": true + }, + "@react-dnd/invariant": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-2.0.0.tgz", + "integrity": "sha512-xL4RCQBCBDJ+GRwKTFhGUW8GXa4yoDfJrPbLblc3U09ciS+9ZJXJ3Qrcs/x2IODOdIE5kQxvMmE2UKyqUictUw==", + "dev": true + }, + "@react-dnd/shallowequal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-2.0.0.tgz", + "integrity": "sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg==", + "dev": true + }, + "@restart/context": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz", + "integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q==", + "dev": true + }, + "@restart/hooks": { + "version": "0.3.26", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.3.26.tgz", + "integrity": "sha512-7Hwk2ZMYm+JLWcb7R9qIXk1OoUg1Z+saKWqZXlrvFwT3w6UArVNWgxYOzf+PJoK9zZejp8okPAKTctthhXLt5g==", + "dev": true, + "requires": { + "lodash": "^4.17.20", + "lodash-es": "^4.17.20" + } + }, "@rollup/plugin-node-resolve": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz", @@ -2168,6 +2296,12 @@ "@babel/types": "^7.3.0" } }, + "@types/classnames": { + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/@types/classnames/-/classnames-2.2.11.tgz", + "integrity": "sha512-2koNhpWm3DgWRp5tpkiJ8JGc1xTn2q0l+jUNUE7oMKXUf5NpI9AIdC4kbjGNFBdHtcxBD18LAksoudAVhFKCjw==", + "dev": true + }, "@types/eslint": { "version": "7.2.6", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.6.tgz", @@ -2199,11 +2333,27 @@ "@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==", + "dev": true, + "requires": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "@types/html-minifier-terser": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", "integrity": "sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA==" }, + "@types/invariant": { + "version": "2.2.34", + "resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.34.tgz", + "integrity": "sha512-lYUtmJ9BqUN688fGY1U1HZoWT1/Jrmgigx2loq4ZcJpICECm/Om3V314BxdzypO0u5PORKGMM6x0OXaljV1YFg==", + "dev": true + }, "@types/istanbul-lib-coverage": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", @@ -2244,6 +2394,12 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" }, + "@types/lodash": { + "version": "4.14.168", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz", + "integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==", + "dev": true + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -2269,11 +2425,44 @@ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.1.tgz", "integrity": "sha512-DxZZbyMAM9GWEzXL+BMZROWz9oo6A9EilwwOMET2UVu2uZTqMWS5S69KVtuVKaRjCUpcrOXRalet86/OpG4kqw==" }, + "@types/prop-types": { + "version": "15.7.3", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==", + "dev": true + }, "@types/q": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" }, + "@types/react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.2.tgz", + "integrity": "sha512-Xt40xQsrkdvjn1EyWe1Bc0dJLcil/9x2vAuW7ya+PuQip4UYUaXyhzWmAbwRsdMgwOFHpfp7/FFZebDU6Y8VHA==", + "dev": true, + "requires": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + }, + "dependencies": { + "csstype": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.6.tgz", + "integrity": "sha512-+ZAmfyWMT7TiIlzdqJgjMb7S4f1beorDbWbsocyK4RaiqA5RTX3K14bnBWmmA9QEM0gRdsjyyrEmcyga8Zsxmw==", + "dev": true + } + } + }, + "@types/react-transition-group": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.1.tgz", + "integrity": "sha512-vIo69qKKcYoJ8wKCJjwSgCTM+z3chw3g18dkrDfVX665tMH7tmbDxEAnPdey4gTlwZz5QuHGzd+hul0OVZDqqQ==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/resolve": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", @@ -2320,6 +2509,12 @@ } } }, + "@types/warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI=", + "dev": true + }, "@types/webpack": { "version": "4.41.26", "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.26.tgz", @@ -2984,6 +3179,15 @@ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.1.2.tgz", "integrity": "sha512-V+Nq70NxKhYt89ArVcaNL9FDryB3vQOd+BFXZIfO3RP6rwtj+2yqqqdHEkacutglPaZLkJeuXKCjCJDMGPtPqg==" }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "dev": true, + "requires": { + "follow-redirects": "^1.10.0" + } + }, "axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -3965,6 +4169,12 @@ } } }, + "classnames": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", + "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==", + "dev": true + }, "clean-css": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", @@ -3995,6 +4205,12 @@ "wrap-ansi": "^6.2.0" } }, + "clsx": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", + "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==", + "dev": true + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -4508,6 +4724,16 @@ } } }, + "css-vendor": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", + "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.8.3", + "is-in-browser": "^1.0.2" + } + }, "css-what": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", @@ -4684,6 +4910,12 @@ } } }, + "csstype": { + "version": "2.6.15", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.15.tgz", + "integrity": "sha512-FNeiVKudquehtR3t9TRRnsHL+lJhuHF5Zn9dt01jpojlurLEPDhhEtUkWmAUJ7/fOLaLG4dCDEnUsR0N1rZSsg==", + "dev": true + }, "cyclist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", @@ -4970,6 +5202,17 @@ "path-type": "^4.0.0" } }, + "dnd-core": { + "version": "11.1.3", + "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-11.1.3.tgz", + "integrity": "sha512-QugF55dNW+h+vzxVJ/LSJeTeUw9MCJ2cllhmVThVPEtF16ooBkxj0WBE5RB+AceFxMFo1rO6bJKXtqKl+JNnyA==", + "dev": true, + "requires": { + "@react-dnd/asap": "^4.0.0", + "@react-dnd/invariant": "^2.0.0", + "redux": "^4.0.4" + } + }, "dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", @@ -5013,6 +5256,24 @@ "utila": "~0.4" } }, + "dom-helpers": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.0.tgz", + "integrity": "sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + }, + "dependencies": { + "csstype": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.6.tgz", + "integrity": "sha512-+ZAmfyWMT7TiIlzdqJgjMb7S4f1beorDbWbsocyK4RaiqA5RTX3K14bnBWmmA9QEM0gRdsjyyrEmcyga8Zsxmw==", + "dev": true + } + } + }, "dom-serializer": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", @@ -6668,6 +6929,56 @@ } } }, + "frontend-collective-react-dnd-scrollzone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/frontend-collective-react-dnd-scrollzone/-/frontend-collective-react-dnd-scrollzone-1.0.2.tgz", + "integrity": "sha512-me/D9PZJq9j/sjEjs/OPmm6V6nbaHbhgeQiwrWu0t35lhwAOKWc+QBzzKKcZQeboYTkgE8UvCD9el+5ANp+g5Q==", + "dev": true, + "requires": { + "hoist-non-react-statics": "^3.1.0", + "lodash.throttle": "^4.0.1", + "prop-types": "^15.5.9", + "raf": "^3.2.0", + "react": "^16.3.0", + "react-display-name": "^0.2.0", + "react-dom": "^16.3.0" + }, + "dependencies": { + "react": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + } + }, + "react-dom": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", + "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.19.1" + } + }, + "scheduler": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", + "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + } + } + }, "fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -6856,6 +7167,12 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" }, + "graphql": { + "version": "15.5.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.5.0.tgz", + "integrity": "sha512-OmaM7y0kaK31NKG31q4YbD2beNYa6jBBKtMFT6gLYJljHLJr42IqJ8KX08u3Li/0ifzTU5HjmoOOrwa5BRLeDA==", + "dev": true + }, "growly": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", @@ -6996,6 +7313,20 @@ "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" }, + "history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "dev": true, + "requires": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -7006,6 +7337,14 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "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" + } + }, "hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -7325,6 +7664,12 @@ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==" }, + "hyphenate-style-name": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", + "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==", + "dev": true + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -7369,6 +7714,12 @@ "resolved": "https://registry.npmjs.org/immer/-/immer-7.0.9.tgz", "integrity": "sha512-Vs/gxoM4DqNAYR7pugIxi0Xc8XAun/uy7AQu4fLLqaTBHxjOP9pJ266Q9MWA/ly4z6rAFZbvViOtihxUZ7O28A==" }, + "immutable": { + "version": "4.0.0-rc.12", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0-rc.12.tgz", + "integrity": "sha512-0M2XxkZLx/mi3t8NVwIm1g8nHoEmM9p9UBl/G9k4+hm0kBgOVdMV/B3CY5dQ8qG8qc80NN4gDV4HQv6FTJ5q7A==", + "dev": true + }, "import-cwd": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", @@ -7425,6 +7776,15 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, + "indefinite-observable": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/indefinite-observable/-/indefinite-observable-2.0.1.tgz", + "integrity": "sha512-G8vgmork+6H9S8lUAg1gtXEj2JxIQTo0g2PbFiYOdjkziSI0F7UYBiVwhZRuixhBCNGczAls34+5HJPyZysvxQ==", + "dev": true, + "requires": { + "symbol-observable": "1.2.0" + } + }, "indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", @@ -7478,6 +7838,15 @@ "side-channel": "^1.0.4" } }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, "ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", @@ -7655,6 +8024,12 @@ "is-extglob": "^2.1.1" } }, + "is-in-browser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", + "integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU=", + "dev": true + }, "is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", @@ -9463,6 +9838,101 @@ "verror": "1.10.0" } }, + "jss": { + "version": "10.5.1", + "resolved": "https://registry.npmjs.org/jss/-/jss-10.5.1.tgz", + "integrity": "sha512-hbbO3+FOTqVdd7ZUoTiwpHzKXIo5vGpMNbuXH1a0wubRSWLWSBvwvaq4CiHH/U42CmjOnp6lVNNs/l+Z7ZdDmg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.3.1", + "csstype": "^3.0.2", + "indefinite-observable": "^2.0.1", + "is-in-browser": "^1.1.3", + "tiny-warning": "^1.0.2" + }, + "dependencies": { + "csstype": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.6.tgz", + "integrity": "sha512-+ZAmfyWMT7TiIlzdqJgjMb7S4f1beorDbWbsocyK4RaiqA5RTX3K14bnBWmmA9QEM0gRdsjyyrEmcyga8Zsxmw==", + "dev": true + } + } + }, + "jss-plugin-camel-case": { + "version": "10.5.1", + "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.5.1.tgz", + "integrity": "sha512-9+oymA7wPtswm+zxVti1qiowC5q7bRdCJNORtns2JUj/QHp2QPXYwSNRD8+D2Cy3/CEMtdJzlNnt5aXmpS6NAg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.3.1", + "hyphenate-style-name": "^1.0.3", + "jss": "10.5.1" + } + }, + "jss-plugin-default-unit": { + "version": "10.5.1", + "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.5.1.tgz", + "integrity": "sha512-D48hJBc9Tj3PusvlillHW8Fz0y/QqA7MNmTYDQaSB/7mTrCZjt7AVRROExoOHEtd2qIYKOYJW3Jc2agnvsXRlQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.5.1" + } + }, + "jss-plugin-global": { + "version": "10.5.1", + "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.5.1.tgz", + "integrity": "sha512-jX4XpNgoaB8yPWw/gA1aPXJEoX0LNpvsROPvxlnYe+SE0JOhuvF7mA6dCkgpXBxfTWKJsno7cDSCgzHTocRjCQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.5.1" + } + }, + "jss-plugin-nested": { + "version": "10.5.1", + "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.5.1.tgz", + "integrity": "sha512-xXkWKOCljuwHNjSYcXrCxBnjd8eJp90KVFW1rlhvKKRXnEKVD6vdKXYezk2a89uKAHckSvBvBoDGsfZrldWqqQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.5.1", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-props-sort": { + "version": "10.5.1", + "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.5.1.tgz", + "integrity": "sha512-t+2vcevNmMg4U/jAuxlfjKt46D/jHzCPEjsjLRj/J56CvP7Iy03scsUP58Iw8mVnaV36xAUZH2CmAmAdo8994g==", + "dev": true, + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.5.1" + } + }, + "jss-plugin-rule-value-function": { + "version": "10.5.1", + "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.5.1.tgz", + "integrity": "sha512-3gjrSxsy4ka/lGQsTDY8oYYtkt2esBvQiceGBB4PykXxHoGRz14tbCK31Zc6DHEnIeqsjMUGbq+wEly5UViStQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.5.1", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-vendor-prefixer": { + "version": "10.5.1", + "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.5.1.tgz", + "integrity": "sha512-cLkH6RaPZWHa1TqSfd2vszNNgxT1W0omlSjAd6hCFHp3KIocSrW21gaHjlMU26JpTHwkc+tJTCQOmE/O1A4FKQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.3.1", + "css-vendor": "^2.0.8", + "jss": "10.5.1" + } + }, "jsx-ast-utils": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", @@ -9587,16 +10057,70 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "dev": true + }, "lodash._reinterpolate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" }, + "lodash.assignwith": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz", + "integrity": "sha1-EnqX8CrcQXUalU0ksN4X4QDgOOs=", + "dev": true + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, + "lodash.find": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.find/-/lodash.find-4.6.0.tgz", + "integrity": "sha1-ywcE1Hq3F4n/oN6Ll92Sb7iLE7E=", + "dev": true + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", + "dev": true + }, + "lodash.isundefined": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash.isundefined/-/lodash.isundefined-3.0.1.tgz", + "integrity": "sha1-I+89lTVWUgOmbO/VuDD4SJEa+0g=", + "dev": true + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", @@ -9619,6 +10143,12 @@ "lodash._reinterpolate": "^3.0.0" } }, + "lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=", + "dev": true + }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -9841,6 +10371,15 @@ "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==" }, + "mini-create-react-context": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz", + "integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==", + "requires": { + "@babel/runtime": "^7.12.1", + "tiny-warning": "^1.0.3" + } + }, "mini-css-extract-plugin": { "version": "0.11.3", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.11.3.tgz", @@ -10018,6 +10557,30 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "mui-datatables": { + "version": "3.7.6", + "resolved": "https://registry.npmjs.org/mui-datatables/-/mui-datatables-3.7.6.tgz", + "integrity": "sha512-yfM7NVWdZLRES4lGGVKnHvCZhbL/lo8sGMGaC0iBkc8nDghd49kFZVNxoC7jwivUrZslwDeroHpXCLghUh7f8A==", + "dev": true, + "requires": { + "@babel/runtime-corejs3": "^7.12.1", + "clsx": "^1.1.1", + "lodash.assignwith": "^4.2.0", + "lodash.clonedeep": "^4.5.0", + "lodash.debounce": "^4.0.8", + "lodash.find": "^4.6.0", + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "lodash.isundefined": "^3.0.1", + "lodash.memoize": "^4.1.2", + "lodash.merge": "^4.6.2", + "prop-types": "^15.7.2", + "react-dnd": "^11.1.3", + "react-dnd-html5-backend": "^11.1.3", + "react-sortable-tree": "^2.7.1", + "react-to-print": "^2.8.0" + } + }, "multicast-dns": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", @@ -10032,6 +10595,12 @@ "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=" }, + "nanoclone": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz", + "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==", + "dev": true + }, "nanoid": { "version": "3.1.20", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", @@ -10840,6 +11409,12 @@ "ts-pnp": "^1.1.6" } }, + "popper.js": { + "version": "1.16.1-lts", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz", + "integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA==", + "dev": true + }, "portfinder": { "version": "1.0.28", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", @@ -11972,6 +12547,22 @@ "react-is": "^16.8.1" } }, + "prop-types-extra": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "dev": true, + "requires": { + "react-is": "^16.3.2", + "warning": "^4.0.0" + } + }, + "property-expr": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.4.tgz", + "integrity": "sha512-sFPkHQjVKheDNnPvotjQmm3KD3uk1fWKUN7CrpdbwmUx3CrG3QiM8QpTSimvig5vTXmTvjz7+TDvXOI9+4rkcg==", + "dev": true + }, "proxy-addr": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", @@ -12155,6 +12746,32 @@ "whatwg-fetch": "^3.4.1" } }, + "react-bootstrap": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.5.0.tgz", + "integrity": "sha512-t1o4kP3coj2HIaBepJxGAc7HZ1fWGria/s0Yr9JUmNkCilyrnXtK209qn28vuZ4muhnA0uR0GMMXAMrLsLyiIw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.2", + "@restart/context": "^2.1.4", + "@restart/hooks": "^0.3.21", + "@types/classnames": "^2.2.10", + "@types/invariant": "^2.2.33", + "@types/prop-types": "^15.7.3", + "@types/react": ">=16.9.35", + "@types/react-transition-group": "^4.4.0", + "@types/warning": "^3.0.0", + "classnames": "^2.2.6", + "dom-helpers": "^5.1.2", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "prop-types-extra": "^1.1.0", + "react-overlays": "^4.1.1", + "react-transition-group": "^4.4.1", + "uncontrollable": "^7.0.0", + "warning": "^4.0.3" + } + }, "react-dev-utils": { "version": "11.0.2", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.2.tgz", @@ -12261,6 +12878,33 @@ } } }, + "react-display-name": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/react-display-name/-/react-display-name-0.2.5.tgz", + "integrity": "sha512-I+vcaK9t4+kypiSgaiVWAipqHRXYmZIuAiS8vzFvXHHXVigg/sMKwlRgLy6LH2i3rmP+0Vzfl5lFsFRwF1r3pg==", + "dev": true + }, + "react-dnd": { + "version": "11.1.3", + "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-11.1.3.tgz", + "integrity": "sha512-8rtzzT8iwHgdSC89VktwhqdKKtfXaAyC4wiqp0SywpHG12TTLvfOoL6xNEIUWXwIEWu+CFfDn4GZJyynCEuHIQ==", + "dev": true, + "requires": { + "@react-dnd/shallowequal": "^2.0.0", + "@types/hoist-non-react-statics": "^3.3.1", + "dnd-core": "^11.1.3", + "hoist-non-react-statics": "^3.3.0" + } + }, + "react-dnd-html5-backend": { + "version": "11.1.3", + "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-11.1.3.tgz", + "integrity": "sha512-/1FjNlJbW/ivkUxlxQd7o3trA5DE33QiRZgxent3zKme8DwF4Nbw3OFVhTRFGaYhHFNL1rZt6Rdj1D78BjnNLw==", + "dev": true, + "requires": { + "dnd-core": "^11.1.3" + } + }, "react-dom": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.1.tgz", @@ -12276,16 +12920,133 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz", "integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==" }, + "react-image-resizer": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-image-resizer/-/react-image-resizer-1.3.0.tgz", + "integrity": "sha512-JZwNWumImYwPNeaf+MV5wEtUvyPK8crjLYo7AVf3/3LQ92oPwi/Clxmg76f14EQm73cbwxKgXTlJbFOSRGQGtA==", + "dev": true + }, "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==" }, + "react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", + "dev": true + }, + "react-overlays": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-4.1.1.tgz", + "integrity": "sha512-WtJifh081e6M24KnvTQoNjQEpz7HoLxqt8TwZM7LOYIkYJ8i/Ly1Xi7RVte87ZVnmqQ4PFaFiNHZhSINPSpdBQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.1", + "@popperjs/core": "^2.5.3", + "@restart/hooks": "^0.3.25", + "@types/warning": "^3.0.0", + "dom-helpers": "^5.2.0", + "prop-types": "^15.7.2", + "uncontrollable": "^7.0.0", + "warning": "^4.0.3" + } + }, + "react-redux": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.2.tgz", + "integrity": "sha512-8+CQ1EvIVFkYL/vu6Olo7JFLWop1qRUeb46sGtIMDCSpgwPQq8fPLpirIB0iTqFe9XYEFPHssdX8/UwN6pAkEA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.1", + "hoist-non-react-statics": "^3.3.2", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-is": "^16.13.1" + } + }, "react-refresh": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", "integrity": "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==" }, + "react-router": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz", + "integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==", + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "mini-create-react-context": "^0.4.0", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "dependencies": { + "history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "requires": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "requires": { + "isarray": "0.0.1" + } + } + } + }, + "react-router-dom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz", + "integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.2.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "dependencies": { + "history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "dev": true, + "requires": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + } + } + }, "react-scripts": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-4.0.2.tgz", @@ -12352,6 +13113,56 @@ "workbox-webpack-plugin": "5.1.4" } }, + "react-sortable-tree": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/react-sortable-tree/-/react-sortable-tree-2.8.0.tgz", + "integrity": "sha512-gTjwxRNt7z0FC76KeNTnGqx1qUSlV3N78mMPRushBpSUXzZYhiFNsWHUIruyPnaAbw4SA7LgpItV7VieAuwDpw==", + "dev": true, + "requires": { + "frontend-collective-react-dnd-scrollzone": "^1.0.2", + "lodash.isequal": "^4.5.0", + "prop-types": "^15.6.1", + "react-dnd": "^11.1.3", + "react-dnd-html5-backend": "^11.1.3", + "react-lifecycles-compat": "^3.0.4", + "react-virtualized": "^9.21.2" + } + }, + "react-to-print": { + "version": "2.12.3", + "resolved": "https://registry.npmjs.org/react-to-print/-/react-to-print-2.12.3.tgz", + "integrity": "sha512-JpjPh2WDo2nraxgyt5p3kHMMZZDs52uDcgJJi7BbgmE/j3v1RcTtr3s3uvDk82WRjLWggDm1Ro2J9/L9qkH4cQ==", + "dev": true, + "requires": { + "prop-types": "^15.7.2" + } + }, + "react-transition-group": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz", + "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + }, + "react-virtualized": { + "version": "9.22.3", + "resolved": "https://registry.npmjs.org/react-virtualized/-/react-virtualized-9.22.3.tgz", + "integrity": "sha512-MKovKMxWTcwPSxE1kK1HcheQTWfuCxAuBoSTf2gwyMM21NdX/PXUhnoP8Uc5dRKd+nKm8v41R36OellhdCpkrw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "clsx": "^1.0.4", + "dom-helpers": "^5.1.3", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-lifecycles-compat": "^3.0.4" + } + }, "read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", @@ -12467,6 +13278,27 @@ "strip-indent": "^3.0.0" } }, + "redux": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz", + "integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "symbol-observable": "^1.2.0" + } + }, + "redux-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redux-observable/-/redux-observable-1.2.0.tgz", + "integrity": "sha512-yeR90RP2WzZzCxxnQPlh2uFzyfFLsfXu8ROh53jGDPXVqj71uNDMmvi/YKQkd9ofiVoO4OYb1snbowO49tCEMg==", + "dev": true + }, + "redux-thunk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz", + "integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==" + }, "regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -12722,6 +13554,11 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, + "resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -12954,6 +13791,15 @@ "aproba": "^1.1.1" } }, + "rxjs": { + "version": "6.6.6", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.6.tgz", + "integrity": "sha512-/oTwee4N4iWzAMAL9xdGKjkEHmIwupR3oXbQjCKywF1BeFohswF3vZdogbmEF6pZkOsXTzWkrZszrWpQTByYVg==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -14101,6 +14947,12 @@ "util.promisify": "~1.0.0" } }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "dev": true + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -14378,6 +15230,16 @@ "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" }, + "tiny-invariant": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", + "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" + }, + "tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -14435,6 +15297,12 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, + "toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha1-riF2gXXRVZ1IvvNUILL0li8JwzA=", + "dev": true + }, "tough-cookie": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", @@ -14560,6 +15428,18 @@ "is-typedarray": "^1.0.0" } }, + "uncontrollable": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", + "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.6.3", + "@types/react": ">=16.9.11", + "invariant": "^2.2.4", + "react-lifecycles-compat": "^3.0.4" + } + }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", @@ -14853,6 +15733,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -14902,6 +15787,15 @@ "makeerror": "1.0.x" } }, + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, "watchpack": { "version": "1.7.5", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", @@ -16370,6 +17264,21 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + }, + "yup": { + "version": "0.32.9", + "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.9.tgz", + "integrity": "sha512-Ci1qN+i2H0XpY7syDQ0k5zKQ/DoxO0LzPg8PAR/X4Mpj6DqaeCoIYEEjDJwhArh3Fa7GWbQQVDZKeXYlSH4JMg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.10.5", + "@types/lodash": "^4.14.165", + "lodash": "^4.17.20", + "lodash-es": "^4.17.15", + "nanoclone": "^0.2.1", + "property-expr": "^2.0.4", + "toposort": "^2.0.2" + } } } } diff --git a/package.json b/package.json index 6a3faf4..ea59324 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,9 @@ "@testing-library/user-event": "^12.7.1", "react": "^17.0.1", "react-dom": "^17.0.1", + "react-router": "^5.2.0", "react-scripts": "4.0.2", + "redux-thunk": "^2.3.0", "web-vitals": "^1.1.0" }, "scripts": { @@ -34,5 +36,23 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "@material-ui/core": "^4.11.3", + "@material-ui/icons": "^4.11.2", + "axios": "^0.21.1", + "graphql": "^15.5.0", + "history": "^4.10.1", + "immutable": "^4.0.0-rc.12", + "lodash": "^4.17.21", + "mui-datatables": "^3.7.6", + "react-bootstrap": "^1.5.0", + "react-image-resizer": "^1.3.0", + "react-redux": "^7.2.2", + "react-router-dom": "^5.2.0", + "redux": "^4.0.5", + "yup": "^0.32.9", + "redux-observable": "^1.2.0", + "rxjs": "^6.6.6" } } diff --git a/src/App.css b/src/App.css index 74b5e05..039660f 100644 --- a/src/App.css +++ b/src/App.css @@ -26,8 +26,38 @@ .App-link { color: #61dafb; + text-align: center; + justify-content: center; +} +.FoodTypeLink{ + color: black; + text-align: center; +} +.fullPage{ + padding: 120px 0; + position: relative; + min-height: 65vh; + display:flex!important; + margin:0; + border:0; + color:#FFF; + align-items: center; + background-size: cover; + background-position: center center; + height: 100%; +} +.CardImage{ + height: 180px; + marginLeft: 113px; + paddingLeft: 56.25%; + paddingTop: 56.25%; + marginTop: 10px; + width: 10px; +} +.Images{ + width: 150px; + height: 150px; } - @keyframes App-logo-spin { from { transform: rotate(0deg); diff --git a/src/App.js b/src/App.js index 3784575..8cff8ea 100644 --- a/src/App.js +++ b/src/App.js @@ -1,25 +1,19 @@ -import logo from './logo.svg'; +import {NavBar} from "./core/navbar/navbar"; import './App.css'; +import {Routes} from "./core/routes/routes"; +import {BrowserRouter as Router} from "react-router-dom"; +import {Provider} from 'react-redux' +import {configureStore} from "./core/store/store" -function App() { - return ( -
-
- logo -

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

- - Learn React - -
-
- ); -} +const store = configureStore() + + +const App = () => + + + + + + export default App; diff --git a/src/core/history.js b/src/core/history.js new file mode 100644 index 0000000..edc15c9 --- /dev/null +++ b/src/core/history.js @@ -0,0 +1,2 @@ +import {createBrowserHistory as history} from 'history' +export default history(); \ No newline at end of file diff --git a/src/core/images/background.jpeg b/src/core/images/background.jpeg new file mode 100644 index 0000000..7f2777e Binary files /dev/null and b/src/core/images/background.jpeg differ diff --git a/src/core/images/background.jpg b/src/core/images/background.jpg new file mode 100644 index 0000000..430a898 Binary files /dev/null and b/src/core/images/background.jpg differ diff --git a/src/core/images/brothImg.jpeg b/src/core/images/brothImg.jpeg new file mode 100644 index 0000000..bbe65d7 Binary files /dev/null and b/src/core/images/brothImg.jpeg differ diff --git a/src/core/images/burgerImg.jpeg b/src/core/images/burgerImg.jpeg new file mode 100644 index 0000000..0895062 Binary files /dev/null and b/src/core/images/burgerImg.jpeg differ diff --git a/src/core/images/crazySandwich.jpeg b/src/core/images/crazySandwich.jpeg new file mode 100644 index 0000000..ffdcad5 Binary files /dev/null and b/src/core/images/crazySandwich.jpeg differ diff --git a/src/core/images/desertImg.jpeg b/src/core/images/desertImg.jpeg new file mode 100644 index 0000000..cc24c2c Binary files /dev/null and b/src/core/images/desertImg.jpeg differ diff --git a/src/core/images/fancySandiwch.jpeg b/src/core/images/fancySandiwch.jpeg new file mode 100644 index 0000000..3bf89bd Binary files /dev/null and b/src/core/images/fancySandiwch.jpeg differ diff --git a/src/core/images/funnySandwich.jpeg b/src/core/images/funnySandwich.jpeg new file mode 100644 index 0000000..698c1db Binary files /dev/null and b/src/core/images/funnySandwich.jpeg differ diff --git a/src/core/images/pizzaImg.jpeg b/src/core/images/pizzaImg.jpeg new file mode 100644 index 0000000..98d3900 Binary files /dev/null and b/src/core/images/pizzaImg.jpeg differ diff --git a/src/core/images/sandwichImg.jpeg b/src/core/images/sandwichImg.jpeg new file mode 100644 index 0000000..a0c558c Binary files /dev/null and b/src/core/images/sandwichImg.jpeg differ diff --git a/src/core/images/sodaImg.jpeg b/src/core/images/sodaImg.jpeg new file mode 100644 index 0000000..15ab143 Binary files /dev/null and b/src/core/images/sodaImg.jpeg differ diff --git a/src/core/images/uglySandwich.jpeg b/src/core/images/uglySandwich.jpeg new file mode 100644 index 0000000..977d1ea Binary files /dev/null and b/src/core/images/uglySandwich.jpeg differ diff --git a/src/core/navbar/hooks/use-routes-on-click.jsx b/src/core/navbar/hooks/use-routes-on-click.jsx new file mode 100644 index 0000000..2765659 --- /dev/null +++ b/src/core/navbar/hooks/use-routes-on-click.jsx @@ -0,0 +1,7 @@ +import history from "../../../core/history" + +export const useRoutesOnClick = link =>{ + return () =>{ + history.push(link) + } +} \ No newline at end of file diff --git a/src/core/navbar/navbar-icons/navbar-icons.jsx b/src/core/navbar/navbar-icons/navbar-icons.jsx new file mode 100644 index 0000000..4bfb2d8 --- /dev/null +++ b/src/core/navbar/navbar-icons/navbar-icons.jsx @@ -0,0 +1,10 @@ +import {IconButton} from "@material-ui/core"; +import {useRoutesOnClick} from "../hooks/use-routes-on-click"; + +export const NavbarIcons = ({link, icon, edge = 'start'}) => { + const onClick = useRoutesOnClick(link); + + return + {icon} + +} \ No newline at end of file diff --git a/src/core/navbar/navbar-shopping-cart/navbar-shopping-cart.jsx b/src/core/navbar/navbar-shopping-cart/navbar-shopping-cart.jsx new file mode 100644 index 0000000..568b3b0 --- /dev/null +++ b/src/core/navbar/navbar-shopping-cart/navbar-shopping-cart.jsx @@ -0,0 +1,17 @@ +import {Badge, IconButton} from "@material-ui/core"; +import {useRoutesOnClick} from "../hooks/use-routes-on-click"; +import React from "react"; +import {useSelector} from "react-redux"; + +export const NavbarShoppingCart = ({link, icon, edge = 'start'}) => { + const onClick = useRoutesOnClick(link); + const shoppingCartData = useSelector(selector) + + return + + {icon} + + +} + +const selector = ({shoppingCartReducer}) => shoppingCartReducer.items \ No newline at end of file diff --git a/src/core/navbar/navbar-title/navbar-title.jsx b/src/core/navbar/navbar-title/navbar-title.jsx new file mode 100644 index 0000000..9036a76 --- /dev/null +++ b/src/core/navbar/navbar-title/navbar-title.jsx @@ -0,0 +1,5 @@ +import {Typography} from "@material-ui/core"; + +export const NavbarTitle = ({text}) => + {text} + \ No newline at end of file diff --git a/src/core/navbar/navbar.jsx b/src/core/navbar/navbar.jsx new file mode 100644 index 0000000..f82765e --- /dev/null +++ b/src/core/navbar/navbar.jsx @@ -0,0 +1,17 @@ +import {AppBar, Toolbar} from '@material-ui/core' +import HomeIcon from '@material-ui/icons/Home' +import {RestaurantMenu} from "@material-ui/icons"; +import {NavbarIcons} from "./navbar-icons/navbar-icons"; +import {NavbarTitle} from "./navbar-title/navbar-title"; +import AddShoppingCartIcon from '@material-ui/icons/AddShoppingCart'; +import {NavbarShoppingCart} from "./navbar-shopping-cart/navbar-shopping-cart"; + +export const NavBar = () => + + + } /> + } /> + + } edge={'end'} /> + + \ No newline at end of file diff --git a/src/core/routes/routes.jsx b/src/core/routes/routes.jsx new file mode 100644 index 0000000..92f2326 --- /dev/null +++ b/src/core/routes/routes.jsx @@ -0,0 +1,16 @@ +import {Router, Route, Switch} from "react-router-dom"; +import {Home} from "../../home/home"; +import {FoodMenu} from "../../menu/containers"; +import history from '.././history'; +import {SandwichMenu} from "../../sandwich-menu/containers"; +import {ShoppingCart} from "../../shopping-cart/containers"; + +export const Routes = () => + + + + + + + + \ No newline at end of file diff --git a/src/core/site-error/error.jsx b/src/core/site-error/error.jsx new file mode 100644 index 0000000..9520367 --- /dev/null +++ b/src/core/site-error/error.jsx @@ -0,0 +1,5 @@ +import {Box} from "@material-ui/core"; + +export const Error = () => +
The site has ran into an error. Please try again shortly
+
\ No newline at end of file diff --git a/src/core/store/store.js b/src/core/store/store.js new file mode 100644 index 0000000..45c841e --- /dev/null +++ b/src/core/store/store.js @@ -0,0 +1,11 @@ +import {createStore, applyMiddleware} from "redux"; +import {rootReducers} from "../../startup/reducers/index"; +import {createEpicMiddleware} from 'redux-observable' +import {rootEpic} from "../../startup/epics"; + +export const configureStore = () => { + const epicMiddleWare = createEpicMiddleware(); + const store = createStore(rootReducers, applyMiddleware(epicMiddleWare)); + epicMiddleWare.run(rootEpic) + return store; +} \ No newline at end of file diff --git a/src/home/home.jsx b/src/home/home.jsx new file mode 100644 index 0000000..1055c03 --- /dev/null +++ b/src/home/home.jsx @@ -0,0 +1,15 @@ +import logo from '../logo.svg' +import {Link} from "react-router-dom"; + +export const Home = () => +
+
+ logo +

+ Welcome to React Restaurant +

+ + Go to menu + +
+
\ No newline at end of file diff --git a/src/menu/components/menu.jsx b/src/menu/components/menu.jsx new file mode 100644 index 0000000..2634031 --- /dev/null +++ b/src/menu/components/menu.jsx @@ -0,0 +1,8 @@ +import background from '../../core/images/background.jpg' +import {FoodCards} from "../containers/food-cards/food-cards"; + + +export const Menu = () => +
+ +
diff --git a/src/menu/containers/context.js b/src/menu/containers/context.js new file mode 100644 index 0000000..7138e89 --- /dev/null +++ b/src/menu/containers/context.js @@ -0,0 +1,3 @@ +import {createContext} from "react"; + +export const MenuContext = createContext({}) \ No newline at end of file diff --git a/src/menu/containers/food-card/body/food-card-body.jsx b/src/menu/containers/food-card/body/food-card-body.jsx new file mode 100644 index 0000000..408865a --- /dev/null +++ b/src/menu/containers/food-card/body/food-card-body.jsx @@ -0,0 +1,5 @@ +import {Typography} from "@material-ui/core"; + +export const FoodCardBody = ({foodItem}) => + {foodItem.description} + \ No newline at end of file diff --git a/src/menu/containers/food-card/food-card.jsx b/src/menu/containers/food-card/food-card.jsx new file mode 100644 index 0000000..c6a382b --- /dev/null +++ b/src/menu/containers/food-card/food-card.jsx @@ -0,0 +1,19 @@ +import {Card, CardActionArea, CardContent, CardMedia} from "@material-ui/core"; +import history from "../../../core/history"; +import {FoodCardTitle} from "./title/food-card-title"; +import {FoodCardBody} from "./body/food-card-body"; + +export const FoodCard = ({foodItem}) => + history.push(`menu/${foodItem.path}`)}> + + + + + + + \ No newline at end of file diff --git a/src/menu/containers/food-card/title/food-card-title.jsx b/src/menu/containers/food-card/title/food-card-title.jsx new file mode 100644 index 0000000..8f95987 --- /dev/null +++ b/src/menu/containers/food-card/title/food-card-title.jsx @@ -0,0 +1,5 @@ +import {Typography} from "@material-ui/core"; + +export const FoodCardTitle = ({foodItem}) => + {foodItem.name} + \ No newline at end of file diff --git a/src/menu/containers/food-cards/food-cards.jsx b/src/menu/containers/food-cards/food-cards.jsx new file mode 100644 index 0000000..f472ad2 --- /dev/null +++ b/src/menu/containers/food-cards/food-cards.jsx @@ -0,0 +1,13 @@ +import {Box, Grid} from "@material-ui/core"; +import {useMenuContext} from "../hooks/use-menu-context"; +import {FoodCard} from "../food-card/food-card"; + +export const FoodCards = () => + + {useMenuContext().data.map(foodItem => + + + + )} + + \ No newline at end of file diff --git a/src/menu/containers/hooks/use-defaul-menu-context.js b/src/menu/containers/hooks/use-defaul-menu-context.js new file mode 100644 index 0000000..1223907 --- /dev/null +++ b/src/menu/containers/hooks/use-defaul-menu-context.js @@ -0,0 +1,6 @@ +import {useState} from "react"; + +export const useDefaultMenuContext = () => { + const [data, setData] = useState([]) + return {data, setData} +} \ No newline at end of file diff --git a/src/menu/containers/hooks/use-init.js b/src/menu/containers/hooks/use-init.js new file mode 100644 index 0000000..2803a6a --- /dev/null +++ b/src/menu/containers/hooks/use-init.js @@ -0,0 +1,8 @@ +import {useMenuContext} from "./use-menu-context"; +import {foodData} from '../../data/food' +import {useEffect} from "react"; + +export const useInit = () => { + const {setData} = useMenuContext() + useEffect(() => setData(() => foodData),[]) +} \ No newline at end of file diff --git a/src/menu/containers/hooks/use-menu-context.js b/src/menu/containers/hooks/use-menu-context.js new file mode 100644 index 0000000..fd1bdd0 --- /dev/null +++ b/src/menu/containers/hooks/use-menu-context.js @@ -0,0 +1,4 @@ +import {useContext} from "react"; +import {MenuContext} from "../context"; + +export const useMenuContext = () => useContext(MenuContext) diff --git a/src/menu/containers/index.jsx b/src/menu/containers/index.jsx new file mode 100644 index 0000000..99488b0 --- /dev/null +++ b/src/menu/containers/index.jsx @@ -0,0 +1,10 @@ +import {MenuContext} from "./context"; +import {useDefaultMenuContext} from "./hooks/use-defaul-menu-context"; +import {InitBehaviour} from "./init-behaviour"; +import {Menu} from "../components/menu"; + +export const FoodMenu = () => + + + + \ No newline at end of file diff --git a/src/menu/containers/init-behaviour.js b/src/menu/containers/init-behaviour.js new file mode 100644 index 0000000..bb7711e --- /dev/null +++ b/src/menu/containers/init-behaviour.js @@ -0,0 +1,6 @@ +import {useInit} from "./hooks/use-init"; + +export const InitBehaviour = () => { + useInit() + return '' +} \ No newline at end of file diff --git a/src/menu/data/food.js b/src/menu/data/food.js new file mode 100644 index 0000000..22e99b4 --- /dev/null +++ b/src/menu/data/food.js @@ -0,0 +1,59 @@ +import sandwichImg from '../../core/images/sandwichImg.jpeg' +import burgerImg from '../../core/images/burgerImg.jpeg' +import pizzaImg from '../../core/images/pizzaImg.jpeg' +import brothImg from '../../core/images/brothImg.jpeg' +import desertImg from '../../core/images/desertImg.jpeg' +import sodaImg from '../../core/images/sodaImg.jpeg' + +export const foodData = [ + { + id:1, + name: "Sandwich", + img: sandwichImg, + alt: 'sandwich image', + path: 'sandwiches', + description: 'Aici poti gasi toate tipurile de sandwich-uri' + }, + { + id:2, + name: "Burger", + img: burgerImg, + alt: 'burger image', + path: 'burgers', + description: 'Aici poti gasi toate tipurile de burgeri' + }, + { + id:3, + name: "Pizza", + img: pizzaImg, + alt: 'pizza image', + path: 'pizzas', + description: 'Aici poti gasi toate tipurile de pizza' + }, + { + id:4, + name: "Ciorba", + img: brothImg, + alt: 'broth image', + path: 'broths', + description: 'Aici poti gasi toate tipurile de ciorbe' + }, + { + id:5, + name: "Desert", + img: desertImg, + alt: 'desert image', + path: 'deserts', + description: 'Aici poti gasi toate tipurile de deserturi' + }, + { + id:6, + name: "Racoritoare", + img: sodaImg, + alt: 'soda image', + path: 'sodas', + description: 'Aici poti gasi toate tipurile de sucuri' + }, +] + + \ No newline at end of file diff --git a/src/sandwich-menu/actions/get-all-sandwiches-api-attempt.js b/src/sandwich-menu/actions/get-all-sandwiches-api-attempt.js new file mode 100644 index 0000000..695772f --- /dev/null +++ b/src/sandwich-menu/actions/get-all-sandwiches-api-attempt.js @@ -0,0 +1,3 @@ +export const GET_ALL_SANDWICHES_API_ATTEMPT = 'GET_ALL_SANDWICHES_API_ATTEMPT' + +export const getItemsApiAttempt = () => ({type: GET_ALL_SANDWICHES_API_ATTEMPT}) \ No newline at end of file diff --git a/src/sandwich-menu/actions/get-all-sandwiches-api-failure.js b/src/sandwich-menu/actions/get-all-sandwiches-api-failure.js new file mode 100644 index 0000000..cee394f --- /dev/null +++ b/src/sandwich-menu/actions/get-all-sandwiches-api-failure.js @@ -0,0 +1,3 @@ +export const GET_ALL_SANDWICHES_API_FAILURE = 'GET_ALL_SANDWICHES_API_FAILURE' + +export const getItemsApiFailure = () => ({type: GET_ALL_SANDWICHES_API_FAILURE}) \ No newline at end of file diff --git a/src/sandwich-menu/actions/get-all-sandwiches-api-success.js b/src/sandwich-menu/actions/get-all-sandwiches-api-success.js new file mode 100644 index 0000000..b3e3d45 --- /dev/null +++ b/src/sandwich-menu/actions/get-all-sandwiches-api-success.js @@ -0,0 +1,3 @@ +export const GET_ALL_SANDWICHES_API_SUCCESS = 'GET_ALL_SANDWICHES_API_SUCCESS' + +export const getItemsApiSuccess = (data) => ({type: GET_ALL_SANDWICHES_API_SUCCESS, payload: data}) \ No newline at end of file diff --git a/src/sandwich-menu/actions/index.js b/src/sandwich-menu/actions/index.js new file mode 100644 index 0000000..e83e3dc --- /dev/null +++ b/src/sandwich-menu/actions/index.js @@ -0,0 +1,3 @@ +export * from './get-all-sandwiches-api-attempt' +export * from './get-all-sandwiches-api-failure' +export * from './get-all-sandwiches-api-success' \ No newline at end of file diff --git a/src/sandwich-menu/components/sandwich-menu.jsx b/src/sandwich-menu/components/sandwich-menu.jsx new file mode 100644 index 0000000..57ddbdf --- /dev/null +++ b/src/sandwich-menu/components/sandwich-menu.jsx @@ -0,0 +1,15 @@ +import React from "react"; +import {useSelector} from "react-redux"; +import {DataTable} from "../containers/mui-data-table/data-table"; +import {Error} from '../../core/site-error/error' +import {Box} from "@material-ui/core"; + +export const Menu = () => { + const data = useSelector(selector) + + return + {data.status === 'true' ? : } + +} + +const selector = ({ sandwichMenuReducer }) => sandwichMenuReducer.items; diff --git a/src/sandwich-menu/containers/context.js b/src/sandwich-menu/containers/context.js new file mode 100644 index 0000000..703a358 --- /dev/null +++ b/src/sandwich-menu/containers/context.js @@ -0,0 +1,3 @@ +import {createContext} from "react"; + +export const SandwichContext = createContext({}) \ No newline at end of file diff --git a/src/sandwich-menu/containers/details/body.jsx b/src/sandwich-menu/containers/details/body.jsx new file mode 100644 index 0000000..7ccc4de --- /dev/null +++ b/src/sandwich-menu/containers/details/body.jsx @@ -0,0 +1,17 @@ +import {Box, Grid, TableCell, TableRow} from "@material-ui/core"; +import React from "react"; +import {FoodDetails} from "../details/food-details/food-details" + +export const ShowDetails = (value) => { + const ingredients= value.value; + + return + + + + + + + + +} \ No newline at end of file diff --git a/src/sandwich-menu/containers/details/food-details/food-details.jsx b/src/sandwich-menu/containers/details/food-details/food-details.jsx new file mode 100644 index 0000000..0e07d96 --- /dev/null +++ b/src/sandwich-menu/containers/details/food-details/food-details.jsx @@ -0,0 +1,6 @@ +import React from "react"; +import {IngredientDetails} from "./ingredient-details/ingredient-details"; + +export const FoodDetails = ({ingredients}) => + Object.entries(ingredients).map(([key, value]) => ) + diff --git a/src/sandwich-menu/containers/details/food-details/ingredient-details/ingredient-details.jsx b/src/sandwich-menu/containers/details/food-details/ingredient-details/ingredient-details.jsx new file mode 100644 index 0000000..1d782a7 --- /dev/null +++ b/src/sandwich-menu/containers/details/food-details/ingredient-details/ingredient-details.jsx @@ -0,0 +1,6 @@ +import {Grid} from "@material-ui/core"; +import React from "react"; + +export const IngredientDetails = ({foodType}) => + Contine : {foodType.name} {foodType.weight} + \ No newline at end of file diff --git a/src/sandwich-menu/containers/details/title.jsx b/src/sandwich-menu/containers/details/title.jsx new file mode 100644 index 0000000..1b2512c --- /dev/null +++ b/src/sandwich-menu/containers/details/title.jsx @@ -0,0 +1,15 @@ +import {Box, TableCell, TableRow, Typography} from "@material-ui/core"; +import { Details as DetailsIcon } from '@material-ui/icons' +import React from "react"; + +export const Title = () => + + + + + + Detalii despre ingrediente + Toate ingredientele folosite in sandwich-ul selectat + + + \ No newline at end of file diff --git a/src/sandwich-menu/containers/hooks/use-default-sandwich-menu.js b/src/sandwich-menu/containers/hooks/use-default-sandwich-menu.js new file mode 100644 index 0000000..e39330f --- /dev/null +++ b/src/sandwich-menu/containers/hooks/use-default-sandwich-menu.js @@ -0,0 +1,6 @@ +import {useState} from "react"; + +export const useDefaultSandwichMenu = () => { + const [selected, setSelected] = useState([]) + return {selected, setSelected} +} \ No newline at end of file diff --git a/src/sandwich-menu/containers/hooks/use-init.js b/src/sandwich-menu/containers/hooks/use-init.js new file mode 100644 index 0000000..5d41ce7 --- /dev/null +++ b/src/sandwich-menu/containers/hooks/use-init.js @@ -0,0 +1,8 @@ +import {useEffect} from "react"; +import {useDispatch} from "react-redux"; +import {getItemsApiAttempt} from "../../actions"; + +export const useInit = () =>{ + const dispatch = useDispatch() + useEffect(() => dispatch(getItemsApiAttempt()),[dispatch]) +} \ No newline at end of file diff --git a/src/sandwich-menu/containers/hooks/use-on-add-cart.js b/src/sandwich-menu/containers/hooks/use-on-add-cart.js new file mode 100644 index 0000000..4d23d5b --- /dev/null +++ b/src/sandwich-menu/containers/hooks/use-on-add-cart.js @@ -0,0 +1,18 @@ +import {useDispatch, useSelector} from "react-redux"; +import {addItems} from "../../../shopping-cart/actions" +import {useSandwichContext} from "./use-sandwich-context"; + +export const useOnAddCart = (selector) => { + const {selected, setSelected} = useSandwichContext() + const data = useSelector(selector) + const dispatch = useDispatch() + const itemsToAdd = { + data: data.data, + selectedAdd: selected + } + + return () => { + dispatch(addItems(itemsToAdd)) + setSelected([]) + } +} \ No newline at end of file diff --git a/src/sandwich-menu/containers/hooks/use-sandwich-context.js b/src/sandwich-menu/containers/hooks/use-sandwich-context.js new file mode 100644 index 0000000..32674ec --- /dev/null +++ b/src/sandwich-menu/containers/hooks/use-sandwich-context.js @@ -0,0 +1,4 @@ +import {useContext} from "react"; +import {SandwichContext} from "../context"; + +export const useSandwichContext = () => useContext(SandwichContext) \ No newline at end of file diff --git a/src/sandwich-menu/containers/index.jsx b/src/sandwich-menu/containers/index.jsx new file mode 100644 index 0000000..7edf7d1 --- /dev/null +++ b/src/sandwich-menu/containers/index.jsx @@ -0,0 +1,9 @@ +import {Menu} from "../components/sandwich-menu"; +import {useDefaultSandwichMenu} from "./hooks/use-default-sandwich-menu"; +import {InitBehaviour} from "./init-behaviour"; +import {SandwichContext} from "./context"; + +export const SandwichMenu = () => + + + \ No newline at end of file diff --git a/src/sandwich-menu/containers/init-behaviour.js b/src/sandwich-menu/containers/init-behaviour.js new file mode 100644 index 0000000..bb7711e --- /dev/null +++ b/src/sandwich-menu/containers/init-behaviour.js @@ -0,0 +1,6 @@ +import {useInit} from "./hooks/use-init"; + +export const InitBehaviour = () => { + useInit() + return '' +} \ No newline at end of file diff --git a/src/sandwich-menu/containers/mui-data-table/data-table.jsx b/src/sandwich-menu/containers/mui-data-table/data-table.jsx new file mode 100644 index 0000000..8f23459 --- /dev/null +++ b/src/sandwich-menu/containers/mui-data-table/data-table.jsx @@ -0,0 +1,31 @@ +import {Box, Grid, IconButton} from "@material-ui/core"; +import MUIDataTable from "mui-datatables"; +import {columns} from "../table-columns-api"; +import React from "react"; +import {useSetOptions} from "../options"; +import AddShoppingCartIcon from "@material-ui/icons/AddShoppingCart"; +import {useOnAddCart} from "../hooks/use-on-add-cart"; + +export const DataTable = ({data, selector}) =>{ + const onClick = useOnAddCart(selector); + const options = useSetOptions(data) + + return + + + + + + + Adauga in cos + + + + + +} \ No newline at end of file diff --git a/src/sandwich-menu/containers/options.jsx b/src/sandwich-menu/containers/options.jsx new file mode 100644 index 0000000..02ee4ed --- /dev/null +++ b/src/sandwich-menu/containers/options.jsx @@ -0,0 +1,31 @@ +import {Title} from "./details/title"; +import {ShowDetails} from "./details/body"; +import React from "react"; +import {useSandwichContext} from "./hooks/use-sandwich-context"; + +export const useSetOptions = (data) => { + const {selected, setSelected} = useSandwichContext(); + const options = { + filterType: 'dropdown', + viewColumns: false, + filter: false, + print: false, + rowsSelected: selected, + download: false, + textLabels: { + selectedRows: { + text: "produs(e) selectat(e)" + } + }, + selectableRowsOnClick: true, + selectableRowsHeader: false, + onRowSelectionChange: (currentRowsSelected, allRowsSelected, rowsSelected) => setSelected(rowsSelected), + expandableRows: true, + customToolbarSelect: () =>
, + renderExpandableRow: (rowData, rowMeta) => <> + + <ShowDetails value={data[rowMeta.dataIndex].ingredients}/> + </>, + }; + return options; +} \ No newline at end of file diff --git a/src/sandwich-menu/containers/table-columns-api.jsx b/src/sandwich-menu/containers/table-columns-api.jsx new file mode 100644 index 0000000..07fda34 --- /dev/null +++ b/src/sandwich-menu/containers/table-columns-api.jsx @@ -0,0 +1,31 @@ +import {Grid} from "@material-ui/core"; +import React from "react"; + +export const columns=[ + { + name: 'id', + label: 'Id', + options: { + filter:true, + sort: true, + }, + }, + { + name: 'name', + label: 'Denumire', + options: { + filter:true, + sort: true, + customBodyRender: rowData => <Grid item xs={12} sm={12} md={10} lg={10}>{rowData}</Grid> + }, + }, + { + name: 'price', + label: 'Pret', + options: { + filter:true, + sort: true, + customBodyRender: (rowData) => <Grid item xs={12} sm={12} md={10} lg={10}>{rowData} $</Grid> + } + }, +] \ No newline at end of file diff --git a/src/sandwich-menu/containers/table-columns.jsx b/src/sandwich-menu/containers/table-columns.jsx new file mode 100644 index 0000000..a742fe6 --- /dev/null +++ b/src/sandwich-menu/containers/table-columns.jsx @@ -0,0 +1,66 @@ +import {Grid} from "@material-ui/core"; +import React from "react"; + +export const columns=[ + { + name: 'img', + label: 'Poza', + options: { + filter: false, + sort: false, + customBodyRender: (rowData) => + <Grid item xs={12} sm={12} md={10} lg={10}> + <img className={'Images'} src={rowData} /> + </Grid> + } + }, + { + name: 'id', + label: 'Id', + options: { + filter:true, + sort: true, + display: false + }, + }, + { + name: 'name', + label: 'Denumire', + options: { + filter:true, + sort: true, + customBodyRender: rowData => <Grid item xs={12} sm={12} md={10} lg={10}>{rowData}</Grid> + }, + + }, + { + name: 'price', + label: 'Pret', + options: { + filter:true, + sort: true, + customBodyRender: (rowData) => <Grid item xs={12} sm={12} md={10} lg={10}>{rowData} $</Grid> + } + }, + { + name: 'alt', + label: 'Alt', + options: { + filter:true, + sort: true, + display: false + }, + + }, + { + name: 'description', + label: 'Descriere', + options: { + filter:true, + sort: true, + empty: true, + customBodyRender: rowData => <Grid item xs={12} sm={12} md={10} lg={10}>{rowData}</Grid>, + }, + + }, +] \ No newline at end of file diff --git a/src/sandwich-menu/data/sandwich-data.js b/src/sandwich-menu/data/sandwich-data.js new file mode 100644 index 0000000..8211290 --- /dev/null +++ b/src/sandwich-menu/data/sandwich-data.js @@ -0,0 +1,111 @@ +import funnySandwich from "../../core/images/funnySandwich.jpeg" +import crazySandwich from "../../core/images/crazySandwich.jpeg" +import uglySandwich from "../../core/images/uglySandwich.jpeg" +import fancySandwich from "../../core/images/fancySandiwch.jpeg" + +export const sandwichData = [ + { + id : 1, + name : 'Funny sandwich', + price : 12.00, + img : funnySandwich, + alt: 'funny sandwich', + description:'A sandwich with good jokes inside', + ingredients: { + meat: { + name: "Bacon", + weight: '150 gr' + }, + cheese: { + name: "Mozzarela", + weight: '20 gr' + }, + salad:{ + name: 'Rosii', + weight: '5 gr', + }, + extra: { + name: "Weed", + weight: '1 gr' + }, + } + }, + { + id: 2, + name: 'Crazy sandwich', + price: 14.00, + img: crazySandwich, + alt: 'crazy sandwich', + description: 'A sandwich with some shady stuff', + ingredients: { + meat: { + name: "Pork", + weight: '150 gr' + }, + cheese: { + name: "Cream Cheese", + weight: '30 gr' + }, + salad: { + name: 'Castraveti', + weight: '5 gr', + }, + extra: { + name: "Jalapeno", + weight: '5 gr' + }, + }, + }, + { + id : 3, + name : 'Ugly sandwich', + price : 10.00, + img : uglySandwich, + alt : 'ugly sandwich', + description:'A sandwich with low self-esteem', + ingredients: { + meat: { + name: "Parizel", + weight: '150 gr' + }, + cheese: { + name: "Branza de oaie", + weight: '30 gr' + }, + salad: { + name: 'Salata', + weight: '5 gr', + }, + extra: { + name: "Ceapa", + weight: '5 gr' + }, + }, + }, + { + id : 4, + name : 'Fancy sandwich', + price : 15.00, + img : fancySandwich, + alt : 'fancy sandwich', + description:'A sandwich with good manners and good looks', + ingredients: { + meat: { + name: "Black angus", + weight: '150 gr' + }, + cheese: { + name: "Feta", + weight: '30 gr' + }, + salad: { + name: 'Varza', + weight: '5 gr', + }, + extra: { + name: "Aur", + weight: '5 gr' + }, + }, + }, +] \ No newline at end of file diff --git a/src/sandwich-menu/epics/sandwich-menu.js b/src/sandwich-menu/epics/sandwich-menu.js new file mode 100644 index 0000000..2adaba0 --- /dev/null +++ b/src/sandwich-menu/epics/sandwich-menu.js @@ -0,0 +1,11 @@ +import {ofType} from "redux-observable"; +import {catchError, map, mergeMap} from "rxjs/operators" +import {GET_ALL_SANDWICHES_API_ATTEMPT, getItemsApiFailure, getItemsApiSuccess} from "../actions"; +import axios from "axios"; +import {from} from "rxjs"; + +export const sandwichMenuEpic = action$ => action$ + .pipe(ofType(GET_ALL_SANDWICHES_API_ATTEMPT)) + .pipe(mergeMap(() => axios.get('https://octa-api.herokuapp.com/'))) + .pipe(map(response => getItemsApiSuccess(response.data))) + .pipe(catchError(error => from([getItemsApiFailure()]))); \ No newline at end of file diff --git a/src/sandwich-menu/reducers/sandwich-menu.js b/src/sandwich-menu/reducers/sandwich-menu.js new file mode 100644 index 0000000..3fd26b9 --- /dev/null +++ b/src/sandwich-menu/reducers/sandwich-menu.js @@ -0,0 +1,37 @@ +import * as yup from 'yup' +import {Record} from "immutable"; + +const SchemaState = yup.object().noUnknown() + .shape({ + items: yup.object().noUnknown() + .shape({ + data: yup.array() + .default([]), + status: yup.string() + .default('false') + }) +}) + +const makeState = data =>{ + const casted = new Record(SchemaState.cast(data))().toJS() + + return {...SchemaState.default(), ...casted} +} + +export const sandwichMenuReducer = (state = makeState(), action) =>{ + switch (action.type){ + case 'GET_ALL_SANDWICHES_API_ATTEMPT': + + return makeState({...state}) + case 'GET_ALL_SANDWICHES_API_SUCCESS': + + return makeState({...state, items: {data: [...action.payload.data], status: action.payload.success}}) + + case 'GET_ALL_SANDWICHES_API_FAILURE': + + return makeState({...state, items: {status: 'false'}}) + + default: + return makeState({...state}) + } +} \ No newline at end of file diff --git a/src/shopping-cart/actions/add-item-to-shopping-cart.js b/src/shopping-cart/actions/add-item-to-shopping-cart.js new file mode 100644 index 0000000..3f0adde --- /dev/null +++ b/src/shopping-cart/actions/add-item-to-shopping-cart.js @@ -0,0 +1,3 @@ +export const ADD_ITEM_TO_SHOPPING_CART = 'ADD_ITEM_TO_SHOPPING_CART' + +export const addItems = item => ({type: ADD_ITEM_TO_SHOPPING_CART, payload: item}) diff --git a/src/shopping-cart/actions/get-rate-attempt.js b/src/shopping-cart/actions/get-rate-attempt.js new file mode 100644 index 0000000..6169e35 --- /dev/null +++ b/src/shopping-cart/actions/get-rate-attempt.js @@ -0,0 +1,3 @@ +export const GET_RATE_API_ATTEMPT = 'GET_RATE_API_ATTEMPT' + +export const getRateAttempt = () => ({type: GET_RATE_API_ATTEMPT}) \ No newline at end of file diff --git a/src/shopping-cart/actions/get-rate-failure.js b/src/shopping-cart/actions/get-rate-failure.js new file mode 100644 index 0000000..29c284f --- /dev/null +++ b/src/shopping-cart/actions/get-rate-failure.js @@ -0,0 +1,3 @@ +export const GET_RATE_API_FAILURE = 'GET_RATE_API_FAILURE' + +export const getRateFailure = () => ({type: GET_RATE_API_FAILURE}) \ No newline at end of file diff --git a/src/shopping-cart/actions/get-rate-success.js b/src/shopping-cart/actions/get-rate-success.js new file mode 100644 index 0000000..c772dc4 --- /dev/null +++ b/src/shopping-cart/actions/get-rate-success.js @@ -0,0 +1,3 @@ +export const GET_RATE_API_SUCCESS = 'GET_RATE_API_SUCCESS' + +export const getRateSuccess = (rate) => ({type:GET_RATE_API_SUCCESS, payload: rate}) \ No newline at end of file diff --git a/src/shopping-cart/actions/index.js b/src/shopping-cart/actions/index.js new file mode 100644 index 0000000..ce79792 --- /dev/null +++ b/src/shopping-cart/actions/index.js @@ -0,0 +1,5 @@ +export * from "./add-item-to-shopping-cart" +export * from "./remove-item-from-shopping-cart" +export * from "./get-rate-attempt" +export * from "./get-rate-success" +export * from "./get-rate-failure" \ No newline at end of file diff --git a/src/shopping-cart/actions/remove-item-from-shopping-cart.js b/src/shopping-cart/actions/remove-item-from-shopping-cart.js new file mode 100644 index 0000000..ac7f42d --- /dev/null +++ b/src/shopping-cart/actions/remove-item-from-shopping-cart.js @@ -0,0 +1,3 @@ +export const REMOVE_ITEM_FROM_SHOPPING_CART = 'REMOVE_ITEM_FROM_SHOPPING_CART' + +export const removeItems = items => ({type: REMOVE_ITEM_FROM_SHOPPING_CART, payload: items}) \ No newline at end of file diff --git a/src/shopping-cart/components/shopping-cart.jsx b/src/shopping-cart/components/shopping-cart.jsx new file mode 100644 index 0000000..e0ea1a4 --- /dev/null +++ b/src/shopping-cart/components/shopping-cart.jsx @@ -0,0 +1,32 @@ +import {Box} from "@material-ui/core"; +import React from "react"; +import MUIDataTable from 'mui-datatables' +import {useSetTotalPrice} from "../containers/hooks/use-set-total-price"; +import {useSetColumns} from "../containers/table-columns"; +import {PaymentDetails} from "../containers/payment-details/payment-details"; +import {useSelector} from "react-redux"; +import {useSetOptions} from "../containers/options"; + +const _ = require('lodash'); +export const ShoppingCartComponent = () => { + const {shoppingCartData, rate} = useSelector(selector) + const totalPrice = useSetTotalPrice(shoppingCartData); + const options = useSetOptions(selector); + const columns = useSetColumns(shoppingCartData); + + return <Box m={5}> + <MUIDataTable + data={_.uniqBy(shoppingCartData,item => item.id)} + columns={columns} + options={options} + title={'ShoppingCart'} + /> + <PaymentDetails totalPrice={totalPrice} rate={rate}/> + </Box> +} + +const selector = ({ shoppingCartReducer, ratesReducer}) => ({ + shoppingCartData: shoppingCartReducer.items, + rate: ratesReducer.rate, +}) + diff --git a/src/shopping-cart/containers/context.js b/src/shopping-cart/containers/context.js new file mode 100644 index 0000000..d6d4b9d --- /dev/null +++ b/src/shopping-cart/containers/context.js @@ -0,0 +1,3 @@ +import {createContext} from "react"; + +export const ShoppingCartContext = createContext({}) \ No newline at end of file diff --git a/src/shopping-cart/containers/hooks/use-default-shopping-cart.js b/src/shopping-cart/containers/hooks/use-default-shopping-cart.js new file mode 100644 index 0000000..c15f700 --- /dev/null +++ b/src/shopping-cart/containers/hooks/use-default-shopping-cart.js @@ -0,0 +1,6 @@ +import {useState} from "react"; + +export const useDefaultShoppingCart = () =>{ + const [selected, setSelected]= useState([]); + return {selected,setSelected} +} \ No newline at end of file diff --git a/src/shopping-cart/containers/hooks/use-delete-selected-rows.js b/src/shopping-cart/containers/hooks/use-delete-selected-rows.js new file mode 100644 index 0000000..2d379d0 --- /dev/null +++ b/src/shopping-cart/containers/hooks/use-delete-selected-rows.js @@ -0,0 +1,19 @@ +import {useDispatch, useSelector} from "react-redux"; +import {removeItems} from "../../actions"; +import {useShoppingCartContext} from "./use-shopping-cart-context"; + +export const useDeleteSelectedRows = (selector) => +{ + const {selected,setSelected} = useShoppingCartContext(); + const {shoppingCartData} = useSelector(selector) + const dispatch = useDispatch() + const itemsToDelete = { + selectedDelete: selected, + shoppingCartData: shoppingCartData, + } + + return () => { + dispatch(removeItems(itemsToDelete)) + setSelected([]) + } +} \ No newline at end of file diff --git a/src/shopping-cart/containers/hooks/use-init.js b/src/shopping-cart/containers/hooks/use-init.js new file mode 100644 index 0000000..c4b5b7f --- /dev/null +++ b/src/shopping-cart/containers/hooks/use-init.js @@ -0,0 +1,8 @@ +import {useEffect} from "react"; +import {useDispatch} from "react-redux"; +import {getRateAttempt} from "../../actions"; + +export const useInit = () => { + const dispatch = useDispatch() + useEffect(() => dispatch(getRateAttempt())) +} \ No newline at end of file diff --git a/src/shopping-cart/containers/hooks/use-make-shopping-cart.js b/src/shopping-cart/containers/hooks/use-make-shopping-cart.js new file mode 100644 index 0000000..b6960b3 --- /dev/null +++ b/src/shopping-cart/containers/hooks/use-make-shopping-cart.js @@ -0,0 +1,8 @@ +export const useMakeShoppingCart = (shoppingCartData) =>{ + let tempShoppingCartData = [] + tempShoppingCartData = shoppingCartData.filter(item => { + + }) + + return shoppingCartData +} \ No newline at end of file diff --git a/src/shopping-cart/containers/hooks/use-set-total-price.js b/src/shopping-cart/containers/hooks/use-set-total-price.js new file mode 100644 index 0000000..9035529 --- /dev/null +++ b/src/shopping-cart/containers/hooks/use-set-total-price.js @@ -0,0 +1,7 @@ +export const useSetTotalPrice = (shoppingCartData) => +{ + let totalPrice=0 + shoppingCartData.map(item => totalPrice+= item.price) + + return totalPrice; +} \ No newline at end of file diff --git a/src/shopping-cart/containers/hooks/use-shopping-cart-context.js b/src/shopping-cart/containers/hooks/use-shopping-cart-context.js new file mode 100644 index 0000000..ed43fe2 --- /dev/null +++ b/src/shopping-cart/containers/hooks/use-shopping-cart-context.js @@ -0,0 +1,4 @@ +import {useContext} from "react"; +import {ShoppingCartContext} from "../context"; + +export const useShoppingCartContext = () => useContext(ShoppingCartContext) \ No newline at end of file diff --git a/src/shopping-cart/containers/index.jsx b/src/shopping-cart/containers/index.jsx new file mode 100644 index 0000000..671e636 --- /dev/null +++ b/src/shopping-cart/containers/index.jsx @@ -0,0 +1,9 @@ +import {ShoppingCartContext} from "./context"; +import {ShoppingCartComponent} from "../components/shopping-cart"; +import {useDefaultShoppingCart} from "./hooks/use-default-shopping-cart"; +import {InitBehaviour} from "./init-behaviour"; + +export const ShoppingCart = () => <ShoppingCartContext.Provider value={useDefaultShoppingCart()}> +<InitBehaviour /> +<ShoppingCartComponent /> +</ShoppingCartContext.Provider> \ No newline at end of file diff --git a/src/shopping-cart/containers/init-behaviour.js b/src/shopping-cart/containers/init-behaviour.js new file mode 100644 index 0000000..2b815a6 --- /dev/null +++ b/src/shopping-cart/containers/init-behaviour.js @@ -0,0 +1,6 @@ +import {useInit} from "./hooks/use-init"; + +export const InitBehaviour = () =>{ + useInit() + return '' +} \ No newline at end of file diff --git a/src/shopping-cart/containers/options.jsx b/src/shopping-cart/containers/options.jsx new file mode 100644 index 0000000..1e4f789 --- /dev/null +++ b/src/shopping-cart/containers/options.jsx @@ -0,0 +1,43 @@ +import React, {useState} from "react"; +import {useDeleteSelectedRows} from "./hooks/use-delete-selected-rows"; +import {useShoppingCartContext} from "./hooks/use-shopping-cart-context"; +import {Badge, Box, IconButton, Toolbar} from "@material-ui/core"; +import DeleteIcon from "@material-ui/icons/Delete"; + +export const useSetOptions = (selector) =>{ + const {selected,setSelected} = useShoppingCartContext(); + const onClick = useDeleteSelectedRows(selector); + const options = { + filterType: 'dropdown', + viewColumns: false, + filter: false, + print: false, + rowsSelected: selected, + selectableRowsOnClick: true, + download: false, + pagination:false, + search: false, + textLabels:{ + selectedRows : { + text: "produs(e) selectat(e)" + }, + body:{ + noMatch: "Nici un produs" + } + }, + onRowSelectionChange: (currentRowsSelected, allRowsSelected, rowsSelected) => setSelected(rowsSelected), + customToolbarSelect: () => + <Toolbar> + <div>Sterge produs(e)</div> + <Box mr={5}> + <IconButton onClick={onClick}> + <Badge badgeContent={selected.length} color='secondary'> + <DeleteIcon /> + </Badge> + </IconButton> + </Box> + </Toolbar>, + }; + + return options; +} \ No newline at end of file diff --git a/src/shopping-cart/containers/payment-details/body/payment-body.jsx b/src/shopping-cart/containers/payment-details/body/payment-body.jsx new file mode 100644 index 0000000..d0bf7e1 --- /dev/null +++ b/src/shopping-cart/containers/payment-details/body/payment-body.jsx @@ -0,0 +1,6 @@ +import {Typography} from "@material-ui/core"; +import React from "react"; + +export const PaymentBody = ({text}) =><Typography variant="body2" color="textSecondary" align='center'> + {text} +</Typography> \ No newline at end of file diff --git a/src/shopping-cart/containers/payment-details/payment-details.jsx b/src/shopping-cart/containers/payment-details/payment-details.jsx new file mode 100644 index 0000000..cca50d3 --- /dev/null +++ b/src/shopping-cart/containers/payment-details/payment-details.jsx @@ -0,0 +1,18 @@ +import {Box, Card, CardContent} from "@material-ui/core"; +import React from "react"; +import {PaymentTitle} from "./title/payment-title"; +import {PaymentBody} from "./body/payment-body"; +import {PaymentSubTitle} from "./subtitle/payment-subtitle"; + + +export const PaymentDetails = ({totalPrice, rate}) =><Box mt={5}> + <Card> + <CardContent> + <PaymentTitle text={'Detalii plata'}/> + <PaymentBody text={`Pret produse: ${totalPrice} $`} /> + <PaymentBody text={'Pret transport: 5 $'} /> + <PaymentSubTitle text={` Pret total: ${totalPrice+5} $`} /> + <PaymentSubTitle text={` Pret total in lei: ${Math.round((totalPrice+5)*rate)} lei`} /> + </CardContent> + </Card> +</Box> \ No newline at end of file diff --git a/src/shopping-cart/containers/payment-details/subtitle/payment-subtitle.jsx b/src/shopping-cart/containers/payment-details/subtitle/payment-subtitle.jsx new file mode 100644 index 0000000..e1866c9 --- /dev/null +++ b/src/shopping-cart/containers/payment-details/subtitle/payment-subtitle.jsx @@ -0,0 +1,6 @@ +import {Typography} from "@material-ui/core"; +import React from "react"; + +export const PaymentSubTitle = ({text}) =><Typography variant="h5" align='center'> + {text} +</Typography> \ No newline at end of file diff --git a/src/shopping-cart/containers/payment-details/title/payment-title.jsx b/src/shopping-cart/containers/payment-details/title/payment-title.jsx new file mode 100644 index 0000000..3fa7de3 --- /dev/null +++ b/src/shopping-cart/containers/payment-details/title/payment-title.jsx @@ -0,0 +1,6 @@ +import {Typography} from "@material-ui/core"; +import React from "react"; + +export const PaymentTitle = ({text}) =><Typography variant='h4' align='center'> + {text} +</Typography> \ No newline at end of file diff --git a/src/shopping-cart/containers/table-columns.jsx b/src/shopping-cart/containers/table-columns.jsx new file mode 100644 index 0000000..3caa70d --- /dev/null +++ b/src/shopping-cart/containers/table-columns.jsx @@ -0,0 +1,62 @@ +import {Grid} from "@material-ui/core"; +import React from "react"; + +export const useSetColumns = (shoppingCartData) => { + const _ = require('lodash'); + + return [ + { + name: 'id', + label: 'Id', + options: { + filter: false, + sort: false, + display: true + }, + }, + { + name: 'name', + label: 'Denumire', + options: { + filter: true, + sort: true, + customBodyRender: rowData => <Grid item xs={12} sm={12} md={10} lg={10}>{rowData}</Grid> + }, + }, + { + name: 'description', + label: 'Descriere', + options: { + filter: true, + sort: true, + customBodyRender: rowData => + <Grid item xs={12} sm={12} md={10} lg={10}> + {rowData} + </Grid>, + }, + }, + { + name: 'price', + label: 'Pret', + options: { + filter: true, + sort: true, + customBodyRender: rowData => <Grid item xs={12} sm={12} md={10} lg={10}>{rowData} $</Grid> + }, + }, + { + name: 'count', + label: "Nr. Produse", + options:{ + filter:false, + sort:true, + customBodyRender: (rowData, currentTableData) => { + const rowId= currentTableData.rowData[0] + const counter = _.countBy(shoppingCartData, item => item.id === rowId) + + return <Grid item xs={12} sm={12} md={10} lg={10}>{counter[true]} </Grid> + } + } + }, + ] +} \ No newline at end of file diff --git a/src/shopping-cart/epics/get-rate.js b/src/shopping-cart/epics/get-rate.js new file mode 100644 index 0000000..10f28c8 --- /dev/null +++ b/src/shopping-cart/epics/get-rate.js @@ -0,0 +1,11 @@ +import {ofType} from "redux-observable"; +import {GET_RATE_API_ATTEMPT, getRateFailure, getRateSuccess} from "../actions"; +import {mergeMap, map, tap, catchError} from "rxjs/operators"; +import axios from "axios"; +import {from} from "rxjs"; + +export const getRateEpic = action$ => action$ + .pipe(ofType(GET_RATE_API_ATTEMPT)) + .pipe(mergeMap(() => axios.get('https://octa-api.herokuapp.com/rate'))) + .pipe(map(response => getRateSuccess(response))) + .pipe(catchError(err => from([getRateFailure()]))) \ No newline at end of file diff --git a/src/shopping-cart/reducers/rates.js b/src/shopping-cart/reducers/rates.js new file mode 100644 index 0000000..b4bf2a8 --- /dev/null +++ b/src/shopping-cart/reducers/rates.js @@ -0,0 +1,31 @@ +import * as yup from "yup" +import {Record} from "immutable"; + +const SchemaState = yup.object().noUnknown() + .shape({ + rate: yup.number().default(0), + status: yup.string().default('false') + }) + +const makeState = data =>{ + const casted = new Record(SchemaState.cast(data))().toJS() + + return {...SchemaState.default(),...casted} +} + +export const ratesReducer = (state = makeState(), action) => { + switch(action.type){ + case 'GET_RATE_API_ATTEMPT': + + return makeState({...state}) + case 'GET_RATE_API_SUCCESS': + + return makeState({...state, rate: action.payload.data.value, status: action.payload.data.success}) + case 'GET_RATE_API_FAILURE': + + return makeState({...state, status: 'false'}) + + default: + return makeState({...state}) + } +} \ No newline at end of file diff --git a/src/shopping-cart/reducers/shopping-cart.js b/src/shopping-cart/reducers/shopping-cart.js new file mode 100644 index 0000000..dbbd578 --- /dev/null +++ b/src/shopping-cart/reducers/shopping-cart.js @@ -0,0 +1,33 @@ +import * as yup from "yup" +import {Record} from "immutable"; + +const SchemaState = yup.object().noUnknown() + .shape({ + items: yup.array() + .default([]) + }) + +const makeState = data => { + const casted = new Record(SchemaState.cast(data))().toJS() + + return {...SchemaState.default(), ...casted} +} + +export const shoppingCartReducer = (state = makeState(), action) =>{ + switch (action.type){ + case 'ADD_ITEM_TO_SHOPPING_CART': + const {data, selectedAdd} = action.payload; + const itemsToAdd = selectedAdd.map(selectIndex => data[selectIndex]) + + return makeState({...state , items: [...state.items, ...itemsToAdd]}) + + case 'REMOVE_ITEM_FROM_SHOPPING_CART': + const {selectedDelete, shoppingCartData} = action.payload + const itemsToDelete = selectedDelete.map(item => shoppingCartData[item]) + + return makeState({...state, items: state.items.filter(item => !itemsToDelete.includes(item))}) + + default: + return makeState({...state}); + } +} \ No newline at end of file diff --git a/src/startup/epics/index.js b/src/startup/epics/index.js new file mode 100644 index 0000000..30c0e6c --- /dev/null +++ b/src/startup/epics/index.js @@ -0,0 +1,7 @@ +import {combineEpics} from 'redux-observable' +import {sandwichMenuEpic} from "../../sandwich-menu/epics/sandwich-menu"; +import {getRateEpic} from "../../shopping-cart/epics/get-rate"; + +export const rootEpic = combineEpics( + sandwichMenuEpic, getRateEpic +); \ No newline at end of file diff --git a/src/startup/reducers/index.js b/src/startup/reducers/index.js new file mode 100644 index 0000000..176746a --- /dev/null +++ b/src/startup/reducers/index.js @@ -0,0 +1,8 @@ +import {combineReducers} from "redux"; +import {shoppingCartReducer} from "../../shopping-cart/reducers/shopping-cart"; +import {sandwichMenuReducer} from "../../sandwich-menu/reducers/sandwich-menu"; +import {ratesReducer} from '../../shopping-cart/reducers/rates' + +export const rootReducers = combineReducers({ + shoppingCartReducer, sandwichMenuReducer, ratesReducer +}) \ No newline at end of file