Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"arrowParens": "avoid",
"bracketSpacing": true,
"printWidth": 100,
"semi": true,
"singleQuote": true,
"tabWidth": 2
}
48 changes: 48 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -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] 노선 목록 보여주기
72 changes: 72 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,84 @@
<html lang="kr">
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="./style.css" />
<title>지하철 노선도 관리</title>
</head>
<body>
<div id="app">
<h1>🚇 지하철 노선도 관리 </h1>
<button id='station-manager-button' value='0'>1. 역 관리</button>
<button id='line-manager-button' value='1'>2. 노선 관리</button>
<button id='section-manager-button' value='2'>3. 구간 관리</button>
<button id='map-print-manager-button' value='3'>4. 지하철 노선도 출력</button>
</div>
<div class="tab-screen" id='station-manager-screen'>
<p style='margin: 20px 0px 0px;'>역이름</p>
<input id="station-name-input" placeholder="역 이름을 입력해주세요."/>
<button id="station-add-button" style='margin: 0px 5px;'>역 추가</button>
<h3>🚉 지하철 역 목록</h3>
<table>
<thead>
<tr>
<th>역 이름</th>
<th>설정</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div class="tab-screen" id='line-manager-screen'>
<p style='margin: 20px 0px 0px;'>노선이름</p>
<input id="line-name-input" placeholder="역 이름을 입력해주세요."/>
<div style="margin: 20px 0px 0px">
<span>상행 종점</span>
<select id="line-start-station-selector">
</select>
</div>
<div style="margin: 0px 0px 20px">
<span>하행 종점</span>
<select id="line-end-station-selector">
</select>
</div>
<button id="line-add-button" style='margin: 0px 5px;'>노선 추가</button>
<h3>🚉 노선 목록</h3>
<table>
<thead>
<tr>
<th>노선 이름</th>
<th>상행 종점역</th>
<th>하행 종점역</th>
<th>설정</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<div class="tab-screen" id='section-manager-screen'>
<h3>구간을 수정할 노선을 선택해주세요.</h3>
<div id="buttons"></div>
<div class="section-manager">
<h3 id="title"></h3>
<div>
<h4>구간 등록</h4>
</div>
<div id='section-registration-div'>
</div>
<table>
<thead>
<tr>
<th>순서</th>
<th>이름</th>
<th>설정</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<div class="tab-screen map" id='map-print-manager-screen'></div>
<script type="module" src="src/index.js"></script>
</body>
</html>
40 changes: 40 additions & 0 deletions src/controllers/lineManager.js
Original file line number Diff line number Diff line change
@@ -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);
}
};
65 changes: 65 additions & 0 deletions src/controllers/sectionManager.js
Original file line number Diff line number Diff line change
@@ -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개 이상의 역이 존재해야 합니다.');
}
};
36 changes: 36 additions & 0 deletions src/controllers/stationManager.js
Original file line number Diff line number Diff line change
@@ -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('노선에 포함된 역입니다.');
}
}
};
8 changes: 8 additions & 0 deletions src/controllers/storage.js
Original file line number Diff line number Diff line change
@@ -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) : [];
}
17 changes: 17 additions & 0 deletions src/controllers/tab.js
Original file line number Diff line number Diff line change
@@ -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);
};
35 changes: 35 additions & 0 deletions src/controllers/validation.js
Original file line number Diff line number Diff line change
@@ -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);
};
Loading