From 93591ba74c7aa7c814347c09ec1a836e4dd35119 Mon Sep 17 00:00:00 2001 From: zigsong Date: Sat, 12 Dec 2020 10:16:18 +0900 Subject: [PATCH 01/35] docs: add todos --- docs/README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 docs/README.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..c05bf1201 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,16 @@ +## ✏️ Todos +- [X] 기능 목록 정리 +- [ ] eslint, prettier 세팅 +- [ ] 1, 2, 3, 4번 메뉴 버튼 생성 +- [ ] **역** 지하철 역 등록 +- [ ] **역** 지하철 역 등록 시 이름 에러 핸들링 +- [ ] **역** 지하철 역 목록 조회 +- [ ] **노선** 노선 등록 +- [ ] **노선** 노선 등록 시 이름 에러 핸들링 +- [ ] **노선** 노선 삭제 +- [ ] **노선** 노선 목록 조회 +- [ ] **구간** 구간 추가 +- [ ] **구간** 구간 삭제 +- [ ] **구간** 구간 종점 삭제 시 다음 역을 종점으로 +- [ ] **구간** 노선 포함 역 2개 이하면 제거 불가 +- [ ] 노선에 등록된 역 목록 조회 From 62029cd7cc48515f1fa1aa3a19b539f93679a1b4 Mon Sep 17 00:00:00 2001 From: zigsong Date: Sat, 12 Dec 2020 10:43:21 +0900 Subject: [PATCH 02/35] settings: install eslint & prettier --- .eslintrc.js | 16 + .gitignore | 1 + .prettierrc.json | 11 + docs/README.md | 2 +- package-lock.json | 943 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 29 ++ 6 files changed, 1001 insertions(+), 1 deletion(-) create mode 100644 .eslintrc.js create mode 100644 .gitignore create mode 100644 .prettierrc.json create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..0581aac64 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,16 @@ +// eslint-disable-next-line no-undef +module.exports = { + env: { + browser: true, + es2021: true, + }, + extends: ['eslint:recommended', 'plugin:prettier/recommended'], + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + ecmaVersion: 12, + sourceType: 'module', + }, + rules: {}, +}; diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..b512c09d4 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 000000000..904c1187f --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,11 @@ +{ + "printWidth": 100, + "tabWidth": 2, + "singleQuote": true, + "trailingComma": "all", + "bracketSpacing": true, + "semi": true, + "useTabs": false, + "arrowParens": "avoid", + "endOfLine": "lf" +} diff --git a/docs/README.md b/docs/README.md index c05bf1201..8876841ae 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ ## ✏️ Todos - [X] 기능 목록 정리 -- [ ] eslint, prettier 세팅 +- [X] eslint, prettier 세팅 - [ ] 1, 2, 3, 4번 메뉴 버튼 생성 - [ ] **역** 지하철 역 등록 - [ ] **역** 지하철 역 등록 시 이름 에러 핸들링 diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..e9a1f5b44 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,943 @@ +{ + "name": "javascript-subway-map-precourse", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } + } + }, + "@eslint/eslintrc": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", + "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + } + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.15.0.tgz", + "integrity": "sha512-Vr64xFDT8w30wFll643e7cGrIkPEU50yIiI36OdSIDoSGguIeaLzBo0vpGvzo9RECUqq7htURfwEtKqwytkqzA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^0.2.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^6.0.0", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + } + }, + "eslint-config-prettier": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-7.0.0.tgz", + "integrity": "sha512-8Y8lGLVPPZdaNA7JXqnvETVC7IiVRgAP6afQu9gOQRn90YY3otMNh+x7Vr2vMePQntF+5erdSUBqSzCmU/AxaQ==", + "dev": true + }, + "eslint-plugin-prettier": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.2.0.tgz", + "integrity": "sha512-kOUSJnFjAUFKwVxuzy6sA5yyMx6+o9ino4gCdShzBNx4eyFRudWRYKCFolKjoM40PEiuU6Cn7wBLfq3WsGg7qg==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "file-entry-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", + "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", + "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz", + "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "uri-js": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", + "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "v8-compile-cache": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", + "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 000000000..81ac2d887 --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "name": "javascript-subway-map-precourse", + "version": "1.0.0", + "description": "## 🚀 기능 요구사항", + "main": "index.js", + "directories": { + "doc": "docs" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/zigsong/javascript-subway-map-precourse.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/zigsong/javascript-subway-map-precourse/issues" + }, + "homepage": "https://github.com/zigsong/javascript-subway-map-precourse#readme", + "devDependencies": { + "eslint": "^7.15.0", + "eslint-config-prettier": "^7.0.0", + "eslint-plugin-prettier": "^3.2.0", + "prettier": "^2.2.1" + } +} From 8648a7ab32913affd22ac01a37624a9fbff27920 Mon Sep 17 00:00:00 2001 From: zigsong Date: Sat, 12 Dec 2020 10:43:56 +0900 Subject: [PATCH 03/35] feat: add 4 menu buttons --- docs/README.md | 2 +- index.html | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 8876841ae..02cbd7692 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,7 +1,7 @@ ## ✏️ Todos - [X] 기능 목록 정리 - [X] eslint, prettier 세팅 -- [ ] 1, 2, 3, 4번 메뉴 버튼 생성 +- [X] 1, 2, 3, 4번 메뉴 버튼 생성 - [ ] **역** 지하철 역 등록 - [ ] **역** 지하철 역 등록 시 이름 에러 핸들링 - [ ] **역** 지하철 역 목록 조회 diff --git a/index.html b/index.html index fc99deac2..24ce5311f 100644 --- a/index.html +++ b/index.html @@ -7,6 +7,10 @@

🚇 지하철 노선도 관리

+ + + +
From 3de3e81948f2392cdd2fc4b10aa1f669a3bfeff1 Mon Sep 17 00:00:00 2001 From: zigsong Date: Sat, 12 Dec 2020 12:03:09 +0900 Subject: [PATCH 04/35] feat: add station name --- docs/README.md | 2 +- index.html | 10 ++++++---- src/Station.js | 5 +++++ src/index.js | 12 ++++++++++++ src/stationManage.js | 38 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 src/Station.js create mode 100644 src/stationManage.js diff --git a/docs/README.md b/docs/README.md index 02cbd7692..a26fa1c9b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,7 +2,7 @@ - [X] 기능 목록 정리 - [X] eslint, prettier 세팅 - [X] 1, 2, 3, 4번 메뉴 버튼 생성 -- [ ] **역** 지하철 역 등록 +- [X] **역** 지하철 역 등록 - [ ] **역** 지하철 역 등록 시 이름 에러 핸들링 - [ ] **역** 지하철 역 목록 조회 - [ ] **노선** 노선 등록 diff --git a/index.html b/index.html index 24ce5311f..3ad467e6a 100644 --- a/index.html +++ b/index.html @@ -7,10 +7,12 @@

🚇 지하철 노선도 관리

