Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
6e5d232
Update README.md
nxxc Dec 10, 2020
6959eb2
[feat] 프로젝트 기본 셋팅 & HTML 마크업
nxxc Dec 14, 2020
a5ba93e
[feat] 메뉴 버튼 클릭시 해당하는 메뉴로 변경
nxxc Dec 14, 2020
113380d
[feat] 사용자가 역 이름을 입력할 수 있도록 함
nxxc Dec 14, 2020
2666da3
[feat] 역 이름이 중복되는지 확인한다
nxxc Dec 14, 2020
1fa06ac
[feat] 역 이름이 2글자이상인지 확인한다
nxxc Dec 14, 2020
e9e22ba
[feat] 역 목록에 차례대로 목록을 출력한다
nxxc Dec 14, 2020
a2b9868
[feat] 역 삭제 기능 & 삭제 시 목록 업데이트
nxxc Dec 14, 2020
4fb20e0
[feat] 삭제버튼 클릭시 사용자의 확인을 받는다.
nxxc Dec 14, 2020
69284f3
[feat] state를 공유할 수 있도록 함
nxxc Dec 14, 2020
b0f6ba7
[feat] 노선 입력 기능 추가
nxxc Dec 14, 2020
eabfb06
[feat] 노선이름의 중복 확인
nxxc Dec 14, 2020
5640e7a
[feat] 상행종점과 하행종점이 같은지 확인
nxxc Dec 14, 2020
44017f6
[feat] 노선 목록 출력기능 & HTML 잘못된 마크업수정
nxxc Dec 14, 2020
97865bd
[feat] 노선 삭제 기능 추가
nxxc Dec 14, 2020
efa3dc3
[feat] 노선 삭제 시 사용자 확인 기능
nxxc Dec 14, 2020
f42cd23
[feat] 노선에 포함되어있는 역은 삭제 불가능
nxxc Dec 14, 2020
4ac7480
[feat] 새로고침시 최근 데이터 불러오기
nxxc Dec 14, 2020
6619044
[style] 상수명 변경
nxxc Dec 14, 2020
6575663
[feat] form 제출시 input 영역 초기화
nxxc Dec 14, 2020
1973220
[feat] 사용자가 등록한 노선을 버튼으로 표시
nxxc Dec 14, 2020
67ba272
[feat] 노선 클릭시 해당 노선을 수정할 수 있는 기능
nxxc Dec 14, 2020
5b822d3
[style] state => data 변수명 변경
nxxc Dec 14, 2020
4266f98
[bug] 구간 관리에서 노선이외 클릭시 이벤트 발생 막기
nxxc Dec 14, 2020
8f71beb
[fix] 새로고침 시 Line 생성자가 없어지던 버그 수정
nxxc Dec 15, 2020
f0dd0c9
[feat] 구간 등록 기능
nxxc Dec 15, 2020
f4716ef
[feat] 구간 등록시 상행종점 하행종점 업데이트
nxxc Dec 15, 2020
63d43cf
[feat] 초기 작동시 localStorage 오류 수정
nxxc Dec 15, 2020
1572cce
[feat] 구간 등록시 이미 노선에 포함되어있는지 확인
nxxc Dec 15, 2020
476b3f9
[feat] 구간관리에서 역 삭제기능 추가
nxxc Dec 15, 2020
f56aca3
[feat] 구간 수정시 노선의 최소 길이 확인
nxxc Dec 15, 2020
0ac2089
[feat] 올바르지 않은 입력일 경우 체크
nxxc Dec 15, 2020
16e356f
[refactor] 불필요한 렌더함수 호출 방지
nxxc Dec 15, 2020
6351dfe
[feat] 노선이름이 공백인 경우 추가
nxxc Dec 15, 2020
54fc416
[refactor] 중복되는 메서드들 공유
nxxc Dec 15, 2020
8aa3a8d
[feat] 노선도 출력 기능
nxxc Dec 15, 2020
b7af172
[style] 사용되는 문장들 한곳에서 관리
nxxc Dec 15, 2020
de47d22
[refactor] Line Class 정리하기
nxxc Dec 15, 2020
530958b
[refactor] 메서드의 순서 통일
nxxc Dec 15, 2020
decf895
[refactor] 데이터 동기화 방법 변경
nxxc Dec 15, 2020
3ddc5b0
[refactor] 공백입력 체크 방식변경
nxxc Dec 15, 2020
eb7c22c
[refactor] 함수 이름 변경 & 불필요한 요소 제거
nxxc Dec 15, 2020
a7d591a
[refactor] 함수명 변경 및 코드 스타일 수정
nxxc Dec 15, 2020
1e1698a
[fix] 구간 관리 메뉴벗어나도 그대로 있던 버그 수정
nxxc Dec 15, 2020
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
73 changes: 70 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,81 +3,94 @@
## 🚀 기능 요구사항

### 지하철 역 관련 기능

- 지하철 역을 등록하고 삭제할 수 있다. (단, 노선에 등록된 역은 삭제할 수 없다)
- 중복된 지하철 역 이름이 등록될 수 없다.
- 지하철 역은 2글자 이상이어야 한다.
- 지하철 역의 목록을 조회할 수 있다.

### 지하철 노선 관련 기능

- 지하철 노선을 등록하고 삭제할 수 있다.
- 중복된 지하철 노선 이름이 등록될 수 없다.
- 노선 등록 시 상행 종점역과 하행 종점역을 입력받는다.
- 지하철 노선의 목록을 조회할 수 있다.

### 지하철 구간 추가 기능

- 지하철 노선에 구간을 추가하는 기능은 노선에 역을 추가하는 기능이라고도 할 수 있다.
- 역과 역사이를 구간이라 하고 이 구간들의 모음이 노선이다.
- 역과 역사이를 구간이라 하고 이 구간들의 모음이 노선이다.
- 하나의 역은 여러개의 노선에 추가될 수 있다.
- 역과 역 사이에 새로운 역이 추가 될 수 있다.
- 노선에서 갈래길은 생길 수 없다.

<img width="500" src="/images/section1.png">

### 지하철 구간 삭제 기능

- 노선에 등록된 역을 제거할 수 있다.
- 종점을 제거할 경우 다음 역이 종점이 된다.
- 노선에 포함된 역이 두개 이하일 때는 역을 제거할 수 없다.

<img width="500" src="/images/section2.png">

### 지하철 노선에 등록된 역 조회 기능

- 노선의 상행 종점부터 하행 종점까지 연결된 순서대로 역 목록을 조회할 수 있다.

<br/>

## 💻 프로그램 실행 결과

### 역관리

<img width="100%" src="/images/station_manager.gif">

### 노선관리

<img width="100%" src="/images/line_manager.gif">

### 구간관리

<img width="100%" src="/images/section_manager.gif">

### 노선도 출력
<img width="100%" src="/images/map_print_manager.gif">

<img width="100%" src="/images/map_print_manager.gif">

## ✅ 프로그래밍 요구사항

### 메뉴 버튼

- 역 관리 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값을 가진다.
- 지하철 노선을 추가하는 button 태그는 `#line-add-button` id값을 가진다.
- 지하철 노선을 삭제하는 button 태그는 `.line-delete-button` class값을 가진다.

### 지하철 구간 추가 기능

- 지하철 노선을 선택하는 button 태그는 `.section-line-menu-button` class값을 가진다.
- 지하철 구간을 설정할 역 select 태그는 `#section-station-selector` id값을 가진다.
- 지하철 구간의 순서를 입력하는 input 태그는 `#section-order-input` id값을 가진다.
- 지하철 구간을 등록하는 button 태그는 `#section-add-button` id값을 가진다.
- 지하철 구간을 제거하는 button 태그는 `.section-delete-button` class값을 가진다.

### 지하철 노선도 출력 기능

- 지하철 노선도 출력 버튼을 누르면 `<div class="map"></div>` 태그를 만들고 해당 태그 내부에 노선도를 출력한다.

### 기존 요구사항
Expand All @@ -101,7 +114,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)를 이용하여, 새로고침하더라도 가장 최근에 작업한 정보들을 불러올 수 있도록 한다.

