diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..600d2d33b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode \ No newline at end of file diff --git a/README.md b/README.md index e97a1d649..6bbf130cb 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,43 @@ # ๐Ÿš‡ ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ๋ฏธ์…˜ +## ๊ธฐ๋Šฅ ๊ตฌํ˜„ ๋ชฉ๋ก + +- [x] ๊ธฐ๋Šฅ ๊ตฌํ˜„ ๋ชฉ๋ก ์ž‘์„ฑ ๋ฐ code formatter ์„ค์ • +- [x] ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ ˆ์ด์•„์›ƒ ์žก๊ณ  ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ํ•ด๋‹น ๋‚ด์šฉ ๋ณด์—ฌ์ฃผ๊ธฐ +- [x] ์—ญ ๊ด€๋ฆฌ ๋ ˆ์ด์•„์›ƒ ์žก๊ธฐ +- [x] ์—ญ ์ถ”๊ฐ€ ๋ฐ ์‚ญ์ œ ํ•˜๊ธฐ(์˜ˆ์™ธ ์ƒํ™ฉ ์ฒ˜๋ฆฌ) +- [x] ๋…ธ์„  ๊ด€๋ฆฌ ๋ ˆ์ด์•„์›ƒ ์žก๊ธฐ +- [x] header ๋ชจ๋“ˆ ๋ถ„๋ฆฌํ•˜๊ธฐ +- [x] ์ƒํ–‰ ํ•˜ํ–‰ ์ข…์ ์— ์—ญ ๋ฆฌ์ŠคํŠธ ๋„ฃ๊ธฐ +- [x] ๋…ธ์„  ์ถ”๊ฐ€ ๋ฐ ์‚ญ์ œ ํ•˜๊ธฐ +- [x] ๊ตฌ๊ฐ„ ๊ด€๋ฆฌ ๋ ˆ์ด์•„์›ƒ ์žก๊ธฐ +- [x] ๊ตฌ๊ฐ„ ์„ ํƒ ํ•˜๊ธฐ +- [x] ๊ตฌ๊ฐ„ ๋“ฑ๋ก ๋ฐ ์ œ๊ฑฐ ํ•˜๊ธฐ +- [x] ์ƒ์ˆ˜ ์ •๋ฆฌํ•˜๊ธฐ +- [x] ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ์ถœ๋ ฅ ๋ ˆ์ด์•„์›ƒ ๋ฐ ๋ณด์—ฌ์ฃผ๊ธฐ +- [x] data ์†์„ฑ ์‚ฌ์šฉํ•˜์—ฌ ์œ ์ผํ•œ ๊ฐ’ ๋ถ€์—ฌํ•˜๊ธฐ +- [x] ๋…ธ์„  ์ด๋ฆ„ ๋น„์–ด์žˆ๋Š” ๊ฒฝ์šฐ ์˜ˆ์™ธ์ฒ˜๋ฆฌ + ## ๐Ÿš€ ๊ธฐ๋Šฅ ์š”๊ตฌ์‚ฌํ•ญ ### ์ง€ํ•˜์ฒ  ์—ญ ๊ด€๋ จ ๊ธฐ๋Šฅ + - ์ง€ํ•˜์ฒ  ์—ญ์„ ๋“ฑ๋กํ•˜๊ณ  ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๋‹ค. (๋‹จ, ๋…ธ์„ ์— ๋“ฑ๋ก๋œ ์—ญ์€ ์‚ญ์ œํ•  ์ˆ˜ ์—†๋‹ค) - ์ค‘๋ณต๋œ ์ง€ํ•˜์ฒ  ์—ญ ์ด๋ฆ„์ด ๋“ฑ๋ก๋  ์ˆ˜ ์—†๋‹ค. - ์ง€ํ•˜์ฒ  ์—ญ์€ 2๊ธ€์ž ์ด์ƒ์ด์–ด์•ผ ํ•œ๋‹ค. - ์ง€ํ•˜์ฒ  ์—ญ์˜ ๋ชฉ๋ก์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค. ### ์ง€ํ•˜์ฒ  ๋…ธ์„  ๊ด€๋ จ ๊ธฐ๋Šฅ + - ์ง€ํ•˜์ฒ  ๋…ธ์„ ์„ ๋“ฑ๋กํ•˜๊ณ  ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๋‹ค. - ์ค‘๋ณต๋œ ์ง€ํ•˜์ฒ  ๋…ธ์„  ์ด๋ฆ„์ด ๋“ฑ๋ก๋  ์ˆ˜ ์—†๋‹ค. - ๋…ธ์„  ๋“ฑ๋ก ์‹œ ์ƒํ–‰ ์ข…์ ์—ญ๊ณผ ํ•˜ํ–‰ ์ข…์ ์—ญ์„ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค. - ์ง€ํ•˜์ฒ  ๋…ธ์„ ์˜ ๋ชฉ๋ก์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค. ### ์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ + - ์ง€ํ•˜์ฒ  ๋…ธ์„ ์— ๊ตฌ๊ฐ„์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ธฐ๋Šฅ์€ ๋…ธ์„ ์— ์—ญ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ธฐ๋Šฅ์ด๋ผ๊ณ ๋„ ํ•  ์ˆ˜ ์žˆ๋‹ค. - - ์—ญ๊ณผ ์—ญ์‚ฌ์ด๋ฅผ ๊ตฌ๊ฐ„์ด๋ผ ํ•˜๊ณ  ์ด ๊ตฌ๊ฐ„๋“ค์˜ ๋ชจ์Œ์ด ๋…ธ์„ ์ด๋‹ค. + - ์—ญ๊ณผ ์—ญ์‚ฌ์ด๋ฅผ ๊ตฌ๊ฐ„์ด๋ผ ํ•˜๊ณ  ์ด ๊ตฌ๊ฐ„๋“ค์˜ ๋ชจ์Œ์ด ๋…ธ์„ ์ด๋‹ค. - ํ•˜๋‚˜์˜ ์—ญ์€ ์—ฌ๋Ÿฌ๊ฐœ์˜ ๋…ธ์„ ์— ์ถ”๊ฐ€๋  ์ˆ˜ ์žˆ๋‹ค. - ์—ญ๊ณผ ์—ญ ์‚ฌ์ด์— ์ƒˆ๋กœ์šด ์—ญ์ด ์ถ”๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค. - ๋…ธ์„ ์—์„œ ๊ฐˆ๋ž˜๊ธธ์€ ์ƒ๊ธธ ์ˆ˜ ์—†๋‹ค. @@ -24,6 +45,7 @@ ### ์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„ ์‚ญ์ œ ๊ธฐ๋Šฅ + - ๋…ธ์„ ์— ๋“ฑ๋ก๋œ ์—ญ์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค. - ์ข…์ ์„ ์ œ๊ฑฐํ•  ๊ฒฝ์šฐ ๋‹ค์Œ ์—ญ์ด ์ข…์ ์ด ๋œ๋‹ค. - ๋…ธ์„ ์— ํฌํ•จ๋œ ์—ญ์ด ๋‘๊ฐœ ์ดํ•˜์ผ ๋•Œ๋Š” ์—ญ์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์—†๋‹ค. @@ -31,6 +53,7 @@ ### ์ง€ํ•˜์ฒ  ๋…ธ์„ ์— ๋“ฑ๋ก๋œ ์—ญ ์กฐํšŒ ๊ธฐ๋Šฅ + - ๋…ธ์„ ์˜ ์ƒํ–‰ ์ข…์ ๋ถ€ํ„ฐ ํ•˜ํ–‰ ์ข…์ ๊นŒ์ง€ ์—ฐ๊ฒฐ๋œ ์ˆœ์„œ๋Œ€๋กœ ์—ญ ๋ชฉ๋ก์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค.
@@ -38,32 +61,38 @@ ## ๐Ÿ’ป ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ๊ฒฐ๊ณผ ### ์—ญ๊ด€๋ฆฌ + ### ๋…ธ์„ ๊ด€๋ฆฌ + ### ๊ตฌ๊ฐ„๊ด€๋ฆฌ + ### ๋…ธ์„ ๋„ ์ถœ๋ ฅ - + ## โœ… ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ์‚ฌํ•ญ ### ๋ฉ”๋‰ด ๋ฒ„ํŠผ + - ์—ญ ๊ด€๋ฆฌ button ํƒœ๊ทธ๋Š” `#station-manager-button` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - ๋…ธ์„  ๊ด€๋ฆฌ button ํƒœ๊ทธ๋Š” `#line-manager-button` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - ๊ตฌ๊ฐ„ ๊ด€๋ฆฌ button ํƒœ๊ทธ๋Š” `#section-manager-button` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ์ถœ๋ ฅ ๊ด€๋ฆฌ button ํƒœ๊ทธ๋Š” `#map-print-manager-button` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. ### ์ง€ํ•˜์ฒ  ์—ญ ๊ด€๋ จ ๊ธฐ๋Šฅ + - ์ง€ํ•˜์ฒ  ์—ญ์„ ์ž…๋ ฅํ•˜๋Š” input ํƒœ๊ทธ๋Š” `#station-name-input` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - ์ง€ํ•˜์ฒ  ์—ญ์„ ์ถ”๊ฐ€ํ•˜๋Š” button ํƒœ๊ทธ๋Š” `#station-add-button` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - ์ง€ํ•˜์ฒ  ์—ญ์„ ์‚ญ์ œํ•˜๋Š” button ํƒœ๊ทธ๋Š” `.station-delete-button` class๊ฐ’์„ ๊ฐ€์ง„๋‹ค. ### ์ง€ํ•˜์ฒ  ๋…ธ์„  ๊ด€๋ จ ๊ธฐ๋Šฅ + - ์ง€ํ•˜์ฒ  ๋…ธ์„ ์˜ ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜๋Š” input ํƒœ๊ทธ๋Š” `#line-name-input` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - ์ง€ํ•˜์ฒ  ๋…ธ์„ ์˜ ์ƒํ–‰ ์ข…์ ์„ ์„ ํƒํ•˜๋Š” select ํƒœ๊ทธ๋Š” `#line-start-station-selector` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - ์ง€ํ•˜์ฒ  ๋…ธ์„ ์˜ ํ•˜ํ–‰ ์ข…์ ์„ ์„ ํƒํ•˜๋Š” select ํƒœ๊ทธ๋Š” `#line-end-station-selector` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. @@ -71,6 +100,7 @@ - ์ง€ํ•˜์ฒ  ๋…ธ์„ ์„ ์‚ญ์ œํ•˜๋Š” button ํƒœ๊ทธ๋Š” `.line-delete-button` class๊ฐ’์„ ๊ฐ€์ง„๋‹ค. ### ์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ + - ์ง€ํ•˜์ฒ  ๋…ธ์„ ์„ ์„ ํƒํ•˜๋Š” button ํƒœ๊ทธ๋Š” `.section-line-menu-button` class๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - ์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„์„ ์„ค์ •ํ•  ์—ญ select ํƒœ๊ทธ๋Š” `#section-station-selector` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - ์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„์˜ ์ˆœ์„œ๋ฅผ ์ž…๋ ฅํ•˜๋Š” input ํƒœ๊ทธ๋Š” `#section-order-input` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. @@ -78,6 +108,7 @@ - ์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„์„ ์ œ๊ฑฐํ•˜๋Š” button ํƒœ๊ทธ๋Š” `.section-delete-button` class๊ฐ’์„ ๊ฐ€์ง„๋‹ค. ### ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ์ถœ๋ ฅ ๊ธฐ๋Šฅ + - ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ์ถœ๋ ฅ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด `
` ํƒœ๊ทธ๋ฅผ ๋งŒ๋“ค๊ณ  ํ•ด๋‹น ํƒœ๊ทธ ๋‚ด๋ถ€์— ๋…ธ์„ ๋„๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ### ๊ธฐ์กด ์š”๊ตฌ์‚ฌํ•ญ @@ -101,7 +132,8 @@ - [https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Template_literals](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Template_literals) ### ์ถ”๊ฐ€๋œ ์š”๊ตฌ์‚ฌํ•ญ -- [data](https://developer.mozilla.org/ko/docs/Learn/HTML/Howto/%EB%8D%B0%EC%9D%B4%ED%84%B0_%EC%86%8D%EC%84%B1_%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0)์†์„ฑ์„ ํ™œ์šฉํ•˜์—ฌ html ํƒœ๊ทธ์— ์—ญ, ๋…ธ์„ , ๊ตฌ๊ฐ„์˜ ์œ ์ผํ•œ ๋ฐ์ดํ„ฐ ๊ฐ’๋“ค์„ ๊ด€๋ฆฌํ•œ๋‹ค. + +- [data](https://developer.mozilla.org/ko/docs/Learn/HTML/Howto/%EB%8D%B0%EC%9D%B4%ED%84%B0_%EC%86%8D%EC%84%B1_%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0)์†์„ฑ์„ ํ™œ์šฉํ•˜์—ฌ html ํƒœ๊ทธ์— ์—ญ, ๋…ธ์„ , ๊ตฌ๊ฐ„์˜ ์œ ์ผํ•œ ๋ฐ์ดํ„ฐ ๊ฐ’๋“ค์„ ๊ด€๋ฆฌํ•œ๋‹ค. - [localStorage](https://developer.mozilla.org/ko/docs/Web/API/Window/localStorage)๋ฅผ ์ด์šฉํ•˜์—ฌ, ์ƒˆ๋กœ๊ณ ์นจํ•˜๋”๋ผ๋„ ๊ฐ€์žฅ ์ตœ๊ทผ์— ์ž‘์—…ํ•œ ์ •๋ณด๋“ค์„ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.
diff --git a/index.html b/index.html index fc99deac2..2e648728d 100644 --- a/index.html +++ b/index.html @@ -6,8 +6,69 @@
-

๐Ÿš‡ ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ๊ด€๋ฆฌ

+
+

๐Ÿš‡ ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ๊ด€๋ฆฌ

+ + + + +
+
+
+
์—ญ ์ด๋ฆ„
+ + +

๐Ÿš‰ ์ง€ํ•˜์ฒ  ์—ญ ๋ชฉ๋ก

+ + +
+
+
+
๋…ธ์„  ์ด๋ฆ„
+ +
+ ์ƒํ–‰ ์ข…์  + +
+ ํ•˜ํ–‰ ์ข…์  + +
+ +

๐Ÿš‰ ์ง€ํ•˜์ฒ  ๋…ธ์„  ๋ชฉ๋ก

+ + +
+
+
+
+ diff --git a/src/Header.js b/src/Header.js new file mode 100644 index 000000000..34aa73e8e --- /dev/null +++ b/src/Header.js @@ -0,0 +1,65 @@ +import { + addClickEventFromId, + renderLineTable, + renderStationTable, + putOptionsFromId, + renderSectionSelector, + renderMapContent, +} from "./utils/dom.js"; + +const menuIds = [ + "station-manager-button", + "line-manager-button", + "section-manager-button", + "map-print-manager-button", +]; + +export default class Header { + constructor() { + this.clickMenuEventListener(); + } + + clickMenuEventListener() { + menuIds.forEach((id) => { + addClickEventFromId(id, () => { + this.hideContentChildren(); + this.renderContent(id); + }); + }); + } + + hideContentChildren() { + const contentChildren = Array.from( + document.getElementById("content").children + ); + contentChildren.forEach((el) => (el.style.display = "none")); + const mapContent = document.getElementsByClassName("map")[0]; + if (mapContent !== undefined) { + mapContent.remove(); + } + } + + renderContent(id) { + const isMap = Boolean(id.match("map")); + if (isMap) { + renderMapContent(); + return; + } + const isLine = Boolean(id.match("line")); + if (isLine) { + putOptionsFromId("line-start-station-selector"); + putOptionsFromId("line-end-station-selector"); + renderLineTable(); + } + const isStation = Boolean(id.match("station")); + if (isStation) { + renderStationTable(); + } + const isSection = Boolean(id.match("section")); + if (isSection) { + renderSectionSelector(); + } + const content = document.getElementById(id.replace("button", "content")); + content.style.display = "block"; + } +} diff --git a/src/Line.js b/src/Line.js new file mode 100644 index 000000000..28ecb11c8 --- /dev/null +++ b/src/Line.js @@ -0,0 +1,17 @@ +import { getStateFromStorage, setStateToStorage } from "./utils/storage.js"; +import * as storageKey from "./constants/storageKey.js"; + +export default class Line { + constructor(name, section) { + this.name = name; + this.section = section; + } + + add() { + const lines = getStateFromStorage(storageKey.LINES); + setStateToStorage(storageKey.LINES, { + ...lines, + [this.name]: this.section, + }); + } +} diff --git a/src/constants/message.js b/src/constants/message.js new file mode 100644 index 000000000..065b4ae62 --- /dev/null +++ b/src/constants/message.js @@ -0,0 +1,11 @@ +export const MORE_THAN_2_STATION_NAME = "์—ญ ์ด๋ฆ„์€ 2์ž ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."; +export const ALREADY_EXIST_STATION_NAME = "์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์—ญ์ž…๋‹ˆ๋‹ค."; +export const ALREADY_EXIST_LINE_NAME = "์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๋…ธ์„  ์ด๋ฆ„์ž…๋‹ˆ๋‹ค."; +export const CANT_SAME_START_AND_END = + "์ƒํ–‰ ์ข…์ ๊ณผ ํ•˜ํ–‰ ์ข…์ ์ด ๊ฐ™์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."; +export const ALREAY_EXIST_SAME_END_POINTS = + "์ข…์ ์ด ์ผ์น˜ํ•˜๋Š” ๋…ธ์„ ์ด ์ด๋ฏธ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค."; +export const ALREADY_EXIST_STATION_IN_LINE = "์—ญ์ด ์ด๋ฏธ ๋…ธ์„ ์— ์กด์žฌํ•ฉ๋‹ˆ๋‹ค."; +export const LESS_THAN_2_LINE_SECTION = + "๊ตฌ๊ฐ„์ด 2๊ฐœ ์ดํ•˜์ผ ๋•Œ๋Š” ์‚ญ์ œํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."; +export const MUST_INPUT_LINE_NAME = "๋…ธ์„  ์ด๋ฆ„์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”."; diff --git a/src/constants/skeleton.js b/src/constants/skeleton.js new file mode 100644 index 000000000..8cca7eb39 --- /dev/null +++ b/src/constants/skeleton.js @@ -0,0 +1,38 @@ +export const SECTION_CONTENT = ` +

