Commit 3bddb53f authored by KangMin An's avatar KangMin An
Browse files

Merge branch 'merger' into kangmin

parents 2be6215c e92762f2
......@@ -4,10 +4,9 @@
# VScode setting File
.vscode/*
#
nodemodules/*
./package.json
./package-lock.json
node_modules/*
package-lock.json
package.json
# Arduino File
arduino/code/test/*
\ No newline at end of file
......@@ -18,6 +18,10 @@
.env.test.local
.env.production.local
#DB
src/db
src/data
npm-debug.log*
yarn-debug.log*
yarn-error.log*
......@@ -16,6 +16,9 @@
"moment": "^2.29.1",
"ngx-spinner": "^12.0.0",
"node-sass": "^6.0.1",
"nodemailer": "^6.6.2",
"pg": "^8.6.0",
"pg-hstore": "^2.3.4",
"react": "^17.0.2",
"react-bootstrap": "^1.6.1",
"react-chartjs-2": "^3.0.3",
......@@ -30,6 +33,7 @@
"react-scripts": "4.0.3",
"react-use": "^17.2.4",
"sass": "^1.35.1",
"sequelize": "^6.6.5",
"web-vitals": "^1.1.2"
}
},
......@@ -4327,6 +4331,11 @@
"node": ">=4"
}
},
"node_modules/any-promise": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
"integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
},
"node_modules/anymatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
......@@ -5619,6 +5628,14 @@
"resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
"integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g=="
},
"node_modules/buffer-writer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz",
"integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==",
"engines": {
"node": ">=4"
}
},
"node_modules/buffer-xor": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
......@@ -7553,6 +7570,11 @@
"resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
"integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA=="
},
"node_modules/dottie": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.2.tgz",
"integrity": "sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg=="
},
"node_modules/duplexer": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
......@@ -10769,6 +10791,14 @@
"resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
"integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A=="
},
"node_modules/inflection": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.1.tgz",
"integrity": "sha512-dldYtl2WlN0QDkIDtg8+xFwOS2Tbmp12t1cHa5/YClU6ZQjTFm7B66UcVbh9NQB+HvT5BAd2t5+yKsBkw5pcqA==",
"engines": [
"node >= 0.4.0"
]
},
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
......@@ -14355,7 +14385,6 @@
"version": "0.5.33",
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.33.tgz",
"integrity": "sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==",
"peer": true,
"dependencies": {
"moment": ">= 2.9.0"
},
......@@ -14724,6 +14753,14 @@
"node": ">=0.8.0"
}
},
"node_modules/nodemailer": {
"version": "6.6.2",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.6.2.tgz",
"integrity": "sha512-YSzu7TLbI+bsjCis/TZlAXBoM4y93HhlIgo0P5oiA2ua9Z4k+E2Fod//ybIzdJxOlXGRcHIh/WaeCBehvxZb/Q==",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/nopt": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
......@@ -15262,6 +15299,11 @@
"node": ">=6"
}
},
"node_modules/packet-reader": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz",
"integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ=="
},
"node_modules/pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
......@@ -15433,6 +15475,91 @@
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
"node_modules/pg": {
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.6.0.tgz",
"integrity": "sha512-qNS9u61lqljTDFvmk/N66EeGq3n6Ujzj0FFyNMGQr6XuEv4tgNTXvJQTfJdcvGit5p5/DWPu+wj920hAJFI+QQ==",
"dependencies": {
"buffer-writer": "2.0.0",
"packet-reader": "1.0.0",
"pg-connection-string": "^2.5.0",
"pg-pool": "^3.3.0",
"pg-protocol": "^1.5.0",
"pg-types": "^2.1.0",
"pgpass": "1.x"
},
"engines": {
"node": ">= 8.0.0"
},
"peerDependencies": {
"pg-native": ">=2.0.0"
},
"peerDependenciesMeta": {
"pg-native": {
"optional": true
}
}
},
"node_modules/pg-connection-string": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz",
"integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ=="
},
"node_modules/pg-hstore": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/pg-hstore/-/pg-hstore-2.3.4.tgz",
"integrity": "sha512-N3SGs/Rf+xA1M2/n0JBiXFDVMzdekwLZLAO0g7mpDY9ouX+fDI7jS6kTq3JujmYbtNSJ53TJ0q4G98KVZSM4EA==",
"dependencies": {
"underscore": "^1.13.1"
},
"engines": {
"node": ">= 0.8.x"
}
},
"node_modules/pg-int8": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/pg-pool": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.3.0.tgz",
"integrity": "sha512-0O5huCql8/D6PIRFAlmccjphLYWC+JIzvUhSzXSpGaf+tjTZc4nn+Lr7mLXBbFJfvwbP0ywDv73EiaBsxn7zdg==",
"peerDependencies": {
"pg": ">=8.0"
}
},
"node_modules/pg-protocol": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz",
"integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ=="
},
"node_modules/pg-types": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
"dependencies": {
"pg-int8": "1.0.1",
"postgres-array": "~2.0.0",
"postgres-bytea": "~1.0.0",
"postgres-date": "~1.0.4",
"postgres-interval": "^1.1.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/pgpass": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.4.tgz",
"integrity": "sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==",
"dependencies": {
"split2": "^3.1.1"
}
},
"node_modules/picomatch": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
......@@ -16878,6 +17005,41 @@
"node": ">=6"
}
},
"node_modules/postgres-array": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
"engines": {
"node": ">=4"
}
},
"node_modules/postgres-bytea": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
"integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/postgres-date": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/postgres-interval": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
"dependencies": {
"xtend": "^4.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
......@@ -18427,6 +18589,14 @@
"node": ">= 4"
}
},
"node_modules/retry-as-promised": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-3.2.0.tgz",
"integrity": "sha512-CybGs60B7oYU/qSQ6kuaFmRd9sTZ6oXSc0toqePvV74Ac6/IFZSI1ReFQmtCN+uvW1Mtqdwpvt/LGOiCBAY2Mg==",
"dependencies": {
"any-promise": "^1.3.0"
}
},
"node_modules/reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
......@@ -19296,6 +19466,57 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
},
"node_modules/sequelize": {
"version": "6.6.5",
"resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.6.5.tgz",
"integrity": "sha512-QyRrJrDRiwuiILqTMHUA1yWOPIL12KlfmgZ3hnzQwbMvp2vJ6fzu9bYJQB+qPMosck4mBUggY4Cjoc6Et8FBIQ==",
"dependencies": {
"debug": "^4.1.1",
"dottie": "^2.0.0",
"inflection": "1.13.1",
"lodash": "^4.17.20",
"moment": "^2.26.0",
"moment-timezone": "^0.5.31",
"retry-as-promised": "^3.2.0",
"semver": "^7.3.2",
"sequelize-pool": "^6.0.0",
"toposort-class": "^1.0.1",
"uuid": "^8.1.0",
"validator": "^13.6.0",
"wkx": "^0.5.0"
},
"engines": {
"node": ">=10.0.0"
},
"peerDependenciesMeta": {
"mariadb": {
"optional": true
},
"mysql2": {
"optional": true
},
"pg": {
"optional": true
},
"pg-hstore": {
"optional": true
},
"sqlite3": {
"optional": true
},
"tedious": {
"optional": true
}
}
},
"node_modules/sequelize-pool": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-6.1.0.tgz",
"integrity": "sha512-4YwEw3ZgK/tY/so+GfnSgXkdwIJJ1I32uZJztIEgZeAO6HMgj64OzySbWLgxj+tXhZCJnzRfkY9gINw8Ft8ZMg==",
"engines": {
"node": ">= 10.0.0"
}
},
"node_modules/serialize-javascript": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz",
......@@ -19923,6 +20144,27 @@
"node": ">=0.10.0"
}
},
"node_modules/split2": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz",
"integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==",
"dependencies": {
"readable-stream": "^3.0.0"
}
},
"node_modules/split2/node_modules/readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
......@@ -20977,6 +21219,11 @@
"node": ">=0.6"
}
},
"node_modules/toposort-class": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz",
"integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg="
},
"node_modules/tough-cookie": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
......@@ -21224,6 +21471,11 @@
"react": ">=15.0.0"
}
},
"node_modules/underscore": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz",
"integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g=="
},
"node_modules/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",
......@@ -21533,7 +21785,6 @@
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"optional": true,
"bin": {
"uuid": "dist/bin/uuid"
}
......@@ -21573,6 +21824,14 @@
"spdx-expression-parse": "^3.0.0"
}
},
"node_modules/validator": {
"version": "13.6.0",
"resolved": "https://registry.npmjs.org/validator/-/validator-13.6.0.tgz",
"integrity": "sha512-gVgKbdbHgtxpRyR8K0O6oFZPhhB5tT1jeEHZR0Znr9Svg03U0+r9DXWMrnRAB+HtCStDQKlaIZm42tVsVjqtjg==",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/value-equal": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz",
......@@ -23110,6 +23369,14 @@
"node": ">=4"
}
},
"node_modules/wkx": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz",
"integrity": "sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/word-wrap": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
......@@ -26620,6 +26887,11 @@
"color-convert": "^1.9.0"
}
},
"any-promise": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
"integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
},
"anymatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
......@@ -27664,6 +27936,11 @@
"resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
"integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g=="
},
"buffer-writer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz",
"integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw=="
},
"buffer-xor": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
......@@ -29196,6 +29473,11 @@
"resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
"integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA=="
},
"dottie": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.2.tgz",
"integrity": "sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg=="
},
"duplexer": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
......@@ -31646,6 +31928,11 @@
"resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
"integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A=="
},
"inflection": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.1.tgz",
"integrity": "sha512-dldYtl2WlN0QDkIDtg8+xFwOS2Tbmp12t1cHa5/YClU6ZQjTFm7B66UcVbh9NQB+HvT5BAd2t5+yKsBkw5pcqA=="
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
......@@ -34310,7 +34597,6 @@
"version": "0.5.33",
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.33.tgz",
"integrity": "sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==",
"peer": true,
"requires": {
"moment": ">= 2.9.0"
}
......@@ -34618,6 +34904,11 @@
}
}
},
"nodemailer": {
"version": "6.6.2",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.6.2.tgz",
"integrity": "sha512-YSzu7TLbI+bsjCis/TZlAXBoM4y93HhlIgo0P5oiA2ua9Z4k+E2Fod//ybIzdJxOlXGRcHIh/WaeCBehvxZb/Q=="
},
"nopt": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
......@@ -35005,6 +35296,11 @@
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
},
"packet-reader": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz",
"integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ=="
},
"pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
......@@ -35146,6 +35442,69 @@
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
"pg": {
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.6.0.tgz",
"integrity": "sha512-qNS9u61lqljTDFvmk/N66EeGq3n6Ujzj0FFyNMGQr6XuEv4tgNTXvJQTfJdcvGit5p5/DWPu+wj920hAJFI+QQ==",
"requires": {
"buffer-writer": "2.0.0",
"packet-reader": "1.0.0",
"pg-connection-string": "^2.5.0",
"pg-pool": "^3.3.0",
"pg-protocol": "^1.5.0",
"pg-types": "^2.1.0",
"pgpass": "1.x"
}
},
"pg-connection-string": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz",
"integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ=="
},
"pg-hstore": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/pg-hstore/-/pg-hstore-2.3.4.tgz",
"integrity": "sha512-N3SGs/Rf+xA1M2/n0JBiXFDVMzdekwLZLAO0g7mpDY9ouX+fDI7jS6kTq3JujmYbtNSJ53TJ0q4G98KVZSM4EA==",
"requires": {
"underscore": "^1.13.1"
}
},
"pg-int8": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="
},
"pg-pool": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.3.0.tgz",
"integrity": "sha512-0O5huCql8/D6PIRFAlmccjphLYWC+JIzvUhSzXSpGaf+tjTZc4nn+Lr7mLXBbFJfvwbP0ywDv73EiaBsxn7zdg==",
"requires": {}
},
"pg-protocol": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz",
"integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ=="
},
"pg-types": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
"requires": {
"pg-int8": "1.0.1",
"postgres-array": "~2.0.0",
"postgres-bytea": "~1.0.0",
"postgres-date": "~1.0.4",
"postgres-interval": "^1.1.0"
}
},
"pgpass": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.4.tgz",
"integrity": "sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==",
"requires": {
"split2": "^3.1.1"
}
},
"picomatch": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
......@@ -36310,6 +36669,29 @@
"uniq": "^1.0.1"
}
},
"postgres-array": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="
},
"postgres-bytea": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
"integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU="
},
"postgres-date": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="
},
"postgres-interval": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
"requires": {
"xtend": "^4.0.0"
}
},
"prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
......@@ -37536,6 +37918,14 @@
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
"integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs="
},
"retry-as-promised": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-3.2.0.tgz",
"integrity": "sha512-CybGs60B7oYU/qSQ6kuaFmRd9sTZ6oXSc0toqePvV74Ac6/IFZSI1ReFQmtCN+uvW1Mtqdwpvt/LGOiCBAY2Mg==",
"requires": {
"any-promise": "^1.3.0"
}
},
"reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
......@@ -38219,6 +38609,31 @@
}
}
},
"sequelize": {
"version": "6.6.5",
"resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.6.5.tgz",
"integrity": "sha512-QyRrJrDRiwuiILqTMHUA1yWOPIL12KlfmgZ3hnzQwbMvp2vJ6fzu9bYJQB+qPMosck4mBUggY4Cjoc6Et8FBIQ==",
"requires": {
"debug": "^4.1.1",
"dottie": "^2.0.0",
"inflection": "1.13.1",
"lodash": "^4.17.20",
"moment": "^2.26.0",
"moment-timezone": "^0.5.31",
"retry-as-promised": "^3.2.0",
"semver": "^7.3.2",
"sequelize-pool": "^6.0.0",
"toposort-class": "^1.0.1",
"uuid": "^8.1.0",
"validator": "^13.6.0",
"wkx": "^0.5.0"
}
},
"sequelize-pool": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-6.1.0.tgz",
"integrity": "sha512-4YwEw3ZgK/tY/so+GfnSgXkdwIJJ1I32uZJztIEgZeAO6HMgj64OzySbWLgxj+tXhZCJnzRfkY9gINw8Ft8ZMg=="
},
"serialize-javascript": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz",
......@@ -38754,6 +39169,26 @@
"extend-shallow": "^3.0.0"
}
},
"split2": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz",
"integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==",
"requires": {
"readable-stream": "^3.0.0"
},
"dependencies": {
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
}
}
},
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
......@@ -39575,6 +40010,11 @@
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
},
"toposort-class": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz",
"integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg="
},
"tough-cookie": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
......@@ -39765,6 +40205,11 @@
"react-lifecycles-compat": "^3.0.4"
}
},
"underscore": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz",
"integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g=="
},
"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",
......@@ -40009,8 +40454,7 @@
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"optional": true
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
},
"v8-compile-cache": {
"version": "2.3.0",
......@@ -40043,6 +40487,11 @@
"spdx-expression-parse": "^3.0.0"
}
},
"validator": {
"version": "13.6.0",
"resolved": "https://registry.npmjs.org/validator/-/validator-13.6.0.tgz",
"integrity": "sha512-gVgKbdbHgtxpRyR8K0O6oFZPhhB5tT1jeEHZR0Znr9Svg03U0+r9DXWMrnRAB+HtCStDQKlaIZm42tVsVjqtjg=="
},
"value-equal": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz",
......@@ -41270,6 +41719,14 @@
}
}
},
"wkx": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz",
"integrity": "sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==",
"requires": {
"@types/node": "*"
}
},
"word-wrap": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
......@@ -12,6 +12,9 @@
"moment": "^2.29.1",
"ngx-spinner": "^12.0.0",
"node-sass": "^6.0.1",
"nodemailer": "^6.6.2",
"pg": "^8.6.0",
"pg-hstore": "^2.3.4",
"react": "^17.0.2",
"react-bootstrap": "^1.6.1",
"react-chartjs-2": "^3.0.3",
......@@ -26,6 +29,7 @@
"react-scripts": "4.0.3",
"react-use": "^17.2.4",
"sass": "^1.35.1",
"sequelize": "^6.6.5",
"web-vitals": "^1.1.2"
},
"scripts": {
......
......@@ -34,39 +34,8 @@
redirectUri: 'http://localhost:3000/oauth'
})
}
// 아래는 데모를 위한 UI 코드입니다.
displayToken()
function displayToken() {
const token = getCookie('authorize-access-token')
if (token) {
Kakao.Auth.setAccessToken(token)
Kakao.Auth.getStatusInfo(({ status }) => {
if (status === 'connected') {
document.getElementById('token-result').innerText = 'login success. token: ' + Kakao.Auth.getAccessToken()
} else {
Kakao.Auth.setAccessToken(null)
}
})
}
}
function getCookie(name) {
const value = "; " + document.cookie;
const parts = value.split("; " + name + "=");
if (parts.length === 2) return parts.pop().split(";").shift();
}
</script>
<script type="text/javascript">
function loginWithKakaoPOP() {
Kakao.Auth.login({
success: function (authObj) {
alert(JSON.stringify(authObj))
},
fail: function (err) {
alert(JSON.stringify(err))
},
})
}
</script>
</script>
</head>
<body>
......
......@@ -5,8 +5,12 @@ body {
}
.a:hover {
color: white;
#btnlink {
color: white !important;
text-decoration: none !important;
min-width: 100%;
margin: auto;
height: 100%;
}
.btn-primary:active {
......@@ -15,8 +19,21 @@ body {
}
.card .card-title {
color: rgb(109, 110, 109);
/* background-color: ; */
color: rgb(70, 70, 70);
font-size: 1.5em;
}
#impactTitle {
margin: 1em;
font-size: 1.5em;
}
.card .card-subtitle {
display: flex;
color: rgb(129, 129, 129);
align-items: center;
justify-content: center;
padding: 0.5em;
}
.form-group .form-control {
......@@ -31,24 +48,26 @@ body {
}
#logpng {
width: 25px;
height: auto;
margin-right: 1em;
width: 50%;
height: 6em;
object-fit: cover;
}
#socialLink {
display: flex;
justify-content: center;
align-items: center;
height: 50%;
padding: 0.5em;
margin: 0.5em;
height: 2.5em;
color: gray;
font-size: 10px;
font-size: 0.8em;
width: fit-content;
}
@media (max-width: 767.98px) {
body {
padding: 10px;
padding: 30px;
padding-left: 20px;
padding-right: 20px;
margin: auto;
......@@ -59,7 +78,12 @@ body {
}
#stickyy {
max-width: 300px;
max-width: 400px;
}
#contour {
padding: 10px;
color: rgba(195, 195, 195, 0.753);
}
}
......@@ -82,8 +106,12 @@ body {
top: 40px;
width: fit-content;
height: fit-content;
max-width: 240px;
max-width: 300px;
}
#contour {
display: none;
}
}
\ No newline at end of file
......@@ -2,19 +2,24 @@ import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import './App.css';
import Home from './pages/Home';
import Oauth from './components/Oauth';
import SignupPage from './pages/SignupPage';
import LoginPage from './pages/LoginPage';
import LocalCodePage from './pages/LocalCodePage';
function App() {
return (
<Router>
<>
<Route exact path='/' component={Home} />
<Route path='/oauth' component={Oauth}/>
<Route exact path='/' component={Home} />
<Route exact path='/signup' component={SignupPage} />
<Route exact path='/login' component={LoginPage} />
<Route exact path='/local_code' component={LocalCodePage} />
</>
</Router>
);
}
......
import axios from 'axios';
import { useState } from 'react';
import Oauth from './Oauth';
export function handleLogin({ userId, role, name, tel, email }) {
localStorage.setItem('id', userId)
localStorage.setItem('role', role)
localStorage.setItem('name', name)
localStorage.setItem('tel', tel)
localStorage.setItem('email', email)
}
export async function handleLogout() {
localStorage.clear()
await axios.get('/api/auth/logout')
window.location.href = '/'
}
export function isLogined() {
const userId = localStorage.getItem('id')
if (userId) {
return userId
} else {
return false
}
}
export function isAdmin() {
const role = localStorage.getItem('role')
if (role === 'admin') {
return true
} else {
return false
}
}
export function isOauth(value) {
const TFoauth = value
return TFoauth;
}
// export async function doeCode() {
// const response = await axios.get('http://175.125.254.72:8090/api/data/loccode')
// // console.log('res::', response.data.locCodes)
// const resData = response.data.locCodes
// const doe = resData.DOE
// // console.log('dd', doe) //object
// // console.log('dd::', doe[doe.length-1])
// // console.log('values::', Object.values(doe))
// const doeValue = Object.values(doe)
// // console.log('@@@11', doeValue[0]['code_doe'], typeof(doeValue[0]['code_doe']))
// // console.log('@@@22', doeValue[0]['name_doe'], typeof(doeValue[0]['name_doe']))
// return doeValue
// }
\ No newline at end of file
function catchErrors(error, displayError) {
let errorMsg
if (error.response) {
errorMsg = error.response.data
console.log(errorMsg)
} else if (error.request) {
errorMsg = error.request
console.log(errorMsg)
} else {
errorMsg = error.message
console.log(errorMsg)
}
displayError(errorMsg)
}
export default catchErrors
import { Spinner, Button, Row } from 'react-bootstrap';
// export const KAKAO_AUTH_URL = `https://kauth.kakao.com/oauth/authorize?client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code`;
const { Kakao } = window;
export function LoginWithKakao() {
//authObj : response.data에 들어가 있는 부분 object 형식
Kakao.Auth.loginForm({
// 팝업 + 다른 아이디 로그인시
scope: 'account_email, profile_nickname',
// 추가 동의 받을 동의 항목 ID 목록, 하나의 문자열에 여러 개의 ID를 쉼표(,)로 구분하여 전달
success: function (authObj) {
alert('로그인 되었습니다. @@@@@@@@@')
console.log(JSON.stringify(authObj))
console.log('accT ;;', authObj.access_token)
Kakao.API.request({
// 현재 로그인한 사용자의 카카오계정 정보 불러오기
url: '/v2/user/me',
// 사용자 정보 요청 주소
data: {
property_keys: ["kakao_account.profile", "kakao_account.email"]
// 파라미터를 통해 특정 사용자 정보만 지정해서 요청
},
success: function (response) {
console.log(response);
console.log(response.kakao_account.profile);
const nickValue = Object.values(response.kakao_account.profile)
localStorage.setItem('nickname', nickValue)
const nickname = localStorage.getItem('nickname')
console.log(nickname)
window.location.replace('/' + '?nickname=' + `${nickname}`)
}
});
},
fail: function (err) {
alert(JSON.stringify(err))
},
})
}
export function kakaoLogout() {
// 토큰을 만료시켜 더 이상 해당 액세스 토큰으로 카카오 API를 호출할 수 없도록
console.log('geAccesToken()', Kakao.Auth.getAccessToken())
if (!Kakao.Auth.getAccessToken()) {
alert('Not logged in.')
localStorage.clear();
return;
}
Kakao.Auth.logout(function () {
// 로그인 시 발급받은 토큰을 만료시키는 함수
alert('logout ok\naccess token -> ' + Kakao.Auth.getAccessToken())
localStorage.clear();
window.location.replace('/')
})
}
export function Loading() {
return (
<Row className='d-block'>
<Button id='formbtn' className='d-flex justify-content-center align-items-center m-auto' style={{ width: '200px', height: '200px', flexDirection: 'column' }} disabled>
<Spinner animation="border" role="status">
<span className="sr-only">Loading...</span>
</Spinner>
<br />
Loading...
</Button>
</Row>
)
}
\ No newline at end of file
// const { smtpTransport } = require('./config/email');
// const nodemailer = require('nodemailer');
// /* min ~ max까지 랜덤으로 숫자를 생성하는 함수 */
// var generateRandom = function (min, max) {
// var ranNum = Math.floor(Math.random() * (max - min + 1)) + min;
// return ranNum;
// }
// // transporter 생성
// let transporter = nodemailer.createTransport({
// // host: "mail.회사.계정.입력" *** mail. <-요게 핵심이었다!
// host: "mail.abc.co.kr",
// // 보안 무시
// port: 587,
// // 회사 도메인 내 계정 및 비밀번호
// auth: {
// user: "myid@abc.co.kr",
// pass: "mypassword",
// },
// // 서명받지 않은 사이트의 요청도 받겠다.
// tls: {
// rejectUnauthorized: false
// }
// });
// // 메일 관련 옵션
// let mailOptions = {
// // 발송 메일 주소 (위에서 작성한 회사 계정 아이디)
// from: "myid@abc.co.kr",
// // 수신 메일 주소
// to: "receiverid@domain.com",
// // 제목
// subject: "인증 메일입니다.",
// // 인증 URL
// html: `<p>아래의 링크를 클릭하시면 인증이 완료됩니다.</p>
// <a href='http://localhost:3000/auth?etc'>인증하기</a>`,
// };
// // 메일 보내기
// transporter.sendMail(mailOptions, function (err, info) {
// if (err) {
// // 메일 보내기 에러 발생 시, 콘솔 찍어보기
// console.log("메일보내기 에러쓰");
// console.log(err);
// } else {
// // 성공했다!
// console.log("Email sent: " + info.response);
// }
// });
// // export const auth = {
// // SendEmail: async (req, res) => {
// // const number = generateRandom(111111, 999999)
// // const { sendEmail } = req.body;
// // const mailOptions = {
// // from: "정욱이네러버덕",
// // to: sendEmail,
// // subject: "[러버덕]인증 관련 이메일 입니다",
// // text: "오른쪽 숫자 6자리를 입력해주세요 : " + number
// // };
// // const result = await smtpTransport.sendMail(mailOptions, (error, responses) => {
// // if (error) {
// // return res.status(statusCode.OK).send(util.fail(statusCode.BAD_REQUEST, responseMsg.AUTH_EMAIL_FAIL))
// // } else {
// // /* 클라이언트에게 인증 번호를 보내서 사용자가 맞게 입력하는지 확인! */
// // return res.status(statusCode.OK).send(util.success(statusCode.OK, responseMsg.AUTH_EMAIL_SUCCESS, {
// // number: number
// // }))
// // }
// // smtpTransport.close();
// // });
// // }
// // }
\ No newline at end of file
import React from 'react'
import { Container, Row, Card, Table, Button } from 'react-bootstrap';
import { Row, Card } from 'react-bootstrap';
import { Doughnut } from 'react-chartjs-2'
function ChartDoughnut() {
const cardstyled = {
fontSize: '0.5em',
margin: 'auto',
padding: '1em',
display: 'flex',
justifyContent: 'center',
width: '100%',
borderWidth: '1.5px',
borderRadius: '20px',
borderColor: '#04AB70',
color: 'rgb(110, 189, 142)'
}
const btnstyled = {
background: 'rgb(110, 189, 142)',
margin: '1px',
maxWidth: '100%',
borderWidth: '2px',
fontSize: '10px',
borderColor: 'rgba(195, 195, 195, 0.753)',
borderWidth: '3px',
borderRadius: '20px',
borderColor: 'rgb(110, 189, 142)',
color: '#04AB70'
}
const options = {
......
import React from 'react'
import { Container, Row, Card, Table, Button } from 'react-bootstrap';
import { Row, Card } from 'react-bootstrap';
import { Line } from 'react-chartjs-2'
function ChartLine() {
const cardstyled = {
fontSize: '0.5em',
margin: 'auto',
padding: '1em',
display: 'flex',
justifyContent: 'center',
width: '100%',
borderWidth: '1.5px',
borderRadius: '20px',
borderColor: '#04AB70',
color: 'rgb(110, 189, 142)'
}
const btnstyled = {
background: 'rgb(110, 189, 142)',
margin: '1px',
maxWidth: '100%',
borderWidth: '2px',
fontSize: '10px',
borderColor: 'rgba(195, 195, 195, 0.753)',
borderWidth: '3px',
borderRadius: '20px',
borderColor: 'rgb(110, 189, 142)',
color: '#04AB70'
}
const options = {
legend: {
display: true, // label 보이기 여부
......
import React from 'react'
import { Container, Row, Card, Table, Button } from 'react-bootstrap';
import { Row, Card } from 'react-bootstrap';
function EueSuggest() {
const cardstyled = {
fontSize: '0.5em',
margin: 'auto',
padding: '1em',
display: 'flex',
justifyContent: 'center',
width: '100%',
borderWidth: '1.5px',
borderRadius: '20px',
borderColor: '#04AB70',
color: 'rgb(110, 189, 142)'
}
const btnstyled = {
background: 'rgb(110, 189, 142)',
margin: '1px',
maxWidth: '100%',
borderWidth: '2px',
fontSize: '10px',
borderColor: 'rgba(195, 195, 195, 0.753)',
borderWidth: '3px',
borderRadius: '20px',
borderColor: 'rgb(110, 189, 142)',
color: '#04AB70'
}
return (
......
import React, { useEffect, useRef, useState } from 'react'
import { Container, Row, Card, Table, Button, Col, Modal, ModalTitle, Overlay, Tooltip } from 'react-bootstrap';
import React, { useEffect, useState } from 'react'
import { Row, Card, Button, Col, Modal, } from 'react-bootstrap';
import { CopyToClipboard } from 'react-copy-to-clipboard';
import '../App.css'
function Footer() {
const cardstyled = {
fontSize: '0.5em',
margin: 'auto',
padding: '1em',
display: 'flex',
justifyContent: 'center',
width: '100%',
borderWidth: '1.5px',
borderWidth: '3px',
borderRadius: '20px',
borderColor: '#04AB70',
color: 'rgb(110, 189, 142)'
borderColor: 'rgb(110, 189, 142)',
color: '#04AB70'
}
const btnstyled = {
const btnstyled2 = {
background: 'white',
margin: '1px',
maxWidth: 'fit-content',
borderWidth: '2px',
fontSize: '10px',
color: 'rgb(110, 189, 142)',
borderColor: 'rgba(195, 195, 195, 0.753)',
borderRadius: '20px',
}
const [donateShow, setDonateShow] = useState(false);
const [isCopyshow, setCopyShow] = useState(false);
const HandleClose = () => setDonateShow(false);
function clickAndCopy() {
function clickAndTwoSec() {
return new Promise((resolve) => setTimeout(resolve, 2000))
}
// function CopyShow() {
const [isCopyshow, setCopyShow] = useState(false);
useEffect(() => {
if (isCopyshow) {
clickAndCopy().then(() => {
clickAndTwoSec().then(() => {
setCopyShow(false);
});
}
}, [isCopyshow]);
// isCopyshow 가 바뀔 때만 effect를 재실행한다.
// }
const handleClick = () => setCopyShow(true);
return (
<Row className='text-center w-100 my-2'>
<Card style={cardstyled}>
<Row className='my-1 d-flex justify-content-center' style={{ fontSize: '15px', color: 'rgb(109, 110, 109)' }}>
<Card.Title>
서버비용 후원하기
</Row>
<Row className='my-1 d-flex justify-content-center'>
</Card.Title>
<Card.Subtitle style={{fontWeight: 'lighter'}}>
이용하시는데 불편함이 없도록 광고 없이 운영하고 있습니다. <br />
서버비용 충당 후원금이 남을시 UNICEF 기부하겠습니다.
</Row>
<Row className='my-1 d-flex justify-content-center'>
<Button variant='light' style={btnstyled} onClick={() => setDonateShow(true)}>
</Card.Subtitle>
<Row className='my-2 d-flex justify-content-center'>
<Button variant='light' style={btnstyled2} onClick={() => setDonateShow(true)}>
후원하기
</Button>
<Modal
size='sm'
size='md'
show={donateShow}
onHide={() => setDonateShow(false)}
onHide={HandleClose}
style={{ top: '80px', left: '1vw' }}
>
<Modal.Header className='d-flex justify-content-center'>
<Modal.Title style={{fontSize: '1em'}}>
Thank you for your Donation
<Modal.Title>
Thank you for Donation
</Modal.Title>
</Modal.Header>
<Modal.Body>
<Col className='d-flex justify-content-center text-center' style={{ flexDirection: 'column' }}>
<p style={{ color: 'rgb(109, 110, 109)', margin: '1em', fontSize: '15px' }}>
<Card style={{ color: 'rgb(109, 110, 109)', paddingTop: '10px' }}>
카카오뱅크
</p>
<CopyToClipboard text={'박상호 3333-16-7299769'}>
<p className='m-auto' style={btnstyled} >
박상호 3333-16-7299769
<Button variant='light'
disabled={isCopyshow}
onClick={!isCopyshow ? handleClick : null}
style={{
background: 'lightgray',
margin: '5px',
maxWidth: 'fit-content',
borderWidth: '2px',
fontSize: '10px',
color: 'black',
border: 'none',
whiteSpace: 'nowrap'
}}>
{isCopyshow ? '복사 성공!' : '복사'}
</Button>
</p>
</CopyToClipboard>
<CopyToClipboard text={'박상호 3333-16-7299769'}>
<p className='m-auto' style={btnstyled2} >
박상호 3333-16-7299769
<Button variant='light'
disabled={isCopyshow}
onClick={!isCopyshow ? handleClick : null}
style={{
background: 'lightgray',
margin: '5px',
maxWidth: 'fit-content',
borderWidth: '2px',
fontSize: '14px',
color: 'black',
border: 'none',
whiteSpace: 'nowrap'
}}>
{isCopyshow ? '복사 성공!' : '복사'}
</Button>
</p>
</CopyToClipboard>
</Card>
</Col>
</Modal.Body>
<Modal.Footer>
<Button variant='light' style={btnstyled2} onClick={HandleClose}>
닫기
</Button>
</Modal.Footer>
</Modal>
</Row>
<Row className='my-1 d-flex justify-content-center flex-direction-column' style={{ color: 'rgb(109, 110, 109)', flexDirection: 'column' }}>
<Row className='d-flex justify-content-center flex-direction-column' style={{ color: 'rgb(109, 110, 109)', flexDirection: 'column', fontSize: '0.8em' }}>
<Col>
<a href='https://www.notion.so/EUE-047f1812c6c24096a528dfd3330c227d' style={{ color: 'rgb(110, 189, 142)' }}>TEAM EUE </a> : 안강민, 박상호, 박예
</Col>
......
import React from 'react'
import '../App.css'
import { Form, Button, Row, Col, Card, DropdownButton, Dropdown, ButtonGroup } from 'react-bootstrap';
import { useState } from 'react';
import axios from 'axios';
// import { doeCode } from '../utils/Auth';
function LocCodeChange() {
const cardstyled = {
margin: 'auto',
padding: '1em',
display: 'flex',
justifyContent: 'center',
width: '100%',
borderWidth: '3px',
borderRadius: '20px',
borderColor: 'rgb(110, 189, 142)',
color: '#04AB70'
}
const inboxstyled = {
display: 'flex',
flexDirection: 'column',
maxWidth: '80%',
justifyContent: 'center',
margin: 'auto',
padding: '10px'
}
const btnstyled2 = {
background: 'white',
margin: '1px',
maxWidth: 'fit-content',
borderWidth: '2px',
color: 'rgb(110, 189, 142)',
borderColor: 'rgba(195, 195, 195, 0.753)',
borderRadius: '20px'
}
const [locCodeShow, setLocCodeShow] = useState(false)
function handleClickLoc() {
setLocCodeShow(true);
const auth = document.getElementById('loc-code')
auth.style.visibility = 'visible'
}
// console.log(typeof (locCode()))
// console.log(locCode())
// const [ddoe, setDdoe] = useState([])
// async function DoeCode() {
// await doeCode().then((res) => {
// // // // for (let i = 0; i < res.length; i++) {
// // // console.log(res[0]['code_doe'])
// // // console.log(0, res[0]['name_doe'])
// ddoe.push(res[0]['name_doe'])
// ddoe.push(res[1]['name_doe'])
// console.log(ddoe)
// console.log(typeof(ddoe))
// // // }
// })
// }
const res = axios.get("localhost:4500/d/loccode");
// const does = res.data["locCodes"]["DOE"] // object
return (
<Row className='text-center w-100 my-2'>
{/* {DoeCode()} */}
{/* {data} */}
asd
<Card style={cardstyled}>
<Card.Title id='impactTitle'>
Local Code
</Card.Title>
<Card.Subtitle style={{ fontWeight: 'lighter' }}>
Please select a your region
</Card.Subtitle>
<hr />
<Card.Text>
<Form style={inboxstyled}>
<Row className='m-auto w-100 d-flex justify-content-center'>
<Col md={12} xs={12} style={{ padding: '0', display: 'flex', justifyContent: 'center', width: '100%' }}>
{['', '시군구', '읍면동'].map((localname) => (
<DropdownButton
variant='light'
style={btnstyled2}
title='지역코드'
as={ButtonGroup}
title={` ${localname} `}>
<Dropdown.Item></Dropdown.Item>
<Dropdown.Item>Another action</Dropdown.Item>
<Dropdown.Item>Something else here</Dropdown.Item>
</DropdownButton>
))}
<Button variant='light' style={btnstyled2} onClick={!locCodeShow && handleClickLoc}>확인</Button>
</Col>
<Col md={6} xs={4} id='loc-code' style={{
margin: '5px',
border: 'solid',
borderColor: 'rgb(110, 189, 142)',
display: 'flex',
justifyContent: 'center',
padding: '2px',
visibility: 'hidden',
transition: 'all 4s'
}}>
지역코드
</Col>
</Row>
</Form>
</Card.Text>
</Card>
</Row>
)
}
export default LocCodeChange;
\ No newline at end of file
import React, { useState } from 'react'
import { Row, Card, Button, Col, Modal } from 'react-bootstrap';
// import db from "../db/index"
import '../App.css'
import { Link } from 'react-router-dom';
function LocalCode() {
const logined = localStorage.getItem('nickname')
const cardstyled = {
margin: 'auto',
padding: '1em',
display: 'flex',
justifyContent: 'center',
width: '100%',
borderWidth: '3px',
borderRadius: '20px',
borderColor: 'rgba(195, 195, 195, 0.753)',
color: 'rgb(110, 189, 142)'
}
const btnstyled2 = {
background: 'white',
margin: 'auto',
borderWidth: '2px',
fontSize: '0.5em',
color: 'rgb(110, 189, 142)',
borderColor: 'rgba(195, 195, 195, 0.753)',
borderRadius: '20px',
}
const [localChange, setLocalChange] = useState(false)
const nickname = localStorage.getItem('nickname')
return (
<>
<Col className='text-center pt-3 pb-2 px-0'>
<Card style={cardstyled} id='localName'>
<Card.Title>
{logined ?
`${nickname}`
:
<>
GUEST
</>
}, 환영합니다.
</Card.Title>
<Row style={{ alignItems: 'center', margin: 'auto', whiteSpace: 'nowrap' }}>
<Card.Subtitle>
지역코드
</Card.Subtitle>
{logined &&
<Button variant='light' className='ml-1' style={btnstyled2}>
<Link to='/local_code' style={{ textDecoration: 'none', color: 'rgb(110, 189, 142)' }}>
변경
</Link>
</Button>
}
</Row>
<Modal
show={localChange}
onHide={() => setLocalChange(false)}
>
<Modal.Header className='d-block text-center'>
<Modal.Title>
마이페이지
</Modal.Title>
</Modal.Header>
<Modal.Body>
지역이름 (지역코드)
</Modal.Body>
</Modal>
환경을 향한 노력 <br />
<strong>OOO </strong>
</Card>
</Col>
</>
)
}
export default LocalCode;
\ No newline at end of file
import React, { useState } from 'react';
import '../App.css'
import { Form, Button, Row, Col, Card, Alert } from 'react-bootstrap';
import { LoginWithKakao } from '../utils/Oauth';
function LoginComp() {
const cardstyled = {
margin: 'auto',
padding: '1em',
display: 'flex',
justifyContent: 'center',
width: '100%',
borderWidth: '3px',
borderRadius: '20px',
borderColor: 'rgb(110, 189, 142)',
color: '#04AB70'
}
const inboxstyled = {
display: 'flex',
flexDirection: 'column',
maxWidth: '80%',
justifyContent: 'center',
margin: 'auto',
padding: '10px'
}
const [emailSent, setEmailSent] = useState(false)
const [alertShow, setAlertShow] = useState(true)
function CheckEmailSend() {
setEmailSent(!emailSent)
}
return (
<Row className='text-center w-100 my-2'>
<Card style={cardstyled}>
<Card.Title id='impactTitle'>
LOGIN
</Card.Title>
<Card.Subtitle style={{ fontWeight: 'lighter' }}>
Log in with your social media account or email address
</Card.Subtitle>
<hr />
<Card.Text>
<Row className='m-auto d-flex justify-content-center' style={{ width: '80%' }}>
{!emailSent ?
<Alert show={alertShow} variant={'success'}>
<Col>
😍 이메일 전송이 완료 되었습니다.
</Col>
<Alert.Link href='/' style={{ fontSize: '0.8em' }}>
이메일 확인 하러가기
</Alert.Link>
</Alert>
:
<Alert show={alertShow} variant={'danger'}>
<Col>
😭 이메일을 정확하게 적어주세요.
</Col>
</Alert>
}
<Button onClick={() => setAlertShow(true)}>보여주고</Button>
<Button onClick={() => setAlertShow(false)}>안보여주고</Button>
</Row>
<Form style={inboxstyled}>
<Form.Group controlId="formBasicEmail">
<Form.Control type="email" placeholder="Email" />
</Form.Group>
<Button variant='light' type="submit" id='formbtn' onClick={CheckEmailSend}>
LOGIN
</Button>
</Form>
<Row className='d-flex align-items-center m-2'>
<Col>
<hr />
</Col>
OR
<Col>
<hr />
</Col>
</Row>
<Row style={{ margin: 'auto', marginBottom: '5px', display: 'flex', justifyContent: 'center' }}>
<a href="#;" onClick={LoginWithKakao} id='socialLink' >
{/* 세미콜론이 붙으면 최상단 이동 x */}
<img src='http://image.kmib.co.kr/online_image/2020/0626/611514110014734788_1.jpg' id='logpng' alt='KAKAO' />
</a>
</Row>
</Card.Text>
</Card>
</Row>
)
}
export default LoginComp;
\ No newline at end of file
import React from 'react'
import { useState } from 'react';
import { Button, Form, Image, Row, ButtonGroup, Modal, Dropdown, Col } from 'react-bootstrap';
import { Button, Image, Row, ButtonGroup, } from 'react-bootstrap';
import { Link } from 'react-router-dom';
import '../App.css'
import SignUp from '../pages/SignUp'
import LoginwithSocial from '../pages/LoginwithSocial';
import LocalCode from '../components/LocalCode';
import { kakaoLogout } from '../utils/Oauth';
function MainLayer() {
......@@ -12,6 +12,7 @@ function MainLayer() {
border: 'solid',
color: 'rgba(195, 195, 195, 0.753)',
borderRadius: '20px',
borderWidth: '3px',
marginBottom: '1em',
width: '100%',
backgroundSize: 'contain',
......@@ -21,108 +22,59 @@ function MainLayer() {
const btnstyled = {
background: 'rgb(110, 189, 142)',
margin: '1px',
margin: 'auto',
marginBottom: '0.5em',
display: 'flex',
justifyContent: 'center',
maxWidth: '100%',
width: '100%',
borderWidth: '2px',
fontSize: '10px',
borderColor: 'rgba(195, 195, 195, 0.753)',
borderRadius: '20px',
textDecorationColor: 'none',
color: 'white'
}
const loginstyled = {
margin: 'auto',
padding: '2px',
diplay: 'flex',
justifyContent: 'center',
borderRadius: '20px'
}
const titlesty = {
display: 'flex',
justifyContent: 'center',
background: 'rgb(110, 189, 142)',
text: 'center'
}
const [logshow, setLogshow] = useState(false);
const [signshow, setSignshow] = useState(false);
const [isLogin, setIsLogin] = useState(false)
const logined = localStorage.getItem('nickname')
return (
<>
<Row className='d-flex align-items-center m-auto w-100'>
<Col className='m-auto '>
<Link to='/' className=' m-auto'>
<Image src='/images/EUE11.jpg' alt='EUE' style={boxstyled} />
</Link>
</Col>
<Dropdown className='d-sm-block d-md-none' style={{ fontSize: '1em' }}
>
<Dropdown.Toggle style={btnstyled} id="dropdown-basic">
</Dropdown.Toggle>
<Dropdown.Menu className='z-index-10'>
<Dropdown.Item href="#/action-1">
<Button variant='light' className='w-100 m-auto' style={btnstyled} onClick={() => setLogshow(true)}>
LOGIN
</Button>
<Modal
size="sm"
show={logshow}
onHide={() => setLogshow(false)}
aria-labelledby="example-modal-sizes-title-sm"
>
<LoginwithSocial />
</Modal>
</Dropdown.Item>
<Dropdown.Item href="#/action-2">
<Button variant='light' className='w-100 m-auto' style={btnstyled} onClick={() => setSignshow(true)}>
SIGN UP
</Button>
<Modal
size="md"
show={signshow}
onHide={() => setSignshow(false)}
aria-labelledby="example-modal-sizes-title-sm"
>
<SignUp />
</Modal>
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<Link to='/' className=' m-auto'>
<Image src='/images/EUE11.jpg' alt='EUE' style={boxstyled} />
</Link>
</Row>
<Row className='d-none d-md-flex justify-content-center align-items-center my-3 mx-auto w-100'>
<ButtonGroup vertical className='m-auto' style={{ width: '100%' }}>
<Button variant='light' style={btnstyled} onClick={() => setLogshow(true)}>LOGIN</Button>
<Modal
size="sm"
show={logshow}
onHide={() => setLogshow(false)}
aria-labelledby="example-modal-sizes-title-sm"
>
<LoginwithSocial />
</Modal>
<Button variant='light' style={btnstyled} onClick={() => setSignshow(true)}>SIGN UP</Button>
<Modal
size="md"
show={signshow}
onHide={() => setSignshow(false)}
aria-labelledby="example-modal-sizes-title-sm"
>
<SignUp />
</Modal>
<Row className='m-auto d-flex justify-content-center w-100'>
<LocalCode />
</Row>
<Row className='d-flex justify-content-center align-items-center my-2 mx-auto w-100'>
<ButtonGroup vertical className='m-auto' style={{ width: '100%', flexDirection: 'column' }}>
{logined ?
//true
<Button variant='light' style={btnstyled} onClick={kakaoLogout}>
로그아웃
</Button>
:
//false
<Button variant='light' style={btnstyled}>
<Link to='/login' id='btnlink'>
로그인
</Link>
</Button>
}
{!logined &&
<Button variant='light' style={btnstyled}>
<Link to='/signup' id='btnlink'>
회원가입
</Link>
</Button>
}
</ButtonGroup>
</Row>
<Row className='m-auto justify-content-center w-100' id='contour'>
|
</Row>
</>
);
}
......
import axios from 'axios';
import { Spinner, Button, Col, Row } from 'react-bootstrap';
import { KAKAO_AUTH_URL } from './Oauth';
import { Link, Redirect } from 'react-router-dom';
// export const KAKAO_AUTH_URL = `https://kauth.kakao.com/oauth/authorize?client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code`;
function Oauth() {
const REST_API_KEY = 'a564b730d6339b084ecf7775a9a09284';
const REDIRECT_URI = 'http://localhost:3000/oauth';
const url = new URL(window.location.href)
const authorizationCode = url.searchParams.get('code')
console.log('인가 코드', authorizationCode);
const kakaoAuthURl = `https://kauth.kakao.com/oauth/token`
// const KAKAO_AUTH_URL = `https://kauth.kakao.com/oauth/authorize?client_id=${REST_API_KEY}&redirect_uri=${REDIRECT_URI}&response_type=code`
const payload = {
grant_type: "authorization_code",
client_id: `${REST_API_KEY}`,
redirect_uri: `${REDIRECT_URI}`,
code: `${authorizationCode}`
}
const params = new URLSearchParams();
params.append('grant_type', 'authorization_code')
params.append('client_id', `${REST_API_KEY}`)
params.append('redirect_uri', `${REDIRECT_URI}`)
params.append('code', `${authorizationCode}`)
axios.post(kakaoAuthURl, params).then(response => console.log(response))
function locateHome() {
window.location.replace('/')
};
setTimeout(locateHome, 3000)
return (
<Row className='d-block'>
<Col className='text-center m-auto' style={{ fontSize: '5px' }} >
인가코드 : {authorizationCode}
<br />
Params : {params}
</Col>
<Button id='formbtn' className='d-flex justify-content-center align-items-center m-auto' style={{ width: '200px', height: '200px', flexDirection: 'column' }} disabled>
<Spinner animation="border" role="status">
<span className="sr-only">Loading...</span>
</Spinner>
<br />
Loading...
</Button>
</Row>
)
}
export default Oauth;
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment