From 47db1b3edf21d5fe679e65f45abda88b92cc83d3 Mon Sep 17 00:00:00 2001 From: Eun Seok Date: Wed, 6 May 2020 15:58:25 +0900 Subject: [PATCH 01/48] =?UTF-8?q?[feat]=20create=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/controller/LineController.java | 55 ++++++++++++ .../subway/admin/domain/LineStation.java | 1 - .../repository/LineStationRepository.java | 9 ++ .../subway/admin/service/LineService.java | 9 +- src/main/resources/application.properties | 3 +- src/main/resources/schema.sql | 9 ++ .../admin/acceptance/LineAcceptanceTest.java | 83 ++++++++++--------- .../admin/repository/LineRepositoryTest.java | 26 ++++++ 8 files changed, 147 insertions(+), 48 deletions(-) create mode 100644 src/main/java/wooteco/subway/admin/controller/LineController.java create mode 100644 src/main/java/wooteco/subway/admin/repository/LineStationRepository.java create mode 100644 src/test/java/wooteco/subway/admin/repository/LineRepositoryTest.java diff --git a/src/main/java/wooteco/subway/admin/controller/LineController.java b/src/main/java/wooteco/subway/admin/controller/LineController.java new file mode 100644 index 0000000000..54108ff8c2 --- /dev/null +++ b/src/main/java/wooteco/subway/admin/controller/LineController.java @@ -0,0 +1,55 @@ +package wooteco.subway.admin.controller; + +import java.net.URI; +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; + +import wooteco.subway.admin.domain.Line; +import wooteco.subway.admin.dto.LineRequest; +import wooteco.subway.admin.dto.LineResponse; +import wooteco.subway.admin.service.LineService; + +@Controller +public class LineController { + + @Autowired + private LineService lineService; + + @PostMapping("/lines") + @ResponseBody + public ResponseEntity createLine(@RequestBody LineRequest lineRequest) { + Line line = new Line( + lineRequest.getName(), + lineRequest.getStartTime(), + lineRequest.getEndTime(), + lineRequest.getIntervalTime() + ); + + return ResponseEntity.created(URI.create("")).body(lineService.save(line)); + } + + @GetMapping("/lines") + @ResponseBody + public List getLines() { + List lines = lineService.showLines(); + + return lineService.showLines().stream() + .map(LineResponse::of) + .collect(Collectors.toList()); + } + + @GetMapping("/lines/{id}") + @ResponseBody + public LineResponse getLine(@PathVariable Long id) { + return lineService.findLineWithStationsById(id); + } +} diff --git a/src/main/java/wooteco/subway/admin/domain/LineStation.java b/src/main/java/wooteco/subway/admin/domain/LineStation.java index fdd1a8a0e3..965c195407 100644 --- a/src/main/java/wooteco/subway/admin/domain/LineStation.java +++ b/src/main/java/wooteco/subway/admin/domain/LineStation.java @@ -1,7 +1,6 @@ package wooteco.subway.admin.domain; public class LineStation { - // TODO: 테이블 컬럼명과 변수명이 다른 경우 private Long stationId; private Long preStationId; private int distance; diff --git a/src/main/java/wooteco/subway/admin/repository/LineStationRepository.java b/src/main/java/wooteco/subway/admin/repository/LineStationRepository.java new file mode 100644 index 0000000000..4df8fbc21e --- /dev/null +++ b/src/main/java/wooteco/subway/admin/repository/LineStationRepository.java @@ -0,0 +1,9 @@ +package wooteco.subway.admin.repository; + +import org.springframework.data.repository.CrudRepository; + +import wooteco.subway.admin.domain.LineStation; + +public interface LineStationRepository extends CrudRepository { + +} diff --git a/src/main/java/wooteco/subway/admin/service/LineService.java b/src/main/java/wooteco/subway/admin/service/LineService.java index 659426b5bb..f5a1d44558 100644 --- a/src/main/java/wooteco/subway/admin/service/LineService.java +++ b/src/main/java/wooteco/subway/admin/service/LineService.java @@ -1,17 +1,16 @@ package wooteco.subway.admin.service; +import java.util.List; + import org.springframework.stereotype.Service; + import wooteco.subway.admin.domain.Line; -import wooteco.subway.admin.domain.LineStation; -import wooteco.subway.admin.domain.Station; import wooteco.subway.admin.dto.LineResponse; import wooteco.subway.admin.dto.LineStationCreateRequest; import wooteco.subway.admin.repository.LineRepository; import wooteco.subway.admin.repository.StationRepository; -import java.util.List; -import java.util.Set; - +@Service public class LineService { private LineRepository lineRepository; private StationRepository stationRepository; diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8b13789179..d95feaac4c 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,2 @@ - +spring.h2.console.enabled=true +logging.level.org.springframework.jdbc.core.JdbcTemplate=debug \ No newline at end of file diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index 254ef7de53..6c95977cab 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -16,4 +16,13 @@ create table if not exists LINE created_at datetime, updated_at datetime, primary key(id) +); + +create table if not exists LINE_STATION +( + line bigint not null, + station_Id bigint not null, + preStation_Id bigint not null, + distance int not null, + duration int not null ); \ No newline at end of file diff --git a/src/test/java/wooteco/subway/admin/acceptance/LineAcceptanceTest.java b/src/test/java/wooteco/subway/admin/acceptance/LineAcceptanceTest.java index 2bec4c77f6..437d23fe5c 100644 --- a/src/test/java/wooteco/subway/admin/acceptance/LineAcceptanceTest.java +++ b/src/test/java/wooteco/subway/admin/acceptance/LineAcceptanceTest.java @@ -1,7 +1,13 @@ package wooteco.subway.admin.acceptance; -import io.restassured.RestAssured; -import io.restassured.specification.RequestSpecification; +import static org.assertj.core.api.Assertions.*; + +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -9,15 +15,10 @@ import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; -import wooteco.subway.admin.dto.LineResponse; -import java.time.LocalTime; -import java.time.format.DateTimeFormatter; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; +import io.restassured.RestAssured; +import io.restassured.specification.RequestSpecification; +import wooteco.subway.admin.dto.LineResponse; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class LineAcceptanceTest { @@ -33,7 +34,6 @@ public static RequestSpecification given() { return RestAssured.given().log().all(); } - @DisplayName("지하철 노선을 관리한다") @Test void manageLine() { @@ -43,9 +43,10 @@ void manageLine() { createLine("2호선"); createLine("3호선"); // then + System.out.println(">>>>create"); List lines = getLines(); assertThat(lines.size()).isEqualTo(4); - + System.out.println(">>>>getLine"); // when LineResponse line = getLine(lines.get(0).getId()); // then @@ -73,10 +74,10 @@ void manageLine() { private LineResponse getLine(Long id) { return given().when(). - get("/lines/" + id). - then(). - log().all(). - extract().as(LineResponse.class); + get("/lines/" + id). + then(). + log().all(). + extract().as(LineResponse.class); } private void createLine(String name) { @@ -87,14 +88,14 @@ private void createLine(String name) { params.put("intervalTime", "10"); given(). - body(params). - contentType(MediaType.APPLICATION_JSON_VALUE). - accept(MediaType.APPLICATION_JSON_VALUE). - when(). - post("/lines"). - then(). - log().all(). - statusCode(HttpStatus.CREATED.value()); + body(params). + contentType(MediaType.APPLICATION_JSON_VALUE). + accept(MediaType.APPLICATION_JSON_VALUE). + when(). + post("/lines"). + then(). + log().all(). + statusCode(HttpStatus.CREATED.value()); } private void updateLine(Long id, LocalTime startTime, LocalTime endTime) { @@ -104,32 +105,32 @@ private void updateLine(Long id, LocalTime startTime, LocalTime endTime) { params.put("intervalTime", "10"); given(). - body(params). - contentType(MediaType.APPLICATION_JSON_VALUE). - accept(MediaType.APPLICATION_JSON_VALUE). - when(). - put("/lines/" + id). - then(). - log().all(). - statusCode(HttpStatus.OK.value()); + body(params). + contentType(MediaType.APPLICATION_JSON_VALUE). + accept(MediaType.APPLICATION_JSON_VALUE). + when(). + put("/lines/" + id). + then(). + log().all(). + statusCode(HttpStatus.OK.value()); } private List getLines() { return - given(). + given(). when(). - get("/lines"). + get("/lines"). then(). - log().all(). - extract(). - jsonPath().getList(".", LineResponse.class); + log().all(). + extract(). + jsonPath().getList(".", LineResponse.class); } private void deleteLine(Long id) { given(). - when(). - delete("/lines/" + id). - then(). - log().all(); + when(). + delete("/lines/" + id). + then(). + log().all(); } } diff --git a/src/test/java/wooteco/subway/admin/repository/LineRepositoryTest.java b/src/test/java/wooteco/subway/admin/repository/LineRepositoryTest.java new file mode 100644 index 0000000000..285cf7b210 --- /dev/null +++ b/src/test/java/wooteco/subway/admin/repository/LineRepositoryTest.java @@ -0,0 +1,26 @@ +package wooteco.subway.admin.repository; + +import static org.assertj.core.api.Assertions.*; + +import java.time.LocalTime; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.data.jdbc.DataJdbcTest; + +import wooteco.subway.admin.domain.Line; + +@DataJdbcTest +class LineRepositoryTest { + @Autowired + private LineRepository lineRepository; + + @Test + void save() { + Line line = new Line("강남역", LocalTime.of(5, 30), LocalTime.of(23, 30), 10); + + Line persistLine = lineRepository.save(line); + + assertThat(persistLine.getId()).isNotNull(); + } +} \ No newline at end of file From 39c8edf15fa9d1ac7b8ec4737675d79338cc4c6f Mon Sep 17 00:00:00 2001 From: Eun Seok Date: Wed, 6 May 2020 16:30:25 +0900 Subject: [PATCH 02/48] =?UTF-8?q?[feat]=20=EC=9D=B8=EC=88=98=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EC=9C=84=ED=95=9C=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - create 기능 구현 - delete 기능 구현 - update 기능 구현 --- .../admin/controller/LineController.java | 28 +++++++++++++++++-- .../subway/admin/service/LineService.java | 5 ++-- src/main/resources/schema.sql | 4 +-- .../admin/acceptance/LineAcceptanceTest.java | 4 +++ 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/main/java/wooteco/subway/admin/controller/LineController.java b/src/main/java/wooteco/subway/admin/controller/LineController.java index 54108ff8c2..e89a9a4d3a 100644 --- a/src/main/java/wooteco/subway/admin/controller/LineController.java +++ b/src/main/java/wooteco/subway/admin/controller/LineController.java @@ -7,9 +7,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.ResponseBody; @@ -24,6 +26,7 @@ public class LineController { @Autowired private LineService lineService; + // TODO: 2020/05/06 create URI 구현 @PostMapping("/lines") @ResponseBody public ResponseEntity createLine(@RequestBody LineRequest lineRequest) { @@ -49,7 +52,28 @@ public List getLines() { @GetMapping("/lines/{id}") @ResponseBody - public LineResponse getLine(@PathVariable Long id) { - return lineService.findLineWithStationsById(id); + public ResponseEntity getLine(@PathVariable Long id) { + return ResponseEntity.ok(lineService.findLineWithStationsById(id)); } + + @PutMapping("/lines/{id}") + @ResponseBody + public ResponseEntity updateLine(@PathVariable Long id, @RequestBody LineRequest lineRequest) { + Line line = new Line( + lineRequest.getName(), + lineRequest.getStartTime(), + lineRequest.getEndTime(), + lineRequest.getIntervalTime() + ); + lineService.updateLine(id, line); + return ResponseEntity.ok().build(); + } + + @DeleteMapping("/lines/{id}") + @ResponseBody + public ResponseEntity deleteLine(@PathVariable Long id) { + lineService.deleteLineById(id); + return ResponseEntity.ok().build(); + } + } diff --git a/src/main/java/wooteco/subway/admin/service/LineService.java b/src/main/java/wooteco/subway/admin/service/LineService.java index f5a1d44558..f28c96d7bb 100644 --- a/src/main/java/wooteco/subway/admin/service/LineService.java +++ b/src/main/java/wooteco/subway/admin/service/LineService.java @@ -47,7 +47,8 @@ public void removeLineStation(Long lineId, Long stationId) { } public LineResponse findLineWithStationsById(Long id) { - // TODO: 구현 - return new LineResponse(); + Line line = lineRepository.findById(id) + .orElseThrow(() -> new IllegalArgumentException("해당 아이디가 존지하지 않습니다")); + return LineResponse.of(line); } } diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index 6c95977cab..c37c67b9ff 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -21,8 +21,8 @@ create table if not exists LINE create table if not exists LINE_STATION ( line bigint not null, - station_Id bigint not null, - preStation_Id bigint not null, + station_id bigint not null, + pre_station_id bigint, distance int not null, duration int not null ); \ No newline at end of file diff --git a/src/test/java/wooteco/subway/admin/acceptance/LineAcceptanceTest.java b/src/test/java/wooteco/subway/admin/acceptance/LineAcceptanceTest.java index 437d23fe5c..e8b70309da 100644 --- a/src/test/java/wooteco/subway/admin/acceptance/LineAcceptanceTest.java +++ b/src/test/java/wooteco/subway/admin/acceptance/LineAcceptanceTest.java @@ -44,9 +44,11 @@ void manageLine() { createLine("3호선"); // then System.out.println(">>>>create"); + List lines = getLines(); assertThat(lines.size()).isEqualTo(4); System.out.println(">>>>getLine"); + // when LineResponse line = getLine(lines.get(0).getId()); // then @@ -55,6 +57,7 @@ void manageLine() { assertThat(line.getStartTime()).isNotNull(); assertThat(line.getEndTime()).isNotNull(); assertThat(line.getIntervalTime()).isNotNull(); + System.out.println(">>>isNotNull"); // when LocalTime startTime = LocalTime.of(8, 00); @@ -64,6 +67,7 @@ void manageLine() { LineResponse updatedLine = getLine(line.getId()); assertThat(updatedLine.getStartTime()).isEqualTo(startTime); assertThat(updatedLine.getEndTime()).isEqualTo(endTime); + System.out.println(">>>update"); // when deleteLine(line.getId()); From de22f8602cc4c97f7a76f79cef868a398f529e89 Mon Sep 17 00:00:00 2001 From: Eun Seok Date: Wed, 6 May 2020 17:23:32 +0900 Subject: [PATCH 03/48] =?UTF-8?q?[feat]=20resource=20file=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 27 +- .../admin/controller/LineController.java | 10 +- .../admin/controller/WebController.java | 13 + src/main/resources/static/api/index.js | 50 + src/main/resources/static/css/admin-app.css | 56 + src/main/resources/static/css/admin-edge.css | 7 + src/main/resources/static/css/admin-line.css | 7 + .../resources/static/css/admin-station.css | 7 + .../resources/static/images/logo_small.png | Bin 0 -> 740 bytes .../resources/static/images/main_logo.png | Bin 0 -> 4214 bytes src/main/resources/static/js/AdminApp.js | 14 + .../resources/static/js/views/AdminEdge.js | 68 + .../resources/static/js/views/AdminLine.js | 105 + .../resources/static/js/views/AdminStation.js | 46 + .../static/lib/slider/tiny-slider.css | 140 + .../static/lib/slider/tiny-slider.js | 3655 +++++++++++++++++ src/main/resources/static/ui/Modal.js | 24 + src/main/resources/static/utils/constants.js | 12 + .../static/utils/defaultSubwayData.js | 352 ++ .../resources/static/utils/subwayMockData.js | 1 + src/main/resources/static/utils/templates.js | 74 + src/main/resources/templates/admin-edge.hbs | 162 + src/main/resources/templates/admin-line.hbs | 97 + .../resources/templates/admin-station.hbs | 51 + src/main/resources/templates/index.hbs | 43 + 25 files changed, 5005 insertions(+), 16 deletions(-) create mode 100644 src/main/java/wooteco/subway/admin/controller/WebController.java create mode 100644 src/main/resources/static/api/index.js create mode 100644 src/main/resources/static/css/admin-app.css create mode 100644 src/main/resources/static/css/admin-edge.css create mode 100644 src/main/resources/static/css/admin-line.css create mode 100644 src/main/resources/static/css/admin-station.css create mode 100644 src/main/resources/static/images/logo_small.png create mode 100644 src/main/resources/static/images/main_logo.png create mode 100644 src/main/resources/static/js/AdminApp.js create mode 100644 src/main/resources/static/js/views/AdminEdge.js create mode 100644 src/main/resources/static/js/views/AdminLine.js create mode 100644 src/main/resources/static/js/views/AdminStation.js create mode 100755 src/main/resources/static/lib/slider/tiny-slider.css create mode 100644 src/main/resources/static/lib/slider/tiny-slider.js create mode 100644 src/main/resources/static/ui/Modal.js create mode 100644 src/main/resources/static/utils/constants.js create mode 100644 src/main/resources/static/utils/defaultSubwayData.js create mode 100644 src/main/resources/static/utils/subwayMockData.js create mode 100644 src/main/resources/static/utils/templates.js create mode 100644 src/main/resources/templates/admin-edge.hbs create mode 100644 src/main/resources/templates/admin-line.hbs create mode 100644 src/main/resources/templates/admin-station.hbs create mode 100644 src/main/resources/templates/index.hbs diff --git a/build.gradle b/build.gradle index dc14a93f38..b51e451b4d 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { - id 'org.springframework.boot' version '2.2.5.RELEASE' - id 'io.spring.dependency-management' version '1.0.9.RELEASE' - id 'java' + id 'org.springframework.boot' version '2.2.5.RELEASE' + id 'io.spring.dependency-management' version '1.0.9.RELEASE' + id 'java' } group = 'com.example' @@ -9,20 +9,21 @@ version = '0.0.1-SNAPSHOT' sourceCompatibility = '1.8' repositories { - mavenCentral() + mavenCentral() } dependencies { - implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.springframework.boot:spring-boot-starter-data-jdbc' - implementation 'net.rakugakibox.spring.boot:logback-access-spring-boot-starter:2.7.1' - testImplementation 'io.rest-assured:rest-assured:3.3.0' - testImplementation('org.springframework.boot:spring-boot-starter-test') { - exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' - } - runtimeOnly 'com.h2database:h2' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-data-jdbc' + implementation 'net.rakugakibox.spring.boot:logback-access-spring-boot-starter:2.7.1' + implementation 'pl.allegro.tech.boot:handlebars-spring-boot-starter:0.3.1' + testImplementation 'io.rest-assured:rest-assured:3.3.0' + testImplementation('org.springframework.boot:spring-boot-starter-test') { + exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' + } + runtimeOnly 'com.h2database:h2' } test { - useJUnitPlatform() + useJUnitPlatform() } diff --git a/src/main/java/wooteco/subway/admin/controller/LineController.java b/src/main/java/wooteco/subway/admin/controller/LineController.java index e89a9a4d3a..eff4922665 100644 --- a/src/main/java/wooteco/subway/admin/controller/LineController.java +++ b/src/main/java/wooteco/subway/admin/controller/LineController.java @@ -26,18 +26,22 @@ public class LineController { @Autowired private LineService lineService; - // TODO: 2020/05/06 create URI 구현 + @GetMapping("/admin-line") + public String adminLine() { + return "admin-line"; + } + @PostMapping("/lines") @ResponseBody public ResponseEntity createLine(@RequestBody LineRequest lineRequest) { + System.out.println(lineRequest); Line line = new Line( lineRequest.getName(), lineRequest.getStartTime(), lineRequest.getEndTime(), lineRequest.getIntervalTime() ); - - return ResponseEntity.created(URI.create("")).body(lineService.save(line)); + return ResponseEntity.created(URI.create("/index")).body(lineService.save(line)); } @GetMapping("/lines") diff --git a/src/main/java/wooteco/subway/admin/controller/WebController.java b/src/main/java/wooteco/subway/admin/controller/WebController.java new file mode 100644 index 0000000000..4c83aa777c --- /dev/null +++ b/src/main/java/wooteco/subway/admin/controller/WebController.java @@ -0,0 +1,13 @@ +package wooteco.subway.admin.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class WebController { + + @GetMapping("/") + public String index() { + return "index"; + } +} diff --git a/src/main/resources/static/api/index.js b/src/main/resources/static/api/index.js new file mode 100644 index 0000000000..b082c91934 --- /dev/null +++ b/src/main/resources/static/api/index.js @@ -0,0 +1,50 @@ +const BASE_URL = "localhost:8080"; + +const METHOD = { + PUT() { + return { + method: "PUT" + }; + }, + DELETE() { + return { + method: "DELETE" + }; + }, + POST(data) { + return { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + content: data + }) + }; + } +}; + +const api = (() => { + const request = (uri, config) => fetch(uri, config).then(data => data.json()); + + const station = { + get() { + request(`${BASE_URL}/stations`); + }, + create(data) { + request(`${BASE_URL}/station`, METHOD.POST(data)); + }, + update(data) { + request(`${BASE_URL}/station/${id}`, METHOD.PUT(data)); + }, + delete(id) { + request(`${BASE_URL}/station/${id}`, METHOD.DELETE); + } + }; + + return { + station + }; +})(); + +export default api; diff --git a/src/main/resources/static/css/admin-app.css b/src/main/resources/static/css/admin-app.css new file mode 100644 index 0000000000..62d329e1a0 --- /dev/null +++ b/src/main/resources/static/css/admin-app.css @@ -0,0 +1,56 @@ +.app-container { + height: calc(100vh - 78px); +} + +.main-logo { + width: 170px; +} + +.modal { + transition: opacity 0.25s ease; +} + +body { + overflow-y: hidden; +} + +body.modal-active { + overflow-x: hidden; + overflow-y: visible !important; +} + +.width-350px { + width: 350px; +} + +.width-400px { + width: 400px; +} + +.width-450px { + width: 450px; +} + +.top-28px { + top: 28px; +} + +.left-10px { + left: 10px; +} + +.right-10px { + right: 10px; +} + +.top-50 { + top: 50%; +} + +.bottom-6px { + bottom: 6px; +} + +.height-90 { + height: 90%; +} diff --git a/src/main/resources/static/css/admin-edge.css b/src/main/resources/static/css/admin-edge.css new file mode 100644 index 0000000000..ee3d31ce83 --- /dev/null +++ b/src/main/resources/static/css/admin-edge.css @@ -0,0 +1,7 @@ +#subway-station-name { + width: calc(100% - 60px); +} + +.slider-list { + height: calc(100vh - 275px); +} diff --git a/src/main/resources/static/css/admin-line.css b/src/main/resources/static/css/admin-line.css new file mode 100644 index 0000000000..c51e659c17 --- /dev/null +++ b/src/main/resources/static/css/admin-line.css @@ -0,0 +1,7 @@ +.subway-lines-container { + max-height: calc(100vh - 450px); +} + +.lines-list { + height: calc(100% - 400px); +} diff --git a/src/main/resources/static/css/admin-station.css b/src/main/resources/static/css/admin-station.css new file mode 100644 index 0000000000..53eba95b6b --- /dev/null +++ b/src/main/resources/static/css/admin-station.css @@ -0,0 +1,7 @@ +.station-list-container { + max-height: calc(100% - 100px); +} + +#station-name { + width: calc(100% - 61px); +} diff --git a/src/main/resources/static/images/logo_small.png b/src/main/resources/static/images/logo_small.png new file mode 100644 index 0000000000000000000000000000000000000000..c3e4d9db993fcf6f068d8080c79f9af48a4ff644 GIT binary patch literal 740 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 aZjlgaXa>{ { + initNavigation(); + }; + + return { + init + }; +} + +const adminApp = new AdminApp(); +adminApp.init(); diff --git a/src/main/resources/static/js/views/AdminEdge.js b/src/main/resources/static/js/views/AdminEdge.js new file mode 100644 index 0000000000..4f1aa5b705 --- /dev/null +++ b/src/main/resources/static/js/views/AdminEdge.js @@ -0,0 +1,68 @@ +import { + optionTemplate, + subwayLinesItemTemplate +} from "../../utils/templates.js"; +import { defaultSubwayLines } from "../../utils/subwayMockData.js"; +import tns from "../../lib/slider/tiny-slider.js"; +import { EVENT_TYPE } from "../../utils/constants.js"; +import Modal from "../../ui/Modal.js"; + +function AdminEdge() { + const $subwayLinesSlider = document.querySelector(".subway-lines-slider"); + const createSubwayEdgeModal = new Modal(); + + const initSubwayLinesSlider = () => { + $subwayLinesSlider.innerHTML = defaultSubwayLines + .map(line => subwayLinesItemTemplate(line)) + .join(""); + tns({ + container: ".subway-lines-slider", + loop: true, + slideBy: "page", + speed: 400, + autoplayButtonOutput: false, + mouseDrag: true, + lazyload: true, + controlsContainer: "#slider-controls", + items: 1, + edgePadding: 25 + }); + }; + + const initSubwayLineOptions = () => { + const subwayLineOptionTemplate = defaultSubwayLines + .map(line => optionTemplate(line.title)) + .join(""); + const $stationSelectOptions = document.querySelector( + "#station-select-options" + ); + $stationSelectOptions.insertAdjacentHTML( + "afterbegin", + subwayLineOptionTemplate + ); + }; + + const onRemoveStationHandler = event => { + const $target = event.target; + const isDeleteButton = $target.classList.contains("mdi-delete"); + if (isDeleteButton) { + $target.closest(".list-item").remove(); + } + }; + + const initEventListeners = () => { + $subwayLinesSlider.addEventListener( + EVENT_TYPE.CLICK, + onRemoveStationHandler + ); + }; + + this.init = () => { + initSubwayLinesSlider(); + initSubwayLineOptions(); + initEventListeners(); + }; +} + +const adminEdge = new AdminEdge(); +adminEdge.init(); diff --git a/src/main/resources/static/js/views/AdminLine.js b/src/main/resources/static/js/views/AdminLine.js new file mode 100644 index 0000000000..83a6b2254f --- /dev/null +++ b/src/main/resources/static/js/views/AdminLine.js @@ -0,0 +1,105 @@ +import {EVENT_TYPE} from "../../utils/constants.js"; +import {colorSelectOptionTemplate, subwayLinesTemplate} from "../../utils/templates.js"; +import {defaultSubwayLines} from "../../utils/subwayMockData.js"; +import {subwayLineColorOptions} from "../../utils/defaultSubwayData.js"; +import Modal from "../../ui/Modal.js"; + +function AdminLine() { + const $subwayLineList = document.querySelector("#subway-line-list"); + const $subwayLineNameInput = document.querySelector("#subway-line-name"); + const $subwayLineColorInput = document.querySelector("#subway-line-color"); + + const $createSubwayLineButton = document.querySelector( + "#subway-line-create-form #submit-button" + ); + const subwayLineModal = new Modal(); + + const onCreateSubwayLine = event => { + event.preventDefault(); + + const newSubwayLine = { + title: $subwayLineNameInput.value, + bgColor: $subwayLineColorInput.value + }; + + // 유효성검사 + // $subwayLineList.insertAdjacentHTML( + // "beforeend", + // subwayLinesTemplate(newSubwayLine) + // ); + subwayLineModal.toggle(); + $subwayLineNameInput.value = ""; + $subwayLineColorInput.value = ""; + }; + + const onDeleteSubwayLine = event => { + const $target = event.target; + const isDeleteButton = $target.classList.contains("mdi-delete"); + if (isDeleteButton) { + $target.closest(".subway-line-item").remove(); + } + }; + + const onUpdateSubwayLine = event => { + const $target = event.target; + const isUpdateButton = $target.classList.contains("mdi-pencil"); + if (isUpdateButton) { + subwayLineModal.toggle(); + } + }; + + const onEditSubwayLine = event => { + const $target = event.target; + const isDeleteButton = $target.classList.contains("mdi-pencil"); + }; + + const initDefaultSubwayLines = () => { + defaultSubwayLines.map(line => { + $subwayLineList.insertAdjacentHTML( + "beforeend", + subwayLinesTemplate(line) + ); + }); + }; + + const initEventListeners = () => { + $subwayLineList.addEventListener(EVENT_TYPE.CLICK, onDeleteSubwayLine); + $subwayLineList.addEventListener(EVENT_TYPE.CLICK, onUpdateSubwayLine); + $createSubwayLineButton.addEventListener( + EVENT_TYPE.CLICK, + onCreateSubwayLine + ); + }; + + const onSelectColorHandler = event => { + event.preventDefault(); + const $target = event.target; + if ($target.classList.contains("color-select-option")) { + document.querySelector("#subway-line-color").value = + $target.dataset.color; + } + }; + + const initCreateSubwayLineForm = () => { + const $colorSelectContainer = document.querySelector( + "#subway-line-color-select-container" + ); + const colorSelectTemplate = subwayLineColorOptions + .map((option, index) => colorSelectOptionTemplate(option, index)) + .join(""); + $colorSelectContainer.insertAdjacentHTML("beforeend", colorSelectTemplate); + $colorSelectContainer.addEventListener( + EVENT_TYPE.CLICK, + onSelectColorHandler + ); + }; + + this.init = () => { + initDefaultSubwayLines(); + initEventListeners(); + initCreateSubwayLineForm(); + }; +} + +const adminLine = new AdminLine(); +adminLine.init(); diff --git a/src/main/resources/static/js/views/AdminStation.js b/src/main/resources/static/js/views/AdminStation.js new file mode 100644 index 0000000000..1c290276fe --- /dev/null +++ b/src/main/resources/static/js/views/AdminStation.js @@ -0,0 +1,46 @@ +import { EVENT_TYPE, ERROR_MESSAGE, KEY_TYPE } from "../../utils/constants.js"; +import { listItemTemplate } from "../../utils/templates.js"; + +function AdminStation() { + const $stationInput = document.querySelector("#station-name"); + const $stationList = document.querySelector("#station-list"); + + const onAddStationHandler = event => { + if (event.key !== KEY_TYPE.ENTER) { + return; + } + event.preventDefault(); + const $stationNameInput = document.querySelector("#station-name"); + const stationName = $stationNameInput.value; + if (!stationName) { + alert(ERROR_MESSAGE.NOT_EMPTY); + return; + } + $stationNameInput.value = ""; + $stationList.insertAdjacentHTML("beforeend", listItemTemplate(stationName)); + }; + + const onRemoveStationHandler = event => { + const $target = event.target; + const isDeleteButton = $target.classList.contains("mdi-delete"); + if (isDeleteButton) { + $target.closest(".list-item").remove(); + } + }; + + const initEventListeners = () => { + $stationInput.addEventListener(EVENT_TYPE.KEY_PRESS, onAddStationHandler); + $stationList.addEventListener(EVENT_TYPE.CLICK, onRemoveStationHandler); + }; + + const init = () => { + initEventListeners(); + }; + + return { + init + }; +} + +const adminStation = new AdminStation(); +adminStation.init(); diff --git a/src/main/resources/static/lib/slider/tiny-slider.css b/src/main/resources/static/lib/slider/tiny-slider.css new file mode 100755 index 0000000000..4cb211af8a --- /dev/null +++ b/src/main/resources/static/lib/slider/tiny-slider.css @@ -0,0 +1,140 @@ +.tns-outer { + padding: 0 !important; +} +.tns-outer [hidden] { + display: none !important; +} +.tns-outer [aria-controls], +.tns-outer [data-action] { + cursor: pointer; +} +.tns-slider { + -webkit-transition: all 0s; + -moz-transition: all 0s; + transition: all 0s; +} +.tns-slider > .tns-item { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.tns-horizontal.tns-subpixel { + white-space: nowrap; +} +.tns-horizontal.tns-subpixel > .tns-item { + display: inline-block; + vertical-align: top; + white-space: normal; +} +.tns-horizontal.tns-no-subpixel:after { + content: ""; + display: table; + clear: both; +} +.tns-horizontal.tns-no-subpixel > .tns-item { + float: left; +} +.tns-horizontal.tns-carousel.tns-no-subpixel > .tns-item { + margin-right: -100%; +} +.tns-no-calc { + position: relative; + left: 0; +} +.tns-gallery { + position: relative; + left: 0; + min-height: 1px; +} +.tns-gallery > .tns-item { + position: absolute; + left: -100%; + -webkit-transition: transform 0s, opacity 0s; + -moz-transition: transform 0s, opacity 0s; + transition: transform 0s, opacity 0s; +} +.tns-gallery > .tns-slide-active { + position: relative; + left: auto !important; +} +.tns-gallery > .tns-moving { + -webkit-transition: all 0.25s; + -moz-transition: all 0.25s; + transition: all 0.25s; +} +.tns-autowidth { + display: inline-block; +} +.tns-lazy-img { + -webkit-transition: opacity 0.6s; + -moz-transition: opacity 0.6s; + transition: opacity 0.6s; + opacity: 0.6; +} +.tns-lazy-img.tns-complete { + opacity: 1; +} +.tns-ah { + -webkit-transition: height 0s; + -moz-transition: height 0s; + transition: height 0s; +} +.tns-ovh { + overflow: hidden; +} +.tns-visually-hidden { + position: absolute; + left: -10000em; +} +.tns-transparent { + opacity: 0; + visibility: hidden; +} +.tns-fadeIn { + opacity: 1; + filter: alpha(opacity=100); + z-index: 0; +} +.tns-normal, +.tns-fadeOut { + opacity: 0; + filter: alpha(opacity=0); + z-index: -1; +} +.tns-vpfix { + white-space: nowrap; +} +.tns-vpfix > div, +.tns-vpfix > li { + display: inline-block; +} +.tns-t-subp2 { + margin: 0 auto; + width: 310px; + position: relative; + height: 10px; + overflow: hidden; +} +.tns-t-ct { + width: 2333.3333333%; + width: -webkit-calc(100% * 70 / 3); + width: -moz-calc(100% * 70 / 3); + width: calc(100% * 70 / 3); + position: absolute; + right: 0; +} +.tns-t-ct:after { + content: ""; + display: table; + clear: both; +} +.tns-t-ct > div { + width: 1.4285714%; + width: -webkit-calc(100% / 70); + width: -moz-calc(100% / 70); + width: calc(100% / 70); + height: 10px; + float: left; +} + +/*# sourceMappingURL=sourcemaps/tiny-slider.css.map */ diff --git a/src/main/resources/static/lib/slider/tiny-slider.js b/src/main/resources/static/lib/slider/tiny-slider.js new file mode 100644 index 0000000000..de774bdda3 --- /dev/null +++ b/src/main/resources/static/lib/slider/tiny-slider.js @@ -0,0 +1,3655 @@ +var tns = (function() { + var win = window + + var raf = + win.requestAnimationFrame || + win.webkitRequestAnimationFrame || + win.mozRequestAnimationFrame || + win.msRequestAnimationFrame || + function(cb) { + return setTimeout(cb, 16) + } + + var win$1 = window + + var caf = + win$1.cancelAnimationFrame || + win$1.mozCancelAnimationFrame || + function(id) { + clearTimeout(id) + } + + function extend() { + var obj, + name, + copy, + target = arguments[0] || {}, + i = 1, + length = arguments.length + + for (; i < length; i++) { + if ((obj = arguments[i]) !== null) { + for (name in obj) { + copy = obj[name] + + if (target === copy) { + continue + } else if (copy !== undefined) { + target[name] = copy + } + } + } + } + return target + } + + function checkStorageValue(value) { + return ['true', 'false'].indexOf(value) >= 0 ? JSON.parse(value) : value + } + + function setLocalStorage(storage, key, value, access) { + if (access) { + try { + storage.setItem(key, value) + } catch (e) {} + } + return value + } + + function getSlideId() { + var id = window.tnsId + window.tnsId = !id ? 1 : id + 1 + + return 'tns' + window.tnsId + } + + function getBody() { + var doc = document, + body = doc.body + + if (!body) { + body = doc.createElement('body') + body.fake = true + } + + return body + } + + var docElement = document.documentElement + + function setFakeBody(body) { + var docOverflow = '' + if (body.fake) { + docOverflow = docElement.style.overflow + //avoid crashing IE8, if background image is used + body.style.background = '' + //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible + body.style.overflow = docElement.style.overflow = 'hidden' + docElement.appendChild(body) + } + + return docOverflow + } + + function resetFakeBody(body, docOverflow) { + if (body.fake) { + body.remove() + docElement.style.overflow = docOverflow + // Trigger layout so kinetic scrolling isn't disabled in iOS6+ + // eslint-disable-next-line + docElement.offsetHeight + } + } + + // get css-calc + + function calc() { + var doc = document, + body = getBody(), + docOverflow = setFakeBody(body), + div = doc.createElement('div'), + result = false + + body.appendChild(div) + try { + var str = '(10px * 10)', + vals = ['calc' + str, '-moz-calc' + str, '-webkit-calc' + str], + val + for (var i = 0; i < 3; i++) { + val = vals[i] + div.style.width = val + if (div.offsetWidth === 100) { + result = val.replace(str, '') + break + } + } + } catch (e) {} + + body.fake ? resetFakeBody(body, docOverflow) : div.remove() + + return result + } + + // get subpixel support value + + function percentageLayout() { + // check subpixel layout supporting + var doc = document, + body = getBody(), + docOverflow = setFakeBody(body), + wrapper = doc.createElement('div'), + outer = doc.createElement('div'), + str = '', + count = 70, + perPage = 3, + supported = false + + wrapper.className = 'tns-t-subp2' + outer.className = 'tns-t-ct' + + for (var i = 0; i < count; i++) { + str += '
' + } + + outer.innerHTML = str + wrapper.appendChild(outer) + body.appendChild(wrapper) + + supported = Math.abs(wrapper.getBoundingClientRect().left - outer.children[count - perPage].getBoundingClientRect().left) < 2 + + body.fake ? resetFakeBody(body, docOverflow) : wrapper.remove() + + return supported + } + + function mediaquerySupport() { + var doc = document, + body = getBody(), + docOverflow = setFakeBody(body), + div = doc.createElement('div'), + style = doc.createElement('style'), + rule = '@media all and (min-width:1px){.tns-mq-test{position:absolute}}', + position + + style.type = 'text/css' + div.className = 'tns-mq-test' + + body.appendChild(style) + body.appendChild(div) + + if (style.styleSheet) { + style.styleSheet.cssText = rule + } else { + style.appendChild(doc.createTextNode(rule)) + } + + position = window.getComputedStyle ? window.getComputedStyle(div).position : div.currentStyle['position'] + + body.fake ? resetFakeBody(body, docOverflow) : div.remove() + + return position === 'absolute' + } + + // create and append style sheet + function createStyleSheet(media) { + // Create the