๊ตฌ๊ฐ„์„ ์ˆ˜์ •ํ•  ๋…ธ์„ ์„ ์„ ํƒํ•ด์ฃผ์„ธ์š”.

+
+
+

+

๊ตฌ๊ฐ„ ๋“ฑ๋ก

+ + + + + +
+
+`; + +export const STATION_TABLE_BODY = ` + + ์—ญ ์ด๋ฆ„ + ์„ค์ • + +`; + +export const LINE_TABLE_BODY = ` + + ๋…ธ์„  ์ด๋ฆ„ + ์ƒํ–‰ ์ข…์ ์—ญ + ํ•˜ํ–‰ ์ข…์ ์—ญ + ์„ค์ • + +`; + +export const SECTION_TABLE_BODY = ` + + ์ˆœ์„œ + ์ด๋ฆ„ + ์„ค์ • + +`; diff --git a/src/constants/storageKey.js b/src/constants/storageKey.js new file mode 100644 index 000000000..a20021f0f --- /dev/null +++ b/src/constants/storageKey.js @@ -0,0 +1,2 @@ +export const STATIONS = "STATIONS"; +export const LINES = "LINES"; diff --git a/src/index.js b/src/index.js index e69de29bb..efd25fdc0 100644 --- a/src/index.js +++ b/src/index.js @@ -0,0 +1,68 @@ +import { existStationName, pushNewStation } from "./utils/station.js"; +import { + addClickEventFromId, + resetLineTable, + renderStationTable, + renderLineTable, +} from "./utils/dom.js"; +import * as message from "./constants/message.js"; +import { existLineName, existLineSameEndPoints } from "./utils/line.js"; +import Header from "./Header.js"; +import Line from "./Line.js"; + +export default class SubwayMapManager { + constructor() { + new Header(); + this.clickAddStationEventListener(); + this.lineAddClickEventListener(); + } + + clickAddStationEventListener() { + addClickEventFromId("station-add-button", () => { + const stationInputValue = document.getElementById("station-name-input") + .value; + if (stationInputValue.length < 2) { + alert(message.MORE_THAN_2_STATION_NAME); + return; + } + const isExistStationName = existStationName(stationInputValue); + if (isExistStationName) { + alert(message.ALREADY_EXIST_STATION_NAME); + return; + } + pushNewStation(stationInputValue); + renderStationTable(); + }); + } + + lineAddClickEventListener() { + addClickEventFromId("line-add-button", () => { + const lineNameValue = document.getElementById("line-name-input").value; + const startValue = document.getElementById("line-start-station-selector") + .value; + const endValue = document.getElementById("line-end-station-selector") + .value; + if (!lineNameValue) { + alert(message.MUST_INPUT_LINE_NAME); + return; + } + if (existLineName(lineNameValue)) { + alert(message.ALREADY_EXIST_LINE_NAME); + return; + } + if (startValue === endValue) { + alert(message.CANT_SAME_START_AND_END); + return; + } + if (existLineSameEndPoints([startValue, endValue])) { + alert(message.ALREAY_EXIST_SAME_END_POINTS); + return; + } + new Line(lineNameValue, [startValue, endValue]).add(); + resetLineTable(); + renderLineTable(); + }); + } +} + +new SubwayMapManager(); diff --git a/src/utils/dom.js b/src/utils/dom.js new file mode 100644 index 000000000..be19eea16 --- /dev/null +++ b/src/utils/dom.js @@ -0,0 +1,198 @@ +import * as storageKey from "../constants/storageKey.js"; +import * as skeleton from "../constants/skeleton.js"; +import * as message from "../constants/message.js"; +import { getStationOptions, removeLine } from "./line.js"; +import { removeStation } from "./station.js"; +import { getStateFromStorage, setStateToStorage } from "./storage.js"; + +const DELETE = "์‚ญ์ œ"; +const DELETE_AT_LINE = "๋…ธ์„ ์—์„œ ์ œ๊ฑฐ"; + +export const addClickEventFromId = (id, event) => { + const element = document.getElementById(id); + element.addEventListener("click", event); +}; + +export const resetStationTable = () => { + const stationTableBody = document.getElementById("station-table-body"); + stationTableBody.innerHTML = skeleton.STATION_TABLE_BODY; +}; + +export const renderStationTable = () => { + const stations = getStateFromStorage(storageKey.STATIONS); + resetStationTable(); + if (!stations) { + return; + } + const stationTableBody = document.getElementById("station-table-body"); + stations.forEach((station) => { + const tableRow = document.createElement("tr"); + const stationTableData = document.createElement("td"); + const tableSetData = document.createElement("td"); + const stationDeleteButton = document.createElement("button"); + stationTableData.innerText = station; + stationDeleteButton.setAttribute("class", "station-delete-button"); + stationDeleteButton.innerText = DELETE; + stationDeleteButton.onclick = () => { + removeStation(station); + renderStationTable(); + }; + tableRow.dataset.station = station; + tableSetData.append(stationDeleteButton); + tableRow.append(stationTableData, tableSetData); + stationTableBody.append(tableRow); + }); +}; + +export const resetLineTable = () => { + const lineTableBody = document.getElementById("line-table-body"); + lineTableBody.innerHTML = skeleton.LINE_TABLE_BODY; +}; + +export const renderLineTable = () => { + const lines = getStateFromStorage(storageKey.LINES); + resetLineTable(); + if (!lines) { + return; + } + const lineTableBody = document.getElementById("line-table-body"); + for (const key in lines) { + const tableRow = document.createElement("tr"); + const nameEl = document.createElement("td"); + const startEl = document.createElement("td"); + const endEl = document.createElement("td"); + const setEl = document.createElement("td"); + const lineDeleteButton = document.createElement("button"); + nameEl.innerText = key; + startEl.innerText = lines[key][0]; + endEl.innerText = lines[key].slice(-1)[0]; + lineDeleteButton.setAttribute("class", "line-delete-button"); + lineDeleteButton.innerText = DELETE; + lineDeleteButton.onclick = () => { + removeLine(key); + renderLineTable(); + }; + tableRow.dataset.line = key; + setEl.append(lineDeleteButton); + tableRow.append(nameEl, startEl, endEl, setEl); + lineTableBody.append(tableRow); + } +}; + +export const putOptionsFromId = (id) => { + const element = document.getElementById(id); + element.innerHTML = getStationOptions(); +}; + +export const renderSectionSelector = () => { + const lines = getStateFromStorage(storageKey.LINES); + if (!lines) { + return; + } + const sectionManagerContent = document.getElementById( + "section-manager-content" + ); + sectionManagerContent.innerHTML = skeleton.SECTION_CONTENT; + const sectionSelectorContainer = document.getElementById( + "section-selector-container" + ); + for (const key in lines) { + const lineSelectorButton = document.createElement("button"); + lineSelectorButton.setAttribute("class", "section-line-menu-button"); + lineSelectorButton.dataset.line = key; + lineSelectorButton.innerText = key; + lineSelectorButton.onclick = () => renderModifySectionContainer(key); + sectionSelectorContainer.appendChild(lineSelectorButton); + } +}; + +export const addSection = (lineName) => { + const lines = getStateFromStorage(storageKey.LINES); + const section = lines[lineName]; + const station = document.getElementById("section-station-selector").value; + let order = document.getElementById("section-order-input").value; + if (section.indexOf(station) > -1) { + alert(message.ALREADY_EXIST_STATION_IN_LINE); + return; + } + section.splice(order, 0, station); + setStateToStorage(storageKey.LINES, { + ...lines, + [lineName]: section, + }); + renderSectionTable(lineName); +}; + +export const renderModifySectionContainer = (lineName) => { + const sectionModifyContainer = document.getElementById( + "section-modify-container" + ); + const sectionManageTitle = document.getElementById("section-manage-title"); + const sectionAddButton = document.getElementById("section-add-button"); + sectionAddButton.onclick = () => addSection(lineName); + sectionModifyContainer.style.display = "block"; + sectionManageTitle.innerText = `${lineName} ๊ด€๋ฆฌ`; + putOptionsFromId("section-station-selector"); + renderSectionTable(lineName); +}; + +export const resetSectionTable = () => { + const sectionTableBody = document.getElementById("section-table-body"); + sectionTableBody.innerHTML = skeleton.SECTION_TABLE_BODY; +}; + +export const removeSection = (lineName, station) => { + const lines = getStateFromStorage(storageKey.LINES); + if (lines[lineName].length < 3) { + alert(message.LESS_THAN_2_LINE_SECTION); + return; + } + setStateToStorage(storageKey.LINES, { + ...lines, + [lineName]: lines[lineName].filter((el) => el !== station), + }); + renderSectionTable(lineName); +}; + +export const renderSectionTable = (lineName) => { + const selectedSection = getStateFromStorage(storageKey.LINES)[lineName]; + resetSectionTable(); + const sectionTableBody = document.getElementById("section-table-body"); + selectedSection.forEach((station, i) => { + const tableRow = document.createElement("tr"); + const orderEl = document.createElement("td"); + const nameEl = document.createElement("td"); + const setEl = document.createElement("td"); + const deleteButton = document.createElement("button"); + orderEl.innerText = i; + nameEl.innerText = station; + deleteButton.innerText = DELETE_AT_LINE; + deleteButton.onclick = () => removeSection(lineName, station); + tableRow.dataset.section = `${lineName}-${i}`; + setEl.append(deleteButton); + tableRow.append(orderEl, nameEl, setEl); + sectionTableBody.append(tableRow); + }); +}; + +export const combineMap = (acc, [line, section]) => { + return ( + acc + + `

