diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..1c12442ae --- /dev/null +++ b/.prettierrc @@ -0,0 +1,8 @@ +{ + "arrowParens": "avoid", + "bracketSpacing": true, + "printWidth": 100, + "semi": true, + "singleQuote": true, + "tabWidth": 2 +} \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..ee39fb902 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,48 @@ +# ๐Ÿš‡ ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ๋ฏธ์…˜ + +## ๐Ÿš€ ๊ตฌํ˜„ํ•  ๊ธฐ๋Šฅ ๋ชฉ๋ก + +- [x] ๊ฐ๊ฐ์˜ ๊ด€๋ฆฌ ๋ฒ„ํŠผ ์ƒ์„ฑ +- [x] element๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํ™”๋ฉด์— ๋„์šฐ๋Š” ๊ธฐ๋Šฅ +- [x] Line ์ƒ์„ฑ +- [x] localStorage์— ๋ฐ์ดํ„ฐ ์ €์žฅ ๋ฐ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ + +1. ์—ญ ๊ด€๋ฆฌ + +- [x] ์—ญ ๊ด€๋ฆฌ ๋ฒ„ํŠผ ํด๋ฆญ์‹œ ์—ญ ์ด๋ฆ„ ์ž…๋ ฅ, ์ง€ํ•˜์ฒ  ์—ญ ๋ชฉ๋ก ๋ณด์—ฌ์ฃผ๊ธฐ +- [x] ์—ญ ์ด๋ฆ„ ์ž…๋ ฅ, ์ถ”๊ฐ€ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” +- [x] ์—ญ ์ด๋ฆ„ ์ค‘๋ณต ์ฒดํฌ +- [x] ์—ญ ์ด๋ฆ„ 2๊ธ€์ž ์ด์ƒ ์ฒดํฌ +- [x] ์—ญ ๋“ฑ๋ก์‹œ ํ™”๋ฉด์— ํ‘œ์‹œ +- [x] ์—ญ ๊ด€๋ฆฌ๋กœ ๋“ค์–ด๊ฐˆ ๋•Œ ์ด์ „ ๋ชฉ๋ก ํ‘œ์‹œ +- [x] ์—ญ ์‚ญ์ œ ๊ธฐ๋Šฅ `alert`์‚ฌ์šฉ +- [x] ์—ญ ์‚ญ์ œ์‹œ ๋…ธ์„ ์— ์žˆ๋Š”์ง€ ํ™•์ธ + +2. ๋…ธ์„  ๊ด€๋ฆฌ + +- [x] ๋…ธ์„  ๊ด€๋ฆฌ ๋ฒ„ํŠผ ํด๋ฆญ์‹œ ๋…ธ์„  ์ด๋ฆ„ ์ž…๋ ฅ, ์ข…์  ์„ ํƒ, ๋…ธ์„  ๋ชฉ๋ก ๋ณด์—ฌ์ฃผ๊ธฐ +- [x] ๋…ธ์„  ์ด๋ฆ„ ์ž…๋ ฅ, ์ถ”๊ฐ€ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” +- [x] ์ข…์  ๋ฆฌ์ŠคํŠธ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ +- [x] ๋…ธ์„  ์ด๋ฆ„ ์ค‘๋ณต ์ฒดํฌ +- [x] ๋…ธ์„  ๋“ฑ๋ก์‹œ ํ™”๋ฉด์— ํ‘œ์‹œ +- [x] ๋…ธ์„  ๊ด€๋ฆฌ๋กœ ๋“ค์–ด๊ฐˆ ๋•Œ ์ด์ „ ๋ชฉ๋ก ํ‘œ์‹œ +- [x] ๋…ธ์„  ์‚ญ์ œ ๊ธฐ๋Šฅ `alert`์‚ฌ์šฉ + +3. ๊ตฌ๊ฐ„ ๊ด€๋ฆฌ + +- [x] ๋…ธ์„  ๊ด€๋ฆฌ ๋ฒ„ํŠผ ํด๋ฆญ์‹œ ์ˆ˜์ •ํ•  ๋…ธ์„  ์„ ํƒ ๋ฒ„ํŠผ +- [x] ์ˆ˜์ • ํ•  ๋…ธ์„  ์„ ํƒ์‹œ ๊ด€๋ฆฌ ํ™”๋ฉด ๋ณด์—ฌ์ฃผ๊ธฐ +- [x] ๋‹ค๋ฅธ ํƒญ ๋ˆ„๋ฅผ ๋•Œ ๊ด€๋ฆฌ ํ™”๋ฉด ๋‹ซ๊ธฐ +- [x] ์—ญ ์„ ํƒ ๋ฆฌ์ŠคํŠธ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ +- [x] ๊ด€๋ฆฌ ํ˜ธ์„  ๋ณด์—ฌ์ฃผ๊ธฐ +- [x] ๊ตฌ๊ฐ„ ์ •๋ณด ๋ถˆ๋Ÿฌ์˜ค๊ธฐ +- [x] ์ˆœ์„œ ์ž…๋ ฅ, ๋“ฑ๋ก ๋ฒ„ํŠผ ํ™œ์„ฑํ™” +- [x] ๋…ธ์„ ์ด ์ค‘๋ณต๋˜๋Š” ์—ญ์ด ์žˆ์œผ๋ฉด ์•ˆ๋จ +- [x] ์—ญ๊ณผ ์—ญ ์‚ฌ์ด์—๋งŒ ์ถ”๊ฐ€๋˜๋„๋ก +- [x] ์—ญ์„ ์ œ๊ฑฐํ•˜๋Š” ๊ธฐ๋Šฅ +- [x] ์—ญ ๊ฐœ์ˆ˜๊ฐ€ 2๊ฐœ ์ดํ•˜๊ฐ€ ๋˜๋ฉด ์•ˆ๋จ + +4. ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ์ถœ๋ ฅ + +- [x] ๋…ธ์„ ๋„ ์ถœ๋ ฅ ๋ฒ„ํŠผ ํด๋ฆญ์‹œ ๋…ธ์„ ๋„ ํ™”๋ฉด ๋ณด์—ฌ์ฃผ๊ธฐ +- [x] ๋…ธ์„  ๋ชฉ๋ก ๋ณด์—ฌ์ฃผ๊ธฐ diff --git a/index.html b/index.html index fc99deac2..cbbeb0065 100644 --- a/index.html +++ b/index.html @@ -2,12 +2,84 @@ + ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ๊ด€๋ฆฌ

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

