박민정

[merge] Merge client into develop

Showing 38 changed files with 1046 additions and 60 deletions
......@@ -4,6 +4,43 @@
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@ant-design/colors": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-6.0.0.tgz",
"integrity": "sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==",
"requires": {
"@ctrl/tinycolor": "^3.4.0"
}
},
"@ant-design/icons": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-4.6.2.tgz",
"integrity": "sha512-QsBG2BxBYU/rxr2eb8b2cZ4rPKAPBpzAR+0v6rrZLp/lnyvflLH3tw1vregK+M7aJauGWjIGNdFmUfpAOtw25A==",
"requires": {
"@ant-design/colors": "^6.0.0",
"@ant-design/icons-svg": "^4.0.0",
"@babel/runtime": "^7.11.2",
"classnames": "^2.2.6",
"rc-util": "^5.9.4"
}
},
"@ant-design/icons-svg": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.1.0.tgz",
"integrity": "sha512-Fi03PfuUqRs76aI3UWYpP864lkrfPo0hluwGqh7NJdLhvH4iRDc3jbJqZIvRDLHKbXrvAfPPV3+zjUccfFvWOQ=="
},
"@ant-design/react-slick": {
"version": "0.28.3",
"resolved": "https://registry.npmjs.org/@ant-design/react-slick/-/react-slick-0.28.3.tgz",
"integrity": "sha512-u3onF2VevGRbkGbgpldVX/nzd7LFtLeZJE0x2xIFT2qYHKkJZ6QT/jQ7KqYK4UpeTndoyrbMqLN4DiJza4BVBg==",
"requires": {
"@babel/runtime": "^7.10.4",
"classnames": "^2.2.5",
"json2mq": "^0.2.0",
"lodash": "^4.17.21",
"resize-observer-polyfill": "^1.5.0"
}
},
"@babel/code-frame": {
"version": "7.12.13",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
......@@ -1203,6 +1240,11 @@
"resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz",
"integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg=="
},
"@ctrl/tinycolor": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.0.tgz",
"integrity": "sha512-JZButFdZ1+/xAfpguQHoabIXkcqRRKpMrWKBkpEZZyxfY9C1DpADFB8PEqGSTeFr135SaTRfKqGKx5xSCLI7ZQ=="
},
"@eslint/eslintrc": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.1.tgz",
......@@ -2276,6 +2318,15 @@
"@types/node": "*"
}
},
"@types/hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
"requires": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"@types/html-minifier-terser": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz",
......@@ -2354,11 +2405,37 @@
"resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz",
"integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA=="
},
"@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=="
},
"@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.9",
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.9.tgz",
"integrity": "sha512-2Cw7FvevpJxQrCb+k5t6GH1KIvmadj5uBbjPaLlJB/nZWUj56e1ZqcD6zsoMFB47MsJUTFl9RJ132A7hb3QFJA==",
"requires": {
"@types/prop-types": "*",
"@types/scheduler": "*",
"csstype": "^3.0.2"
}
},
"@types/react-redux": {
"version": "7.1.16",
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.16.tgz",
"integrity": "sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw==",
"requires": {
"@types/hoist-non-react-statics": "^3.3.0",
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0",
"redux": "^4.0.0"
}
},
"@types/resolve": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz",
......@@ -2367,6 +2444,11 @@
"@types/node": "*"
}
},
"@types/scheduler": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz",
"integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA=="
},
"@types/source-list-map": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
......@@ -2851,6 +2933,55 @@
"color-convert": "^1.9.0"
}
},
"antd": {
"version": "4.16.1",
"resolved": "https://registry.npmjs.org/antd/-/antd-4.16.1.tgz",
"integrity": "sha512-v7KfUYvEAiqfTECKC4/VkpRPB/4RRxZLR3b2kKCYEtcj4nEHvsOKfO5CDbWVtSUmCehxOXNR2lV+UNy06KHBnA==",
"requires": {
"@ant-design/colors": "^6.0.0",
"@ant-design/icons": "^4.6.2",
"@ant-design/react-slick": "~0.28.1",
"@babel/runtime": "^7.12.5",
"array-tree-filter": "^2.1.0",
"classnames": "^2.2.6",
"copy-to-clipboard": "^3.2.0",
"lodash": "^4.17.21",
"moment": "^2.25.3",
"rc-cascader": "~1.4.0",
"rc-checkbox": "~2.3.0",
"rc-collapse": "~3.1.0",
"rc-dialog": "~8.5.1",
"rc-drawer": "~4.3.0",
"rc-dropdown": "~3.2.0",
"rc-field-form": "~1.20.0",
"rc-image": "~5.2.4",
"rc-input-number": "~7.1.0",
"rc-mentions": "~1.6.1",
"rc-menu": "~9.0.9",
"rc-motion": "^2.4.0",
"rc-notification": "~4.5.7",
"rc-pagination": "~3.1.6",
"rc-picker": "~2.5.10",
"rc-progress": "~3.1.0",
"rc-rate": "~2.9.0",
"rc-resize-observer": "^1.0.0",
"rc-select": "~12.1.6",
"rc-slider": "~9.7.1",
"rc-steps": "~4.1.0",
"rc-switch": "~3.2.0",
"rc-table": "~7.15.1",
"rc-tabs": "~11.9.1",
"rc-textarea": "~0.3.0",
"rc-tooltip": "~5.1.1",
"rc-tree": "~4.1.0",
"rc-tree-select": "~4.3.0",
"rc-trigger": "^5.2.1",
"rc-upload": "~4.3.0",
"rc-util": "^5.13.1",
"scroll-into-view-if-needed": "^2.2.25",
"warning": "^4.0.3"
}
},
"anymatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
......@@ -2919,6 +3050,11 @@
"is-string": "^1.0.5"
}
},
"array-tree-filter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz",
"integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw=="
},
"array-union": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
......@@ -3040,6 +3176,11 @@
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
},
"async-validator": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-3.5.2.tgz",
"integrity": "sha512-8eLCg00W9pIRZSB781UUX/H6Oskmm8xloZfr09lz5bikRpBVDlJ3hRVuxxP1SxcwsEYfJ4IU8Q19Y8/893r3rQ=="
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
......@@ -4085,6 +4226,11 @@
}
}
},
"classnames": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
"integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
},
"clean-css": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
......@@ -4253,6 +4399,11 @@
}
}
},
"compute-scroll-into-view": {
"version": "1.0.17",
"resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.17.tgz",
"integrity": "sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg=="
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
......@@ -4372,6 +4523,14 @@
"resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
"integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
},
"copy-to-clipboard": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz",
"integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==",
"requires": {
"toggle-selection": "^1.0.6"
}
},
"core-js": {
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.13.1.tgz",
......@@ -4799,6 +4958,11 @@
}
}
},
"csstype": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz",
"integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw=="
},
"cyclist": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
......@@ -4828,6 +4992,11 @@
"whatwg-url": "^8.0.0"
}
},
"date-fns": {
"version": "2.22.1",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.22.1.tgz",
"integrity": "sha512-yUFPQjrxEmIsMqlHhAhmxkuH769baF21Kk+nZwZGyrMoyLA+LugaQtC0+Tqf9CBUUULWwUJt6Q5ySI3LJDDCGg=="
},
"debug": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
......@@ -5112,6 +5281,11 @@
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.6.tgz",
"integrity": "sha512-DplGLZd8L1lN64jlT27N9TVSESFR5STaEJvX+thCby7fuCHonfPpAlodYc3vuUYbDuDec5w8AMP7oCM5TWFsqw=="
},
"dom-align": {
"version": "1.12.2",
"resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.2.tgz",
"integrity": "sha512-pHuazgqrsTFrGU2WLDdXxCFabkdQDx72ddkraZNih1KsMcN5qsRSTR9O4VJRlwTPCPb5COYg3LOfiMHHcPInHg=="
},
"dom-converter": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz",
......@@ -6659,6 +6833,14 @@
}
}
},
"flux-standard-action": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/flux-standard-action/-/flux-standard-action-2.1.1.tgz",
"integrity": "sha512-W86GzmXmIiTVq/dpYVd2HtTIUX9c35Iq3ao3xR6qcKtuXgbu+BDEj72op5VnEIe/kpuSbhl+I8kT1iS2hpcusw==",
"requires": {
"lodash": "^4.17.15"
}
},
"follow-redirects": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
......@@ -7834,6 +8016,11 @@
"resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
"integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="
},
"is-promise": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
"integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="
},
"is-regex": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz",
......@@ -9530,6 +9717,14 @@
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE="
},
"json2mq": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz",
"integrity": "sha1-tje9O6nqvhIsg+lyBIOusQ0skEo=",
"requires": {
"string-convert": "^0.2.0"
}
},
"json3": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz",
......@@ -10104,6 +10299,11 @@
"minimist": "^1.2.5"
}
},
"moment": {
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
},
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
......@@ -12250,6 +12450,382 @@
}
}
},
"rc-align": {
"version": "4.0.9",
"resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.9.tgz",
"integrity": "sha512-myAM2R4qoB6LqBul0leaqY8gFaiECDJ3MtQDmzDo9xM9NRT/04TvWOYd2YHU9zvGzqk9QXF6S9/MifzSKDZeMw==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "2.x",
"dom-align": "^1.7.0",
"rc-util": "^5.3.0",
"resize-observer-polyfill": "^1.5.1"
}
},
"rc-cascader": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-1.4.3.tgz",
"integrity": "sha512-Q4l9Mv8aaISJ+giVnM9IaXxDeMqHUGLvi4F+LksS6pHlaKlN4awop/L+IMjIXpL+ug/ojaCyv/ixcVopJYYCVA==",
"requires": {
"@babel/runtime": "^7.12.5",
"array-tree-filter": "^2.1.0",
"rc-trigger": "^5.0.4",
"rc-util": "^5.0.1",
"warning": "^4.0.1"
}
},
"rc-checkbox": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/rc-checkbox/-/rc-checkbox-2.3.2.tgz",
"integrity": "sha512-afVi1FYiGv1U0JlpNH/UaEXdh6WUJjcWokj/nUN2TgG80bfG+MDdbfHKlLcNNba94mbjy2/SXJ1HDgrOkXGAjg==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.1"
}
},
"rc-collapse": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/rc-collapse/-/rc-collapse-3.1.1.tgz",
"integrity": "sha512-/oetKApTHzGGeR8Q8vD168EXkCs2MpEIrURGyy2D+LrrJd29LY/huuIMvOiJoSV6W3bcGhJqIdgHtg1Dxn1smA==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "2.x",
"rc-motion": "^2.3.4",
"rc-util": "^5.2.1",
"shallowequal": "^1.1.0"
}
},
"rc-dialog": {
"version": "8.5.2",
"resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-8.5.2.tgz",
"integrity": "sha512-3n4taFcjqhTE9uNuzjB+nPDeqgRBTEGBfe46mb1e7r88DgDo0lL4NnxY/PZ6PJKd2tsCt+RrgF/+YeTvJ/Thsw==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.6",
"rc-motion": "^2.3.0",
"rc-util": "^5.6.1"
}
},
"rc-drawer": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/rc-drawer/-/rc-drawer-4.3.1.tgz",
"integrity": "sha512-GMfFy4maqxS9faYXEhQ+0cA1xtkddEQzraf6SAdzWbn444DrrLogwYPk1NXSpdXjLCLxgxOj9MYtyYG42JsfXg==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.6",
"rc-util": "^5.7.0"
}
},
"rc-dropdown": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/rc-dropdown/-/rc-dropdown-3.2.0.tgz",
"integrity": "sha512-j1HSw+/QqlhxyTEF6BArVZnTmezw2LnSmRk6I9W7BCqNCKaRwleRmMMs1PHbuaG8dKHVqP6e21RQ7vPBLVnnNw==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.6",
"rc-trigger": "^5.0.4"
}
},
"rc-field-form": {
"version": "1.20.1",
"resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-1.20.1.tgz",
"integrity": "sha512-f64KEZop7zSlrG4ef/PLlH12SLn6iHDQ3sTG+RfKBM45hikwV1i8qMf53xoX12NvXXWg1VwchggX/FSso4bWaA==",
"requires": {
"@babel/runtime": "^7.8.4",
"async-validator": "^3.0.3",
"rc-util": "^5.8.0"
}
},
"rc-image": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/rc-image/-/rc-image-5.2.4.tgz",
"integrity": "sha512-kWOjhZC1OoGKfvWqtDoO9r8WUNswBwnjcstI6rf7HMudz0usmbGvewcWqsOhyaBRJL9+I4eeG+xiAoxV1xi75Q==",
"requires": {
"@babel/runtime": "^7.11.2",
"classnames": "^2.2.6",
"rc-dialog": "~8.5.0",
"rc-util": "^5.0.6"
}
},
"rc-input-number": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-7.1.3.tgz",
"integrity": "sha512-o7/YTXAnxio53lCV402OcFRn8/jcm6YfKjCzPd+al0drQ7oyQkjQqcWbacSQwwN4gCHmqXGfgnRuAuBHoYz1dw==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.5",
"rc-util": "^5.9.8"
}
},
"rc-mentions": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-1.6.1.tgz",
"integrity": "sha512-LDzGI8jJVGnkhpTZxZuYBhMz3avcZZqPGejikchh97xPni/g4ht714Flh7DVvuzHQ+BoKHhIjobHnw1rcP8erg==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.6",
"rc-menu": "^9.0.0",
"rc-textarea": "^0.3.0",
"rc-trigger": "^5.0.4",
"rc-util": "^5.0.1"
}
},
"rc-menu": {
"version": "9.0.10",
"resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.0.10.tgz",
"integrity": "sha512-wb7fZZ3f5KBqr7v3q8U1DB5K4SEm31KLPe/aANyrHajVJjQpiiGTMLF7ZB7vyqjC4QJq0SJewB4FkumT2U86fw==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "2.x",
"rc-motion": "^2.4.3",
"rc-overflow": "^1.2.0",
"rc-trigger": "^5.1.2",
"rc-util": "^5.12.0",
"shallowequal": "^1.1.0"
}
},
"rc-motion": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.4.4.tgz",
"integrity": "sha512-ms7n1+/TZQBS0Ydd2Q5P4+wJTSOrhIrwNxLXCZpR7Fa3/oac7Yi803HDALc2hLAKaCTQtw9LmQeB58zcwOsqlQ==",
"requires": {
"@babel/runtime": "^7.11.1",
"classnames": "^2.2.1",
"rc-util": "^5.2.1"
}
},
"rc-notification": {
"version": "4.5.7",
"resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-4.5.7.tgz",
"integrity": "sha512-zhTGUjBIItbx96SiRu3KVURcLOydLUHZCPpYEn1zvh+re//Tnq/wSxN4FKgp38n4HOgHSVxcLEeSxBMTeBBDdw==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "2.x",
"rc-motion": "^2.2.0",
"rc-util": "^5.0.1"
}
},
"rc-overflow": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/rc-overflow/-/rc-overflow-1.2.1.tgz",
"integrity": "sha512-TCB8QiEnmNUbsJZX1GU8ZvIgVxk42eu3yaRdDZc2HFjVeT3HBSfscVaCVzBuH3NR5IWrQLodI0p6MZEGFn+KiA==",
"requires": {
"@babel/runtime": "^7.11.1",
"classnames": "^2.2.1",
"rc-resize-observer": "^1.0.0",
"rc-util": "^5.5.1"
}
},
"rc-pagination": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/rc-pagination/-/rc-pagination-3.1.6.tgz",
"integrity": "sha512-Pb2zJEt8uxXzYCWx/2qwsYZ3vSS9Eqdw0cJBli6C58/iYhmvutSBqrBJh51Z5UzYc5ZcW5CMeP5LbbKE1J3rpw==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.1"
}
},
"rc-picker": {
"version": "2.5.10",
"resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-2.5.10.tgz",
"integrity": "sha512-d2or2jql9SSY8CaRPybpbKkXBq3bZ6g88UKyWQZBLTCrc92Xm87RfRC/P3UEQo/CLmia3jVF7IXVi1HmNe2DZA==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.1",
"date-fns": "^2.15.0",
"moment": "^2.24.0",
"rc-trigger": "^5.0.4",
"rc-util": "^5.4.0",
"shallowequal": "^1.1.0"
}
},
"rc-progress": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/rc-progress/-/rc-progress-3.1.4.tgz",
"integrity": "sha512-XBAif08eunHssGeIdxMXOmRQRULdHaDdIFENQ578CMb4dyewahmmfJRyab+hw4KH4XssEzzYOkAInTLS7JJG+Q==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.6"
}
},
"rc-rate": {
"version": "2.9.1",
"resolved": "https://registry.npmjs.org/rc-rate/-/rc-rate-2.9.1.tgz",
"integrity": "sha512-MmIU7FT8W4LYRRHJD1sgG366qKtSaKb67D0/vVvJYR0lrCuRrCiVQ5qhfT5ghVO4wuVIORGpZs7ZKaYu+KMUzA==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.5",
"rc-util": "^5.0.1"
}
},
"rc-resize-observer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-1.0.0.tgz",
"integrity": "sha512-RgKGukg1mlzyGdvzF7o/LGFC8AeoMH9aGzXTUdp6m+OApvmRdUuOscq/Y2O45cJA+rXt1ApWlpFoOIioXL3AGg==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.1",
"rc-util": "^5.0.0",
"resize-observer-polyfill": "^1.5.1"
}
},
"rc-select": {
"version": "12.1.10",
"resolved": "https://registry.npmjs.org/rc-select/-/rc-select-12.1.10.tgz",
"integrity": "sha512-LQdUhYncvcULlrNcAShYicc1obPtnNK7/rvCD+YCm0b2BLLYxl3M3b/HOX6o+ppPej+yZulkUPeU6gcgcp9nag==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "2.x",
"rc-motion": "^2.0.1",
"rc-overflow": "^1.0.0",
"rc-trigger": "^5.0.4",
"rc-util": "^5.9.8",
"rc-virtual-list": "^3.2.0"
}
},
"rc-slider": {
"version": "9.7.2",
"resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-9.7.2.tgz",
"integrity": "sha512-mVaLRpDo6otasBs6yVnG02ykI3K6hIrLTNfT5eyaqduFv95UODI9PDS6fWuVVehVpdS4ENgOSwsTjrPVun+k9g==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.5",
"rc-tooltip": "^5.0.1",
"rc-util": "^5.0.0",
"shallowequal": "^1.1.0"
}
},
"rc-steps": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/rc-steps/-/rc-steps-4.1.3.tgz",
"integrity": "sha512-GXrMfWQOhN3sVze3JnzNboHpQdNHcdFubOETUHyDpa/U3HEKBZC3xJ8XK4paBgF4OJ3bdUVLC+uBPc6dCxvDYA==",
"requires": {
"@babel/runtime": "^7.10.2",
"classnames": "^2.2.3",
"rc-util": "^5.0.1"
}
},
"rc-switch": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/rc-switch/-/rc-switch-3.2.2.tgz",
"integrity": "sha512-+gUJClsZZzvAHGy1vZfnwySxj+MjLlGRyXKXScrtCTcmiYNPzxDFOxdQ/3pK1Kt/0POvwJ/6ALOR8gwdXGhs+A==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.1",
"rc-util": "^5.0.1"
}
},
"rc-table": {
"version": "7.15.2",
"resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.15.2.tgz",
"integrity": "sha512-TAs7kCpIZwc2mtvD8CMrXSM6TqJDUsy0rUEV1YgRru33T8bjtAtc+9xW/KC1VWROJlHSpU0R0kXjFs9h/6+IzQ==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.5",
"rc-resize-observer": "^1.0.0",
"rc-util": "^5.13.0",
"shallowequal": "^1.1.0"
}
},
"rc-tabs": {
"version": "11.9.1",
"resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-11.9.1.tgz",
"integrity": "sha512-CLNx3qaWnO8KBWPd+7r52Pfk0MoPyKtlr+2ltWq2I9iqAjd1nZu6iBpQP7wbWBwIomyeFNw/WjHdRN7VcX5Qtw==",
"requires": {
"@babel/runtime": "^7.11.2",
"classnames": "2.x",
"rc-dropdown": "^3.2.0",
"rc-menu": "^9.0.0",
"rc-resize-observer": "^1.0.0",
"rc-util": "^5.5.0"
}
},
"rc-textarea": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-0.3.4.tgz",
"integrity": "sha512-ILUYx831ZukQPv3m7R4RGRtVVWmL1LV4ME03L22mvT56US0DGCJJaRTHs4vmpcSjFHItph5OTmhodY4BOwy81A==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.1",
"rc-resize-observer": "^1.0.0",
"rc-util": "^5.7.0"
}
},
"rc-tooltip": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-5.1.1.tgz",
"integrity": "sha512-alt8eGMJulio6+4/uDm7nvV+rJq9bsfxFDCI0ljPdbuoygUscbsMYb6EQgwib/uqsXQUvzk+S7A59uYHmEgmDA==",
"requires": {
"@babel/runtime": "^7.11.2",
"rc-trigger": "^5.0.0"
}
},
"rc-tree": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-4.1.5.tgz",
"integrity": "sha512-q2vjcmnBDylGZ9/ZW4F9oZMKMJdbFWC7um+DAQhZG1nqyg1iwoowbBggUDUaUOEryJP+08bpliEAYnzJXbI5xQ==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "2.x",
"rc-motion": "^2.0.1",
"rc-util": "^5.0.0",
"rc-virtual-list": "^3.0.1"
}
},
"rc-tree-select": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-4.3.3.tgz",
"integrity": "sha512-0tilOHLJA6p+TNg4kD559XnDX3PTEYuoSF7m7ryzFLAYvdEEPtjn0QZc5z6L0sMKBiBlj8a2kf0auw8XyHU3lA==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "2.x",
"rc-select": "^12.0.0",
"rc-tree": "^4.0.0",
"rc-util": "^5.0.5"
}
},
"rc-trigger": {
"version": "5.2.8",
"resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-5.2.8.tgz",
"integrity": "sha512-Tn84oGmvNBLXI+ptpzxyJx4ArKTduuB6l74ShDLhDaJaF9f5JAMizfx31L30ELVIzRr3Ze4sekG7rzwPGwVOdw==",
"requires": {
"@babel/runtime": "^7.11.2",
"classnames": "^2.2.6",
"rc-align": "^4.0.0",
"rc-motion": "^2.0.0",
"rc-util": "^5.5.0"
}
},
"rc-upload": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/rc-upload/-/rc-upload-4.3.0.tgz",
"integrity": "sha512-wDXf1ZdUTwBIfagTof1MJDjOHZ6xluD0xcgojYZeAZSi+3Doyc21jNV8bRIeK5jx/OQmllrpQp1/MWKkqvkBhg==",
"requires": {
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.5",
"rc-util": "^5.2.0"
}
},
"rc-util": {
"version": "5.13.1",
"resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.13.1.tgz",
"integrity": "sha512-Dws2tjXBBihfjVQFlG5JzZ/5O3Wutctm0W94Wb1+M7GD2roWJPrQdSa4AkWm2pn0Ms32zoVPPkWodFeAYZPLfA==",
"requires": {
"@babel/runtime": "^7.12.5",
"react-is": "^16.12.0",
"shallowequal": "^1.1.0"
}
},
"rc-virtual-list": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.2.6.tgz",
"integrity": "sha512-8FiQLDzm3c/tMX0d62SQtKDhLH7zFlSI6pWBAPt+TUntEqd3Lz9zFAmpvTu8gkvUom/HCsDSZs4wfV4wDPWC0Q==",
"requires": {
"classnames": "^2.2.6",
"rc-resize-observer": "^1.0.0",
"rc-util": "^5.0.7"
}
},
"react": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz",
......@@ -12438,6 +13014,19 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"react-redux": {
"version": "7.2.4",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.4.tgz",
"integrity": "sha512-hOQ5eOSkEJEXdpIKbnRyl04LhaWabkDPV+Ix97wqQX3T3d2NQ8DUblNXXtNMavc7DpswyQM6xfaN4HQDKNY2JA==",
"requires": {
"@babel/runtime": "^7.12.1",
"@types/react-redux": "^7.1.16",
"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",
......@@ -12670,6 +13259,28 @@
"strip-indent": "^3.0.0"
}
},
"redux": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.1.0.tgz",
"integrity": "sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g==",
"requires": {
"@babel/runtime": "^7.9.2"
}
},
"redux-promise": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/redux-promise/-/redux-promise-0.6.0.tgz",
"integrity": "sha512-R2mGxJbPFgXyCNbFDE6LjTZhCEuACF54g1bxld3nqBhnRMX0OsUyWk77moF7UMGkUdl5WOAwc4BC5jOd1dunqQ==",
"requires": {
"flux-standard-action": "^2.0.3",
"is-promise": "^2.1.0"
}
},
"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",
......@@ -12824,6 +13435,11 @@
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
"resize-observer-polyfill": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
},
"resolve": {
"version": "1.18.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz",
......@@ -13299,6 +13915,14 @@
"ajv-keywords": "^3.5.2"
}
},
"scroll-into-view-if-needed": {
"version": "2.2.28",
"resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.28.tgz",
"integrity": "sha512-8LuxJSuFVc92+0AdNv4QOxRL4Abeo1DgLnGNkn1XlaujPH/3cCFz3QI60r2VNu4obJJROzgnIUw5TKQkZvZI1w==",
"requires": {
"compute-scroll-into-view": "^1.0.17"
}
},
"select-hose": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
......@@ -13473,6 +14097,11 @@
"safe-buffer": "^5.0.1"
}
},
"shallowequal": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
"integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
},
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
......@@ -13992,6 +14621,11 @@
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
},
"string-convert": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz",
"integrity": "sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c="
},
"string-length": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
......@@ -14555,6 +15189,11 @@
"is-number": "^7.0.0"
}
},
"toggle-selection": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
"integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI="
},
"toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
......@@ -15007,6 +15646,14 @@
"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==",
"requires": {
"loose-envify": "^1.0.0"
}
},
"watchpack": {
"version": "1.7.5",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",
......
......@@ -6,12 +6,17 @@
"@testing-library/jest-dom": "^5.12.0",
"@testing-library/react": "^11.2.7",
"@testing-library/user-event": "^12.8.3",
"antd": "^4.16.1",
"axios": "^0.21.1",
"http-proxy-middleware": "^2.0.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-redux": "^7.2.4",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"redux": "^4.1.0",
"redux-promise": "^0.6.0",
"redux-thunk": "^2.3.0",
"web-vitals": "^1.1.2"
},
"scripts": {
......
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link
//Link
} from "react-router-dom";
import LandingPage from './components/views/LandingPage/LandingPage'
import LoginPage from './components/views/LoginPage/LoginPage'
import RegisterPage from './components/views/RegisterPage/RegisterPage'
import auth from './hoc/authentication'
function App() {
return (
<Router>
<div>
{/*
A <Switch> looks through all its children <Route>
elements and renders the first one whose path
matches the current URL. Use a <Switch> any time
you have multiple routes, but you want only one
of them to render at a time
*/}
<Switch>
<Route exact path="/">
<LandingPage />
</Route> {/*
<Route exact path="/" component={LandingPage} /> 로 해도 똑같은 결과가 나옴!
*/}
{/* null, false에 대한 옵션 설명은 auth로 가서 확인*/}
<Route exact path="/" component={auth(LandingPage, null)} />
<Route path="/login">
<LoginPage />
</Route>
<Route exact path="/login" component={auth(LoginPage, false)}/>
<Route path="/register">
<RegisterPage />
</Route>
<Route exact path="/register" component={auth(RegisterPage, false)}/>
{/*
<Route exact path="/" component={LandingPage} />
<Route exact path="/login" component={LoginPage}/>
<Route exact path="/register" component={RegisterPage}/>
*/}
</Switch>
</div>
</Router>
......
// type들만 관리하는 곳
export const LOGIN_USER = "login_user";
export const REGISTER_USER = "resgier_user";
export const AUTH_USER = "auth_user";
\ No newline at end of file
import axios from 'axios';
import {
LOGIN_USER,
REGISTER_USER,
AUTH_USER
} from './types';
export function loginUser(logInfo) {
const request = axios.post('/api/users/login', logInfo) // logInfo를 post로 전달
.then(response => response.data); // 서버에서 받은 데이터를 request에 저장
return { // return을 통해 Reducer로 보냄
// Reducer에서 previousState, action을 이용해 nextState로 만들기 때문 :: (previousState, action) => nextState
// request를 reducer로 보내는 작업
// action은 type과 response을 넣어줘야 함
type: "LOGIN_USER",
payload: request // payroad == response
}
}
export function RegisterUser(regInfo) {
const request = axios.post('/api/users/register', regInfo) // logInfo를 post로 전달
.then(response => response.data); // 서버에서 받은 데이터를 request에 저장
return { // return을 통해 Reducer로 보냄.
// Reducer에서 previousState, action을 이용해 nextState로 만들기 때문 :: (previousState, action) => nextState
// request를 reducer로 보내는 작업
// action은 type과 response을 넣어줘야 함
type: "REGISTER_USER",
payload: request // payroad == response
}
}
export function auth() {
const request = axios.get('/api/users/auth') // logInfo를 post로 전달
.then(response => response.data); // 서버에서 받은 데이터를 request에 저장
return {
type: "AUTH_USER",
payload: request // payroad == response
}
}
\ No newline at end of file
// Redux에 있는 Store에 Reducer들이 여러가지 있을 수 있다.
// -> why? : Reducer 안에서 하는 일은
// state가 어떻게 변하는지를 보여준 다음, 변한 마지막 값을 return 해주는 것.
// 웹서비스를 제작하면서 user state, comment state ... 등등 다양한 기능에 대한 state들이 존재할 수 있고
// 각각 state마다 reducer가 있어서 user reducer, comment reducer ... 등등 다양한 reducer들이 존재할 수 있음.
// ------------------------------------
// 이렇게 나눠진 다양한 reducer을 combineReducers을 통해 rootReducer에서 하나로 합쳐주는 기능을 만들 것임.
import { combineReducers } from 'redux';
import user from './user_reducer'; // user(회원가입, 로그인, 인증, 로그아웃 기능이 있음) reducer
// import comment from './comment_reducer'; // comment기능이 있을 때 reducer
const rootReducer = combineReducers( {
user
})
// 다른 곳에서도 rootReducer을 쓸 수 있도록
export default rootReducer;
\ No newline at end of file
import {
LOGIN_USER,
REGISTER_USER,
AUTH_USER
} from '../_actions/types';
// reducer은 (previousState, action) => (nextState)로
export default function (prevState = {}, action) {
switch (action.type) {
case LOGIN_USER:
return {...prevState, loginSuccess:action.payload} // 위의 prevState를 그대로 가져오고,
// user_action.js에 있는 payload를 그대로 가져와서 return.
// loginSuccess는 server/index.js 에서 login에 성공하면 json type으로 loginSuccess: true를 전달하라고 했기 때문
break;
case REGISTER_USER:
return {...prevState, success:action.payload}
// success는 server/index.js 에서 register에 성공하면 json type으로 success: true를 전달하라고 했기 때문
break;
case AUTH_USER:
return {...prevState, user:action.payload}
break;
default:
return prevState;
}
}
\ No newline at end of file
import React, {useEffect} from 'react'
import axios from 'axios'
import { withRouter } from 'react-router-dom';
function LandingPage(props) {
// 로그아웃 버튼 클릭 됐을 때
const onLogoutClickedEvent = () => {
axios.get('/api/users/logout')
.then(response => {
// 만약 success:true이면 로그인 페이지로 가기
if(response.data.success)
props.history.push("/login");
else
alert("Fail to logout.")
})
}
// 랜딩페이지에 들어오자마자
useEffect(() => {
axios.get('/api/hello') // get request를 서버로 보냄 (endpoint는 /api/hello)
.then(response => console.log(response.data)) // 서버로부터 응답 받은 내용을 콘솔에 출력
}, [])
return (
<div style={{justifyContent:'center', alignItems: 'center', display:'flex', width:'100%'}}>
<h1>시작 페이지</h1>
<button onClick ={onLogoutClickedEvent}> Logout </button>
</div>
)
}
export default withRouter(LandingPage)
\ No newline at end of file
import axios from 'axios';
//import { response } from 'express';
import React from 'react'
import {useState} from 'react'
import {useDispatch} from 'react-redux';
import {loginUser} from '../../../_actions/user_action'
import { withRouter } from 'react-router-dom';
function LoginPage(props) {
// 이 로그인페이지 안에서 input에 타이핑을 함으로써 데이터를 변화시켜주므로 state 사용.
// 1-1. state을 사용하기 위해 state 만들어줌.
const [Email, setEmail] = useState(""); // 1-2. email을 위한 state
const [Password, setPassword] = useState(""); // 1-2. password를 위한 state
//1-3. 아래 input value에 넣어줌
// 2-1. 타이핑할 때 타이핑 하는 거 보이게 하도록 핸들러를 만들어줌
const emailEvent = (event) => {
setEmail(event.currentTarget.value)
}
const passwordEvent = (event) => {
setPassword(event.currentTarget.value)
}
const dispatch = useDispatch();
const submitEvent = (event) => {
event.preventDefault(); // 이걸 하지 않으면 버튼을 누를 때마다 refresh돼서 데이터 처리를 할 수 없음
//console.log('Email', Email); // 잘 나오는지 확인
//console.log('Password', Password); // 잘 나오는지 확인
let logInfo = { // 보내주기 위해 저장
email: Email,
password: Password
}
dispatch(loginUser(logInfo)) // _actions폴더 user_action.js에 있음
.then(response => {
if(response.payload.loginSuccess)
props.history.push('/');
else
alert('Error');
})
}
return (
<div style={{
justifyContent:'center', alignItems: 'center', display:'flex', width:'100%', height:'50vh'
}}>
<form onSubmit={submitEvent}>
<label>Email</label>
<input type="email" value={Email} onChange={emailEvent} />
{/* input type="email"이라서 '이메일 주소에 '@'를 포함해주세요'라는 경고문 뜸. */}
<label>Password</label>
<input type="password" value={Password} onChange={passwordEvent} />
<br/>
<button>
Login
</button>
</form>
</div>
)
}
export default withRouter(LoginPage)
import React from 'react'
import {useState} from 'react'
import {useDispatch} from 'react-redux';
import {RegisterUser} from '../../../_actions/user_action'
import { withRouter } from 'react-router-dom';
function RegisterPage(props) {
// 이 로그인페이지 안에서 input에 타이핑을 함으로써 데이터를 변화시켜주므로 state 사용.
// 1-1. state을 사용하기 위해 state 만들어줌.
const [Name, setName] = useState("");
const [Email, setEmail] = useState(""); // 1-2. email을 위한 state
const [Password, setPassword] = useState(""); // 1-2. password를 위한 state
const [Password2, setPassword2] = useState("");
//1-3. 아래 input value에 넣어줌
// 2-1. 타이핑할 때 타이핑 하는 거 보이게 하도록 핸들러를 만들어줌
const emailEvent = (event) => {
setEmail(event.currentTarget.value)
}
const passwordEvent = (event) => {
setPassword(event.currentTarget.value)
}
const password2Event = (event) => {
setPassword2(event.currentTarget.value)
}
const NameEvent = (event) => {
setName(event.currentTarget.value)
}
const dispatch = useDispatch();
const submitEvent = (event) => {
event.preventDefault(); // 이걸 하지 않으면 버튼을 누를 때마다 refresh돼서 데이터 처리를 할 수 없음
//console.log('Email', Email); // 잘 나오는지 확인
//console.log('Password', Password); // 잘 나오는지 확인
// 비밀번호 두개가 같아야 회원가입이 되도록
if(Password !== Password2)
return alert('비밀번호가 일치하지 않습니다.')
let regiInfo = { // 보내주기 위해 저장
name : Name,
email: Email,
password: Password
}
dispatch(RegisterUser(regiInfo)) // _actions폴더 user_action.js에 있음
.then(response => {
if(response.payload.success)
props.history.push('/login');
else
alert('Fail to sign up');
})
}
return (
<div style={{
justifyContent:'center', alignItems: 'center', display:'flex', width:'100%', height:'50vh'
}}>
<form onSubmit={submitEvent} style={{display: 'flex', flexDirection: 'column'}}>
<label>Name</label>
<input type="text" value={Name} onChange={NameEvent} />
<label>Email</label>
<input type="email" value={Email} onChange={emailEvent} />
{/* input type="email"이라서 '이메일 주소에 '@'를 포함해주세요'라는 경고문 뜸. */}
<label>Password</label>
<input type="password" value={Password} onChange={passwordEvent} />
<label>Confirm Password</label>
<input type="password" value={Password2} onChange={password2Event} />
<br/>
<button>
Sign In
</button>
</form>
</div>
)
}
export default withRouter(RegisterPage)
// 사용자의 상태를 보고
// 해당 페이지에 들어갈 수 있게 할지 안할지 결정해 줌. hoc 이용.
import axios from 'axios';
import React, {useEffect} from 'react';
//import {useEffect} from 'react';
import {useDispatch} from 'react-redux';
import {auth} from '../_actions/user_action'
export default function (SpecificComponent, option, adminRoute = null){
// ㄴ option 종류
// - null 아무나 출입 가능한 페이지
// - true 로그인한 유저만 출입 가능
// - false 로그인한 유저 출입 불가능
function AuthenticationCheck(props) {
//1. backend에 request를 날려서 사용자의 상태를 확인
const dispatch = useDispatch(); // 1-1. dispatch 사용
useEffect(() => {
dispatch(auth()) // 페이지가 이동할 때마다 dispatch가 작동해서 backend에 request를 줌
.then(response => { // 받은 response
console.log(response);
// 로그인 안했다면
if(!response.payload.isAuth) {
if(option) { // 만약 위 option이 true이면 (로그인한 유저만 출입 가능한 페이지로 가게 하려면)
props.history.push('/login'); // 로그인 하게 함
}
}
// 로그인 했다면
else {
if(adminRoute && !response.payload.isAdmin) { // admin만 갈 수 있는 페이지를 admin이 false 사람이 들어가려 한다면
props.history.push('/'); // 홈페이지로 돌아가게 함
}
else {
if(option===false) {// 로그인한 유저가 출입 불가능한 곳을 가려고 한다면
props.history.push('/'); // 홈페이지로 돌아가게 함
}
}
}
})
},[])
return (
<SpecificComponent />
)
}
return AuthenticationCheck
}
\ No newline at end of file
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { Provider } from 'react-redux' // app에 redux를 연결시켜주기 위해 redux에서 제공하는 provider 사용
import { createStore } from 'redux'; // redux에서 createStore 가져옴.
import { applyMiddleware } from 'redux'; // object만 받는 store가 promise나 functions도 받기 위해 middleware을 사용함
import promiseMiddleware from 'redux-promise';
import ReduxThunk from 'redux-thunk';
import Reducer from './_reducers';
import 'antd/dist/antd.css';
const createStoreWithMiddleware = applyMiddleware(promiseMiddleware, ReduxThunk)(createStore)
ReactDOM.render(
// App에 Redux를 연결
<Provider
store={createStoreWithMiddleware(Reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__()
)}
>
<App />
</Provider>
, document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log resu lts (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
import React from 'react'
function LoginPage() {
return (
<div>
LoginPage
</div>
)
}
export default LoginPage
import React from 'react'
function RegisterPage() {
return (
<div>
RegisterPage
</div>
)
}
export default RegisterPage
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();