- - - - +
+ + + + +
diff --git a/src/Station.js b/src/Station.js new file mode 100644 index 000000000..6a5883651 --- /dev/null +++ b/src/Station.js @@ -0,0 +1,5 @@ +export default class Station { + constructor(name) { + this.name = name; + } +} diff --git a/src/index.js b/src/index.js index e69de29bb..d5dc4473c 100644 --- a/src/index.js +++ b/src/index.js @@ -0,0 +1,12 @@ +import { initStationManage } from './stationManage.js'; + +export default function SubwayMap() { + const stationMngBtn = document.getElementById('station-manager-button'); + // const lineMngBtn = document.getElementById('line-manager-button'); + // const sectionMngBtn = document.getElementById('section-manager-button'); + // const mapPrintMngBtn = document.getElementById('map-print-manager-button'); + + stationMngBtn.addEventListener('click', () => initStationManage()); +} + +new SubwayMap(); diff --git a/src/stationManage.js b/src/stationManage.js new file mode 100644 index 000000000..a9b8a5e42 --- /dev/null +++ b/src/stationManage.js @@ -0,0 +1,38 @@ +const app = document.getElementById('app'); +const nameInputArea = document.createElement('p'); +const nameLabel = document.createElement('b'); +nameLabel.innerHTML = '역 이름'; + +const nameInput = document.createElement('input'); +nameInput.setAttribute('id', 'station-name-input'); +nameInput.setAttribute('placeholder', '역 이름을 입력해주세요'); + +const nameSubmit = document.createElement('button'); +nameSubmit.setAttribute('id', 'station-add-button'); +nameSubmit.textContent = '역 추가'; + +nameInputArea.appendChild(nameLabel); +nameInputArea.appendChild(document.createElement('br')); +nameInputArea.appendChild(nameInput); +nameInputArea.appendChild(nameSubmit); + +export const initStationManage = () => { + app.appendChild(nameInputArea); + + nameInput.addEventListener('keypress', e => { + let name = nameInput.value; + if (e.key === 'Enter') { + addStation(name); + } + }); + + nameSubmit.addEventListener('click', () => { + let name = nameInput.value; + addStation(name); + }); +}; + +const addStation = name => { + nameInput.value = ''; + console.log(name); +}; From f2ee0bf5ce10ca5060ded060ec3b8ea3f10bb1ad Mon Sep 17 00:00:00 2001 From: zigsong Date: Sat, 12 Dec 2020 12:20:41 +0900 Subject: [PATCH 05/35] refactor: separate functions adding station name --- src/stationManage.js | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/stationManage.js b/src/stationManage.js index a9b8a5e42..4492ea89b 100644 --- a/src/stationManage.js +++ b/src/stationManage.js @@ -1,38 +1,46 @@ const app = document.getElementById('app'); -const nameInputArea = document.createElement('p'); -const nameLabel = document.createElement('b'); -nameLabel.innerHTML = '역 이름'; -const nameInput = document.createElement('input'); -nameInput.setAttribute('id', 'station-name-input'); -nameInput.setAttribute('placeholder', '역 이름을 입력해주세요'); +export const initStationManage = () => { + createInputArea(); + createResultArea(); +}; -const nameSubmit = document.createElement('button'); -nameSubmit.setAttribute('id', 'station-add-button'); -nameSubmit.textContent = '역 추가'; +const createInputArea = () => { + const nameInputArea = document.createElement('p'); + const nameLabel = document.createElement('b'); + nameLabel.innerHTML = '역 이름'; -nameInputArea.appendChild(nameLabel); -nameInputArea.appendChild(document.createElement('br')); -nameInputArea.appendChild(nameInput); -nameInputArea.appendChild(nameSubmit); + const nameInput = document.createElement('input'); + nameInput.setAttribute('id', 'station-name-input'); + nameInput.setAttribute('placeholder', '역 이름을 입력해주세요'); + + const nameSubmit = document.createElement('button'); + nameSubmit.setAttribute('id', 'station-add-button'); + nameSubmit.innerHTML = '역 추가'; + + nameInputArea.appendChild(nameLabel); + nameInputArea.appendChild(document.createElement('br')); + nameInputArea.appendChild(nameInput); + nameInputArea.appendChild(nameSubmit); -export const initStationManage = () => { app.appendChild(nameInputArea); nameInput.addEventListener('keypress', e => { let name = nameInput.value; if (e.key === 'Enter') { - addStation(name); + addStation(name, nameInput); } }); nameSubmit.addEventListener('click', () => { let name = nameInput.value; - addStation(name); + addStation(name, nameInput); }); }; -const addStation = name => { +const addStation = (name, nameInput) => { nameInput.value = ''; console.log(name); }; + +const createResultArea = () => {}; From f70a2b200bf2602bf4342ffc3cdd460ca38fbcad Mon Sep 17 00:00:00 2001 From: zigsong Date: Sat, 12 Dec 2020 14:25:40 +0900 Subject: [PATCH 06/35] feat: print station table & update table when added --- docs/README.md | 3 ++- src/stationManage.js | 57 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index a26fa1c9b..101c4fb35 100644 --- a/docs/README.md +++ b/docs/README.md @@ -3,8 +3,9 @@ - [X] eslint, prettier 세팅 - [X] 1, 2, 3, 4번 메뉴 버튼 생성 - [X] **역** 지하철 역 등록 +- [X] (추가)**역** localStorage에 지하철 역 등록 - [ ] **역** 지하철 역 등록 시 이름 에러 핸들링 -- [ ] **역** 지하철 역 목록 조회 +- [X] **역** 지하철 역 목록 조회 - [ ] **노선** 노선 등록 - [ ] **노선** 노선 등록 시 이름 에러 핸들링 - [ ] **노선** 노선 삭제 diff --git a/src/stationManage.js b/src/stationManage.js index 4492ea89b..537c72507 100644 --- a/src/stationManage.js +++ b/src/stationManage.js @@ -40,7 +40,60 @@ const createInputArea = () => { const addStation = (name, nameInput) => { nameInput.value = ''; - console.log(name); + const currStations = JSON.parse(localStorage.getItem('stations')); + const updatedStations = [...currStations, name]; + localStorage.setItem('stations', JSON.stringify(updatedStations)); + console.log(JSON.parse(localStorage.getItem('stations'))); + addTable(name); }; -const createResultArea = () => {}; +const createResultArea = () => { + const tableName = document.createElement('h2'); + tableName.innerHTML = '🚉 지하철 역 목록'; + app.appendChild(tableName); + + const stationTable = document.createElement('table'); + stationTable.setAttribute('border', 1); + stationTable.setAttribute('id', 'station-table'); + + const stationNameHeader = document.createElement('th'); + stationNameHeader.innerHTML = '역 이름'; + const stationSettingHeader = document.createElement('th'); + stationSettingHeader.innerHTML = '설정'; + + stationTable.appendChild(stationNameHeader); + stationTable.appendChild(stationSettingHeader); + + const stations = JSON.parse(localStorage.getItem('stations')); + + stations.map(name => { + const tableRow = document.createElement('tr'); + const nameData = document.createElement('td'); + nameData.innerHTML = name; + + const deleteBtn = document.createElement('button'); + deleteBtn.innerHTML = '삭제'; + + tableRow.appendChild(nameData); + tableRow.appendChild(deleteBtn); + + stationTable.appendChild(tableRow); + }); + + app.appendChild(stationTable); +}; + +const addTable = name => { + const stationTable = document.getElementById('station-table'); + const newRow = document.createElement('tr'); + const newData = document.createElement('td'); + newData.innerHTML = name; + + const deleteBtn = document.createElement('button'); + deleteBtn.innerHTML = '삭제'; + + newRow.appendChild(newData); + newRow.appendChild(deleteBtn); + + stationTable.appendChild(newRow); +}; From 331141c4a6eb71fa7c75423b8b95fff2c769d256 Mon Sep 17 00:00:00 2001 From: zigsong Date: Sat, 12 Dec 2020 14:38:58 +0900 Subject: [PATCH 07/35] feat: delete station (from browser & localstorage) --- docs/README.md | 1 + src/stationManage.js | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/docs/README.md b/docs/README.md index 101c4fb35..4b855ebe2 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,6 +4,7 @@ - [X] 1, 2, 3, 4번 메뉴 버튼 생성 - [X] **역** 지하철 역 등록 - [X] (추가)**역** localStorage에 지하철 역 등록 +- [X] (추가)**역** 역 삭제 (localStorage에서도 삭제) - [ ] **역** 지하철 역 등록 시 이름 에러 핸들링 - [X] **역** 지하철 역 목록 조회 - [ ] **노선** 노선 등록 diff --git a/src/stationManage.js b/src/stationManage.js index 537c72507..3147436ee 100644 --- a/src/stationManage.js +++ b/src/stationManage.js @@ -68,11 +68,13 @@ const createResultArea = () => { stations.map(name => { const tableRow = document.createElement('tr'); + tableRow.setAttribute('data-station', name); const nameData = document.createElement('td'); nameData.innerHTML = name; const deleteBtn = document.createElement('button'); deleteBtn.innerHTML = '삭제'; + deleteBtn.addEventListener('click', () => deleteStation(name)); tableRow.appendChild(nameData); tableRow.appendChild(deleteBtn); @@ -86,14 +88,25 @@ const createResultArea = () => { const addTable = name => { const stationTable = document.getElementById('station-table'); const newRow = document.createElement('tr'); + newRow.setAttribute('data-station', name); const newData = document.createElement('td'); newData.innerHTML = name; const deleteBtn = document.createElement('button'); deleteBtn.innerHTML = '삭제'; + deleteBtn.addEventListener('click', () => deleteStation(name)); newRow.appendChild(newData); newRow.appendChild(deleteBtn); stationTable.appendChild(newRow); }; + +const deleteStation = name => { + const stationTable = document.getElementById('station-table'); + const currStations = JSON.parse(localStorage.getItem('stations')); + const updatedStations = currStations.filter(station => station !== name); + localStorage.setItem('stations', JSON.stringify(updatedStations)); + const rowToBeDeleted = stationTable.querySelector(`[data-station=${name}]`); + stationTable.removeChild(rowToBeDeleted); +}; From f1e506263793e773b5f979bf99f3e04b636f6048 Mon Sep 17 00:00:00 2001 From: zigsong Date: Sat, 12 Dec 2020 14:43:46 +0900 Subject: [PATCH 08/35] feat: name input error handling when adding station --- docs/README.md | 2 +- src/stationManage.js | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 4b855ebe2..1456e38ba 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,7 +5,7 @@ - [X] **역** 지하철 역 등록 - [X] (추가)**역** localStorage에 지하철 역 등록 - [X] (추가)**역** 역 삭제 (localStorage에서도 삭제) -- [ ] **역** 지하철 역 등록 시 이름 에러 핸들링 +- [X] **역** 지하철 역 등록 시 이름 에러 핸들링 - [X] **역** 지하철 역 목록 조회 - [ ] **노선** 노선 등록 - [ ] **노선** 노선 등록 시 이름 에러 핸들링 diff --git a/src/stationManage.js b/src/stationManage.js index 3147436ee..d287619e6 100644 --- a/src/stationManage.js +++ b/src/stationManage.js @@ -39,6 +39,7 @@ const createInputArea = () => { }; const addStation = (name, nameInput) => { + if (!validateName(name)) return; nameInput.value = ''; const currStations = JSON.parse(localStorage.getItem('stations')); const updatedStations = [...currStations, name]; @@ -47,6 +48,18 @@ const addStation = (name, nameInput) => { addTable(name); }; +const validateName = name => { + const currStations = JSON.parse(localStorage.getItem('stations')); + if (currStations.includes(name)) { + alert('중복된 역 이름이 존재합니다.'); + return false; + } else if (name.length < 2) { + alert('역 이름을 2자 이상으로 입력해 주세요.'); + return false; + } + return true; +}; + const createResultArea = () => { const tableName = document.createElement('h2'); tableName.innerHTML = '🚉 지하철 역 목록'; From e79cbc6d622b69a43425556fc79757d95e5063ea Mon Sep 17 00:00:00 2001 From: zigsong Date: Sat, 12 Dec 2020 21:43:56 +0900 Subject: [PATCH 09/35] refactor: rename stationManage to stationManager --- src/index.js | 4 ++-- src/{stationManage.js => stationManager.js} | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/{stationManage.js => stationManager.js} (98%) diff --git a/src/index.js b/src/index.js index d5dc4473c..68747affa 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,4 @@ -import { initStationManage } from './stationManage.js'; +import { initStationManager } from './stationManager.js'; export default function SubwayMap() { const stationMngBtn = document.getElementById('station-manager-button'); @@ -6,7 +6,7 @@ export default function SubwayMap() { // const sectionMngBtn = document.getElementById('section-manager-button'); // const mapPrintMngBtn = document.getElementById('map-print-manager-button'); - stationMngBtn.addEventListener('click', () => initStationManage()); + stationMngBtn.addEventListener('click', () => initStationManager()); } new SubwayMap(); diff --git a/src/stationManage.js b/src/stationManager.js similarity index 98% rename from src/stationManage.js rename to src/stationManager.js index d287619e6..4dd9f7d14 100644 --- a/src/stationManage.js +++ b/src/stationManager.js @@ -1,6 +1,6 @@ const app = document.getElementById('app'); -export const initStationManage = () => { +export const initStationManager = () => { createInputArea(); createResultArea(); }; From 32ca149da68769f270dd747a8ca2cfd9da75f286 Mon Sep 17 00:00:00 2001 From: zigsong Date: Sat, 12 Dec 2020 21:51:34 +0900 Subject: [PATCH 10/35] feat: alert confirm message if delete station --- src/stationManager.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/stationManager.js b/src/stationManager.js index 4dd9f7d14..a163c8b2f 100644 --- a/src/stationManager.js +++ b/src/stationManager.js @@ -116,10 +116,12 @@ const addTable = name => { }; const deleteStation = name => { - const stationTable = document.getElementById('station-table'); - const currStations = JSON.parse(localStorage.getItem('stations')); - const updatedStations = currStations.filter(station => station !== name); - localStorage.setItem('stations', JSON.stringify(updatedStations)); - const rowToBeDeleted = stationTable.querySelector(`[data-station=${name}]`); - stationTable.removeChild(rowToBeDeleted); + if (confirm('정말 삭제하시겠습니까?')) { + const stationTable = document.getElementById('station-table'); + const currStations = JSON.parse(localStorage.getItem('stations')); + const updatedStations = currStations.filter(station => station !== name); + localStorage.setItem('stations', JSON.stringify(updatedStations)); + const rowToBeDeleted = stationTable.querySelector(`[data-station=${name}]`); + stationTable.removeChild(rowToBeDeleted); + } }; From e7f251c53b9416a9dccf21eaa5e0bb6653c4dfa4 Mon Sep 17 00:00:00 2001 From: zigsong Date: Sat, 12 Dec 2020 22:53:19 +0900 Subject: [PATCH 11/35] feat: get line info input --- docs/README.md | 2 +- src/index.js | 4 ++- src/lineManager.js | 68 +++++++++++++++++++++++++++++++++++++++++++ src/stationManager.js | 3 ++ src/utils.js | 9 ++++++ 5 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 src/lineManager.js create mode 100644 src/utils.js diff --git a/docs/README.md b/docs/README.md index 1456e38ba..81a0e0bf5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,7 +7,7 @@ - [X] (추가)**역** 역 삭제 (localStorage에서도 삭제) - [X] **역** 지하철 역 등록 시 이름 에러 핸들링 - [X] **역** 지하철 역 목록 조회 -- [ ] **노선** 노선 등록 +- [X] **노선** 노선 등록 (input 받기) - [ ] **노선** 노선 등록 시 이름 에러 핸들링 - [ ] **노선** 노선 삭제 - [ ] **노선** 노선 목록 조회 diff --git a/src/index.js b/src/index.js index 68747affa..2d1245e05 100644 --- a/src/index.js +++ b/src/index.js @@ -1,12 +1,14 @@ import { initStationManager } from './stationManager.js'; +import { initLineManager } from './lineManager.js'; export default function SubwayMap() { const stationMngBtn = document.getElementById('station-manager-button'); - // const lineMngBtn = document.getElementById('line-manager-button'); + const lineMngBtn = document.getElementById('line-manager-button'); // const sectionMngBtn = document.getElementById('section-manager-button'); // const mapPrintMngBtn = document.getElementById('map-print-manager-button'); stationMngBtn.addEventListener('click', () => initStationManager()); + lineMngBtn.addEventListener('click', () => initLineManager()); } new SubwayMap(); diff --git a/src/lineManager.js b/src/lineManager.js new file mode 100644 index 000000000..e54dacafd --- /dev/null +++ b/src/lineManager.js @@ -0,0 +1,68 @@ +import { clearPage } from './utils.js'; + +const app = document.getElementById('app'); + +export const initLineManager = () => { + clearPage(); + createInputArea(); + createSelectbox(); + createSubmitBtn(); + // createResultArea(); +}; + +const createInputArea = () => { + const lineInputArea = document.createElement('p'); + const lineLabel = document.createElement('b'); + lineLabel.innerHTML = '노선 이름'; + + const lineInput = document.createElement('input'); + lineInput.setAttribute('id', 'line-name-input'); + lineInput.setAttribute('placeholder', '노선 이름을 입력해주세요'); + + lineInputArea.appendChild(lineLabel); + lineInputArea.appendChild(document.createElement('br')); + lineInputArea.appendChild(lineInput); + + app.appendChild(lineInputArea); +}; + +const createSelectbox = () => { + const lineSelectArea = document.createElement('div'); + const currStations = JSON.parse(localStorage.getItem('stations')); + + const upwardSelect = document.createElement('select'); + upwardSelect.setAttribute('id', 'line-start-station-selector'); + const upwardLabel = document.createElement('b'); + upwardLabel.innerHTML = '상행 종점'; + + const downwardSelect = document.createElement('select'); + downwardSelect.setAttribute('id', 'line-end-station-selector'); + const downwardLabel = document.createElement('b'); + downwardLabel.innerHTML = '하행 종점'; + + currStations.map(station => { + [upwardSelect, downwardSelect].map(select => { + const option = document.createElement('option'); + option.value = station; + option.text = station; + select.options.add(option); + }); + }); + + lineSelectArea.appendChild(upwardLabel); + lineSelectArea.appendChild(upwardSelect); + lineSelectArea.appendChild(document.createElement('br')); + lineSelectArea.appendChild(downwardLabel); + lineSelectArea.appendChild(downwardSelect); + + app.appendChild(lineSelectArea); +}; + +const createSubmitBtn = () => { + const lineSubmit = document.createElement('button'); + lineSubmit.setAttribute('id', 'line-add-button'); + lineSubmit.innerHTML = '노선 추가'; + + app.appendChild(document.createElement('br')); + app.appendChild(lineSubmit); +}; diff --git a/src/stationManager.js b/src/stationManager.js index a163c8b2f..86d1f46e1 100644 --- a/src/stationManager.js +++ b/src/stationManager.js @@ -1,6 +1,9 @@ +import { clearPage } from './utils.js'; + const app = document.getElementById('app'); export const initStationManager = () => { + clearPage(); createInputArea(); createResultArea(); }; diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 000000000..c70553edd --- /dev/null +++ b/src/utils.js @@ -0,0 +1,9 @@ +const app = document.getElementById('app'); + +export const clearPage = () => { + const contents = app.childNodes; + let i = contents.length; + while (i-- > 4) { + app.removeChild(contents[i]); + } +}; From 8b76e0055089f84eab168de3758034fa06f2ef7c Mon Sep 17 00:00:00 2001 From: zigsong Date: Sat, 12 Dec 2020 23:54:27 +0900 Subject: [PATCH 12/35] feat: add lines in localStorage --- docs/README.md | 1 + src/lineManager.js | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/docs/README.md b/docs/README.md index 81a0e0bf5..6fcf4d825 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,6 +8,7 @@ - [X] **역** 지하철 역 등록 시 이름 에러 핸들링 - [X] **역** 지하철 역 목록 조회 - [X] **노선** 노선 등록 (input 받기) +- [X] (추가)**노선** localStorage에 노선 등록 - [ ] **노선** 노선 등록 시 이름 에러 핸들링 - [ ] **노선** 노선 삭제 - [ ] **노선** 노선 목록 조회 diff --git a/src/lineManager.js b/src/lineManager.js index e54dacafd..cfc8decaa 100644 --- a/src/lineManager.js +++ b/src/lineManager.js @@ -7,6 +7,7 @@ export const initLineManager = () => { createInputArea(); createSelectbox(); createSubmitBtn(); + getInput(); // createResultArea(); }; @@ -66,3 +67,43 @@ const createSubmitBtn = () => { app.appendChild(document.createElement('br')); app.appendChild(lineSubmit); }; + +const getInput = () => { + const lineInput = document.getElementById('line-name-input'); + const upwardSelect = document.getElementById('line-start-station-selector'); + let startStation = upwardSelect.options[upwardSelect.selectedIndex].value; + upwardSelect.addEventListener('change', () => { + startStation = upwardSelect.value; + }); + const downwardSelect = document.getElementById('line-end-station-selector'); + let endStation = downwardSelect.options[downwardSelect.selectedIndex].value; + downwardSelect.addEventListener('change', () => { + endStation = downwardSelect.value; + }); + + const lineSubmit = document.getElementById('line-add-button'); + + lineSubmit.addEventListener('keypress', e => { + let lineName = lineInput.value; + if (e.key === 'Enter') { + addLine(lineName, lineInput, startStation, endStation); + } + }); + + lineSubmit.addEventListener('click', () => { + let lineName = lineInput.value; + addLine(lineName, lineInput, startStation, endStation); + }); +}; + +const addLine = (lineName, lineInput, start, end) => { + lineInput.value = ''; + console.log(lineName, start, end); + + const currLines = JSON.parse(localStorage.getItem('lines')); + console.log(currLines); + const updatedLines = currLines; + updatedLines[lineName] = [start, end]; + localStorage.setItem('lines', JSON.stringify(updatedLines)); + console.log(JSON.parse(localStorage.getItem('lines'))); +}; From 9610a3ed5d38a81382e86b61301109cdc30d2d2f Mon Sep 17 00:00:00 2001 From: zigsong Date: Sat, 12 Dec 2020 23:57:43 +0900 Subject: [PATCH 13/35] feat: validate line name input(no duplicate) --- docs/README.md | 2 +- src/lineManager.js | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 6fcf4d825..bd3175357 100644 --- a/docs/README.md +++ b/docs/README.md @@ -9,7 +9,7 @@ - [X] **역** 지하철 역 목록 조회 - [X] **노선** 노선 등록 (input 받기) - [X] (추가)**노선** localStorage에 노선 등록 -- [ ] **노선** 노선 등록 시 이름 에러 핸들링 +- [X] **노선** 노선 등록 시 이름 에러 핸들링 - [ ] **노선** 노선 삭제 - [ ] **노선** 노선 목록 조회 - [ ] **구간** 구간 추가 diff --git a/src/lineManager.js b/src/lineManager.js index cfc8decaa..2a3a0ba6b 100644 --- a/src/lineManager.js +++ b/src/lineManager.js @@ -97,6 +97,8 @@ const getInput = () => { }; const addLine = (lineName, lineInput, start, end) => { + if (!validateName(lineName)) return; + lineInput.value = ''; console.log(lineName, start, end); @@ -107,3 +109,12 @@ const addLine = (lineName, lineInput, start, end) => { localStorage.setItem('lines', JSON.stringify(updatedLines)); console.log(JSON.parse(localStorage.getItem('lines'))); }; + +const validateName = lineName => { + const currLines = JSON.parse(localStorage.getItem('lines')); + if (Object.keys(currLines).includes(lineName)) { + alert('중복된 노선 이름이 존재합니다.'); + return false; + } + return true; +}; From 29bea38d099dff7e78a7a7ca341ac3528e5d31d7 Mon Sep 17 00:00:00 2001 From: zigsong Date: Sun, 13 Dec 2020 00:11:00 +0900 Subject: [PATCH 14/35] feat: print lines table --- docs/README.md | 2 +- src/lineManager.js | 51 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index bd3175357..c39b70b7c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -11,7 +11,7 @@ - [X] (추가)**노선** localStorage에 노선 등록 - [X] **노선** 노선 등록 시 이름 에러 핸들링 - [ ] **노선** 노선 삭제 -- [ ] **노선** 노선 목록 조회 +- [X] **노선** 노선 목록 조회 - [ ] **구간** 구간 추가 - [ ] **구간** 구간 삭제 - [ ] **구간** 구간 종점 삭제 시 다음 역을 종점으로 diff --git a/src/lineManager.js b/src/lineManager.js index 2a3a0ba6b..ecdfc87fd 100644 --- a/src/lineManager.js +++ b/src/lineManager.js @@ -8,7 +8,7 @@ export const initLineManager = () => { createSelectbox(); createSubmitBtn(); getInput(); - // createResultArea(); + createResultArea(); }; const createInputArea = () => { @@ -118,3 +118,52 @@ const validateName = lineName => { } return true; }; + +const createResultArea = () => { + const tableName = document.createElement('h2'); + tableName.innerHTML = '🚉 지하철 노선 목록'; + app.appendChild(tableName); + + const lineTable = document.createElement('table'); + lineTable.setAttribute('border', 1); + lineTable.setAttribute('id', 'line-table'); + + const lineNameHeader = document.createElement('th'); + lineNameHeader.innerHTML = '노선 이름'; + const upwardEndStation = document.createElement('th'); + upwardEndStation.innerHTML = '상행 종점역'; + const downwardEndStation = document.createElement('th'); + downwardEndStation.innerHTML = '하행 종점역'; + const lineSettingHeader = document.createElement('th'); + lineSettingHeader.innerHTML = '설정'; + + lineTable.appendChild(lineNameHeader); + lineTable.appendChild(upwardEndStation); + lineTable.appendChild(downwardEndStation); + lineTable.appendChild(lineSettingHeader); + + const lines = JSON.parse(localStorage.getItem('lines')); + + Object.entries(lines).map(([line, stations]) => { + const tableRow = document.createElement('tr'); + tableRow.setAttribute('data-line', line); + + const nameData = document.createElement('td'); + nameData.innerHTML = line; + const upwardEndData = document.createElement('td'); + upwardEndData.innerHTML = stations[0]; + const downwardEndData = document.createElement('td'); + downwardEndData.innerHTML = stations[1]; + const deleteBtn = document.createElement('button'); + deleteBtn.innerHTML = '삭제'; + + tableRow.appendChild(nameData); + tableRow.appendChild(upwardEndData); + tableRow.appendChild(downwardEndData); + tableRow.appendChild(deleteBtn); + + lineTable.appendChild(tableRow); + }); + + app.appendChild(lineTable); +}; From 303128f5361dd57ba5242f03f6e8cb1044421456 Mon Sep 17 00:00:00 2001 From: zigsong Date: Sun, 13 Dec 2020 00:14:21 +0900 Subject: [PATCH 15/35] feat: add new line info to table --- src/lineManager.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/lineManager.js b/src/lineManager.js index ecdfc87fd..5198b3c7c 100644 --- a/src/lineManager.js +++ b/src/lineManager.js @@ -108,6 +108,8 @@ const addLine = (lineName, lineInput, start, end) => { updatedLines[lineName] = [start, end]; localStorage.setItem('lines', JSON.stringify(updatedLines)); console.log(JSON.parse(localStorage.getItem('lines'))); + + addTable(lineName, start, end); }; const validateName = lineName => { @@ -167,3 +169,25 @@ const createResultArea = () => { app.appendChild(lineTable); }; + +const addTable = (lineName, start, end) => { + const lineTable = document.getElementById('line-table'); + const newRow = document.createElement('tr'); + newRow.setAttribute('data-line', lineName); + + const newData = document.createElement('td'); + newData.innerHTML = lineName; + const upwardEndData = document.createElement('td'); + upwardEndData.innerHTML = start; + const downwardEndData = document.createElement('td'); + downwardEndData.innerHTML = end; + const deleteBtn = document.createElement('button'); + deleteBtn.innerHTML = '삭제'; + + newRow.appendChild(newData); + newRow.appendChild(upwardEndData); + newRow.appendChild(downwardEndData); + newRow.appendChild(deleteBtn); + + lineTable.appendChild(newRow); +}; From 44fb122a096da46d508ef353e383fac7734374fb Mon Sep 17 00:00:00 2001 From: zigsong Date: Sun, 13 Dec 2020 16:02:00 +0900 Subject: [PATCH 16/35] refactor: print table headers when localStorage is empty --- docs/README.md | 1 + src/lineManager.js | 46 ++++++++++++++++++++++--------------------- src/stationManager.js | 30 +++++++++++++++------------- 3 files changed, 41 insertions(+), 36 deletions(-) diff --git a/docs/README.md b/docs/README.md index c39b70b7c..62ed92f3b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -12,6 +12,7 @@ - [X] **노선** 노선 등록 시 이름 에러 핸들링 - [ ] **노선** 노선 삭제 - [X] **노선** 노선 목록 조회 +- [X] (추가)**역&노선** localStorage가 비어있을 때 출력 - [ ] **구간** 구간 추가 - [ ] **구간** 구간 삭제 - [ ] **구간** 구간 종점 삭제 시 다음 역을 종점으로 diff --git a/src/lineManager.js b/src/lineManager.js index 5198b3c7c..d4eccd516 100644 --- a/src/lineManager.js +++ b/src/lineManager.js @@ -104,7 +104,7 @@ const addLine = (lineName, lineInput, start, end) => { const currLines = JSON.parse(localStorage.getItem('lines')); console.log(currLines); - const updatedLines = currLines; + const updatedLines = currLines ? currLines : {}; updatedLines[lineName] = [start, end]; localStorage.setItem('lines', JSON.stringify(updatedLines)); console.log(JSON.parse(localStorage.getItem('lines'))); @@ -114,7 +114,7 @@ const addLine = (lineName, lineInput, start, end) => { const validateName = lineName => { const currLines = JSON.parse(localStorage.getItem('lines')); - if (Object.keys(currLines).includes(lineName)) { + if (currLines && Object.keys(currLines).includes(lineName)) { alert('중복된 노선 이름이 존재합니다.'); return false; } @@ -146,26 +146,28 @@ const createResultArea = () => { const lines = JSON.parse(localStorage.getItem('lines')); - Object.entries(lines).map(([line, stations]) => { - const tableRow = document.createElement('tr'); - tableRow.setAttribute('data-line', line); - - const nameData = document.createElement('td'); - nameData.innerHTML = line; - const upwardEndData = document.createElement('td'); - upwardEndData.innerHTML = stations[0]; - const downwardEndData = document.createElement('td'); - downwardEndData.innerHTML = stations[1]; - const deleteBtn = document.createElement('button'); - deleteBtn.innerHTML = '삭제'; - - tableRow.appendChild(nameData); - tableRow.appendChild(upwardEndData); - tableRow.appendChild(downwardEndData); - tableRow.appendChild(deleteBtn); - - lineTable.appendChild(tableRow); - }); + if (lines) { + Object.entries(lines).map(([line, stations]) => { + const tableRow = document.createElement('tr'); + tableRow.setAttribute('data-line', line); + + const nameData = document.createElement('td'); + nameData.innerHTML = line; + const upwardEndData = document.createElement('td'); + upwardEndData.innerHTML = stations[0]; + const downwardEndData = document.createElement('td'); + downwardEndData.innerHTML = stations[1]; + const deleteBtn = document.createElement('button'); + deleteBtn.innerHTML = '삭제'; + + tableRow.appendChild(nameData); + tableRow.appendChild(upwardEndData); + tableRow.appendChild(downwardEndData); + tableRow.appendChild(deleteBtn); + + lineTable.appendChild(tableRow); + }); + } app.appendChild(lineTable); }; diff --git a/src/stationManager.js b/src/stationManager.js index 86d1f46e1..3e7cc7edc 100644 --- a/src/stationManager.js +++ b/src/stationManager.js @@ -45,7 +45,7 @@ const addStation = (name, nameInput) => { if (!validateName(name)) return; nameInput.value = ''; const currStations = JSON.parse(localStorage.getItem('stations')); - const updatedStations = [...currStations, name]; + const updatedStations = currStations ? [...currStations, name] : [name]; localStorage.setItem('stations', JSON.stringify(updatedStations)); console.log(JSON.parse(localStorage.getItem('stations'))); addTable(name); @@ -53,7 +53,7 @@ const addStation = (name, nameInput) => { const validateName = name => { const currStations = JSON.parse(localStorage.getItem('stations')); - if (currStations.includes(name)) { + if (currStations && currStations.includes(name)) { alert('중복된 역 이름이 존재합니다.'); return false; } else if (name.length < 2) { @@ -82,21 +82,23 @@ const createResultArea = () => { const stations = JSON.parse(localStorage.getItem('stations')); - stations.map(name => { - const tableRow = document.createElement('tr'); - tableRow.setAttribute('data-station', name); - const nameData = document.createElement('td'); - nameData.innerHTML = name; + if (stations) { + stations.map(name => { + const tableRow = document.createElement('tr'); + tableRow.setAttribute('data-station', name); + const nameData = document.createElement('td'); + nameData.innerHTML = name; - const deleteBtn = document.createElement('button'); - deleteBtn.innerHTML = '삭제'; - deleteBtn.addEventListener('click', () => deleteStation(name)); + const deleteBtn = document.createElement('button'); + deleteBtn.innerHTML = '삭제'; + deleteBtn.addEventListener('click', () => deleteStation(name)); - tableRow.appendChild(nameData); - tableRow.appendChild(deleteBtn); + tableRow.appendChild(nameData); + tableRow.appendChild(deleteBtn); - stationTable.appendChild(tableRow); - }); + stationTable.appendChild(tableRow); + }); + } app.appendChild(stationTable); }; From 7e272e2bc39f992221381542901489c2504e3b87 Mon Sep 17 00:00:00 2001 From: zigsong Date: Sun, 13 Dec 2020 16:17:54 +0900 Subject: [PATCH 17/35] feat: delete line (from table & localStorage) --- docs/README.md | 2 +- src/lineManager.js | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index 62ed92f3b..ec0b6e211 100644 --- a/docs/README.md +++ b/docs/README.md @@ -10,7 +10,7 @@ - [X] **노선** 노선 등록 (input 받기) - [X] (추가)**노선** localStorage에 노선 등록 - [X] **노선** 노선 등록 시 이름 에러 핸들링 -- [ ] **노선** 노선 삭제 +- [X] **노선** 노선 삭제 - [X] **노선** 노선 목록 조회 - [X] (추가)**역&노선** localStorage가 비어있을 때 출력 - [ ] **구간** 구간 추가 diff --git a/src/lineManager.js b/src/lineManager.js index d4eccd516..bc9d6eead 100644 --- a/src/lineManager.js +++ b/src/lineManager.js @@ -149,7 +149,7 @@ const createResultArea = () => { if (lines) { Object.entries(lines).map(([line, stations]) => { const tableRow = document.createElement('tr'); - tableRow.setAttribute('data-line', line); + tableRow.setAttribute('data-line', `_${line}`); const nameData = document.createElement('td'); nameData.innerHTML = line; @@ -159,6 +159,7 @@ const createResultArea = () => { downwardEndData.innerHTML = stations[1]; const deleteBtn = document.createElement('button'); deleteBtn.innerHTML = '삭제'; + deleteBtn.addEventListener('click', () => deleteLine(line)); tableRow.appendChild(nameData); tableRow.appendChild(upwardEndData); @@ -175,7 +176,7 @@ const createResultArea = () => { const addTable = (lineName, start, end) => { const lineTable = document.getElementById('line-table'); const newRow = document.createElement('tr'); - newRow.setAttribute('data-line', lineName); + newRow.setAttribute('data-line', `_${lineName}`); const newData = document.createElement('td'); newData.innerHTML = lineName; @@ -185,6 +186,7 @@ const addTable = (lineName, start, end) => { downwardEndData.innerHTML = end; const deleteBtn = document.createElement('button'); deleteBtn.innerHTML = '삭제'; + deleteBtn.addEventListener('click', () => deleteLine(lineName)); newRow.appendChild(newData); newRow.appendChild(upwardEndData); @@ -193,3 +195,15 @@ const addTable = (lineName, start, end) => { lineTable.appendChild(newRow); }; + +const deleteLine = lineName => { + if (confirm('정말 삭제하시겠습니까?')) { + const lineTable = document.getElementById('line-table'); + const currLines = JSON.parse(localStorage.getItem('lines')); + delete currLines[lineName]; + localStorage.setItem('lines', JSON.stringify(currLines)); + console.log(JSON.parse(localStorage.getItem('lines'))); + const rowToBeDeleted = lineTable.querySelector(`[data-line=_${lineName}]`); + lineTable.removeChild(rowToBeDeleted); + } +}; From 225af9ba4a57b781f6d0d498b3c7a1744dfefee6 Mon Sep 17 00:00:00 2001 From: zigsong Date: Sun, 13 Dec 2020 17:52:39 +0900 Subject: [PATCH 18/35] feat: add section page & inputs --- docs/README.md | 2 +- src/index.js | 4 +- src/sectionManager.js | 102 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 src/sectionManager.js diff --git a/docs/README.md b/docs/README.md index ec0b6e211..785e286c4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -13,7 +13,7 @@ - [X] **노선** 노선 삭제 - [X] **노선** 노선 목록 조회 - [X] (추가)**역&노선** localStorage가 비어있을 때 출력 -- [ ] **구간** 구간 추가 +- [X] **구간** 구간 추가 - [ ] **구간** 구간 삭제 - [ ] **구간** 구간 종점 삭제 시 다음 역을 종점으로 - [ ] **구간** 노선 포함 역 2개 이하면 제거 불가 diff --git a/src/index.js b/src/index.js index 2d1245e05..33a9f7e66 100644 --- a/src/index.js +++ b/src/index.js @@ -1,14 +1,16 @@ import { initStationManager } from './stationManager.js'; import { initLineManager } from './lineManager.js'; +import { initSectionManager } from './sectionManager.js'; export default function SubwayMap() { const stationMngBtn = document.getElementById('station-manager-button'); const lineMngBtn = document.getElementById('line-manager-button'); - // const sectionMngBtn = document.getElementById('section-manager-button'); + const sectionMngBtn = document.getElementById('section-manager-button'); // const mapPrintMngBtn = document.getElementById('map-print-manager-button'); stationMngBtn.addEventListener('click', () => initStationManager()); lineMngBtn.addEventListener('click', () => initLineManager()); + sectionMngBtn.addEventListener('click', () => initSectionManager()); } new SubwayMap(); diff --git a/src/sectionManager.js b/src/sectionManager.js new file mode 100644 index 000000000..23aba1aa3 --- /dev/null +++ b/src/sectionManager.js @@ -0,0 +1,102 @@ +import { clearPage } from './utils.js'; + +const app = document.getElementById('app'); + +export const initSectionManager = () => { + clearPage(); + createInputArea(); +}; + +const createInputArea = () => { + const sectionHeader = document.createElement('div'); + const sectionTitle = document.createElement('h3'); + sectionTitle.innerText = '구간을 수정할 노선을 선택해주세요.'; + sectionHeader.appendChild(sectionTitle); + + const currLines = JSON.parse(localStorage.getItem('lines')); + if (currLines) { + Object.keys(currLines).map(line => { + const lineBtn = document.createElement('button'); + lineBtn.setAttribute('class', 'section-line-menu-button'); + lineBtn.innerHTML = line; + lineBtn.style.margin = '2px'; + lineBtn.addEventListener('click', () => { + clearInputs(); + manageLineSection(line); + }); + sectionHeader.appendChild(lineBtn); + }); + } + + app.appendChild(sectionHeader); +}; + +const clearInputs = () => { + const sectionInputArea = document.getElementById('section-input'); + const selectArea = document.getElementById('section-selector'); + + if (sectionInputArea && selectArea) { + app.removeChild(sectionInputArea); + app.removeChild(selectArea); + } +}; + +const manageLineSection = line => { + const sectionInputArea = document.createElement('div'); + sectionInputArea.setAttribute('id', 'section-input'); + + const manageTitle = document.createElement('h3'); + manageTitle.innerHTML = `${line} 관리`; + const registerText = document.createElement('b'); + registerText.innerHTML = '구간 등록'; + + sectionInputArea.appendChild(manageTitle); + sectionInputArea.appendChild(registerText); + sectionInputArea.appendChild(document.createElement('br')); + + app.appendChild(sectionInputArea); + createSelectArea(line); + // createResultArea(); +}; + +const createSelectArea = line => { + const selectArea = document.createElement('div'); + selectArea.setAttribute('id', 'section-selector'); + + const currStations = JSON.parse(localStorage.getItem('stations')); + const stationSelect = document.createElement('select'); + stationSelect.setAttribute('id', 'section-station-selector'); + currStations.map(station => { + const option = document.createElement('option'); + option.value = station; + option.text = station; + stationSelect.options.add(option); + }); + + let selectedStation = stationSelect.options[stationSelect.selectedIndex].value; + stationSelect.addEventListener('change', () => { + selectedStation = stationSelect.value; + }); + + const orderInput = document.createElement('input'); + orderInput.type = 'number'; + orderInput.setAttribute('id', 'section-order-input'); + + const sectionSubmit = document.createElement('button'); + sectionSubmit.setAttribute('id', 'section-add-button'); + sectionSubmit.innerHTML = '등록'; + sectionSubmit.addEventListener('click', () => addToSection(line, selectedStation, orderInput)); + + selectArea.appendChild(stationSelect); + selectArea.appendChild(orderInput); + selectArea.appendChild(sectionSubmit); + + app.appendChild(selectArea); +}; + +const addToSection = (line, station, orderInput) => { + const order = orderInput.value; + orderInput.value = ''; + + console.log(line, station, order); +}; From 5ac03a4960d66723b49619e1c90c719cf083b18b Mon Sep 17 00:00:00 2001 From: zigsong Date: Sun, 13 Dec 2020 18:21:21 +0900 Subject: [PATCH 19/35] feat: add section to localStorage --- docs/README.md | 1 + src/lineManager.js | 5 ++--- src/sectionManager.js | 10 +++++++++- src/stationManager.js | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/docs/README.md b/docs/README.md index 785e286c4..33fd9e196 100644 --- a/docs/README.md +++ b/docs/README.md @@ -14,6 +14,7 @@ - [X] **노선** 노선 목록 조회 - [X] (추가)**역&노선** localStorage가 비어있을 때 출력 - [X] **구간** 구간 추가 +- [X] (추가)**구간** localStorage에 구간 추가 - [ ] **구간** 구간 삭제 - [ ] **구간** 구간 종점 삭제 시 다음 역을 종점으로 - [ ] **구간** 노선 포함 역 2개 이하면 제거 불가 diff --git a/src/lineManager.js b/src/lineManager.js index bc9d6eead..460a99ef3 100644 --- a/src/lineManager.js +++ b/src/lineManager.js @@ -100,14 +100,13 @@ const addLine = (lineName, lineInput, start, end) => { if (!validateName(lineName)) return; lineInput.value = ''; - console.log(lineName, start, end); const currLines = JSON.parse(localStorage.getItem('lines')); - console.log(currLines); + // console.log(currLines); const updatedLines = currLines ? currLines : {}; updatedLines[lineName] = [start, end]; localStorage.setItem('lines', JSON.stringify(updatedLines)); - console.log(JSON.parse(localStorage.getItem('lines'))); + // console.log(JSON.parse(localStorage.getItem('lines'))); addTable(lineName, start, end); }; diff --git a/src/sectionManager.js b/src/sectionManager.js index 23aba1aa3..8a62650fe 100644 --- a/src/sectionManager.js +++ b/src/sectionManager.js @@ -98,5 +98,13 @@ const addToSection = (line, station, orderInput) => { const order = orderInput.value; orderInput.value = ''; - console.log(line, station, order); + const currLines = JSON.parse(localStorage.getItem('lines')); + const currStations = currLines[line]; + console.log(currStations); + + currStations.splice(order, 0, station); + const updatedLines = currLines; + updatedLines[line] = currStations; + localStorage.setItem('lines', JSON.stringify(updatedLines)); + console.log(JSON.parse(localStorage.getItem('lines'))); }; diff --git a/src/stationManager.js b/src/stationManager.js index 3e7cc7edc..ea289ea77 100644 --- a/src/stationManager.js +++ b/src/stationManager.js @@ -47,7 +47,7 @@ const addStation = (name, nameInput) => { const currStations = JSON.parse(localStorage.getItem('stations')); const updatedStations = currStations ? [...currStations, name] : [name]; localStorage.setItem('stations', JSON.stringify(updatedStations)); - console.log(JSON.parse(localStorage.getItem('stations'))); + // console.log(JSON.parse(localStorage.getItem('stations'))); addTable(name); }; From 973a9294ca9794f4f8dd698b26ea32f1b5eccff9 Mon Sep 17 00:00:00 2001 From: zigsong Date: Sun, 13 Dec 2020 18:23:22 +0900 Subject: [PATCH 20/35] refactor: edit end station logic in lineManager --- docs/README.md | 1 + src/lineManager.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 33fd9e196..b4963b03d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -15,6 +15,7 @@ - [X] (추가)**역&노선** localStorage가 비어있을 때 출력 - [X] **구간** 구간 추가 - [X] (추가)**구간** localStorage에 구간 추가 +- [X] (추가)**노선** 종점역 로직 수정 - [ ] **구간** 구간 삭제 - [ ] **구간** 구간 종점 삭제 시 다음 역을 종점으로 - [ ] **구간** 노선 포함 역 2개 이하면 제거 불가 diff --git a/src/lineManager.js b/src/lineManager.js index 460a99ef3..a2f430f94 100644 --- a/src/lineManager.js +++ b/src/lineManager.js @@ -155,7 +155,7 @@ const createResultArea = () => { const upwardEndData = document.createElement('td'); upwardEndData.innerHTML = stations[0]; const downwardEndData = document.createElement('td'); - downwardEndData.innerHTML = stations[1]; + downwardEndData.innerHTML = stations[stations.length - 1]; const deleteBtn = document.createElement('button'); deleteBtn.innerHTML = '삭제'; deleteBtn.addEventListener('click', () => deleteLine(line)); From 91e870211ebbcf40474ec904e5f6a2d96b033e6c Mon Sep 17 00:00:00 2001 From: zigsong Date: Sun, 13 Dec 2020 18:34:56 +0900 Subject: [PATCH 21/35] feat: print section table --- docs/README.md | 1 + src/sectionManager.js | 51 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index b4963b03d..7e483ae88 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,6 +16,7 @@ - [X] **구간** 구간 추가 - [X] (추가)**구간** localStorage에 구간 추가 - [X] (추가)**노선** 종점역 로직 수정 +- [X] (추가)**구간** 구간 출력 - [ ] **구간** 구간 삭제 - [ ] **구간** 구간 종점 삭제 시 다음 역을 종점으로 - [ ] **구간** 노선 포함 역 2개 이하면 제거 불가 diff --git a/src/sectionManager.js b/src/sectionManager.js index 8a62650fe..25c086b0b 100644 --- a/src/sectionManager.js +++ b/src/sectionManager.js @@ -23,6 +23,7 @@ const createInputArea = () => { lineBtn.addEventListener('click', () => { clearInputs(); manageLineSection(line); + createResultArea(line); }); sectionHeader.appendChild(lineBtn); }); @@ -34,10 +35,12 @@ const createInputArea = () => { const clearInputs = () => { const sectionInputArea = document.getElementById('section-input'); const selectArea = document.getElementById('section-selector'); + const sectionTable = document.getElementById('section-table'); - if (sectionInputArea && selectArea) { + if (sectionInputArea && selectArea && sectionTable) { app.removeChild(sectionInputArea); app.removeChild(selectArea); + app.removeChild(sectionTable); } }; @@ -52,7 +55,6 @@ const manageLineSection = line => { sectionInputArea.appendChild(manageTitle); sectionInputArea.appendChild(registerText); - sectionInputArea.appendChild(document.createElement('br')); app.appendChild(sectionInputArea); createSelectArea(line); @@ -108,3 +110,48 @@ const addToSection = (line, station, orderInput) => { localStorage.setItem('lines', JSON.stringify(updatedLines)); console.log(JSON.parse(localStorage.getItem('lines'))); }; + +const createResultArea = line => { + const sectionTable = document.createElement('table'); + sectionTable.setAttribute('border', 1); + sectionTable.setAttribute('id', 'section-table'); + sectionTable.style.marginTop = '20px'; + + const sectionOrder = document.createElement('th'); + sectionOrder.innerHTML = '순서'; + const sectionName = document.createElement('th'); + sectionName.innerHTML = '이름'; + const sectionSettingHeader = document.createElement('th'); + sectionSettingHeader.innerHTML = '설정'; + + sectionTable.appendChild(sectionOrder); + sectionTable.appendChild(sectionName); + sectionTable.appendChild(sectionSettingHeader); + + app.appendChild(sectionTable); + + const currLines = JSON.parse(localStorage.getItem('lines')); + if (currLines) { + const currStations = currLines[line]; + currStations.map((station, idx) => { + const tableRow = document.createElement('tr'); + tableRow.setAttribute('data-line', line); + tableRow.setAttribute('data-station', station); + + const indexData = document.createElement('td'); + indexData.innerHTML = idx; + const nameData = document.createElement('td'); + nameData.innerHTML = station; + const deleteBtn = document.createElement('button'); + deleteBtn.innerHTML = '노선에서 제거'; + + tableRow.appendChild(indexData); + tableRow.appendChild(nameData); + tableRow.appendChild(deleteBtn); + + sectionTable.appendChild(tableRow); + }); + } + + app.appendChild(sectionTable); +}; From 4a5aa8eab77c99bdf01df3af4e04410a3d424f38 Mon Sep 17 00:00:00 2001 From: zigsong Date: Sun, 13 Dec 2020 18:47:18 +0900 Subject: [PATCH 22/35] feat: delete station from section --- docs/README.md | 4 ++-- src/sectionManager.js | 29 ++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index 7e483ae88..c730394b6 100644 --- a/docs/README.md +++ b/docs/README.md @@ -17,7 +17,7 @@ - [X] (추가)**구간** localStorage에 구간 추가 - [X] (추가)**노선** 종점역 로직 수정 - [X] (추가)**구간** 구간 출력 -- [ ] **구간** 구간 삭제 -- [ ] **구간** 구간 종점 삭제 시 다음 역을 종점으로 +- [X] **구간** 구간 삭제 +- [X] **구간** 구간 종점 삭제 시 다음 역을 종점으로 - [ ] **구간** 노선 포함 역 2개 이하면 제거 불가 - [ ] 노선에 등록된 역 목록 조회 diff --git a/src/sectionManager.js b/src/sectionManager.js index 25c086b0b..b74a731de 100644 --- a/src/sectionManager.js +++ b/src/sectionManager.js @@ -58,7 +58,6 @@ const manageLineSection = line => { app.appendChild(sectionInputArea); createSelectArea(line); - // createResultArea(); }; const createSelectArea = line => { @@ -109,6 +108,14 @@ const addToSection = (line, station, orderInput) => { updatedLines[line] = currStations; localStorage.setItem('lines', JSON.stringify(updatedLines)); console.log(JSON.parse(localStorage.getItem('lines'))); + + removeCurrResult(); + createResultArea(line); +}; + +const removeCurrResult = () => { + const sectionTable = document.getElementById('section-table'); + app.removeChild(sectionTable); }; const createResultArea = line => { @@ -144,6 +151,7 @@ const createResultArea = line => { nameData.innerHTML = station; const deleteBtn = document.createElement('button'); deleteBtn.innerHTML = '노선에서 제거'; + deleteBtn.addEventListener('click', () => deleteStation(station, line)); tableRow.appendChild(indexData); tableRow.appendChild(nameData); @@ -155,3 +163,22 @@ const createResultArea = line => { app.appendChild(sectionTable); }; + +const deleteStation = (station, line) => { + if (confirm('정말 삭제하시겠습니까?')) { + const sectionTable = document.getElementById('section-table'); + const currLines = JSON.parse(localStorage.getItem('lines')); + const currStations = currLines[line]; + currStations.splice(currStations.indexOf(station), 1); + const updatedLines = currLines; + updatedLines[line] = currStations; + localStorage.setItem('lines', JSON.stringify(updatedLines)); + console.log(JSON.parse(localStorage.getItem('lines'))); + + const rowToBeDeleted = sectionTable.querySelector(`[data-station=${station}]`); + sectionTable.removeChild(rowToBeDeleted); + + removeCurrResult(); + createResultArea(line); + } +}; From 2de353617db4d3590e40500ad6827c50abe5d242 Mon Sep 17 00:00:00 2001 From: zigsong Date: Sun, 13 Dec 2020 18:51:07 +0900 Subject: [PATCH 23/35] feat: disable delete station if stations are under two --- docs/README.md | 2 +- src/sectionManager.js | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/README.md b/docs/README.md index c730394b6..b5d7fc6ac 100644 --- a/docs/README.md +++ b/docs/README.md @@ -19,5 +19,5 @@ - [X] (추가)**구간** 구간 출력 - [X] **구간** 구간 삭제 - [X] **구간** 구간 종점 삭제 시 다음 역을 종점으로 -- [ ] **구간** 노선 포함 역 2개 이하면 제거 불가 +- [X] **구간** 노선 포함 역 2개 이하면 제거 불가 - [ ] 노선에 등록된 역 목록 조회 diff --git a/src/sectionManager.js b/src/sectionManager.js index b74a731de..1779cd583 100644 --- a/src/sectionManager.js +++ b/src/sectionManager.js @@ -165,10 +165,16 @@ const createResultArea = line => { }; const deleteStation = (station, line) => { + const sectionTable = document.getElementById('section-table'); + const currLines = JSON.parse(localStorage.getItem('lines')); + const currStations = currLines[line]; + + if (currStations.length <= 2) { + alert('노선에 포함된 역이 2개 이하일 때는 역을 삭제할 수 없습니다.'); + return; + } + if (confirm('정말 삭제하시겠습니까?')) { - const sectionTable = document.getElementById('section-table'); - const currLines = JSON.parse(localStorage.getItem('lines')); - const currStations = currLines[line]; currStations.splice(currStations.indexOf(station), 1); const updatedLines = currLines; updatedLines[line] = currStations; From 3ba557faaeea3ab32a21de77ade150624bab45f7 Mon Sep 17 00:00:00 2001 From: zigsong Date: Sun, 13 Dec 2020 19:00:27 +0900 Subject: [PATCH 24/35] feat: print map --- docs/README.md | 2 +- src/index.js | 4 +++- src/mapManager.js | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 src/mapManager.js diff --git a/docs/README.md b/docs/README.md index b5d7fc6ac..9c3d0dd19 100644 --- a/docs/README.md +++ b/docs/README.md @@ -20,4 +20,4 @@ - [X] **구간** 구간 삭제 - [X] **구간** 구간 종점 삭제 시 다음 역을 종점으로 - [X] **구간** 노선 포함 역 2개 이하면 제거 불가 -- [ ] 노선에 등록된 역 목록 조회 +- [X] 노선에 등록된 역 목록 조회 diff --git a/src/index.js b/src/index.js index 33a9f7e66..80489ef92 100644 --- a/src/index.js +++ b/src/index.js @@ -1,16 +1,18 @@ import { initStationManager } from './stationManager.js'; import { initLineManager } from './lineManager.js'; import { initSectionManager } from './sectionManager.js'; +import { initMapManager } from './mapManager.js'; export default function SubwayMap() { const stationMngBtn = document.getElementById('station-manager-button'); const lineMngBtn = document.getElementById('line-manager-button'); const sectionMngBtn = document.getElementById('section-manager-button'); - // const mapPrintMngBtn = document.getElementById('map-print-manager-button'); + const mapPrintMngBtn = document.getElementById('map-print-manager-button'); stationMngBtn.addEventListener('click', () => initStationManager()); lineMngBtn.addEventListener('click', () => initLineManager()); sectionMngBtn.addEventListener('click', () => initSectionManager()); + mapPrintMngBtn.addEventListener('click', () => initMapManager()); } new SubwayMap(); diff --git a/src/mapManager.js b/src/mapManager.js new file mode 100644 index 000000000..78c3cb247 --- /dev/null +++ b/src/mapManager.js @@ -0,0 +1,33 @@ +import { clearPage } from './utils.js'; + +const app = document.getElementById('app'); + +export const initMapManager = () => { + clearPage(); + createResultArea(); +}; + +const createResultArea = () => { + const resultArea = document.createElement('div'); + resultArea.setAttribute('class', 'map'); + + const currLines = JSON.parse(localStorage.getItem('lines')); + if (currLines) { + Object.entries(currLines).map(([line, stations]) => { + const lineTitle = document.createElement('h3'); + lineTitle.innerHTML = line; + const stationList = document.createElement('ul'); + + stations.map(station => { + const stationItem = document.createElement('li'); + stationItem.innerHTML = station; + stationList.appendChild(stationItem); + }); + + resultArea.appendChild(lineTitle); + resultArea.appendChild(stationList); + }); + + app.appendChild(resultArea); + } +}; From 7cf00f8c4a636e3e2193f26dc95b39f4cb23e5f8 Mon Sep 17 00:00:00 2001 From: zigsong Date: Sun, 13 Dec 2020 23:09:06 +0900 Subject: [PATCH 25/35] refactor: add classnames to deleteButtons --- src/lineManager.js | 4 +++- src/sectionManager.js | 1 + src/stationManager.js | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/lineManager.js b/src/lineManager.js index a2f430f94..b9805bbd0 100644 --- a/src/lineManager.js +++ b/src/lineManager.js @@ -157,6 +157,7 @@ const createResultArea = () => { const downwardEndData = document.createElement('td'); downwardEndData.innerHTML = stations[stations.length - 1]; const deleteBtn = document.createElement('button'); + deleteBtn.setAttribute('class', 'line-delete-button'); deleteBtn.innerHTML = '삭제'; deleteBtn.addEventListener('click', () => deleteLine(line)); @@ -184,6 +185,7 @@ const addTable = (lineName, start, end) => { const downwardEndData = document.createElement('td'); downwardEndData.innerHTML = end; const deleteBtn = document.createElement('button'); + deleteBtn.setAttribute('class', 'line-delete-button'); deleteBtn.innerHTML = '삭제'; deleteBtn.addEventListener('click', () => deleteLine(lineName)); @@ -201,7 +203,7 @@ const deleteLine = lineName => { const currLines = JSON.parse(localStorage.getItem('lines')); delete currLines[lineName]; localStorage.setItem('lines', JSON.stringify(currLines)); - console.log(JSON.parse(localStorage.getItem('lines'))); + // console.log(JSON.parse(localStorage.getItem('lines'))); const rowToBeDeleted = lineTable.querySelector(`[data-line=_${lineName}]`); lineTable.removeChild(rowToBeDeleted); } diff --git a/src/sectionManager.js b/src/sectionManager.js index 1779cd583..18c514297 100644 --- a/src/sectionManager.js +++ b/src/sectionManager.js @@ -150,6 +150,7 @@ const createResultArea = line => { const nameData = document.createElement('td'); nameData.innerHTML = station; const deleteBtn = document.createElement('button'); + deleteBtn.setAttribute('class', 'section-delete-button'); deleteBtn.innerHTML = '노선에서 제거'; deleteBtn.addEventListener('click', () => deleteStation(station, line)); diff --git a/src/stationManager.js b/src/stationManager.js index ea289ea77..21761372a 100644 --- a/src/stationManager.js +++ b/src/stationManager.js @@ -47,7 +47,6 @@ const addStation = (name, nameInput) => { const currStations = JSON.parse(localStorage.getItem('stations')); const updatedStations = currStations ? [...currStations, name] : [name]; localStorage.setItem('stations', JSON.stringify(updatedStations)); - // console.log(JSON.parse(localStorage.getItem('stations'))); addTable(name); }; @@ -90,6 +89,7 @@ const createResultArea = () => { nameData.innerHTML = name; const deleteBtn = document.createElement('button'); + deleteBtn.setAttribute('class', 'station-delete-button'); deleteBtn.innerHTML = '삭제'; deleteBtn.addEventListener('click', () => deleteStation(name)); @@ -111,6 +111,7 @@ const addTable = name => { newData.innerHTML = name; const deleteBtn = document.createElement('button'); + deleteBtn.setAttribute('class', 'station-delete-button'); deleteBtn.innerHTML = '삭제'; deleteBtn.addEventListener('click', () => deleteStation(name)); From 5d0e6eb70adfd4214a610bb1b05fbba1dcb09659 Mon Sep 17 00:00:00 2001 From: zigsong Date: Mon, 14 Dec 2020 00:50:53 +0900 Subject: [PATCH 26/35] refactor: function creating textInput & submitBtn & selectbox --- src/lineManager.js | 86 +++++++++++++------------------------------ src/sectionManager.js | 34 ++++++++--------- src/stationManager.js | 45 +++++++++------------- src/utils.js | 35 ++++++++++++++++++ 4 files changed, 94 insertions(+), 106 deletions(-) diff --git a/src/lineManager.js b/src/lineManager.js index b9805bbd0..8557c3a04 100644 --- a/src/lineManager.js +++ b/src/lineManager.js @@ -1,98 +1,64 @@ -import { clearPage } from './utils.js'; +import { clearPage, createTextInput, createSubmitBtn, createSelectbox } from './utils.js'; const app = document.getElementById('app'); export const initLineManager = () => { clearPage(); - createInputArea(); - createSelectbox(); - createSubmitBtn(); - getInput(); - createResultArea(); + createPage(); + // createResultArea(); }; -const createInputArea = () => { - const lineInputArea = document.createElement('p'); - const lineLabel = document.createElement('b'); - lineLabel.innerHTML = '노선 이름'; - - const lineInput = document.createElement('input'); - lineInput.setAttribute('id', 'line-name-input'); - lineInput.setAttribute('placeholder', '노선 이름을 입력해주세요'); - - lineInputArea.appendChild(lineLabel); - lineInputArea.appendChild(document.createElement('br')); - lineInputArea.appendChild(lineInput); - - app.appendChild(lineInputArea); +const createPage = () => { + createTextInput('노선 이름', 'line-name-input', '노선 이름을 입력해주세요'); + const submitBtn = createSubmitBtn('line-add-button', '노선 추가'); + createSelectArea(); + handleSubmit(submitBtn); + createResultArea(); }; -const createSelectbox = () => { +const createSelectArea = () => { const lineSelectArea = document.createElement('div'); const currStations = JSON.parse(localStorage.getItem('stations')); const upwardSelect = document.createElement('select'); - upwardSelect.setAttribute('id', 'line-start-station-selector'); + createSelectbox(upwardSelect, 'line-start-station-selector', currStations); const upwardLabel = document.createElement('b'); upwardLabel.innerHTML = '상행 종점'; const downwardSelect = document.createElement('select'); - downwardSelect.setAttribute('id', 'line-end-station-selector'); + createSelectbox(downwardSelect, 'line-end-station-selector', currStations); const downwardLabel = document.createElement('b'); downwardLabel.innerHTML = '하행 종점'; - currStations.map(station => { - [upwardSelect, downwardSelect].map(select => { - const option = document.createElement('option'); - option.value = station; - option.text = station; - select.options.add(option); - }); - }); - - lineSelectArea.appendChild(upwardLabel); - lineSelectArea.appendChild(upwardSelect); - lineSelectArea.appendChild(document.createElement('br')); - lineSelectArea.appendChild(downwardLabel); - lineSelectArea.appendChild(downwardSelect); + [upwardLabel, upwardSelect, document.createElement('br'), downwardLabel, downwardSelect].map( + elem => { + lineSelectArea.appendChild(elem); + }, + ); app.appendChild(lineSelectArea); }; -const createSubmitBtn = () => { - const lineSubmit = document.createElement('button'); - lineSubmit.setAttribute('id', 'line-add-button'); - lineSubmit.innerHTML = '노선 추가'; - +const handleSubmit = submitBtn => { app.appendChild(document.createElement('br')); - app.appendChild(lineSubmit); -}; + app.appendChild(submitBtn); -const getInput = () => { - const lineInput = document.getElementById('line-name-input'); + const inputText = document.getElementById('line-name-input'); const upwardSelect = document.getElementById('line-start-station-selector'); + const downwardSelect = document.getElementById('line-end-station-selector'); + let startStation = upwardSelect.options[upwardSelect.selectedIndex].value; + let endStation = downwardSelect.options[downwardSelect.selectedIndex].value; upwardSelect.addEventListener('change', () => { startStation = upwardSelect.value; }); - const downwardSelect = document.getElementById('line-end-station-selector'); - let endStation = downwardSelect.options[downwardSelect.selectedIndex].value; downwardSelect.addEventListener('change', () => { endStation = downwardSelect.value; }); - const lineSubmit = document.getElementById('line-add-button'); - - lineSubmit.addEventListener('keypress', e => { - let lineName = lineInput.value; - if (e.key === 'Enter') { - addLine(lineName, lineInput, startStation, endStation); - } - }); - - lineSubmit.addEventListener('click', () => { - let lineName = lineInput.value; - addLine(lineName, lineInput, startStation, endStation); + submitBtn.addEventListener('click', () => { + let lineName = inputText.value; + addLine(lineName, inputText, startStation, endStation); }); }; diff --git a/src/sectionManager.js b/src/sectionManager.js index 18c514297..b1c0de4c0 100644 --- a/src/sectionManager.js +++ b/src/sectionManager.js @@ -1,18 +1,23 @@ -import { clearPage } from './utils.js'; +import { clearPage, createTextInput, createSubmitBtn, createSelectbox } from './utils.js'; const app = document.getElementById('app'); export const initSectionManager = () => { clearPage(); - createInputArea(); + printGuideText(); }; -const createInputArea = () => { +const printGuideText = () => { const sectionHeader = document.createElement('div'); const sectionTitle = document.createElement('h3'); sectionTitle.innerText = '구간을 수정할 노선을 선택해주세요.'; sectionHeader.appendChild(sectionTitle); + createMenuButtons(sectionHeader); + app.appendChild(sectionHeader); +}; + +const createMenuButtons = sectionHeader => { const currLines = JSON.parse(localStorage.getItem('lines')); if (currLines) { Object.keys(currLines).map(line => { @@ -28,8 +33,6 @@ const createInputArea = () => { sectionHeader.appendChild(lineBtn); }); } - - app.appendChild(sectionHeader); }; const clearInputs = () => { @@ -66,13 +69,7 @@ const createSelectArea = line => { const currStations = JSON.parse(localStorage.getItem('stations')); const stationSelect = document.createElement('select'); - stationSelect.setAttribute('id', 'section-station-selector'); - currStations.map(station => { - const option = document.createElement('option'); - option.value = station; - option.text = station; - stationSelect.options.add(option); - }); + createSelectbox(stationSelect, 'section-station-selector', currStations); let selectedStation = stationSelect.options[stationSelect.selectedIndex].value; stationSelect.addEventListener('change', () => { @@ -82,15 +79,14 @@ const createSelectArea = line => { const orderInput = document.createElement('input'); orderInput.type = 'number'; orderInput.setAttribute('id', 'section-order-input'); + orderInput.setAttribute('placholder', '순서'); - const sectionSubmit = document.createElement('button'); - sectionSubmit.setAttribute('id', 'section-add-button'); - sectionSubmit.innerHTML = '등록'; - sectionSubmit.addEventListener('click', () => addToSection(line, selectedStation, orderInput)); + const submitBtn = createSubmitBtn('section-add-button', '등록'); + submitBtn.addEventListener('click', () => addToSection(line, selectedStation, orderInput)); - selectArea.appendChild(stationSelect); - selectArea.appendChild(orderInput); - selectArea.appendChild(sectionSubmit); + [stationSelect, orderInput, submitBtn].map(elem => { + selectArea.appendChild(elem); + }); app.appendChild(selectArea); }; diff --git a/src/stationManager.js b/src/stationManager.js index 21761372a..6ad0f205e 100644 --- a/src/stationManager.js +++ b/src/stationManager.js @@ -1,43 +1,34 @@ -import { clearPage } from './utils.js'; +import { clearPage, createSubmitBtn, createTextInput } from './utils.js'; const app = document.getElementById('app'); export const initStationManager = () => { clearPage(); - createInputArea(); - createResultArea(); + createPage(); }; -const createInputArea = () => { - const nameInputArea = document.createElement('p'); - const nameLabel = document.createElement('b'); - nameLabel.innerHTML = '역 이름'; - - const nameInput = document.createElement('input'); - nameInput.setAttribute('id', 'station-name-input'); - nameInput.setAttribute('placeholder', '역 이름을 입력해주세요'); - - const nameSubmit = document.createElement('button'); - nameSubmit.setAttribute('id', 'station-add-button'); - nameSubmit.innerHTML = '역 추가'; - - nameInputArea.appendChild(nameLabel); - nameInputArea.appendChild(document.createElement('br')); - nameInputArea.appendChild(nameInput); - nameInputArea.appendChild(nameSubmit); +const createPage = () => { + createTextInput('역 이름', 'station-name-input', '역 이름을 입력해주세요'); + const submitBtn = createSubmitBtn('station-add-button', '역 추가'); + handleSubmit(submitBtn); + createResultArea(); +}; - app.appendChild(nameInputArea); +const handleSubmit = submitBtn => { + const inputArea = document.getElementById('input-container'); + inputArea.appendChild(submitBtn); + const inputText = document.getElementById('station-name-input'); - nameInput.addEventListener('keypress', e => { - let name = nameInput.value; + inputText.addEventListener('keypress', e => { + let name = inputText.value; if (e.key === 'Enter') { - addStation(name, nameInput); + addStation(name, inputText); } }); - nameSubmit.addEventListener('click', () => { - let name = nameInput.value; - addStation(name, nameInput); + submitBtn.addEventListener('click', () => { + let name = inputText.value; + addStation(name, inputText); }); }; diff --git a/src/utils.js b/src/utils.js index c70553edd..6254d9df6 100644 --- a/src/utils.js +++ b/src/utils.js @@ -7,3 +7,38 @@ export const clearPage = () => { app.removeChild(contents[i]); } }; + +export const createTextInput = (labelName, inputId, placeHolder) => { + const inputArea = document.createElement('p'); + inputArea.setAttribute('id', 'input-container'); + const inputLabel = document.createElement('b'); + inputLabel.innerHTML = labelName; + + const inputText = document.createElement('input'); + inputText.setAttribute('id', inputId); + inputText.setAttribute('placeholder', placeHolder); + + inputArea.appendChild(inputLabel); + inputArea.appendChild(document.createElement('br')); + inputArea.appendChild(inputText); + + app.appendChild(inputArea); +}; + +export const createSubmitBtn = (btnId, btnText) => { + const submitBtn = document.createElement('button'); + submitBtn.setAttribute('id', btnId); + submitBtn.innerHTML = btnText; + + return submitBtn; +}; + +export const createSelectbox = (select, selectorId, options) => { + select.setAttribute('id', selectorId); + options.map(val => { + const option = document.createElement('option'); + option.value = val; + option.text = val; + select.options.add(option); + }); +}; From 6f0610c79c82484af7124f10a9c5a5b722fe97dd Mon Sep 17 00:00:00 2001 From: zigsong Date: Mon, 14 Dec 2020 18:13:59 +0900 Subject: [PATCH 27/35] refactor: function creating table & separate add table data & refactor setting data attribute --- src/lineManager.js | 78 ++++++++++++++++++++----------------------- src/sectionManager.js | 63 +++++++++++++++------------------- src/stationManager.js | 54 +++++++++++++----------------- src/utils.js | 17 ++++++++++ 4 files changed, 104 insertions(+), 108 deletions(-) diff --git a/src/lineManager.js b/src/lineManager.js index 8557c3a04..92bf8cef9 100644 --- a/src/lineManager.js +++ b/src/lineManager.js @@ -1,4 +1,10 @@ -import { clearPage, createTextInput, createSubmitBtn, createSelectbox } from './utils.js'; +import { + clearPage, + createTextInput, + createSubmitBtn, + createSelectbox, + createTable, +} from './utils.js'; const app = document.getElementById('app'); @@ -91,58 +97,46 @@ const createResultArea = () => { tableName.innerHTML = '🚉 지하철 노선 목록'; app.appendChild(tableName); - const lineTable = document.createElement('table'); - lineTable.setAttribute('border', 1); - lineTable.setAttribute('id', 'line-table'); - - const lineNameHeader = document.createElement('th'); - lineNameHeader.innerHTML = '노선 이름'; - const upwardEndStation = document.createElement('th'); - upwardEndStation.innerHTML = '상행 종점역'; - const downwardEndStation = document.createElement('th'); - downwardEndStation.innerHTML = '하행 종점역'; - const lineSettingHeader = document.createElement('th'); - lineSettingHeader.innerHTML = '설정'; - - lineTable.appendChild(lineNameHeader); - lineTable.appendChild(upwardEndStation); - lineTable.appendChild(downwardEndStation); - lineTable.appendChild(lineSettingHeader); + const lineTableHeaders = ['노선 이름', '상행 종점역', '하행 종점역', '설정']; + const lineTable = createTable('line-table', lineTableHeaders); const lines = JSON.parse(localStorage.getItem('lines')); - if (lines) { - Object.entries(lines).map(([line, stations]) => { - const tableRow = document.createElement('tr'); - tableRow.setAttribute('data-line', `_${line}`); - - const nameData = document.createElement('td'); - nameData.innerHTML = line; - const upwardEndData = document.createElement('td'); - upwardEndData.innerHTML = stations[0]; - const downwardEndData = document.createElement('td'); - downwardEndData.innerHTML = stations[stations.length - 1]; - const deleteBtn = document.createElement('button'); - deleteBtn.setAttribute('class', 'line-delete-button'); - deleteBtn.innerHTML = '삭제'; - deleteBtn.addEventListener('click', () => deleteLine(line)); - - tableRow.appendChild(nameData); - tableRow.appendChild(upwardEndData); - tableRow.appendChild(downwardEndData); - tableRow.appendChild(deleteBtn); - - lineTable.appendChild(tableRow); - }); + addTableData(lineTable, lines); } app.appendChild(lineTable); }; +const addTableData = (table, lines) => { + Object.entries(lines).map(([line, stations]) => { + const tableRow = document.createElement('tr'); + tableRow.dataset['line'] = `_${line}`; + + const nameData = document.createElement('td'); + nameData.innerHTML = line; + const upwardEndData = document.createElement('td'); + upwardEndData.innerHTML = stations[0]; + const downwardEndData = document.createElement('td'); + downwardEndData.innerHTML = stations[stations.length - 1]; + + const deleteBtn = document.createElement('button'); + deleteBtn.setAttribute('class', 'line-delete-button'); + deleteBtn.innerHTML = '삭제'; + deleteBtn.addEventListener('click', () => deleteLine(line)); + + [nameData, upwardEndData, downwardEndData, deleteBtn].map(data => { + tableRow.appendChild(data); + }); + + table.appendChild(tableRow); + }); +}; + const addTable = (lineName, start, end) => { const lineTable = document.getElementById('line-table'); const newRow = document.createElement('tr'); - newRow.setAttribute('data-line', `_${lineName}`); + newRow.dataset['line'] = `_${lineName}`; const newData = document.createElement('td'); newData.innerHTML = lineName; diff --git a/src/sectionManager.js b/src/sectionManager.js index b1c0de4c0..299f6cb19 100644 --- a/src/sectionManager.js +++ b/src/sectionManager.js @@ -1,4 +1,4 @@ -import { clearPage, createTextInput, createSubmitBtn, createSelectbox } from './utils.js'; +import { clearPage, createSubmitBtn, createSelectbox, createTable } from './utils.js'; const app = document.getElementById('app'); @@ -115,52 +115,43 @@ const removeCurrResult = () => { }; const createResultArea = line => { - const sectionTable = document.createElement('table'); - sectionTable.setAttribute('border', 1); - sectionTable.setAttribute('id', 'section-table'); + const sectionTableHeaders = ['순서', '이름', '설정']; + const sectionTable = createTable('section-table', sectionTableHeaders); sectionTable.style.marginTop = '20px'; - - const sectionOrder = document.createElement('th'); - sectionOrder.innerHTML = '순서'; - const sectionName = document.createElement('th'); - sectionName.innerHTML = '이름'; - const sectionSettingHeader = document.createElement('th'); - sectionSettingHeader.innerHTML = '설정'; - - sectionTable.appendChild(sectionOrder); - sectionTable.appendChild(sectionName); - sectionTable.appendChild(sectionSettingHeader); - app.appendChild(sectionTable); const currLines = JSON.parse(localStorage.getItem('lines')); if (currLines) { const currStations = currLines[line]; - currStations.map((station, idx) => { - const tableRow = document.createElement('tr'); - tableRow.setAttribute('data-line', line); - tableRow.setAttribute('data-station', station); - - const indexData = document.createElement('td'); - indexData.innerHTML = idx; - const nameData = document.createElement('td'); - nameData.innerHTML = station; - const deleteBtn = document.createElement('button'); - deleteBtn.setAttribute('class', 'section-delete-button'); - deleteBtn.innerHTML = '노선에서 제거'; - deleteBtn.addEventListener('click', () => deleteStation(station, line)); - - tableRow.appendChild(indexData); - tableRow.appendChild(nameData); - tableRow.appendChild(deleteBtn); - - sectionTable.appendChild(tableRow); - }); + addTableData(sectionTable, line, currStations); } app.appendChild(sectionTable); }; +const addTableData = (table, line, stations) => { + stations.map((station, idx) => { + const tableRow = document.createElement('tr'); + tableRow.dataset['line'] = line; + tableRow.dataset['station'] = station; + + const indexData = document.createElement('td'); + indexData.innerHTML = idx; + const nameData = document.createElement('td'); + nameData.innerHTML = station; + const deleteBtn = document.createElement('button'); + deleteBtn.setAttribute('class', 'section-delete-button'); + deleteBtn.innerHTML = '노선에서 제거'; + deleteBtn.addEventListener('click', () => deleteStation(station, line)); + + tableRow.appendChild(indexData); + tableRow.appendChild(nameData); + tableRow.appendChild(deleteBtn); + + table.appendChild(tableRow); + }); +}; + const deleteStation = (station, line) => { const sectionTable = document.getElementById('section-table'); const currLines = JSON.parse(localStorage.getItem('lines')); diff --git a/src/stationManager.js b/src/stationManager.js index 6ad0f205e..8f5593cce 100644 --- a/src/stationManager.js +++ b/src/stationManager.js @@ -1,4 +1,4 @@ -import { clearPage, createSubmitBtn, createTextInput } from './utils.js'; +import { clearPage, createSubmitBtn, createTextInput, createTable } from './utils.js'; const app = document.getElementById('app'); @@ -58,46 +58,40 @@ const createResultArea = () => { tableName.innerHTML = '🚉 지하철 역 목록'; app.appendChild(tableName); - const stationTable = document.createElement('table'); - stationTable.setAttribute('border', 1); - stationTable.setAttribute('id', 'station-table'); - - const stationNameHeader = document.createElement('th'); - stationNameHeader.innerHTML = '역 이름'; - const stationSettingHeader = document.createElement('th'); - stationSettingHeader.innerHTML = '설정'; - - stationTable.appendChild(stationNameHeader); - stationTable.appendChild(stationSettingHeader); + const stationTableHeaders = ['역 이름', '설정']; + const stationTable = createTable('station-table', stationTableHeaders); const stations = JSON.parse(localStorage.getItem('stations')); - if (stations) { - stations.map(name => { - const tableRow = document.createElement('tr'); - tableRow.setAttribute('data-station', name); - const nameData = document.createElement('td'); - nameData.innerHTML = name; - - const deleteBtn = document.createElement('button'); - deleteBtn.setAttribute('class', 'station-delete-button'); - deleteBtn.innerHTML = '삭제'; - deleteBtn.addEventListener('click', () => deleteStation(name)); - - tableRow.appendChild(nameData); - tableRow.appendChild(deleteBtn); - - stationTable.appendChild(tableRow); - }); + addTableData(stationTable, stations); } app.appendChild(stationTable); }; +const addTableData = (table, stations) => { + stations.map(station => { + const tableRow = document.createElement('tr'); + tableRow.dataset['station'] = station; + const nameData = document.createElement('td'); + nameData.innerHTML = station; + + const deleteBtn = document.createElement('button'); + deleteBtn.setAttribute('class', 'station-delete-button'); + deleteBtn.innerHTML = '삭제'; + deleteBtn.addEventListener('click', () => deleteStation(station)); + + tableRow.appendChild(nameData); + tableRow.appendChild(deleteBtn); + + table.appendChild(tableRow); + }); +}; + const addTable = name => { const stationTable = document.getElementById('station-table'); const newRow = document.createElement('tr'); - newRow.setAttribute('data-station', name); + newRow.dataset['station'] = name; const newData = document.createElement('td'); newData.innerHTML = name; diff --git a/src/utils.js b/src/utils.js index 6254d9df6..ed31a9de3 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,5 +1,8 @@ const app = document.getElementById('app'); +const TYPE_STATION = 'stations'; +const TYPE_LINE = 'lines'; + export const clearPage = () => { const contents = app.childNodes; let i = contents.length; @@ -42,3 +45,17 @@ export const createSelectbox = (select, selectorId, options) => { select.options.add(option); }); }; + +export const createTable = (tableId, tableHeaders) => { + const table = document.createElement('table'); + table.setAttribute('border', 1); + table.setAttribute('id', tableId); + + tableHeaders.map(tableHeader => { + const header = document.createElement('th'); + header.innerHTML = tableHeader; + table.appendChild(header); + }); + + return table; +}; From 24fa9ebdcedd1bce2794e9a5495b05ce6fecef07 Mon Sep 17 00:00:00 2001 From: zigsong Date: Mon, 14 Dec 2020 18:45:52 +0900 Subject: [PATCH 28/35] refactor: make strings constants --- src/constants.js | 61 +++++++++++++++++++++++++++++++++++++++++++ src/lineManager.js | 44 +++++++++++++++---------------- src/sectionManager.js | 47 +++++++++++++++++---------------- src/stationManager.js | 33 +++++++++++------------ src/utils.js | 3 --- 5 files changed, 123 insertions(+), 65 deletions(-) create mode 100644 src/constants.js diff --git a/src/constants.js b/src/constants.js new file mode 100644 index 000000000..98e0b53ba --- /dev/null +++ b/src/constants.js @@ -0,0 +1,61 @@ +export const stationText = { + inputLabel: '역 이름', + inputId: 'station-name-input', + placeholder: '역 이름을 입력해주세요', + submitId: 'station-add-button', + submitText: '역 추가', + inputContainer: 'input-container', + alertDuplicateName: '중복된 역 이름이 존재합니다.', + alertNameUnderTwo: '역 이름을 2자 이상으로 입력해 주세요.', + resultTitle: '🚉 지하철 역 목록', + tableHeader1: '역 이름', + tableHeader2: '설정', + tableId: 'station-table', + deleteBtnClass: 'station-delete-button', + deleteBtnText: '삭제', + alertConfirmDelete: '정말 삭제하시겠습니까?', +}; + +export const lineText = { + inputLabel: '노선 이름', + inputId: 'line-name-input', + placeholder: '노선 이름을 입력해주세요', + submitId: 'line-add-button', + submitText: '노선 추가', + startSelectorId: 'line-start-station-selector', + startSelectorText: '상행 종점', + endSelectorId: 'line-end-station-selector', + endSelectorText: '하행 종점', + alertDuplicateName: '중복된 노선 이름이 존재합니다.', + resultTitle: '🚉 지하철 노선 목록', + tableHeader1: '노선 이름', + tableHeader2: '상행 종점역', + tableHeader3: '하행 종점역', + tableHeader4: '설정', + tableId: 'line-table', + deleteBtnClass: 'line-delete-button', + deleteBtnText: '삭제', + alertConfirmDelete: '정말 삭제하시겠습니까?', +}; + +export const sectionText = { + guideText: '구간을 수정할 노선을 선택해주세요.', + menuButtonsClass: 'section-line-menu-button', + inputId: 'section-input', + selectAreaId: 'section-select', + tableId: 'section-table', + manageText: '관리', + registerText: '구간 등록', + selectorId: 'section-station-selector', + orderInputId: 'section-order-input', + placeholder: '순서', + submitId: 'section-add-button', + submitText: '등록', + tableHeader1: '순서', + tableHeader2: '이름', + tableHeader3: '설정', + deleteBtnClass: 'section-delete-button', + deleteBtnText: '노선에서 제거', + alertStationsUnderTwo: '노선에 포함된 역이 2개 이하일 때는 역을 삭제할 수 없습니다.', + alertConfirmDelete: '정말 삭제하시겠습니까?', +}; diff --git a/src/lineManager.js b/src/lineManager.js index 92bf8cef9..e1d23edd7 100644 --- a/src/lineManager.js +++ b/src/lineManager.js @@ -5,6 +5,7 @@ import { createSelectbox, createTable, } from './utils.js'; +import { lineText as T } from './constants.js'; const app = document.getElementById('app'); @@ -15,8 +16,8 @@ export const initLineManager = () => { }; const createPage = () => { - createTextInput('노선 이름', 'line-name-input', '노선 이름을 입력해주세요'); - const submitBtn = createSubmitBtn('line-add-button', '노선 추가'); + createTextInput(T.inputLabel, T.inputId, T.placeholder); + const submitBtn = createSubmitBtn(T.submitId, T.submitText); createSelectArea(); handleSubmit(submitBtn); createResultArea(); @@ -27,14 +28,14 @@ const createSelectArea = () => { const currStations = JSON.parse(localStorage.getItem('stations')); const upwardSelect = document.createElement('select'); - createSelectbox(upwardSelect, 'line-start-station-selector', currStations); + createSelectbox(upwardSelect, T.startSelectorId, currStations); const upwardLabel = document.createElement('b'); - upwardLabel.innerHTML = '상행 종점'; + upwardLabel.innerHTML = T.startSelectorText; const downwardSelect = document.createElement('select'); - createSelectbox(downwardSelect, 'line-end-station-selector', currStations); + createSelectbox(downwardSelect, T.endSelectorId, currStations); const downwardLabel = document.createElement('b'); - downwardLabel.innerHTML = '하행 종점'; + downwardLabel.innerHTML = T.endSelectorText; [upwardLabel, upwardSelect, document.createElement('br'), downwardLabel, downwardSelect].map( elem => { @@ -49,9 +50,9 @@ const handleSubmit = submitBtn => { app.appendChild(document.createElement('br')); app.appendChild(submitBtn); - const inputText = document.getElementById('line-name-input'); - const upwardSelect = document.getElementById('line-start-station-selector'); - const downwardSelect = document.getElementById('line-end-station-selector'); + const inputText = document.getElementById(T.inputId); + const upwardSelect = document.getElementById(T.startSelectorId); + const downwardSelect = document.getElementById(T.endSelectorId); let startStation = upwardSelect.options[upwardSelect.selectedIndex].value; let endStation = downwardSelect.options[downwardSelect.selectedIndex].value; @@ -74,11 +75,9 @@ const addLine = (lineName, lineInput, start, end) => { lineInput.value = ''; const currLines = JSON.parse(localStorage.getItem('lines')); - // console.log(currLines); const updatedLines = currLines ? currLines : {}; updatedLines[lineName] = [start, end]; localStorage.setItem('lines', JSON.stringify(updatedLines)); - // console.log(JSON.parse(localStorage.getItem('lines'))); addTable(lineName, start, end); }; @@ -86,7 +85,7 @@ const addLine = (lineName, lineInput, start, end) => { const validateName = lineName => { const currLines = JSON.parse(localStorage.getItem('lines')); if (currLines && Object.keys(currLines).includes(lineName)) { - alert('중복된 노선 이름이 존재합니다.'); + alert(T.alertDuplicateName); return false; } return true; @@ -94,11 +93,11 @@ const validateName = lineName => { const createResultArea = () => { const tableName = document.createElement('h2'); - tableName.innerHTML = '🚉 지하철 노선 목록'; + tableName.innerHTML = T.resultTitle; app.appendChild(tableName); - const lineTableHeaders = ['노선 이름', '상행 종점역', '하행 종점역', '설정']; - const lineTable = createTable('line-table', lineTableHeaders); + const lineTableHeaders = [T.tableHeader1, T.tableHeader2, T.tableHeader3, T.tableHeader4]; + const lineTable = createTable(T.tableId, lineTableHeaders); const lines = JSON.parse(localStorage.getItem('lines')); if (lines) { @@ -121,8 +120,8 @@ const addTableData = (table, lines) => { downwardEndData.innerHTML = stations[stations.length - 1]; const deleteBtn = document.createElement('button'); - deleteBtn.setAttribute('class', 'line-delete-button'); - deleteBtn.innerHTML = '삭제'; + deleteBtn.setAttribute('class', T.deleteBtnClass); + deleteBtn.innerHTML = T.deleteBtnText; deleteBtn.addEventListener('click', () => deleteLine(line)); [nameData, upwardEndData, downwardEndData, deleteBtn].map(data => { @@ -134,7 +133,7 @@ const addTableData = (table, lines) => { }; const addTable = (lineName, start, end) => { - const lineTable = document.getElementById('line-table'); + const lineTable = document.getElementById(T.tableId); const newRow = document.createElement('tr'); newRow.dataset['line'] = `_${lineName}`; @@ -145,8 +144,8 @@ const addTable = (lineName, start, end) => { const downwardEndData = document.createElement('td'); downwardEndData.innerHTML = end; const deleteBtn = document.createElement('button'); - deleteBtn.setAttribute('class', 'line-delete-button'); - deleteBtn.innerHTML = '삭제'; + deleteBtn.setAttribute('class', T.deleteBtnClass); + deleteBtn.innerHTML = T.deleteBtnText; deleteBtn.addEventListener('click', () => deleteLine(lineName)); newRow.appendChild(newData); @@ -158,12 +157,11 @@ const addTable = (lineName, start, end) => { }; const deleteLine = lineName => { - if (confirm('정말 삭제하시겠습니까?')) { - const lineTable = document.getElementById('line-table'); + if (confirm(T.alertConfirmDelete)) { + const lineTable = document.getElementById(T.tableId); const currLines = JSON.parse(localStorage.getItem('lines')); delete currLines[lineName]; localStorage.setItem('lines', JSON.stringify(currLines)); - // console.log(JSON.parse(localStorage.getItem('lines'))); const rowToBeDeleted = lineTable.querySelector(`[data-line=_${lineName}]`); lineTable.removeChild(rowToBeDeleted); } diff --git a/src/sectionManager.js b/src/sectionManager.js index 299f6cb19..9d9f0c54d 100644 --- a/src/sectionManager.js +++ b/src/sectionManager.js @@ -1,4 +1,5 @@ import { clearPage, createSubmitBtn, createSelectbox, createTable } from './utils.js'; +import { sectionText as T } from './constants.js'; const app = document.getElementById('app'); @@ -10,7 +11,7 @@ export const initSectionManager = () => { const printGuideText = () => { const sectionHeader = document.createElement('div'); const sectionTitle = document.createElement('h3'); - sectionTitle.innerText = '구간을 수정할 노선을 선택해주세요.'; + sectionTitle.innerText = T.guideText; sectionHeader.appendChild(sectionTitle); createMenuButtons(sectionHeader); @@ -22,7 +23,7 @@ const createMenuButtons = sectionHeader => { if (currLines) { Object.keys(currLines).map(line => { const lineBtn = document.createElement('button'); - lineBtn.setAttribute('class', 'section-line-menu-button'); + lineBtn.setAttribute('class', T.menuButtonsClass); lineBtn.innerHTML = line; lineBtn.style.margin = '2px'; lineBtn.addEventListener('click', () => { @@ -36,9 +37,9 @@ const createMenuButtons = sectionHeader => { }; const clearInputs = () => { - const sectionInputArea = document.getElementById('section-input'); - const selectArea = document.getElementById('section-selector'); - const sectionTable = document.getElementById('section-table'); + const sectionInputArea = document.getElementById(T.inputId); + const selectArea = document.getElementById(T.selectAreaId); + const sectionTable = document.getElementById(T.tableId); if (sectionInputArea && selectArea && sectionTable) { app.removeChild(sectionInputArea); @@ -49,15 +50,15 @@ const clearInputs = () => { const manageLineSection = line => { const sectionInputArea = document.createElement('div'); - sectionInputArea.setAttribute('id', 'section-input'); + sectionInputArea.setAttribute('id', T.inputId); const manageTitle = document.createElement('h3'); - manageTitle.innerHTML = `${line} 관리`; - const registerText = document.createElement('b'); - registerText.innerHTML = '구간 등록'; + manageTitle.innerHTML = `${line} ${T.manageText}`; + const registerTitle = document.createElement('b'); + registerTitle.innerHTML = T.registerText; sectionInputArea.appendChild(manageTitle); - sectionInputArea.appendChild(registerText); + sectionInputArea.appendChild(registerTitle); app.appendChild(sectionInputArea); createSelectArea(line); @@ -65,11 +66,11 @@ const manageLineSection = line => { const createSelectArea = line => { const selectArea = document.createElement('div'); - selectArea.setAttribute('id', 'section-selector'); + selectArea.setAttribute('id', T.selectAreaId); const currStations = JSON.parse(localStorage.getItem('stations')); const stationSelect = document.createElement('select'); - createSelectbox(stationSelect, 'section-station-selector', currStations); + createSelectbox(stationSelect, T.selectorId, currStations); let selectedStation = stationSelect.options[stationSelect.selectedIndex].value; stationSelect.addEventListener('change', () => { @@ -78,10 +79,10 @@ const createSelectArea = line => { const orderInput = document.createElement('input'); orderInput.type = 'number'; - orderInput.setAttribute('id', 'section-order-input'); - orderInput.setAttribute('placholder', '순서'); + orderInput.setAttribute('id', T.orderInputId); + orderInput.setAttribute('placholder', T.placeholder); - const submitBtn = createSubmitBtn('section-add-button', '등록'); + const submitBtn = createSubmitBtn(T.submitId, T.submitText); submitBtn.addEventListener('click', () => addToSection(line, selectedStation, orderInput)); [stationSelect, orderInput, submitBtn].map(elem => { @@ -110,13 +111,13 @@ const addToSection = (line, station, orderInput) => { }; const removeCurrResult = () => { - const sectionTable = document.getElementById('section-table'); + const sectionTable = document.getElementById(T.tableId); app.removeChild(sectionTable); }; const createResultArea = line => { - const sectionTableHeaders = ['순서', '이름', '설정']; - const sectionTable = createTable('section-table', sectionTableHeaders); + const sectionTableHeaders = [T.tableHeader1, T.tableHeader2, T.tableHeader3]; + const sectionTable = createTable(T.tableId, sectionTableHeaders); sectionTable.style.marginTop = '20px'; app.appendChild(sectionTable); @@ -140,8 +141,8 @@ const addTableData = (table, line, stations) => { const nameData = document.createElement('td'); nameData.innerHTML = station; const deleteBtn = document.createElement('button'); - deleteBtn.setAttribute('class', 'section-delete-button'); - deleteBtn.innerHTML = '노선에서 제거'; + deleteBtn.setAttribute('class', T.deleteBtnClass); + deleteBtn.innerHTML = T.deleteBtnText; deleteBtn.addEventListener('click', () => deleteStation(station, line)); tableRow.appendChild(indexData); @@ -153,16 +154,16 @@ const addTableData = (table, line, stations) => { }; const deleteStation = (station, line) => { - const sectionTable = document.getElementById('section-table'); + const sectionTable = document.getElementById(T.tableId); const currLines = JSON.parse(localStorage.getItem('lines')); const currStations = currLines[line]; if (currStations.length <= 2) { - alert('노선에 포함된 역이 2개 이하일 때는 역을 삭제할 수 없습니다.'); + alert(T.alertStationsUnderTwo); return; } - if (confirm('정말 삭제하시겠습니까?')) { + if (confirm(T.alertConfirmDelete)) { currStations.splice(currStations.indexOf(station), 1); const updatedLines = currLines; updatedLines[line] = currStations; diff --git a/src/stationManager.js b/src/stationManager.js index 8f5593cce..6ad14b42e 100644 --- a/src/stationManager.js +++ b/src/stationManager.js @@ -1,4 +1,5 @@ import { clearPage, createSubmitBtn, createTextInput, createTable } from './utils.js'; +import { stationText as T } from './constants.js'; const app = document.getElementById('app'); @@ -8,16 +9,16 @@ export const initStationManager = () => { }; const createPage = () => { - createTextInput('역 이름', 'station-name-input', '역 이름을 입력해주세요'); - const submitBtn = createSubmitBtn('station-add-button', '역 추가'); + createTextInput(T.inputLabel, T.inputId, T.placeholder); + const submitBtn = createSubmitBtn(T.submitId, T.submitText); handleSubmit(submitBtn); createResultArea(); }; const handleSubmit = submitBtn => { - const inputArea = document.getElementById('input-container'); + const inputArea = document.getElementById(T.inputContainer); inputArea.appendChild(submitBtn); - const inputText = document.getElementById('station-name-input'); + const inputText = document.getElementById(T.inputId); inputText.addEventListener('keypress', e => { let name = inputText.value; @@ -44,10 +45,10 @@ const addStation = (name, nameInput) => { const validateName = name => { const currStations = JSON.parse(localStorage.getItem('stations')); if (currStations && currStations.includes(name)) { - alert('중복된 역 이름이 존재합니다.'); + alert(T.alertDuplicateName); return false; } else if (name.length < 2) { - alert('역 이름을 2자 이상으로 입력해 주세요.'); + alert(T.alertNameUnderTwo); return false; } return true; @@ -55,11 +56,11 @@ const validateName = name => { const createResultArea = () => { const tableName = document.createElement('h2'); - tableName.innerHTML = '🚉 지하철 역 목록'; + tableName.innerHTML = T.resultTitle; app.appendChild(tableName); - const stationTableHeaders = ['역 이름', '설정']; - const stationTable = createTable('station-table', stationTableHeaders); + const stationTableHeaders = [T.tableHeader1, T.tableHeader2]; + const stationTable = createTable(T.tableId, stationTableHeaders); const stations = JSON.parse(localStorage.getItem('stations')); if (stations) { @@ -77,8 +78,8 @@ const addTableData = (table, stations) => { nameData.innerHTML = station; const deleteBtn = document.createElement('button'); - deleteBtn.setAttribute('class', 'station-delete-button'); - deleteBtn.innerHTML = '삭제'; + deleteBtn.setAttribute('class', T.deleteBtnClass); + deleteBtn.innerHTML = T.deleteBtnText; deleteBtn.addEventListener('click', () => deleteStation(station)); tableRow.appendChild(nameData); @@ -89,15 +90,15 @@ const addTableData = (table, stations) => { }; const addTable = name => { - const stationTable = document.getElementById('station-table'); + const stationTable = document.getElementById(T.tableId); const newRow = document.createElement('tr'); newRow.dataset['station'] = name; const newData = document.createElement('td'); newData.innerHTML = name; const deleteBtn = document.createElement('button'); - deleteBtn.setAttribute('class', 'station-delete-button'); - deleteBtn.innerHTML = '삭제'; + deleteBtn.setAttribute('class', T.deleteBtnClass); + deleteBtn.innerHTML = T.deleteBtnText; deleteBtn.addEventListener('click', () => deleteStation(name)); newRow.appendChild(newData); @@ -107,8 +108,8 @@ const addTable = name => { }; const deleteStation = name => { - if (confirm('정말 삭제하시겠습니까?')) { - const stationTable = document.getElementById('station-table'); + if (confirm(T.alertConfirmDelete)) { + const stationTable = document.getElementById(T.tableId); const currStations = JSON.parse(localStorage.getItem('stations')); const updatedStations = currStations.filter(station => station !== name); localStorage.setItem('stations', JSON.stringify(updatedStations)); diff --git a/src/utils.js b/src/utils.js index ed31a9de3..99e77edd9 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,8 +1,5 @@ const app = document.getElementById('app'); -const TYPE_STATION = 'stations'; -const TYPE_LINE = 'lines'; - export const clearPage = () => { const contents = app.childNodes; let i = contents.length; From ddd975ef3c1e27fd6cfe38721b1b2174c3223ff1 Mon Sep 17 00:00:00 2001 From: zigsong Date: Mon, 14 Dec 2020 21:03:42 +0900 Subject: [PATCH 29/35] refactor: separate function handling localStorage --- src/lineManager.js | 19 +++++++++++-------- src/mapManager.js | 4 +++- src/sectionManager.js | 19 ++++++++++--------- src/stationManager.js | 14 ++++++++------ src/storage.js | 7 +++++++ 5 files changed, 39 insertions(+), 24 deletions(-) create mode 100644 src/storage.js diff --git a/src/lineManager.js b/src/lineManager.js index e1d23edd7..28cc64b8d 100644 --- a/src/lineManager.js +++ b/src/lineManager.js @@ -5,14 +5,16 @@ import { createSelectbox, createTable, } from './utils.js'; +import { getLocalStorage, setLocalStorage } from './storage.js'; import { lineText as T } from './constants.js'; const app = document.getElementById('app'); +const STORAGE_KEY_STATION = 'stations'; +const STORAGE_KEY_LINE = 'lines'; export const initLineManager = () => { clearPage(); createPage(); - // createResultArea(); }; const createPage = () => { @@ -25,7 +27,7 @@ const createPage = () => { const createSelectArea = () => { const lineSelectArea = document.createElement('div'); - const currStations = JSON.parse(localStorage.getItem('stations')); + const currStations = getLocalStorage(STORAGE_KEY_STATION); const upwardSelect = document.createElement('select'); createSelectbox(upwardSelect, T.startSelectorId, currStations); @@ -74,16 +76,17 @@ const addLine = (lineName, lineInput, start, end) => { lineInput.value = ''; - const currLines = JSON.parse(localStorage.getItem('lines')); + const currLines = getLocalStorage(STORAGE_KEY_LINE); const updatedLines = currLines ? currLines : {}; updatedLines[lineName] = [start, end]; - localStorage.setItem('lines', JSON.stringify(updatedLines)); + // localStorage.setItem('lines', JSON.stringify(updatedLines)); + setLocalStorage(STORAGE_KEY_LINE, updatedLines); addTable(lineName, start, end); }; const validateName = lineName => { - const currLines = JSON.parse(localStorage.getItem('lines')); + const currLines = getLocalStorage(STORAGE_KEY_LINE); if (currLines && Object.keys(currLines).includes(lineName)) { alert(T.alertDuplicateName); return false; @@ -99,7 +102,7 @@ const createResultArea = () => { const lineTableHeaders = [T.tableHeader1, T.tableHeader2, T.tableHeader3, T.tableHeader4]; const lineTable = createTable(T.tableId, lineTableHeaders); - const lines = JSON.parse(localStorage.getItem('lines')); + const lines = getLocalStorage(STORAGE_KEY_LINE); if (lines) { addTableData(lineTable, lines); } @@ -159,9 +162,9 @@ const addTable = (lineName, start, end) => { const deleteLine = lineName => { if (confirm(T.alertConfirmDelete)) { const lineTable = document.getElementById(T.tableId); - const currLines = JSON.parse(localStorage.getItem('lines')); + const currLines = getLocalStorage(STORAGE_KEY_LINE); delete currLines[lineName]; - localStorage.setItem('lines', JSON.stringify(currLines)); + setLocalStorage(STORAGE_KEY_LINE, currLines); const rowToBeDeleted = lineTable.querySelector(`[data-line=_${lineName}]`); lineTable.removeChild(rowToBeDeleted); } diff --git a/src/mapManager.js b/src/mapManager.js index 78c3cb247..f1205f013 100644 --- a/src/mapManager.js +++ b/src/mapManager.js @@ -1,6 +1,8 @@ import { clearPage } from './utils.js'; +import { getLocalStorage } from './storage.js'; const app = document.getElementById('app'); +const STORAGE_KEY_LINE = 'lines'; export const initMapManager = () => { clearPage(); @@ -11,7 +13,7 @@ const createResultArea = () => { const resultArea = document.createElement('div'); resultArea.setAttribute('class', 'map'); - const currLines = JSON.parse(localStorage.getItem('lines')); + const currLines = getLocalStorage(STORAGE_KEY_LINE); if (currLines) { Object.entries(currLines).map(([line, stations]) => { const lineTitle = document.createElement('h3'); diff --git a/src/sectionManager.js b/src/sectionManager.js index 9d9f0c54d..9fc12a853 100644 --- a/src/sectionManager.js +++ b/src/sectionManager.js @@ -1,7 +1,10 @@ import { clearPage, createSubmitBtn, createSelectbox, createTable } from './utils.js'; +import { getLocalStorage, setLocalStorage } from './storage.js'; import { sectionText as T } from './constants.js'; const app = document.getElementById('app'); +const STORAGE_KEY_STATION = 'stations'; +const STORAGE_KEY_LINE = 'lines'; export const initSectionManager = () => { clearPage(); @@ -19,7 +22,7 @@ const printGuideText = () => { }; const createMenuButtons = sectionHeader => { - const currLines = JSON.parse(localStorage.getItem('lines')); + const currLines = getLocalStorage(STORAGE_KEY_LINE); if (currLines) { Object.keys(currLines).map(line => { const lineBtn = document.createElement('button'); @@ -68,7 +71,7 @@ const createSelectArea = line => { const selectArea = document.createElement('div'); selectArea.setAttribute('id', T.selectAreaId); - const currStations = JSON.parse(localStorage.getItem('stations')); + const currStations = getLocalStorage(STORAGE_KEY_STATION); const stationSelect = document.createElement('select'); createSelectbox(stationSelect, T.selectorId, currStations); @@ -96,15 +99,14 @@ const addToSection = (line, station, orderInput) => { const order = orderInput.value; orderInput.value = ''; - const currLines = JSON.parse(localStorage.getItem('lines')); + const currLines = getLocalStorage(STORAGE_KEY_LINE); const currStations = currLines[line]; console.log(currStations); currStations.splice(order, 0, station); const updatedLines = currLines; updatedLines[line] = currStations; - localStorage.setItem('lines', JSON.stringify(updatedLines)); - console.log(JSON.parse(localStorage.getItem('lines'))); + setLocalStorage(STORAGE_KEY_LINE, updatedLines); removeCurrResult(); createResultArea(line); @@ -121,7 +123,7 @@ const createResultArea = line => { sectionTable.style.marginTop = '20px'; app.appendChild(sectionTable); - const currLines = JSON.parse(localStorage.getItem('lines')); + const currLines = getLocalStorage(STORAGE_KEY_LINE); if (currLines) { const currStations = currLines[line]; addTableData(sectionTable, line, currStations); @@ -155,7 +157,7 @@ const addTableData = (table, line, stations) => { const deleteStation = (station, line) => { const sectionTable = document.getElementById(T.tableId); - const currLines = JSON.parse(localStorage.getItem('lines')); + const currLines = getLocalStorage(STORAGE_KEY_LINE); const currStations = currLines[line]; if (currStations.length <= 2) { @@ -167,8 +169,7 @@ const deleteStation = (station, line) => { currStations.splice(currStations.indexOf(station), 1); const updatedLines = currLines; updatedLines[line] = currStations; - localStorage.setItem('lines', JSON.stringify(updatedLines)); - console.log(JSON.parse(localStorage.getItem('lines'))); + setLocalStorage(STORAGE_KEY_LINE, updatedLines); const rowToBeDeleted = sectionTable.querySelector(`[data-station=${station}]`); sectionTable.removeChild(rowToBeDeleted); diff --git a/src/stationManager.js b/src/stationManager.js index 6ad14b42e..de31c7fac 100644 --- a/src/stationManager.js +++ b/src/stationManager.js @@ -1,7 +1,9 @@ import { clearPage, createSubmitBtn, createTextInput, createTable } from './utils.js'; +import { getLocalStorage, setLocalStorage } from './storage.js'; import { stationText as T } from './constants.js'; const app = document.getElementById('app'); +const STORAGE_KEY_STATION = 'stations'; export const initStationManager = () => { clearPage(); @@ -36,14 +38,14 @@ const handleSubmit = submitBtn => { const addStation = (name, nameInput) => { if (!validateName(name)) return; nameInput.value = ''; - const currStations = JSON.parse(localStorage.getItem('stations')); + const currStations = getLocalStorage(STORAGE_KEY_STATION); const updatedStations = currStations ? [...currStations, name] : [name]; - localStorage.setItem('stations', JSON.stringify(updatedStations)); + setLocalStorage(STORAGE_KEY_STATION, updatedStations); addTable(name); }; const validateName = name => { - const currStations = JSON.parse(localStorage.getItem('stations')); + const currStations = getLocalStorage(STORAGE_KEY_STATION); if (currStations && currStations.includes(name)) { alert(T.alertDuplicateName); return false; @@ -62,7 +64,7 @@ const createResultArea = () => { const stationTableHeaders = [T.tableHeader1, T.tableHeader2]; const stationTable = createTable(T.tableId, stationTableHeaders); - const stations = JSON.parse(localStorage.getItem('stations')); + const stations = getLocalStorage(STORAGE_KEY_STATION); if (stations) { addTableData(stationTable, stations); } @@ -110,9 +112,9 @@ const addTable = name => { const deleteStation = name => { if (confirm(T.alertConfirmDelete)) { const stationTable = document.getElementById(T.tableId); - const currStations = JSON.parse(localStorage.getItem('stations')); + const currStations = getLocalStorage(STORAGE_KEY_STATION); const updatedStations = currStations.filter(station => station !== name); - localStorage.setItem('stations', JSON.stringify(updatedStations)); + setLocalStorage(STORAGE_KEY_STATION, updatedStations); const rowToBeDeleted = stationTable.querySelector(`[data-station=${name}]`); stationTable.removeChild(rowToBeDeleted); } diff --git a/src/storage.js b/src/storage.js new file mode 100644 index 000000000..9925c64b3 --- /dev/null +++ b/src/storage.js @@ -0,0 +1,7 @@ +export const getLocalStorage = key => { + return JSON.parse(localStorage.getItem(key)); +}; + +export const setLocalStorage = (key, value) => { + localStorage.setItem(key, JSON.stringify(value)); +}; From 7247a8acc9e751ec3f95b9f02d1ffd14c4a36ed8 Mon Sep 17 00:00:00 2001 From: zigsong Date: Tue, 15 Dec 2020 11:25:35 +0900 Subject: [PATCH 30/35] refactor: rename variables & shorten functions --- src/constants.js | 4 ++ src/lineManager.js | 127 +++++++++++++++++------------------------- src/mapManager.js | 42 +++++++------- src/sectionManager.js | 113 +++++++++++++++++++------------------ src/stationManager.js | 69 +++++++++++------------ src/utils.js | 15 ++--- 6 files changed, 175 insertions(+), 195 deletions(-) diff --git a/src/constants.js b/src/constants.js index 98e0b53ba..c21701396 100644 --- a/src/constants.js +++ b/src/constants.js @@ -59,3 +59,7 @@ export const sectionText = { alertStationsUnderTwo: '노선에 포함된 역이 2개 이하일 때는 역을 삭제할 수 없습니다.', alertConfirmDelete: '정말 삭제하시겠습니까?', }; + +export const mapText = { + resultAreaClass: 'map', +}; diff --git a/src/lineManager.js b/src/lineManager.js index 28cc64b8d..7642b0d02 100644 --- a/src/lineManager.js +++ b/src/lineManager.js @@ -11,6 +11,7 @@ import { lineText as T } from './constants.js'; const app = document.getElementById('app'); const STORAGE_KEY_STATION = 'stations'; const STORAGE_KEY_LINE = 'lines'; +const DATA_KEY_LINE = 'line'; export const initLineManager = () => { clearPage(); @@ -19,75 +20,61 @@ export const initLineManager = () => { const createPage = () => { createTextInput(T.inputLabel, T.inputId, T.placeholder); - const submitBtn = createSubmitBtn(T.submitId, T.submitText); createSelectArea(); + const submitBtn = createSubmitBtn(T.submitId, T.submitText); handleSubmit(submitBtn); createResultArea(); }; const createSelectArea = () => { - const lineSelectArea = document.createElement('div'); - const currStations = getLocalStorage(STORAGE_KEY_STATION); + const selectArea = document.createElement('div'); + const stations = getLocalStorage(STORAGE_KEY_STATION); - const upwardSelect = document.createElement('select'); - createSelectbox(upwardSelect, T.startSelectorId, currStations); + const upwardSelect = createSelectbox(T.startSelectorId, stations); const upwardLabel = document.createElement('b'); upwardLabel.innerHTML = T.startSelectorText; - const downwardSelect = document.createElement('select'); - createSelectbox(downwardSelect, T.endSelectorId, currStations); + const downwardSelect = createSelectbox(T.endSelectorId, stations); const downwardLabel = document.createElement('b'); downwardLabel.innerHTML = T.endSelectorText; - [upwardLabel, upwardSelect, document.createElement('br'), downwardLabel, downwardSelect].map( - elem => { - lineSelectArea.appendChild(elem); - }, - ); + selectArea.append(upwardLabel, upwardSelect, document.createElement('br')); + selectArea.append(downwardLabel, downwardSelect); - app.appendChild(lineSelectArea); + app.append(selectArea); }; const handleSubmit = submitBtn => { - app.appendChild(document.createElement('br')); - app.appendChild(submitBtn); + app.append(document.createElement('br'), submitBtn); const inputText = document.getElementById(T.inputId); const upwardSelect = document.getElementById(T.startSelectorId); const downwardSelect = document.getElementById(T.endSelectorId); - let startStation = upwardSelect.options[upwardSelect.selectedIndex].value; - let endStation = downwardSelect.options[downwardSelect.selectedIndex].value; - upwardSelect.addEventListener('change', () => { - startStation = upwardSelect.value; - }); - downwardSelect.addEventListener('change', () => { - endStation = downwardSelect.value; - }); + let startStation = upwardSelect.value; + let endStation = downwardSelect.value; + upwardSelect.addEventListener('change', () => (startStation = upwardSelect.value)); + downwardSelect.addEventListener('change', () => (endStation = downwardSelect.value)); submitBtn.addEventListener('click', () => { - let lineName = inputText.value; - addLine(lineName, inputText, startStation, endStation); + addLine(inputText.value, startStation, endStation); + inputText.value = ''; }); }; -const addLine = (lineName, lineInput, start, end) => { - if (!validateName(lineName)) return; - - lineInput.value = ''; +const addLine = (line, start, end) => { + if (!validateName(line)) return; const currLines = getLocalStorage(STORAGE_KEY_LINE); const updatedLines = currLines ? currLines : {}; - updatedLines[lineName] = [start, end]; - // localStorage.setItem('lines', JSON.stringify(updatedLines)); + updatedLines[line] = [start, end]; setLocalStorage(STORAGE_KEY_LINE, updatedLines); - - addTable(lineName, start, end); + addToTable(line, start, end); }; const validateName = lineName => { - const currLines = getLocalStorage(STORAGE_KEY_LINE); - if (currLines && Object.keys(currLines).includes(lineName)) { + const lines = getLocalStorage(STORAGE_KEY_LINE); + if (lines && Object.keys(lines).includes(lineName)) { alert(T.alertDuplicateName); return false; } @@ -97,75 +84,63 @@ const validateName = lineName => { const createResultArea = () => { const tableName = document.createElement('h2'); tableName.innerHTML = T.resultTitle; - app.appendChild(tableName); + app.append(tableName); const lineTableHeaders = [T.tableHeader1, T.tableHeader2, T.tableHeader3, T.tableHeader4]; const lineTable = createTable(T.tableId, lineTableHeaders); - const lines = getLocalStorage(STORAGE_KEY_LINE); if (lines) { addTableData(lineTable, lines); } - app.appendChild(lineTable); + app.append(lineTable); }; const addTableData = (table, lines) => { Object.entries(lines).map(([line, stations]) => { - const tableRow = document.createElement('tr'); - tableRow.dataset['line'] = `_${line}`; - - const nameData = document.createElement('td'); - nameData.innerHTML = line; - const upwardEndData = document.createElement('td'); - upwardEndData.innerHTML = stations[0]; - const downwardEndData = document.createElement('td'); - downwardEndData.innerHTML = stations[stations.length - 1]; - - const deleteBtn = document.createElement('button'); - deleteBtn.setAttribute('class', T.deleteBtnClass); - deleteBtn.innerHTML = T.deleteBtnText; - deleteBtn.addEventListener('click', () => deleteLine(line)); - - [nameData, upwardEndData, downwardEndData, deleteBtn].map(data => { - tableRow.appendChild(data); - }); - - table.appendChild(tableRow); + const tableRow = addTableRow(line, stations[0], stations[stations.length - 1]); + table.append(tableRow); }); }; -const addTable = (lineName, start, end) => { - const lineTable = document.getElementById(T.tableId); - const newRow = document.createElement('tr'); - newRow.dataset['line'] = `_${lineName}`; +const addTableRow = (line, upwardEnd, downwardEnd) => { + const tableRow = document.createElement('tr'); + tableRow.dataset[DATA_KEY_LINE] = `_${line}`; - const newData = document.createElement('td'); - newData.innerHTML = lineName; + const nameData = document.createElement('td'); + nameData.innerHTML = line; const upwardEndData = document.createElement('td'); - upwardEndData.innerHTML = start; + upwardEndData.innerHTML = upwardEnd; const downwardEndData = document.createElement('td'); - downwardEndData.innerHTML = end; + downwardEndData.innerHTML = downwardEnd; + const deleteBtn = createDeleteBtn(line); + + tableRow.append(nameData, upwardEndData, downwardEndData, deleteBtn); + return tableRow; +}; + +const addToTable = (line, start, end) => { + const lineTable = document.getElementById(T.tableId); + const newRow = addTableRow(line, start, end); + lineTable.append(newRow); +}; + +const createDeleteBtn = line => { const deleteBtn = document.createElement('button'); deleteBtn.setAttribute('class', T.deleteBtnClass); deleteBtn.innerHTML = T.deleteBtnText; - deleteBtn.addEventListener('click', () => deleteLine(lineName)); - - newRow.appendChild(newData); - newRow.appendChild(upwardEndData); - newRow.appendChild(downwardEndData); - newRow.appendChild(deleteBtn); + deleteBtn.addEventListener('click', () => deleteLine(line)); - lineTable.appendChild(newRow); + return deleteBtn; }; -const deleteLine = lineName => { +const deleteLine = line => { if (confirm(T.alertConfirmDelete)) { const lineTable = document.getElementById(T.tableId); const currLines = getLocalStorage(STORAGE_KEY_LINE); - delete currLines[lineName]; + delete currLines[line]; setLocalStorage(STORAGE_KEY_LINE, currLines); - const rowToBeDeleted = lineTable.querySelector(`[data-line=_${lineName}]`); + const rowToBeDeleted = lineTable.querySelector(`[data-${DATA_KEY_LINE}=_${line}]`); lineTable.removeChild(rowToBeDeleted); } }; diff --git a/src/mapManager.js b/src/mapManager.js index f1205f013..0ec15c5db 100644 --- a/src/mapManager.js +++ b/src/mapManager.js @@ -1,5 +1,6 @@ import { clearPage } from './utils.js'; import { getLocalStorage } from './storage.js'; +import { mapText as T } from './constants.js'; const app = document.getElementById('app'); const STORAGE_KEY_LINE = 'lines'; @@ -11,25 +12,28 @@ export const initMapManager = () => { const createResultArea = () => { const resultArea = document.createElement('div'); - resultArea.setAttribute('class', 'map'); - - const currLines = getLocalStorage(STORAGE_KEY_LINE); - if (currLines) { - Object.entries(currLines).map(([line, stations]) => { - const lineTitle = document.createElement('h3'); - lineTitle.innerHTML = line; - const stationList = document.createElement('ul'); - - stations.map(station => { - const stationItem = document.createElement('li'); - stationItem.innerHTML = station; - stationList.appendChild(stationItem); - }); - - resultArea.appendChild(lineTitle); - resultArea.appendChild(stationList); - }); + resultArea.setAttribute('class', T.resultAreaClass); - app.appendChild(resultArea); + const lines = getLocalStorage(STORAGE_KEY_LINE); + if (lines) { + printResult(resultArea, lines); } }; + +const printResult = (resultArea, data) => { + Object.entries(data).map(([line, stations]) => { + const lineTitle = document.createElement('h3'); + lineTitle.innerHTML = line; + const stationList = document.createElement('ul'); + + stations.map(station => { + const stationItem = document.createElement('li'); + stationItem.innerHTML = station; + stationList.append(stationItem); + }); + + resultArea.append(lineTitle, stationList); + }); + + app.append(resultArea); +}; diff --git a/src/sectionManager.js b/src/sectionManager.js index 9fc12a853..79c6d9429 100644 --- a/src/sectionManager.js +++ b/src/sectionManager.js @@ -15,26 +15,26 @@ const printGuideText = () => { const sectionHeader = document.createElement('div'); const sectionTitle = document.createElement('h3'); sectionTitle.innerText = T.guideText; - sectionHeader.appendChild(sectionTitle); + sectionHeader.append(sectionTitle); createMenuButtons(sectionHeader); - app.appendChild(sectionHeader); + app.append(sectionHeader); }; const createMenuButtons = sectionHeader => { - const currLines = getLocalStorage(STORAGE_KEY_LINE); - if (currLines) { - Object.keys(currLines).map(line => { - const lineBtn = document.createElement('button'); - lineBtn.setAttribute('class', T.menuButtonsClass); - lineBtn.innerHTML = line; - lineBtn.style.margin = '2px'; - lineBtn.addEventListener('click', () => { + const lines = getLocalStorage(STORAGE_KEY_LINE); + if (lines) { + Object.keys(lines).map(line => { + const menuBtn = document.createElement('button'); + menuBtn.setAttribute('class', T.menuButtonsClass); + menuBtn.innerHTML = line; + menuBtn.style.margin = '2px'; + menuBtn.addEventListener('click', () => { clearInputs(); - manageLineSection(line); + createPage(line); createResultArea(line); }); - sectionHeader.appendChild(lineBtn); + sectionHeader.append(menuBtn); }); } }; @@ -51,7 +51,7 @@ const clearInputs = () => { } }; -const manageLineSection = line => { +const createPage = line => { const sectionInputArea = document.createElement('div'); sectionInputArea.setAttribute('id', T.inputId); @@ -60,10 +60,9 @@ const manageLineSection = line => { const registerTitle = document.createElement('b'); registerTitle.innerHTML = T.registerText; - sectionInputArea.appendChild(manageTitle); - sectionInputArea.appendChild(registerTitle); + sectionInputArea.append(manageTitle, registerTitle); + app.append(sectionInputArea); - app.appendChild(sectionInputArea); createSelectArea(line); }; @@ -71,28 +70,26 @@ const createSelectArea = line => { const selectArea = document.createElement('div'); selectArea.setAttribute('id', T.selectAreaId); - const currStations = getLocalStorage(STORAGE_KEY_STATION); - const stationSelect = document.createElement('select'); - createSelectbox(stationSelect, T.selectorId, currStations); + const stations = getLocalStorage(STORAGE_KEY_STATION); + const stationSelect = createSelectbox(T.selectorId, stations); - let selectedStation = stationSelect.options[stationSelect.selectedIndex].value; - stationSelect.addEventListener('change', () => { - selectedStation = stationSelect.value; - }); + let selectedStation = stationSelect.value; + stationSelect.addEventListener('change', () => (selectedStation = stationSelect.value)); + const orderInput = createNumberInput(); + const submitBtn = createSubmitBtn(T.submitId, T.submitText); + submitBtn.addEventListener('click', () => addToSection(line, selectedStation, orderInput)); + selectArea.append(stationSelect, orderInput, submitBtn); + app.append(selectArea); +}; + +const createNumberInput = () => { const orderInput = document.createElement('input'); orderInput.type = 'number'; orderInput.setAttribute('id', T.orderInputId); orderInput.setAttribute('placholder', T.placeholder); - const submitBtn = createSubmitBtn(T.submitId, T.submitText); - submitBtn.addEventListener('click', () => addToSection(line, selectedStation, orderInput)); - - [stationSelect, orderInput, submitBtn].map(elem => { - selectArea.appendChild(elem); - }); - - app.appendChild(selectArea); + return orderInput; }; const addToSection = (line, station, orderInput) => { @@ -101,7 +98,6 @@ const addToSection = (line, station, orderInput) => { const currLines = getLocalStorage(STORAGE_KEY_LINE); const currStations = currLines[line]; - console.log(currStations); currStations.splice(order, 0, station); const updatedLines = currLines; @@ -121,15 +117,15 @@ const createResultArea = line => { const sectionTableHeaders = [T.tableHeader1, T.tableHeader2, T.tableHeader3]; const sectionTable = createTable(T.tableId, sectionTableHeaders); sectionTable.style.marginTop = '20px'; - app.appendChild(sectionTable); + app.append(sectionTable); - const currLines = getLocalStorage(STORAGE_KEY_LINE); - if (currLines) { - const currStations = currLines[line]; - addTableData(sectionTable, line, currStations); + const lines = getLocalStorage(STORAGE_KEY_LINE); + if (lines) { + const stations = lines[line]; + addTableData(sectionTable, line, stations); } - app.appendChild(sectionTable); + app.append(sectionTable); }; const addTableData = (table, line, stations) => { @@ -142,39 +138,42 @@ const addTableData = (table, line, stations) => { indexData.innerHTML = idx; const nameData = document.createElement('td'); nameData.innerHTML = station; - const deleteBtn = document.createElement('button'); - deleteBtn.setAttribute('class', T.deleteBtnClass); - deleteBtn.innerHTML = T.deleteBtnText; - deleteBtn.addEventListener('click', () => deleteStation(station, line)); - - tableRow.appendChild(indexData); - tableRow.appendChild(nameData); - tableRow.appendChild(deleteBtn); + const deleteBtn = createDeleteBtn(station, line); - table.appendChild(tableRow); + tableRow.append(indexData, nameData, deleteBtn); + table.append(tableRow); }); }; +const createDeleteBtn = (station, line) => { + const deleteBtn = document.createElement('button'); + deleteBtn.setAttribute('class', T.deleteBtnClass); + deleteBtn.innerHTML = T.deleteBtnText; + deleteBtn.addEventListener('click', () => deleteStation(station, line)); + + return deleteBtn; +}; + const deleteStation = (station, line) => { - const sectionTable = document.getElementById(T.tableId); const currLines = getLocalStorage(STORAGE_KEY_LINE); - const currStations = currLines[line]; + const currStations = getLocalStorage(STORAGE_KEY_LINE)[line]; - if (currStations.length <= 2) { - alert(T.alertStationsUnderTwo); - return; - } + if (!isAbleToDelete(currStations)) return; if (confirm(T.alertConfirmDelete)) { currStations.splice(currStations.indexOf(station), 1); const updatedLines = currLines; updatedLines[line] = currStations; setLocalStorage(STORAGE_KEY_LINE, updatedLines); - - const rowToBeDeleted = sectionTable.querySelector(`[data-station=${station}]`); - sectionTable.removeChild(rowToBeDeleted); - removeCurrResult(); createResultArea(line); } }; + +const isAbleToDelete = stations => { + if (stations.length <= 2) { + alert(T.alertStationsUnderTwo); + return false; + } + return true; +}; diff --git a/src/stationManager.js b/src/stationManager.js index de31c7fac..266a4623b 100644 --- a/src/stationManager.js +++ b/src/stationManager.js @@ -4,6 +4,8 @@ import { stationText as T } from './constants.js'; const app = document.getElementById('app'); const STORAGE_KEY_STATION = 'stations'; +const DATA_KEY_STATION = 'station'; +const STORAGE_KEY_LINE = 'lines'; export const initStationManager = () => { clearPage(); @@ -19,34 +21,34 @@ const createPage = () => { const handleSubmit = submitBtn => { const inputArea = document.getElementById(T.inputContainer); - inputArea.appendChild(submitBtn); + inputArea.append(submitBtn); const inputText = document.getElementById(T.inputId); inputText.addEventListener('keypress', e => { - let name = inputText.value; if (e.key === 'Enter') { - addStation(name, inputText); + addStation(inputText.value); + inputText.value = ''; } }); submitBtn.addEventListener('click', () => { - let name = inputText.value; - addStation(name, inputText); + addStation(inputText.value); + inputText.value = ''; }); }; -const addStation = (name, nameInput) => { +const addStation = name => { if (!validateName(name)) return; - nameInput.value = ''; + const currStations = getLocalStorage(STORAGE_KEY_STATION); const updatedStations = currStations ? [...currStations, name] : [name]; setLocalStorage(STORAGE_KEY_STATION, updatedStations); - addTable(name); + addToTable(name); }; const validateName = name => { - const currStations = getLocalStorage(STORAGE_KEY_STATION); - if (currStations && currStations.includes(name)) { + const stations = getLocalStorage(STORAGE_KEY_STATION); + if (stations && stations.includes(name)) { alert(T.alertDuplicateName); return false; } else if (name.length < 2) { @@ -59,7 +61,6 @@ const validateName = name => { const createResultArea = () => { const tableName = document.createElement('h2'); tableName.innerHTML = T.resultTitle; - app.appendChild(tableName); const stationTableHeaders = [T.tableHeader1, T.tableHeader2]; const stationTable = createTable(T.tableId, stationTableHeaders); @@ -69,44 +70,40 @@ const createResultArea = () => { addTableData(stationTable, stations); } - app.appendChild(stationTable); + app.append(tableName, stationTable); }; const addTableData = (table, stations) => { stations.map(station => { - const tableRow = document.createElement('tr'); - tableRow.dataset['station'] = station; - const nameData = document.createElement('td'); - nameData.innerHTML = station; - - const deleteBtn = document.createElement('button'); - deleteBtn.setAttribute('class', T.deleteBtnClass); - deleteBtn.innerHTML = T.deleteBtnText; - deleteBtn.addEventListener('click', () => deleteStation(station)); + const tableRow = addTableRow(station); + table.append(tableRow); + }); +}; - tableRow.appendChild(nameData); - tableRow.appendChild(deleteBtn); +const addTableRow = station => { + const tableRow = document.createElement('tr'); + tableRow.dataset[DATA_KEY_STATION] = station; + const nameData = document.createElement('td'); + nameData.innerHTML = station; + const deleteBtn = createDeleteBtn(station); - table.appendChild(tableRow); - }); + tableRow.append(nameData, deleteBtn); + return tableRow; }; -const addTable = name => { +const addToTable = name => { const stationTable = document.getElementById(T.tableId); - const newRow = document.createElement('tr'); - newRow.dataset['station'] = name; - const newData = document.createElement('td'); - newData.innerHTML = name; + const newRow = addTableRow(name); + stationTable.append(newRow); +}; +const createDeleteBtn = station => { const deleteBtn = document.createElement('button'); deleteBtn.setAttribute('class', T.deleteBtnClass); deleteBtn.innerHTML = T.deleteBtnText; - deleteBtn.addEventListener('click', () => deleteStation(name)); - - newRow.appendChild(newData); - newRow.appendChild(deleteBtn); + deleteBtn.addEventListener('click', () => deleteStation(station)); - stationTable.appendChild(newRow); + return deleteBtn; }; const deleteStation = name => { @@ -115,7 +112,7 @@ const deleteStation = name => { const currStations = getLocalStorage(STORAGE_KEY_STATION); const updatedStations = currStations.filter(station => station !== name); setLocalStorage(STORAGE_KEY_STATION, updatedStations); - const rowToBeDeleted = stationTable.querySelector(`[data-station=${name}]`); + const rowToBeDeleted = stationTable.querySelector(`[data-${DATA_KEY_STATION}=${name}]`); stationTable.removeChild(rowToBeDeleted); } }; diff --git a/src/utils.js b/src/utils.js index 99e77edd9..9f4a300ab 100644 --- a/src/utils.js +++ b/src/utils.js @@ -18,11 +18,8 @@ export const createTextInput = (labelName, inputId, placeHolder) => { inputText.setAttribute('id', inputId); inputText.setAttribute('placeholder', placeHolder); - inputArea.appendChild(inputLabel); - inputArea.appendChild(document.createElement('br')); - inputArea.appendChild(inputText); - - app.appendChild(inputArea); + inputArea.append(inputLabel, document.createElement('br'), inputText); + app.append(inputArea); }; export const createSubmitBtn = (btnId, btnText) => { @@ -33,14 +30,18 @@ export const createSubmitBtn = (btnId, btnText) => { return submitBtn; }; -export const createSelectbox = (select, selectorId, options) => { +export const createSelectbox = (selectorId, options) => { + const select = document.createElement('select'); select.setAttribute('id', selectorId); + options.map(val => { const option = document.createElement('option'); option.value = val; option.text = val; select.options.add(option); }); + + return select; }; export const createTable = (tableId, tableHeaders) => { @@ -51,7 +52,7 @@ export const createTable = (tableId, tableHeaders) => { tableHeaders.map(tableHeader => { const header = document.createElement('th'); header.innerHTML = tableHeader; - table.appendChild(header); + table.append(header); }); return table; From 175a216973b691447f23d38eec6c39c27be89af0 Mon Sep 17 00:00:00 2001 From: zigsong Date: Tue, 15 Dec 2020 11:46:26 +0900 Subject: [PATCH 31/35] feat: error handling when delete station in line --- docs/README.md | 1 + src/constants.js | 1 + src/stationManager.js | 13 +++++++++++++ 3 files changed, 15 insertions(+) diff --git a/docs/README.md b/docs/README.md index 9c3d0dd19..a72e0ed60 100644 --- a/docs/README.md +++ b/docs/README.md @@ -21,3 +21,4 @@ - [X] **구간** 구간 종점 삭제 시 다음 역을 종점으로 - [X] **구간** 노선 포함 역 2개 이하면 제거 불가 - [X] 노선에 등록된 역 목록 조회 +- [X] (추가)**역** 노선에 등록된 역 삭제 불가 diff --git a/src/constants.js b/src/constants.js index c21701396..44439c4fb 100644 --- a/src/constants.js +++ b/src/constants.js @@ -13,6 +13,7 @@ export const stationText = { tableId: 'station-table', deleteBtnClass: 'station-delete-button', deleteBtnText: '삭제', + alertStationInLine: '노선에 등록된 역은 삭제할 수 없습니다.', alertConfirmDelete: '정말 삭제하시겠습니까?', }; diff --git a/src/stationManager.js b/src/stationManager.js index 266a4623b..a2038daf7 100644 --- a/src/stationManager.js +++ b/src/stationManager.js @@ -107,6 +107,8 @@ const createDeleteBtn = station => { }; const deleteStation = name => { + if (!isAbleToDelete(name)) return; + if (confirm(T.alertConfirmDelete)) { const stationTable = document.getElementById(T.tableId); const currStations = getLocalStorage(STORAGE_KEY_STATION); @@ -116,3 +118,14 @@ const deleteStation = name => { stationTable.removeChild(rowToBeDeleted); } }; + +const isAbleToDelete = name => { + const lines = getLocalStorage(STORAGE_KEY_LINE); + for (let stations of Object.values(lines)) { + if (stations.includes(name)) { + alert(T.alertStationInLine); + return false; + } + } + return true; +}; From 42edf47e837fa2ecc5c841f53d6cca936add3d57 Mon Sep 17 00:00:00 2001 From: zigsong Date: Tue, 15 Dec 2020 20:42:15 +0900 Subject: [PATCH 32/35] refactor: change constant names to uppercase --- src/constants.js | 110 +++++++++++++++++++++--------------------- src/lineManager.js | 34 ++++++------- src/mapManager.js | 2 +- src/sectionManager.js | 40 +++++++-------- src/stationManager.js | 30 ++++++------ 5 files changed, 108 insertions(+), 108 deletions(-) diff --git a/src/constants.js b/src/constants.js index 44439c4fb..231fdadfe 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1,66 +1,66 @@ export const stationText = { - inputLabel: '역 이름', - inputId: 'station-name-input', - placeholder: '역 이름을 입력해주세요', - submitId: 'station-add-button', - submitText: '역 추가', - inputContainer: 'input-container', - alertDuplicateName: '중복된 역 이름이 존재합니다.', - alertNameUnderTwo: '역 이름을 2자 이상으로 입력해 주세요.', - resultTitle: '🚉 지하철 역 목록', - tableHeader1: '역 이름', - tableHeader2: '설정', - tableId: 'station-table', - deleteBtnClass: 'station-delete-button', - deleteBtnText: '삭제', - alertStationInLine: '노선에 등록된 역은 삭제할 수 없습니다.', - alertConfirmDelete: '정말 삭제하시겠습니까?', + INPUT_LABEL: '역 이름', + INPUT_ID: 'station-name-input', + PLACEHOLDER: '역 이름을 입력해주세요', + SUBMIT_ID: 'station-add-button', + SUBMIT_TEXT: '역 추가', + INPUT_CONTAINER: 'input-container', + ALERT_DUPLICATE_NAME: '중복된 역 이름이 존재합니다.', + ALERT_NAME_UNDER_TWO: '역 이름을 2자 이상으로 입력해 주세요.', + RESULT_TITLE: '🚉 지하철 역 목록', + TABLE_HEADER_1: '역 이름', + TABLE_HEADER_2: '설정', + TABLE_ID: 'station-table', + DELETE_BTN_CLASS: 'station-delete-button', + DELETE_BTN_TEXT: '삭제', + ALERT_STATION_IN_LINE: '노선에 등록된 역은 삭제할 수 없습니다.', + ALERT_CONFIRM_DELETE: '정말 삭제하시겠습니까?', }; export const lineText = { - inputLabel: '노선 이름', - inputId: 'line-name-input', - placeholder: '노선 이름을 입력해주세요', - submitId: 'line-add-button', - submitText: '노선 추가', - startSelectorId: 'line-start-station-selector', - startSelectorText: '상행 종점', - endSelectorId: 'line-end-station-selector', - endSelectorText: '하행 종점', - alertDuplicateName: '중복된 노선 이름이 존재합니다.', - resultTitle: '🚉 지하철 노선 목록', - tableHeader1: '노선 이름', - tableHeader2: '상행 종점역', - tableHeader3: '하행 종점역', - tableHeader4: '설정', - tableId: 'line-table', - deleteBtnClass: 'line-delete-button', - deleteBtnText: '삭제', - alertConfirmDelete: '정말 삭제하시겠습니까?', + INPUT_LABEL: '노선 이름', + INPUT_ID: 'line-name-input', + PLACEHOLDER: '노선 이름을 입력해주세요', + SUBMIT_ID: 'line-add-button', + SUBMIT_TEXT: '노선 추가', + START_SELECTOR_ID: 'line-start-station-selector', + START_SELECTOR_TEXT: '상행 종점', + END_SELECTOR_ID: 'line-end-station-selector', + END_SELECTOR_TEXT: '하행 종점', + ALERT_DUPLICATE_NAME: '중복된 노선 이름이 존재합니다.', + RESULT_TITLE: '🚉 지하철 노선 목록', + TABLE_HEADER_1: '노선 이름', + TABLE_HEADER_2: '상행 종점역', + TABLE_HEADER_3: '하행 종점역', + TABLE_HEADER_4: '설정', + TABLE_ID: 'line-table', + DELETE_BTN_CLASS: 'line-delete-button', + DELETE_BTN_TEXT: '삭제', + ALERT_CONFIRM_DELETE: '정말 삭제하시겠습니까?', }; export const sectionText = { - guideText: '구간을 수정할 노선을 선택해주세요.', - menuButtonsClass: 'section-line-menu-button', - inputId: 'section-input', - selectAreaId: 'section-select', - tableId: 'section-table', - manageText: '관리', - registerText: '구간 등록', - selectorId: 'section-station-selector', - orderInputId: 'section-order-input', - placeholder: '순서', - submitId: 'section-add-button', - submitText: '등록', - tableHeader1: '순서', - tableHeader2: '이름', - tableHeader3: '설정', - deleteBtnClass: 'section-delete-button', - deleteBtnText: '노선에서 제거', - alertStationsUnderTwo: '노선에 포함된 역이 2개 이하일 때는 역을 삭제할 수 없습니다.', - alertConfirmDelete: '정말 삭제하시겠습니까?', + GUIDE_TEXT: '구간을 수정할 노선을 선택해주세요.', + MENU_BUTTON_CLASS: 'section-line-menu-button', + INPUT_ID: 'section-input', + SELECT_AREA_ID: 'section-select', + TABLE_ID: 'section-table', + MANAGE_TEXT: '관리', + REGISTER_TEXT: '구간 등록', + SELECTOR_ID: 'section-station-selector', + ORDER_INPUT_ID: 'section-order-input', + PLACEHOLDER: '순서', + SUBMIT_ID: 'section-add-button', + SUBMIT_TEXT: '등록', + TABLE_HEADER_1: '순서', + TABLE_HEADER_2: '이름', + TABLE_HEADER_3: '설정', + DELETE_BTN_CLASS: 'section-delete-button', + DELETE_BTN_TEXT: '노선에서 제거', + ALERT_STATION_UNDER_TWO: '노선에 포함된 역이 2개 이하일 때는 역을 삭제할 수 없습니다.', + ALERT_CONFIRM_DELETE: '정말 삭제하시겠습니까?', }; export const mapText = { - resultAreaClass: 'map', + RESULT_AREA_CLASS: 'map', }; diff --git a/src/lineManager.js b/src/lineManager.js index 7642b0d02..9905efcfc 100644 --- a/src/lineManager.js +++ b/src/lineManager.js @@ -19,9 +19,9 @@ export const initLineManager = () => { }; const createPage = () => { - createTextInput(T.inputLabel, T.inputId, T.placeholder); + createTextInput(T.INPUT_LABEL, T.INPUT_ID, T.PLACEHOLDER); createSelectArea(); - const submitBtn = createSubmitBtn(T.submitId, T.submitText); + const submitBtn = createSubmitBtn(T.SUBMIT_ID, T.SUBMIT_TEXT); handleSubmit(submitBtn); createResultArea(); }; @@ -30,13 +30,13 @@ const createSelectArea = () => { const selectArea = document.createElement('div'); const stations = getLocalStorage(STORAGE_KEY_STATION); - const upwardSelect = createSelectbox(T.startSelectorId, stations); + const upwardSelect = createSelectbox(T.START_SELECTOR_ID, stations); const upwardLabel = document.createElement('b'); - upwardLabel.innerHTML = T.startSelectorText; + upwardLabel.innerHTML = T.START_SELECTOR_TEXT; - const downwardSelect = createSelectbox(T.endSelectorId, stations); + const downwardSelect = createSelectbox(T.END_SELECTOR_ID, stations); const downwardLabel = document.createElement('b'); - downwardLabel.innerHTML = T.endSelectorText; + downwardLabel.innerHTML = T.END_SELECTOR_TEXT; selectArea.append(upwardLabel, upwardSelect, document.createElement('br')); selectArea.append(downwardLabel, downwardSelect); @@ -47,9 +47,9 @@ const createSelectArea = () => { const handleSubmit = submitBtn => { app.append(document.createElement('br'), submitBtn); - const inputText = document.getElementById(T.inputId); - const upwardSelect = document.getElementById(T.startSelectorId); - const downwardSelect = document.getElementById(T.endSelectorId); + const inputText = document.getElementById(T.INPUT_ID); + const upwardSelect = document.getElementById(T.START_SELECTOR_ID); + const downwardSelect = document.getElementById(T.END_SELECTOR_ID); let startStation = upwardSelect.value; let endStation = downwardSelect.value; @@ -75,7 +75,7 @@ const addLine = (line, start, end) => { const validateName = lineName => { const lines = getLocalStorage(STORAGE_KEY_LINE); if (lines && Object.keys(lines).includes(lineName)) { - alert(T.alertDuplicateName); + alert(T.ALERT_DUPLICATE_NAME); return false; } return true; @@ -83,11 +83,11 @@ const validateName = lineName => { const createResultArea = () => { const tableName = document.createElement('h2'); - tableName.innerHTML = T.resultTitle; + tableName.innerHTML = T.RESULT_TITLE; app.append(tableName); - const lineTableHeaders = [T.tableHeader1, T.tableHeader2, T.tableHeader3, T.tableHeader4]; - const lineTable = createTable(T.tableId, lineTableHeaders); + const lineTableHeaders = [T.TABLE_HEADER_1, T.TABLE_HEADER_2, T.TABLE_HEADER_3, T.TABLE_HEADER_4]; + const lineTable = createTable(T.TABLE_ID, lineTableHeaders); const lines = getLocalStorage(STORAGE_KEY_LINE); if (lines) { addTableData(lineTable, lines); @@ -120,22 +120,22 @@ const addTableRow = (line, upwardEnd, downwardEnd) => { }; const addToTable = (line, start, end) => { - const lineTable = document.getElementById(T.tableId); + const lineTable = document.getElementById(T.TABLE_ID); const newRow = addTableRow(line, start, end); lineTable.append(newRow); }; const createDeleteBtn = line => { const deleteBtn = document.createElement('button'); - deleteBtn.setAttribute('class', T.deleteBtnClass); - deleteBtn.innerHTML = T.deleteBtnText; + deleteBtn.setAttribute('class', T.DELETE_BTN_CLASS); + deleteBtn.innerHTML = T.DELETE_BTN_TEXT; deleteBtn.addEventListener('click', () => deleteLine(line)); return deleteBtn; }; const deleteLine = line => { - if (confirm(T.alertConfirmDelete)) { + if (confirm(T.ALERT_CONFIRM_DELETE)) { const lineTable = document.getElementById(T.tableId); const currLines = getLocalStorage(STORAGE_KEY_LINE); delete currLines[line]; diff --git a/src/mapManager.js b/src/mapManager.js index 0ec15c5db..28047022d 100644 --- a/src/mapManager.js +++ b/src/mapManager.js @@ -12,7 +12,7 @@ export const initMapManager = () => { const createResultArea = () => { const resultArea = document.createElement('div'); - resultArea.setAttribute('class', T.resultAreaClass); + resultArea.setAttribute('class', T.RESULT_AREA_CLASS); const lines = getLocalStorage(STORAGE_KEY_LINE); if (lines) { diff --git a/src/sectionManager.js b/src/sectionManager.js index 79c6d9429..f01e6321e 100644 --- a/src/sectionManager.js +++ b/src/sectionManager.js @@ -14,7 +14,7 @@ export const initSectionManager = () => { const printGuideText = () => { const sectionHeader = document.createElement('div'); const sectionTitle = document.createElement('h3'); - sectionTitle.innerText = T.guideText; + sectionTitle.innerText = T.GUIDE_TEXT; sectionHeader.append(sectionTitle); createMenuButtons(sectionHeader); @@ -26,7 +26,7 @@ const createMenuButtons = sectionHeader => { if (lines) { Object.keys(lines).map(line => { const menuBtn = document.createElement('button'); - menuBtn.setAttribute('class', T.menuButtonsClass); + menuBtn.setAttribute('class', T.MENU_BUTTON_CLASS); menuBtn.innerHTML = line; menuBtn.style.margin = '2px'; menuBtn.addEventListener('click', () => { @@ -40,9 +40,9 @@ const createMenuButtons = sectionHeader => { }; const clearInputs = () => { - const sectionInputArea = document.getElementById(T.inputId); - const selectArea = document.getElementById(T.selectAreaId); - const sectionTable = document.getElementById(T.tableId); + const sectionInputArea = document.getElementById(T.INPUT_ID); + const selectArea = document.getElementById(T.SELECT_AREA_ID); + const sectionTable = document.getElementById(T.TABLE_ID); if (sectionInputArea && selectArea && sectionTable) { app.removeChild(sectionInputArea); @@ -53,12 +53,12 @@ const clearInputs = () => { const createPage = line => { const sectionInputArea = document.createElement('div'); - sectionInputArea.setAttribute('id', T.inputId); + sectionInputArea.setAttribute('id', T.INPUT_ID); const manageTitle = document.createElement('h3'); - manageTitle.innerHTML = `${line} ${T.manageText}`; + manageTitle.innerHTML = `${line} ${T.MANAGE_TEXT}`; const registerTitle = document.createElement('b'); - registerTitle.innerHTML = T.registerText; + registerTitle.innerHTML = T.REGISTER_TEXT; sectionInputArea.append(manageTitle, registerTitle); app.append(sectionInputArea); @@ -68,15 +68,15 @@ const createPage = line => { const createSelectArea = line => { const selectArea = document.createElement('div'); - selectArea.setAttribute('id', T.selectAreaId); + selectArea.setAttribute('id', T.SELECTOR_ID); const stations = getLocalStorage(STORAGE_KEY_STATION); - const stationSelect = createSelectbox(T.selectorId, stations); + const stationSelect = createSelectbox(T.SELECTOR_ID, stations); let selectedStation = stationSelect.value; stationSelect.addEventListener('change', () => (selectedStation = stationSelect.value)); const orderInput = createNumberInput(); - const submitBtn = createSubmitBtn(T.submitId, T.submitText); + const submitBtn = createSubmitBtn(T.SUBMIT_ID, T.SUBMIT_TEXT); submitBtn.addEventListener('click', () => addToSection(line, selectedStation, orderInput)); selectArea.append(stationSelect, orderInput, submitBtn); @@ -86,8 +86,8 @@ const createSelectArea = line => { const createNumberInput = () => { const orderInput = document.createElement('input'); orderInput.type = 'number'; - orderInput.setAttribute('id', T.orderInputId); - orderInput.setAttribute('placholder', T.placeholder); + orderInput.setAttribute('id', T.ORDER_INPUT_ID); + orderInput.setAttribute('placholder', T.PLACEHOLDER); return orderInput; }; @@ -109,13 +109,13 @@ const addToSection = (line, station, orderInput) => { }; const removeCurrResult = () => { - const sectionTable = document.getElementById(T.tableId); + const sectionTable = document.getElementById(T.TABLE_ID); app.removeChild(sectionTable); }; const createResultArea = line => { - const sectionTableHeaders = [T.tableHeader1, T.tableHeader2, T.tableHeader3]; - const sectionTable = createTable(T.tableId, sectionTableHeaders); + const sectionTableHeaders = [T.TABLE_HEADER_1, T.TABLE_HEADER_2, T.TABLE_HEADER_3]; + const sectionTable = createTable(T.TABLE_ID, sectionTableHeaders); sectionTable.style.marginTop = '20px'; app.append(sectionTable); @@ -147,8 +147,8 @@ const addTableData = (table, line, stations) => { const createDeleteBtn = (station, line) => { const deleteBtn = document.createElement('button'); - deleteBtn.setAttribute('class', T.deleteBtnClass); - deleteBtn.innerHTML = T.deleteBtnText; + deleteBtn.setAttribute('class', T.DELETE_BTN_CLASS); + deleteBtn.innerHTML = T.DELETE_BTN_TEXT; deleteBtn.addEventListener('click', () => deleteStation(station, line)); return deleteBtn; @@ -160,7 +160,7 @@ const deleteStation = (station, line) => { if (!isAbleToDelete(currStations)) return; - if (confirm(T.alertConfirmDelete)) { + if (confirm(T.ALERT_CONFIRM_DELETE)) { currStations.splice(currStations.indexOf(station), 1); const updatedLines = currLines; updatedLines[line] = currStations; @@ -172,7 +172,7 @@ const deleteStation = (station, line) => { const isAbleToDelete = stations => { if (stations.length <= 2) { - alert(T.alertStationsUnderTwo); + alert(T.ALERT_STATION_UNDER_TWO); return false; } return true; diff --git a/src/stationManager.js b/src/stationManager.js index a2038daf7..65a810e83 100644 --- a/src/stationManager.js +++ b/src/stationManager.js @@ -13,16 +13,16 @@ export const initStationManager = () => { }; const createPage = () => { - createTextInput(T.inputLabel, T.inputId, T.placeholder); - const submitBtn = createSubmitBtn(T.submitId, T.submitText); + createTextInput(T.INPUT_LABEL, T.INPUT_ID, T.PLACEHOLDER); + const submitBtn = createSubmitBtn(T.SUBMIT_ID, T.SUBMIT_TEXT); handleSubmit(submitBtn); createResultArea(); }; const handleSubmit = submitBtn => { - const inputArea = document.getElementById(T.inputContainer); + const inputArea = document.getElementById(T.INPUT_CONTAINER); inputArea.append(submitBtn); - const inputText = document.getElementById(T.inputId); + const inputText = document.getElementById(T.INPUT_ID); inputText.addEventListener('keypress', e => { if (e.key === 'Enter') { @@ -49,10 +49,10 @@ const addStation = name => { const validateName = name => { const stations = getLocalStorage(STORAGE_KEY_STATION); if (stations && stations.includes(name)) { - alert(T.alertDuplicateName); + alert(T.ALERT_DUPLICATE_NAME); return false; } else if (name.length < 2) { - alert(T.alertNameUnderTwo); + alert(T.ALERT_NAME_UNDER_TWO); return false; } return true; @@ -60,10 +60,10 @@ const validateName = name => { const createResultArea = () => { const tableName = document.createElement('h2'); - tableName.innerHTML = T.resultTitle; + tableName.innerHTML = T.RESULT_TITLE; - const stationTableHeaders = [T.tableHeader1, T.tableHeader2]; - const stationTable = createTable(T.tableId, stationTableHeaders); + const stationTableHeaders = [T.TABLE_HEADER_1, T.TABLE_HEADER_2]; + const stationTable = createTable(T.TABLE_ID, stationTableHeaders); const stations = getLocalStorage(STORAGE_KEY_STATION); if (stations) { @@ -92,15 +92,15 @@ const addTableRow = station => { }; const addToTable = name => { - const stationTable = document.getElementById(T.tableId); + const stationTable = document.getElementById(T.TABLE_ID); const newRow = addTableRow(name); stationTable.append(newRow); }; const createDeleteBtn = station => { const deleteBtn = document.createElement('button'); - deleteBtn.setAttribute('class', T.deleteBtnClass); - deleteBtn.innerHTML = T.deleteBtnText; + deleteBtn.setAttribute('class', T.DELETE_BTN_CLASS); + deleteBtn.innerHTML = T.DELETE_BTN_TEXT; deleteBtn.addEventListener('click', () => deleteStation(station)); return deleteBtn; @@ -109,8 +109,8 @@ const createDeleteBtn = station => { const deleteStation = name => { if (!isAbleToDelete(name)) return; - if (confirm(T.alertConfirmDelete)) { - const stationTable = document.getElementById(T.tableId); + if (confirm(T.ALERT_CONFIRM_DELETE)) { + const stationTable = document.getElementById(T.TABLE_ID); const currStations = getLocalStorage(STORAGE_KEY_STATION); const updatedStations = currStations.filter(station => station !== name); setLocalStorage(STORAGE_KEY_STATION, updatedStations); @@ -123,7 +123,7 @@ const isAbleToDelete = name => { const lines = getLocalStorage(STORAGE_KEY_LINE); for (let stations of Object.values(lines)) { if (stations.includes(name)) { - alert(T.alertStationInLine); + alert(T.ALERT_STATION_IN_LINE); return false; } } From 7926f95dcbefa113ae138340813ef13291317b4b Mon Sep 17 00:00:00 2001 From: zigsong Date: Tue, 15 Dec 2020 20:53:10 +0900 Subject: [PATCH 33/35] fix: handle error about id name in sectionManager --- src/constants.js | 1 - src/sectionManager.js | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/constants.js b/src/constants.js index 231fdadfe..9ef11a37a 100644 --- a/src/constants.js +++ b/src/constants.js @@ -43,7 +43,6 @@ export const sectionText = { GUIDE_TEXT: '구간을 수정할 노선을 선택해주세요.', MENU_BUTTON_CLASS: 'section-line-menu-button', INPUT_ID: 'section-input', - SELECT_AREA_ID: 'section-select', TABLE_ID: 'section-table', MANAGE_TEXT: '관리', REGISTER_TEXT: '구간 등록', diff --git a/src/sectionManager.js b/src/sectionManager.js index f01e6321e..5c64f5b8e 100644 --- a/src/sectionManager.js +++ b/src/sectionManager.js @@ -40,8 +40,9 @@ const createMenuButtons = sectionHeader => { }; const clearInputs = () => { + console.log('clear inputs!'); const sectionInputArea = document.getElementById(T.INPUT_ID); - const selectArea = document.getElementById(T.SELECT_AREA_ID); + const selectArea = document.getElementById(T.SELECTOR_ID); const sectionTable = document.getElementById(T.TABLE_ID); if (sectionInputArea && selectArea && sectionTable) { From e019c017f5da0bd862d8ada54328e3aeab8d3afe Mon Sep 17 00:00:00 2001 From: zigsong Date: Tue, 15 Dec 2020 21:00:45 +0900 Subject: [PATCH 34/35] feat: error handling order input in sectionManager --- src/constants.js | 2 ++ src/sectionManager.js | 14 +++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/constants.js b/src/constants.js index 9ef11a37a..8ed8f643d 100644 --- a/src/constants.js +++ b/src/constants.js @@ -56,6 +56,8 @@ export const sectionText = { TABLE_HEADER_3: '설정', DELETE_BTN_CLASS: 'section-delete-button', DELETE_BTN_TEXT: '노선에서 제거', + ALERT_NEGATIVE_ORDER: '0보다 큰 순서를 입력해 주세요.', + ALERT_OVERLOAD_ORDER: '노선 범위에 포함되는 순서를 입력해 주세요.', ALERT_STATION_UNDER_TWO: '노선에 포함된 역이 2개 이하일 때는 역을 삭제할 수 없습니다.', ALERT_CONFIRM_DELETE: '정말 삭제하시겠습니까?', }; diff --git a/src/sectionManager.js b/src/sectionManager.js index 5c64f5b8e..32a2cebb9 100644 --- a/src/sectionManager.js +++ b/src/sectionManager.js @@ -40,7 +40,6 @@ const createMenuButtons = sectionHeader => { }; const clearInputs = () => { - console.log('clear inputs!'); const sectionInputArea = document.getElementById(T.INPUT_ID); const selectArea = document.getElementById(T.SELECTOR_ID); const sectionTable = document.getElementById(T.TABLE_ID); @@ -95,6 +94,7 @@ const createNumberInput = () => { const addToSection = (line, station, orderInput) => { const order = orderInput.value; + if (!validateOrder(line, order)) return; orderInput.value = ''; const currLines = getLocalStorage(STORAGE_KEY_LINE); @@ -109,6 +109,18 @@ const addToSection = (line, station, orderInput) => { createResultArea(line); }; +const validateOrder = (line, order) => { + const lines = getLocalStorage(STORAGE_KEY_LINE); + if (order < 0) { + alert(T.ALERT_NEGATIVE_ORDER); + return false; + } else if (order > lines[line].length) { + alert(T.ALERT_OVERLOAD_ORDER); + return false; + } + return true; +}; + const removeCurrResult = () => { const sectionTable = document.getElementById(T.TABLE_ID); app.removeChild(sectionTable); From 78564e4c57d96c546e6634d7b17a62af40abb18a Mon Sep 17 00:00:00 2001 From: zigsong Date: Tue, 15 Dec 2020 21:15:00 +0900 Subject: [PATCH 35/35] refactor: separate directories --- src/Station.js | 5 ----- src/index.js | 8 ++++---- src/{ => managers}/lineManager.js | 8 ++++---- src/{ => managers}/mapManager.js | 6 +++--- src/{ => managers}/sectionManager.js | 6 +++--- src/{ => managers}/stationManager.js | 6 +++--- src/{ => utils}/constants.js | 0 src/{ => utils}/storage.js | 0 src/{ => utils}/utils.js | 0 9 files changed, 17 insertions(+), 22 deletions(-) delete mode 100644 src/Station.js rename src/{ => managers}/lineManager.js (95%) rename src/{ => managers}/mapManager.js (85%) rename src/{ => managers}/sectionManager.js (97%) rename src/{ => managers}/stationManager.js (95%) rename src/{ => utils}/constants.js (100%) rename src/{ => utils}/storage.js (100%) rename src/{ => utils}/utils.js (100%) diff --git a/src/Station.js b/src/Station.js deleted file mode 100644 index 6a5883651..000000000 --- a/src/Station.js +++ /dev/null @@ -1,5 +0,0 @@ -export default class Station { - constructor(name) { - this.name = name; - } -} diff --git a/src/index.js b/src/index.js index 80489ef92..7f55a0144 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,7 @@ -import { initStationManager } from './stationManager.js'; -import { initLineManager } from './lineManager.js'; -import { initSectionManager } from './sectionManager.js'; -import { initMapManager } from './mapManager.js'; +import { initStationManager } from './managers/stationManager.js'; +import { initLineManager } from './managers/lineManager.js'; +import { initSectionManager } from './managers/sectionManager.js'; +import { initMapManager } from './managers/mapManager.js'; export default function SubwayMap() { const stationMngBtn = document.getElementById('station-manager-button'); diff --git a/src/lineManager.js b/src/managers/lineManager.js similarity index 95% rename from src/lineManager.js rename to src/managers/lineManager.js index 9905efcfc..afd0dd515 100644 --- a/src/lineManager.js +++ b/src/managers/lineManager.js @@ -4,9 +4,9 @@ import { createSubmitBtn, createSelectbox, createTable, -} from './utils.js'; -import { getLocalStorage, setLocalStorage } from './storage.js'; -import { lineText as T } from './constants.js'; +} from '../utils/utils.js'; +import { getLocalStorage, setLocalStorage } from '../utils/storage.js'; +import { lineText as T } from '../utils/constants.js'; const app = document.getElementById('app'); const STORAGE_KEY_STATION = 'stations'; @@ -136,7 +136,7 @@ const createDeleteBtn = line => { const deleteLine = line => { if (confirm(T.ALERT_CONFIRM_DELETE)) { - const lineTable = document.getElementById(T.tableId); + const lineTable = document.getElementById(T.TABLE_ID); const currLines = getLocalStorage(STORAGE_KEY_LINE); delete currLines[line]; setLocalStorage(STORAGE_KEY_LINE, currLines); diff --git a/src/mapManager.js b/src/managers/mapManager.js similarity index 85% rename from src/mapManager.js rename to src/managers/mapManager.js index 28047022d..314443806 100644 --- a/src/mapManager.js +++ b/src/managers/mapManager.js @@ -1,6 +1,6 @@ -import { clearPage } from './utils.js'; -import { getLocalStorage } from './storage.js'; -import { mapText as T } from './constants.js'; +import { clearPage } from '../utils/utils.js'; +import { getLocalStorage } from '../utils/storage.js'; +import { mapText as T } from '../utils/constants.js'; const app = document.getElementById('app'); const STORAGE_KEY_LINE = 'lines'; diff --git a/src/sectionManager.js b/src/managers/sectionManager.js similarity index 97% rename from src/sectionManager.js rename to src/managers/sectionManager.js index 32a2cebb9..6b773c34c 100644 --- a/src/sectionManager.js +++ b/src/managers/sectionManager.js @@ -1,6 +1,6 @@ -import { clearPage, createSubmitBtn, createSelectbox, createTable } from './utils.js'; -import { getLocalStorage, setLocalStorage } from './storage.js'; -import { sectionText as T } from './constants.js'; +import { clearPage, createSubmitBtn, createSelectbox, createTable } from '../utils/utils.js'; +import { getLocalStorage, setLocalStorage } from '../utils/storage.js'; +import { sectionText as T } from '../utils/constants.js'; const app = document.getElementById('app'); const STORAGE_KEY_STATION = 'stations'; diff --git a/src/stationManager.js b/src/managers/stationManager.js similarity index 95% rename from src/stationManager.js rename to src/managers/stationManager.js index 65a810e83..9bb177f05 100644 --- a/src/stationManager.js +++ b/src/managers/stationManager.js @@ -1,6 +1,6 @@ -import { clearPage, createSubmitBtn, createTextInput, createTable } from './utils.js'; -import { getLocalStorage, setLocalStorage } from './storage.js'; -import { stationText as T } from './constants.js'; +import { clearPage, createSubmitBtn, createTextInput, createTable } from '../utils/utils.js'; +import { getLocalStorage, setLocalStorage } from '../utils/storage.js'; +import { stationText as T } from '../utils/constants.js'; const app = document.getElementById('app'); const STORAGE_KEY_STATION = 'stations'; diff --git a/src/constants.js b/src/utils/constants.js similarity index 100% rename from src/constants.js rename to src/utils/constants.js diff --git a/src/storage.js b/src/utils/storage.js similarity index 100% rename from src/storage.js rename to src/utils/storage.js diff --git a/src/utils.js b/src/utils/utils.js similarity index 100% rename from src/utils.js rename to src/utils/utils.js