+ + + +
+
+

์—ญ์ด๋ฆ„

+ + +

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

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

๋…ธ์„ ์ด๋ฆ„

+ +
+ ์ƒํ–‰ ์ข…์  + +
+
+ ํ•˜ํ–‰ ์ข…์  + +
+ +

๐Ÿš‰ ๋…ธ์„  ๋ชฉ๋ก

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

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

+
+
+

+
+

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

+
+
+
+ + + + + + + + + + +
์ˆœ์„œ์ด๋ฆ„์„ค์ •
+
+
+
diff --git a/src/controllers/lineManager.js b/src/controllers/lineManager.js new file mode 100644 index 000000000..495c98931 --- /dev/null +++ b/src/controllers/lineManager.js @@ -0,0 +1,40 @@ +import { notDuplicateLine } from '../controllers/validation.js'; +import { clearFocus } from '../views/utils.js'; +import { showAddedLine } from '../views/lineManager.js'; + +const lineNameInput = document.querySelector('#line-name-input'); +const lineStartSelector = document.querySelector('#line-start-station-selector'); +const lineEndSelector = document.querySelector('#line-end-station-selector'); +const lineAddBtn = document.querySelector('#line-add-button'); + +export const lineAddListener = subwayMap => { + lineAddBtn.addEventListener('click', () => + addNewLine(lineNameInput.value, lineStartSelector.value, lineEndSelector.value, subwayMap) + ); + lineNameInput.addEventListener('keydown', e => { + if (e.keyCode === 13) { + addNewLine(lineNameInput.value, lineStartSelector.value, lineEndSelector.value, subwayMap); + } + }); +}; + +const addNewLine = (name, start, end, subwayMap) => { + if (notDuplicateLine(name.trim(), subwayMap.lineList) && name.trim() !== '') { + if (start !== end) { + subwayMap.addLine(name.trim(), start, end); + showAddedLine(subwayMap); + } else { + alert('์ƒํ–‰ ์ข…์ ๊ณผ ํ•˜ํ–‰ ์ข…์ ์ด ๊ฐ™์Šต๋‹ˆ๋‹ค.'); + } + } else { + alert('์ž˜๋ชป๋œ ๊ฐ’์ž…๋‹ˆ๋‹ค. ๋‹ค์‹œ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.'); + } + clearFocus(lineNameInput); +}; + +export const deleteLine = (name, subwayMap) => { + if (confirm('์ •๋ง๋กœ ์‚ญ์ œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?')) { + subwayMap.delLine(name); + showAddedLine(subwayMap); + } +}; diff --git a/src/controllers/sectionManager.js b/src/controllers/sectionManager.js new file mode 100644 index 000000000..a27e62e30 --- /dev/null +++ b/src/controllers/sectionManager.js @@ -0,0 +1,65 @@ +import { notFirstOrLast, stationNotInSelectedLine, gtTwo } from './validation.js'; +import { clearFocus } from '../views/utils.js'; +import { showAddedSection } from '../views/sectionManager.js'; + +export const changeAddListener = (selectedLineName, subwayMap) => { + const sectionStationSelector = document.querySelector('#section-station-selector'); + const sectionOrderInput = document.querySelector('#section-order-input'); + const sectionAddBtn = document.querySelector('#section-add-button'); + sectionAddBtn.addEventListener('click', () => + addNewSection( + sectionStationSelector.value, + sectionOrderInput.value, + selectedLineName, + subwayMap + ) + ); + sectionOrderInput.addEventListener('keydown', e => { + if (e.keyCode === 13) { + addNewSection( + sectionStationSelector.value, + sectionOrderInput.value, + selectedLineName, + subwayMap + ); + } + }); +}; + +export const sectionRemoveListener = () => { + const sectionOrderInput = document.querySelector('#section-order-input'); + sectionAddBtn.removeEventListener(); + sectionOrderInput.removeEventListener(); +}; + +const addNewSection = (station, order, selectedLineName, subwayMap) => { + const sectionOrderInput = document.querySelector('#section-order-input'); + const lineList = subwayMap.lineList; + const sectionIndex = lineList.findIndex(line => line.name === selectedLineName); + const selectedLine = lineList[sectionIndex].list; + if (notFirstOrLast(order, selectedLine)) { + if (stationNotInSelectedLine(station, selectedLine)) { + subwayMap.addSection(sectionIndex, order, station); + showAddedSection(selectedLineName, subwayMap); + } else { + alert('์ด๋ฏธ ๋…ธ์„ ์— ์กด์žฌํ•˜๋Š” ์—ญ์ž…๋‹ˆ๋‹ค.'); + } + } else { + alert('๊ทธ ์ˆœ์„œ์— ์—ญ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.'); + } + clearFocus(sectionOrderInput); +}; + +export const deleteSection = (lineName, stationName, subwayMap) => { + const lineList = subwayMap.lineList; + const sectionIndex = lineList.findIndex(line => line.name === lineName); + const selectedLineList = lineList[sectionIndex].list; + if (gtTwo(selectedLineList)) { + if (confirm('์ •๋ง๋กœ ์‚ญ์ œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?')) { + subwayMap.delSection(lineName, stationName); + showAddedSection(lineName, subwayMap); + } + } else { + alert('๋…ธ์„ ์— 2๊ฐœ ์ด์ƒ์˜ ์—ญ์ด ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.'); + } +}; diff --git a/src/controllers/stationManager.js b/src/controllers/stationManager.js new file mode 100644 index 000000000..d3cd79571 --- /dev/null +++ b/src/controllers/stationManager.js @@ -0,0 +1,36 @@ +import { geTwo, notDuplicateStation, stationNotInLine } from '../controllers/validation.js'; +import { showAddedStation } from '../views/stationManager.js'; +import { clearFocus } from '../views/utils.js'; + +const stationNameInput = document.querySelector('#station-name-input'); +const stationAddBtn = document.querySelector('#station-add-button'); + +export const stationAddListener = subwayMap => { + stationAddBtn.addEventListener('click', () => addNewStation(stationNameInput.value, subwayMap)); + stationNameInput.addEventListener('keydown', e => { + if (e.keyCode === 13) { + addNewStation(stationNameInput.value, subwayMap); + } + }); +}; + +const addNewStation = (name, subwayMap) => { + if (geTwo(name.trim()) && notDuplicateStation(name.trim(), subwayMap.stationList)) { + subwayMap.addStation(name.trim()); + showAddedStation(subwayMap); + } else { + alert('์ž˜๋ชป๋œ ๊ฐ’์ž…๋‹ˆ๋‹ค. ๋‹ค์‹œ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.'); + } + clearFocus(stationNameInput); +}; + +export const deleteStation = (name, subwayMap) => { + if (confirm('์ •๋ง๋กœ ์‚ญ์ œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?')) { + if (stationNotInLine(name, subwayMap.lineList)) { + subwayMap.delStation(name); + showAddedStation(subwayMap); + } else { + alert('๋…ธ์„ ์— ํฌํ•จ๋œ ์—ญ์ž…๋‹ˆ๋‹ค.'); + } + } +}; diff --git a/src/controllers/storage.js b/src/controllers/storage.js new file mode 100644 index 000000000..7ce25ab8b --- /dev/null +++ b/src/controllers/storage.js @@ -0,0 +1,8 @@ +export function saveData(key, object) { + localStorage.setItem(key, JSON.stringify(object)); +} + +export function loadData(key) { + const data = localStorage.getItem(key); + return data ? JSON.parse(data) : []; +} diff --git a/src/controllers/tab.js b/src/controllers/tab.js new file mode 100644 index 000000000..bf52ba2ea --- /dev/null +++ b/src/controllers/tab.js @@ -0,0 +1,17 @@ +import { tabManager } from '../views/tab.js'; +import { stationAddListener } from './stationManager.js'; +import { lineAddListener } from './lineManager.js'; + +const stationManagerBtn = document.querySelector('#station-manager-button'); +const lineManagerBtn = document.querySelector('#line-manager-button'); +const sectionManagerBtn = document.querySelector('#section-manager-button'); +const mapPrintManagerBtn = document.querySelector('#map-print-manager-button'); + +export const tabController = subwayMap => { + stationManagerBtn.addEventListener('click', e => tabManager(e.target.value, subwayMap)); + lineManagerBtn.addEventListener('click', e => tabManager(e.target.value, subwayMap)); + sectionManagerBtn.addEventListener('click', e => tabManager(e.target.value, subwayMap)); + mapPrintManagerBtn.addEventListener('click', e => tabManager(e.target.value, subwayMap)); + stationAddListener(subwayMap); + lineAddListener(subwayMap); +}; diff --git a/src/controllers/validation.js b/src/controllers/validation.js new file mode 100644 index 000000000..5e293c0fd --- /dev/null +++ b/src/controllers/validation.js @@ -0,0 +1,35 @@ +export const geTwo = name => { + return name.length >= 2; +}; + +export const gtTwo = selectedLineList => { + return selectedLineList.length > 2; +}; + +export const notDuplicateStation = (name, list) => { + return !list.includes(name); +}; + +export const notDuplicateLine = (name, list) => { + for (let element of list) { + if (element.name == name) return false; + } + return true; +}; + +export const stationNotInLine = (station, lineList) => { + for (let line of lineList) { + if (line.list.includes(station)) { + return false; + } + } + return true; +}; + +export const notFirstOrLast = (order, lineList) => { + return order > 0 && order <= lineList.length - 1; +}; + +export const stationNotInSelectedLine = (station, selectedLineList) => { + return !selectedLineList.includes(station); +}; diff --git a/src/index.js b/src/index.js index e69de29bb..43edc892e 100644 --- a/src/index.js +++ b/src/index.js @@ -0,0 +1,83 @@ +import { deleteStation } from './controllers/stationManager.js'; +import { deleteLine } from './controllers/lineManager.js'; +import { deleteSection } from './controllers/sectionManager.js'; +import { saveData, loadData } from './controllers/storage.js'; +import { tabController } from './controllers/tab.js'; +import Line from './models/Line.js'; +import { showSectionManager } from './views/sectionManager.js'; + +export default function SubwayMap() { + this.stationList = loadData('stations'); + this.lineList = loadData('lines'); + + this.addStation = name => { + this.stationList.push(name); + this.saveStation(); + }; + + this.delStation = name => { + const index = this.stationList.findIndex(stationName => stationName === name); + this.stationList.splice(index, 1); + this.saveStation(); + }; + + this.addLine = (name, start, end) => { + this.lineList.push(new Line(name, start, end)); + this.saveLine(); + }; + + this.delLine = name => { + const index = this.lineList.findIndex(element => element.name === name); + this.lineList.splice(index, 1); + this.saveLine(); + }; + + this.addSection = (lineIndex, order, name) => { + this.lineList[lineIndex].list.splice(order, 0, name); + this.saveLine(); + }; + + this.delSection = (lineName, stationName) => { + const lineIndex = this.lineList.findIndex(element => element.name === lineName); + const { list } = this.lineList[lineIndex]; + const stationIndex = list.findIndex(name => name === stationName); + list.splice(stationIndex, 1); + this.saveLine(); + }; + + this.reload = () => { + this.stationList = loadData('stations'); + this.lineList = loadData('lines'); + }; + + this.saveStation = () => { + saveData('stations', this.stationList); + }; + + this.saveLine = () => { + saveData('lines', this.lineList); + }; +} + +const init = subwayMap => { + tabController(subwayMap); +}; + +const subwayMap = new SubwayMap(); +const newBtnAddListener = event => { + if (event.target.classList.contains('station-delete-button')) { + deleteStation(event.target.dataset.stationName, subwayMap); + } + if (event.target.classList.contains('line-delete-button')) { + deleteLine(event.target.dataset.lineName, subwayMap); + } + if (event.target.classList.contains('section-line-menu-button')) { + showSectionManager(event.target.dataset.lineName, subwayMap); + } + if (event.target.classList.contains('section-delete-button')) { + const [line, station] = event.target.dataset.lineStation.split(','); + deleteSection(line, station, subwayMap); + } +}; +document.body.addEventListener('click', newBtnAddListener); +init(subwayMap); diff --git a/src/models/Line.js b/src/models/Line.js new file mode 100644 index 000000000..57acc223b --- /dev/null +++ b/src/models/Line.js @@ -0,0 +1,4 @@ +export default function Line(name, start, end) { + this.name = name; + this.list = [start, end]; +} diff --git a/src/views/lineManager.js b/src/views/lineManager.js new file mode 100644 index 000000000..d4c25b3a6 --- /dev/null +++ b/src/views/lineManager.js @@ -0,0 +1,53 @@ +import { makeElement, appendElements } from './utils.js'; + +export const showLineStationSelector = subwayMap => { + const lineStartSelector = document.querySelector('#line-start-station-selector'); + const lineEndSelector = document.querySelector('#line-end-station-selector'); + let stationsHTML = ''; + subwayMap.stationList.forEach(name => { + const stationOption = makeElement({ + tag: 'option', + value: name, + innerHTML: name, + }); + stationsHTML += stationOption.outerHTML; + }); + lineStartSelector.innerHTML = stationsHTML; + lineEndSelector.innerHTML = stationsHTML; +}; + +export const showAddedLine = subwayMap => { + const lineTbody = document.querySelector('#line-manager-screen table tbody'); + let addedLinesHTML = ''; + subwayMap.lineList.forEach(element => { + const lineTr = makeElement({ + tag: 'tr', + }); + const nameTd = makeElement({ + tag: 'td', + innerHTML: element.name, + }); + const startTd = makeElement({ + tag: 'td', + innerHTML: element.list[0], + }); + const endTd = makeElement({ + tag: 'td', + innerHTML: element.list[element.list.length - 1], + }); + const btnTd = makeElement({ + tag: 'td', + }); + const deleteBtn = makeElement({ + tag: 'button', + elementClass: 'line-delete-button', + innerHTML: '์‚ญ์ œ', + dataName: 'line-name', + dataValue: element.name, + }); + appendElements([deleteBtn], btnTd); + appendElements([nameTd, startTd, endTd, btnTd], lineTr); + addedLinesHTML += lineTr.outerHTML; + }); + lineTbody.innerHTML = addedLinesHTML; +}; diff --git a/src/views/map.js b/src/views/map.js new file mode 100644 index 000000000..3aa7da7ea --- /dev/null +++ b/src/views/map.js @@ -0,0 +1,28 @@ +import { makeElement, appendElements } from './utils.js'; + +export const showMap = subwayMap => { + const mapDiv = document.querySelector('.map'); + let mapsHTML = ''; + subwayMap.lineList.forEach(element => { + const emptyDiv = makeElement({ + tag: 'div', + }); + const nameH3 = makeElement({ + tag: 'h3', + innerHTML: element.name, + }); + const emptyUl = makeElement({ + tag: 'ul', + }); + element.list.forEach(station => { + const stationLi = makeElement({ + tag: 'li', + innerHTML: station, + }); + appendElements([stationLi], emptyUl); + }); + appendElements([nameH3, emptyUl], emptyDiv); + mapsHTML += emptyDiv.outerHTML; + }); + mapDiv.innerHTML = mapsHTML; +}; diff --git a/src/views/sectionManager.js b/src/views/sectionManager.js new file mode 100644 index 000000000..dc26e4ae3 --- /dev/null +++ b/src/views/sectionManager.js @@ -0,0 +1,113 @@ +import { makeElement, appendElements } from './utils.js'; +import { changeAddListener } from '../controllers/sectionManager.js'; + +export const showModifyLineBtn = subwayMap => { + const buttonsDiv = document.querySelector('#buttons'); + const emptyDiv = makeElement({ + tag: 'div', + }); + subwayMap.lineList.forEach(line => { + const button = makeElement({ + tag: 'button', + elementClass: 'section-line-menu-button', + innerHTML: line.name, + styles: 'margin: 0px 5px 0px 0px', + dataName: 'line-name', + dataValue: line.name, + }); + appendElements([button], emptyDiv); + }); + buttonsDiv.innerHTML = emptyDiv.outerHTML; +}; + +export const showSectionManager = (lineName, subwayMap) => { + const sectionManagerDiv = document.querySelector('.section-manager'); + const sectionTitle = document.querySelector('#title'); + sectionManagerDiv.classList.add('active'); + sectionTitle.innerHTML = `${lineName} ๊ด€๋ฆฌ`; + createSectionRegistration(subwayMap); + showAddedSection(lineName, subwayMap); + changeAddListener(lineName, subwayMap); +}; + +export const hideSectionManager = () => { + const sectionManagerDiv = document.querySelector('.section-manager'); + sectionManagerDiv.classList.remove('active'); +}; + +const showSectionStationSelector = subwayMap => { + const sectionStationSelector = document.querySelector('#section-station-selector'); + let stationsHTML = ''; + subwayMap.stationList.forEach(name => { + const stationOption = makeElement({ + tag: 'option', + value: name, + innerHTML: name, + }); + stationsHTML += stationOption.outerHTML; + }); + sectionStationSelector.innerHTML = stationsHTML; +}; + +export const showAddedSection = (lineName, subwayMap) => { + const lineList = subwayMap.lineList; + const sectionTbody = document.querySelector('.section-manager table tbody'); + const sectionIndex = lineList.findIndex(line => line.name === lineName); + const selectedSectionName = lineList[sectionIndex].name; + const selectedSectionList = lineList[sectionIndex].list; + let addedSectionsHTML = ''; + for (let i = 0; i < selectedSectionList.length; ++i) { + const sectionTr = makeElement({ + tag: 'tr', + }); + const orderTd = makeElement({ + tag: 'td', + innerHTML: String(i), + }); + const nameTd = makeElement({ + tag: 'td', + innerHTML: selectedSectionList[i], + }); + const btnTd = makeElement({ + tag: 'td', + }); + const deleteBtn = makeElement({ + tag: 'button', + elementClass: 'section-delete-button', + innerHTML: '๋…ธ์„ ์—์„œ ์ œ๊ฑฐ', + dataName: 'line-station', + dataValue: [selectedSectionName, selectedSectionList[i]], + }); + appendElements([deleteBtn], btnTd); + appendElements([orderTd, nameTd, btnTd], sectionTr); + addedSectionsHTML += sectionTr.outerHTML; + } + sectionTbody.innerHTML = addedSectionsHTML; +}; + +const createSectionRegistration = subwayMap => { + const sectionsRegistrationDiv = document.querySelector('#section-registration-div'); + const emptyDiv = makeElement({ + tag: 'div', + }); + const stationSelect = makeElement({ + tag: 'select', + styles: 'margin: 0px 5px 0px 0px', + id: 'section-station-selector', + }); + const orderInput = makeElement({ + tag: 'input', + type: 'number', + styles: 'margin: 0px 5px 0px 0px', + id: 'section-order-input', + placeholder: '์ˆœ์„œ', + }); + const submitBtn = makeElement({ + tag: 'button', + id: 'section-add-button', + innerHTML: '๋“ฑ๋ก', + }); + appendElements([stationSelect, orderInput, submitBtn], emptyDiv); + sectionsRegistrationDiv.innerHTML = emptyDiv.innerHTML; + showSectionStationSelector(subwayMap); +}; diff --git a/src/views/stationManager.js b/src/views/stationManager.js new file mode 100644 index 000000000..91e6c6b15 --- /dev/null +++ b/src/views/stationManager.js @@ -0,0 +1,29 @@ +import { makeElement, appendElements } from './utils.js'; + +export const showAddedStation = subwayMap => { + const stationTbody = document.querySelector('#station-manager-screen table tbody'); + let addedStationsHTML = ''; + subwayMap.stationList.forEach(name => { + const stationTr = makeElement({ + tag: 'tr', + }); + const nameTd = makeElement({ + tag: 'td', + innerHTML: name, + }); + const btnTd = makeElement({ + tag: 'td', + }); + const deleteBtn = makeElement({ + tag: 'button', + elementClass: 'station-delete-button', + innerHTML: '์‚ญ์ œ', + dataName: 'station-name', + dataValue: name, + }); + appendElements([deleteBtn], btnTd); + appendElements([nameTd, btnTd], stationTr); + addedStationsHTML += stationTr.outerHTML; + }); + stationTbody.innerHTML = addedStationsHTML; +}; diff --git a/src/views/tab.js b/src/views/tab.js new file mode 100644 index 000000000..f192ccad0 --- /dev/null +++ b/src/views/tab.js @@ -0,0 +1,33 @@ +import { showAddedStation } from './stationManager.js'; +import { showLineStationSelector, showAddedLine } from './lineManager.js'; +import { showModifyLineBtn, hideSectionManager } from './sectionManager.js'; +import { showMap } from './map.js'; + +const stationManagerScreen = document.querySelector('#station-manager-screen'); +const lineManagerScreen = document.querySelector('#line-manager-screen'); +const sectionManagerScreen = document.querySelector('#section-manager-screen'); +const mapPrintManagerScreen = document.querySelector('#map-print-manager-screen'); + +const tabList = [ + stationManagerScreen, + lineManagerScreen, + sectionManagerScreen, + mapPrintManagerScreen, +]; + +export const tabManager = (value, subwayMap) => { + for (let i = 0; i < tabList.length; i++) { + if (i == parseInt(value)) { + tabList[i].classList.add('active'); + } else { + tabList[i].classList.remove('active'); + } + hideSectionManager(); + } + subwayMap.reload(); + showAddedStation(subwayMap); + showAddedLine(subwayMap); + showLineStationSelector(subwayMap); + showModifyLineBtn(subwayMap); + showMap(subwayMap); +}; diff --git a/src/views/utils.js b/src/views/utils.js new file mode 100644 index 000000000..ee73b65ea --- /dev/null +++ b/src/views/utils.js @@ -0,0 +1,34 @@ +export const makeElement = ({ + tag, + id, + elementClass, + value, + type, + innerHTML, + placeholder, + styles, + dataName, + dataValue, +}) => { + const element = document.createElement(tag); + if (id) element.id = id; + if (elementClass) element.classList.add(elementClass); + if (value) element.value = value; + if (type) element.type = type; + if (innerHTML) element.innerHTML = innerHTML; + if (placeholder) element.placeholder = placeholder; + if (styles) element.style.cssText = styles; + if (dataName && dataValue) element.setAttribute(`data-${dataName}`, dataValue); + return element; +}; + +export const appendElements = (elements, parent) => { + elements.forEach(element => { + parent.appendChild(element); + }); +}; + +export const clearFocus = targetInput => { + targetInput.value = ''; + targetInput.focus(); +}; diff --git a/style.css b/style.css new file mode 100644 index 000000000..a7ef2ceb3 --- /dev/null +++ b/style.css @@ -0,0 +1,21 @@ +.tab-screen { + display: none; +} + +.section-manager { + display: none; +} + +table { + border: 1px solid gray; + margin-top: 20px; +} + +table th, +table td { + border: 1px solid gray; +} + +.active { + display: block; +}