${line}

` + ); +}; + +export const renderMapContent = () => { + const lines = getStateFromStorage(storageKey.LINES); + if (!lines) { + return; + } + const newEl = document.createElement("div"); + newEl.setAttribute("class", "map"); + newEl.innerHTML = Object.entries(lines).reduce(combineMap, ""); + const contentEl = document.getElementById("content"); + contentEl.appendChild(newEl); +}; diff --git a/src/utils/line.js b/src/utils/line.js new file mode 100644 index 000000000..06e1c3163 --- /dev/null +++ b/src/utils/line.js @@ -0,0 +1,41 @@ +import * as storageKey from "../constants/storageKey.js"; +import { getStateFromStorage } from "./storage.js"; + +export const getStationOptions = () => { + const stations = getStateFromStorage(storageKey.STATIONS); + if (!stations) { + return null; + } + return stations.map((el) => ``).join(""); +}; + +export const existLineName = (name) => { + const lines = getStateFromStorage(storageKey.LINES); + if (!lines) { + return false; + } + return Object.keys(lines).indexOf(name) > -1; +}; + +export const existLineSameEndPoints = ([start, end]) => { + const lines = getStateFromStorage(storageKey.LINES); + if (!lines) { + return false; + } + for (const key in lines) { + const section = lines[key]; + if (section[0] === start && section.slice(-1)[0] === end) { + return true; + } + } + return false; +}; + +export const removeLine = (lineName) => { + const lines = getStateFromStorage(storageKey.LINES); + if (!lines) { + return; + } + delete lines[lineName]; + setStateToStorage(storageKey.LINES, lines); +}; diff --git a/src/utils/station.js b/src/utils/station.js new file mode 100644 index 000000000..aa98f53f8 --- /dev/null +++ b/src/utils/station.js @@ -0,0 +1,29 @@ +import * as storageKey from "../constants/storageKey.js"; +import { getStateFromStorage, setStateToStorage } from "./storage.js"; + +export const existStationName = (name) => { + const stations = getStateFromStorage(storageKey.STATIONS); + if (!stations) { + return false; + } + return stations.indexOf(name) > -1; +}; + +export const removeStation = (name) => { + const stations = getStateFromStorage(storageKey.STATIONS); + if (stations === null) { + return; + } + setStateToStorage( + storageKey.STATIONS, + stations.filter((el) => el !== name) + ); +}; + +export const pushNewStation = (station) => { + const previousStations = getStateFromStorage(storageKey.STATIONS); + const newStations = previousStations + ? [...previousStations, station] + : [station]; + setStateToStorage(storageKey.STATIONS, newStations); +}; diff --git a/src/utils/storage.js b/src/utils/storage.js new file mode 100644 index 000000000..1968d3ce4 --- /dev/null +++ b/src/utils/storage.js @@ -0,0 +1,7 @@ +export const getStateFromStorage = (key) => { + return JSON.parse(localStorage.getItem(key)); +}; + +export const setStateToStorage = (key, data) => { + return localStorage.setItem(key, JSON.stringify(data)); +};