<br/>
Expand All @@ -112,3 +126,56 @@
- **기능을 구현하기 전에 javascript-subway-precourse/docs/README.md 파일에 구현할 기능 목록**을 정리해 추가한다.
- **git의 commit 단위는 앞 단계에서 README.md 파일에 정리한 기능 목록 단위로 추가**한다.
- [프리코스 과제 제출](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse) 문서 절차를 따라 미션을 제출한다.

## 🔥 기능 목록

- 공통 기능

- [x] 각 메뉴를 클릭시 해당 기능을 수행할 수 있게해야 한다. (역 관리, 노선 관리, 구간 관리, 지하철 노선도 출력)
- [x] data를 공유할 수 있도록 각 메뉴에서 data를 동기화 시킨다.
- [x] localStorage를 이용하여 새로고침해도 최근 데이터를 활용해 목록들을 표시한다.
- [x] form 제출 시 input을 초기화 한다.
- [x] 올바르 않은 입력일 경우 경고창을 표시하여 재입력 할 수 있게한다.

- 역 관련 기능

- [x] 사용자가 역 이름을 추가할 수 있게해야 한다.
- [x] 역 이름이 중복되는지 확인해야한다.
- [x] 역 이름이 2글자 이상인지 확인해야 한다. (미만일 경우 경고창 표시)
- [x] 사용자가 입력한 역들을 차례대로 출력해야 한다.
- [x] 삭제 버튼을 클릭시 삭제할 수 있게 해야한다.
- [x] 삭제에 성공했을 경우 목록을 업데이트해서 다시 표시해야 한다.
- [x] 삭제시 사용자의 확인을 받는다
- [x] 삭제 시 노선에 추가되어 있을 경우 삭제할 수 없게 해야 한다.

- 노선 관련 기능

- [x] 노선 이름을 등록 할 수 있게 한다.
- [x] 상행 종점 하행 종점을 등록한 역 목록에서 선택할 수 있게 해야한다.
- [x] 노선 이름이 중복되는지 확인해야한다.
- [x] 상행 종점과 하행 종점이 같은지 확인해야 한다.
- [x] 노선목록을 출력한다.
- [x] 삭제 버튼 클릭 시 삭제할 수 있게 해야한다.
- [x] 삭제에 성공했을 경우 목록을 업데이트 해서 다시 표시해야 한다.
- [x] 삭제 시 사용자의 확인을 받는다.

- 구간 관련 기능

- [x] 사용자가 등록한 노선을 표시해야한다.
- [x] 노선을 클릭 시 그 노선을 수정 할 수 있게 해야한다.
- [x] 사용자가 입력한 역들을 순서에 따라 추가 할 수 있다.
- [x] 새로운 구간 등록시 노선의 상행종점과 하행종점을 업데이트 한다.
- [x] 구간 등록시 노선에 이미 포함된 역인지 확인한다.
- [x] '노선에서 제거' 버튼 클릭시 노선에서 제거 할 수 있게 해야한다.
- [x] 삭제시 노선에 포함된 역이 두개 이하인지 확인해야한다.
- [x] 삭제에 성공했을 경우 목록을 업데이트 해서 다시 표시해야 한다.

- 노선도 출력 기능

- [x] 노선의 상행종점부터 하행종점까지 순서대로 목록을 표시해야 한다.

- 예외사항
- 입력의 모든 공백은 제외한다.
- 노선에 구간 추가 시 현재의 길이보다 더 높은 숫자를 입력한 경우 마지막에 추가된다.


100 changes: 99 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,108 @@
<head>
<meta charset="UTF-8" />
<title>지하철 노선도 관리</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="app">
<h1>🚇 지하철 노선도 관리 </h1>
<h1>🚇 지하철 노선도 관리</h1>
<nav id="menu">
<button id="station-manager-button">1.역 관리</button>
<button id="line-manager-button">2.노선 관리</button>
<button id="section-manager-button">3.구간 관리</button>
<button id="map-print-manager-button">4.지하철 노선도 출력</button>
</nav>
<div id="station-manager">
<form id="station-form">
<label for="station-name-input"><strong>역 이름</strong></label>
<input
type="text"
id="station-name-input"
placeholder="역 이름을 입력하주세요."
/>
<button id="station-add-button">역 추가</button>
</form>
<section id="station-result">
<h2>🚉 지하철 역 목록</h2>
<table id="station-table">
<thead>
<tr>
<th>역 이름</th>
<th>설정</th>
</tr>
</thead>
<tbody id="station-table-body"></tbody>
</table>
</section>
</div>
<div id="line-manager" style="display: none">
<form id="line-form">
<label for="line-name-input"><strong>노선 이름</strong></label>
<input
type="text"
id="line-name-input"
placeholder="노선 이름을 입력해 주세요."
/>
<p>
<strong>상행 종점</strong>
<select id="line-start-station-selector"></select>
</p>
<p>
<strong>하행 종점</strong>
<select id="line-end-station-selector"></select>
</p>
<button id="line-add-button">노선 추가</button>
</form>
<section id="line-result">
<h2>🚉 지하철 노선 목록</h2>
<table id="line-table">
<thead>
<tr>
<th>노선 이름</th>
<th>상행 종점역</th>
<th>하행 종점역</th>
<th>설정</th>
</tr>
</thead>
<tbody id="line-table-body"></tbody>
</table>
</h2>
</section>
</div>
<div id="section-manager" style="display: none">
<h2>구간을 수정할 노선을 선택해 주세요.</h2>
<nav id="section-line-menu">
</nav>
<div id="section-detail">
<form id="section-form">
<h3 id="section-form-header">n호선 관리</h3>
<h4>구간 등록</h4>
<select id="section-station-selector"></select>
<input
type="number"
id="section-order-input"
min="0"
placeholder="순서"
/>
<button id="section-add-button">등록</button>
</form>
<section id="section-result">
<h2>🚉 지하철 노선 목록</h2>
<table id="section-table">
<thead>
<tr>
<th>순서</th>
<th>이름</th>
<th>설정</th>
</tr>
</thead>
<tbody id="section-table-body"></tbody>
</table>
</h2>
</section>
</div>
</div>
<div id="map-print-manager" style="display: none"></div>
</div>
<script type="module" src="src/index.js"></script>
</body>
Expand Down
45 changes: 45 additions & 0 deletions src/factory/Component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
export default class Component {
constructor(props = {}) {
this.data = {};
this.props = props;
this.managerId = props.managerId;
this.syncData = props.syncData;
this.container = document.querySelector(`#${props.containerId}`);
}

setData(nextData) {
this.data = {
...this.data,
...nextData,
};
this.render?.();
}

clearInput() {
this.userInput.value = '';
}

addToTable(value, keyName) {
const newData = { ...this.data };
newData[keyName].push(value);
this.syncData(newData);
}

deleteFromTable(index, keyName) {
const newData = { ...this.data };
newData[keyName].splice(index, 1);
this.syncData(newData);
}

updateTable(template) {
this.table.innerHTML = template;
}

show() {
this.container.style.display = 'block';
}

hide() {
this.container.style.display = 'none';
}
}
35 changes: 35 additions & 0 deletions src/factory/Line.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const MIN_SECTION_LENGTH = 2;

export default class Line {
constructor(props) {
this.props = props;
this.name = props.name;
this.startStation = props.startStation;
this.endStation = props.endStation;
this.section = this.setSection();
}

setSection = () => this.props.section || [this.startStation, this.endStation];

addStationToSection({ stationName, index }) {
this.section.splice(index, 0, stationName);
this.updateStartStation();
this.updateEndStation();
}

deleteStationFromSection({ index }) {
this.section.splice(index, 1);
this.updateStartStation();
this.updateEndStation();
}

checkSectionLength = () => this.section.length === MIN_SECTION_LENGTH;

updateStartStation() {
[this.startStation] = this.section;
}

updateEndStation() {
this.endStation = this.section[this.section.length - 1];
}
}
5 changes: 5 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import SubwayManager from './managers/app.js';

const app = new SubwayManager();

app.init();
Loading