From 5db1c55c38776f1038853b8cfdbe01dc6cfb3750 Mon Sep 17 00:00:00 2001 From: Dain Lee Date: Tue, 14 Mar 2023 14:49:40 +0900 Subject: [PATCH 01/35] =?UTF-8?q?docs:=20=EA=B8=B0=EB=8A=A5=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=EA=B3=BC=20=EC=9A=94=EA=B5=AC=20=EC=82=AC=ED=95=AD=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gabriel Ju Hyun, Yoon --- docs/REQUIREMENTS.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/docs/REQUIREMENTS.md b/docs/REQUIREMENTS.md index e69de29bb..db7edeb76 100644 --- a/docs/REQUIREMENTS.md +++ b/docs/REQUIREMENTS.md @@ -0,0 +1,33 @@ +### ✅ 기능 목록 + +- [ ] API에게 1페이지를 요청한다. +- [ ] 사용자가 더보기를 누르면 1페이지를 추가 요청한다. + - [ ] 사용자가 더보기를 누르면 더 많은 영화 목록을 보여준다. +- [ ] API의 끝 페이지에 도달하면 더보기 버튼을 화면에서 삭제한다. +- [ ] 로딩중에는 스켈레톤 UI를 표시한다. +- [ ] 인기순으로 영화를 정렬한다. + +- [ ] 사용자는 보고 싶은 영화를 검색할 수 있다. + - [ ] 엔터키를 눌러 검색할 수 있다. + - [ ] 검색 버튼을 클릭하여 검색할 수 있다. +- [ ] 입력받은 키워드를 API에 요청한다. + - [ ]❗[ 에러 ] 요청한 API의 상태 코드에 따라서 오류 메시지를 띄워 준다. +- [ ] 입력받은 키워드에 해당하는 영화 목록을 보여준다. + +
+ +### ✨ 요구 사항 + +- API key를 공개된 저장소에 포함하지 않는다. + +- 비동기 통신에서 실패할 경우를 대비한다. +- 비동기 통신에서 일어날 수 있는 다양한 상황을 고려해 본다. +- 비동기 호출을 포함한 사용자 기능 플로우를 선정하고 기능을 포함하여 E2E 테스트를 작성한다. + +- 특정한 패턴에 사고를 끼워 맞추지 않고 단지 역할과 책임에 따라 관심사를 분리한다. +- 어떠한 관점에서 역할과 책임에 따라 관심사를 분리하였는지 리뷰어에게 설명할 수 있어야 한다. + +- 도메인 영역을 TypeScript를 사용해 구현한다. (UI 영역은 선택) +- any를 사용하지 않는다. + +- API에서 응답한 데이터의 규격을 문자열 그대로 활용하지 않고 도메인 객체를 만들어 활용한다. From 281a479ff49e23d3ff7700945c4fac0df6ba843f Mon Sep 17 00:00:00 2001 From: Dain Lee Date: Tue, 14 Mar 2023 16:02:01 +0900 Subject: [PATCH 02/35] =?UTF-8?q?chore:=20=ED=8F=B4=EB=8D=94=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC=20=EB=B0=8F=20=ED=94=84=EB=A6=AC=ED=8B=B0=EC=96=B4=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- babel.config.js | 5 +- index.html | 343 +++++++++++++++++++- package-lock.json | 53 +++ package.json | 3 +- {templates => src/assets}/logo.png | Bin {templates => src/assets}/search_button.png | Bin {templates => src/assets}/star_empty.png | Bin {templates => src/assets}/star_filled.png | Bin {templates => src/css}/common.css | 2 +- {templates => src/css}/reset.css | 0 src/index.js | 0 templates/index.html | 312 ------------------ templates/skeleton.html | 8 +- tsconfig.json | 26 +- webpack.config.js | 2 +- 15 files changed, 419 insertions(+), 335 deletions(-) rename {templates => src/assets}/logo.png (100%) rename {templates => src/assets}/search_button.png (100%) rename {templates => src/assets}/star_empty.png (100%) rename {templates => src/assets}/star_filled.png (100%) rename {templates => src/css}/common.css (96%) rename {templates => src/css}/reset.css (100%) delete mode 100644 src/index.js delete mode 100644 templates/index.html diff --git a/babel.config.js b/babel.config.js index 2afcfd240..dd242dc90 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,3 +1,6 @@ module.exports = { - presets: [["@babel/preset-env", { targets: { node: "current" } }], "@babel/preset-typescript"], + presets: [ + ["@babel/preset-env", { targets: { node: "current" } }], + "@babel/preset-typescript", + ], }; diff --git a/index.html b/index.html index 5efa25cfa..394322bc7 100644 --- a/index.html +++ b/index.html @@ -1,12 +1,349 @@ - + - Document + + 영화관 - 영화 리뷰 미션을 진행하세요 + diff --git a/package-lock.json b/package-lock.json index 984e9963b..bbbd34bb0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "cypress": "^12.3.0", "dotenv-webpack": "^8.0.1", "eslint": "^8.35.0", + "file-loader": "^6.2.0", "html-webpack-plugin": "^5.5.0", "jest": "^29.3.1", "jest-environment-jsdom": "^29.5.0", @@ -3815,6 +3816,15 @@ "tweetnacl": "^0.14.3" } }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -5078,6 +5088,15 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -5973,6 +5992,26 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dev": true, + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -8374,6 +8413,20 @@ "node": ">=6.11.5" } }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", diff --git a/package.json b/package.json index 4e99c76ab..fcfdbb191 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "javascript-movie-review", "version": "1.0.0", "description": "우아한테크코스 레벨1 영화관 미션 저장소", - "main": "src/index.js", + "main": "src/index.ts", "private": "true", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", @@ -36,6 +36,7 @@ "cypress": "^12.3.0", "dotenv-webpack": "^8.0.1", "eslint": "^8.35.0", + "file-loader": "^6.2.0", "html-webpack-plugin": "^5.5.0", "jest": "^29.3.1", "jest-environment-jsdom": "^29.5.0", diff --git a/templates/logo.png b/src/assets/logo.png similarity index 100% rename from templates/logo.png rename to src/assets/logo.png diff --git a/templates/search_button.png b/src/assets/search_button.png similarity index 100% rename from templates/search_button.png rename to src/assets/search_button.png diff --git a/templates/star_empty.png b/src/assets/star_empty.png similarity index 100% rename from templates/star_empty.png rename to src/assets/star_empty.png diff --git a/templates/star_filled.png b/src/assets/star_filled.png similarity index 100% rename from templates/star_filled.png rename to src/assets/star_filled.png diff --git a/templates/common.css b/src/css/common.css similarity index 96% rename from templates/common.css rename to src/css/common.css index b22b31a29..e4f2ff208 100644 --- a/templates/common.css +++ b/src/css/common.css @@ -159,6 +159,6 @@ header .search-box > .search-button { width: 14px; border: 0; text-indent: -1000rem; - background: url("./search_button.png") transparent no-repeat 0 1px; + background: url("../assets/search_button.png") transparent no-repeat 0 1px; background-size: contain; } diff --git a/templates/reset.css b/src/css/reset.css similarity index 100% rename from templates/reset.css rename to src/css/reset.css diff --git a/src/index.js b/src/index.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/templates/index.html b/templates/index.html deleted file mode 100644 index a04bba4c0..000000000 --- a/templates/index.html +++ /dev/null @@ -1,312 +0,0 @@ - - - - - - - - - - - 영화관 - - - - - diff --git a/templates/skeleton.html b/templates/skeleton.html index 8b1bd761f..037381a78 100644 --- a/templates/skeleton.html +++ b/templates/skeleton.html @@ -5,10 +5,10 @@ - - - - + + + + 영화관 diff --git a/tsconfig.json b/tsconfig.json index 81f029a3d..66380203a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,7 @@ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ - "target": "ES2015", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "ES2015" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ @@ -25,9 +25,9 @@ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ /* Modules */ - "module": "ESNext", /* Specify what module code is generated. */ + "module": "ESNext" /* Specify what module code is generated. */, // "rootDir": "./", /* Specify the root folder within your source files. */ - "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + "moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */, // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ @@ -39,7 +39,7 @@ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ /* JavaScript Support */ - "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + "allowJs": true /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */, // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ @@ -50,7 +50,7 @@ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ // "outDir": "./", /* Specify an output folder for all emitted files. */ - "removeComments": true, /* Disable emitting comments. */ + "removeComments": true /* Disable emitting comments. */, // "noEmit": true, /* Disable emitting files from a compilation. */ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ @@ -71,14 +71,14 @@ /* Interop Constraints */ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, /* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */ - "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + "strict": true /* Enable all strict type-checking options. */, + "noImplicitAny": true /* Enable error reporting for expressions and declarations with an implied 'any' type. */, + "strictNullChecks": true /* When type checking, take into account 'null' and 'undefined'. */, // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ @@ -98,6 +98,8 @@ /* Completeness */ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ - } + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "include": ["src"], + "exclude": ["node_modules", "cypress", "dist"] } diff --git a/webpack.config.js b/webpack.config.js index 4a0efabbe..c77c5e332 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -3,7 +3,7 @@ const HtmlWebpackPlugin = require("html-webpack-plugin"); const DotEnv = require("dotenv-webpack"); module.exports = { - entry: "./src/index.js", + entry: "./src/index.ts", mode: "development", resolve: { extensions: [".ts", ".js"], From fbc7b981a21ae0678e8b5ed4e604170c83d5e719 Mon Sep 17 00:00:00 2001 From: Dain Lee Date: Tue, 14 Mar 2023 16:34:54 +0900 Subject: [PATCH 03/35] =?UTF-8?q?fix:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=97=85=EB=A1=9C=EB=93=9C=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webpack.config.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/webpack.config.js b/webpack.config.js index c77c5e332..eb57f161d 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -39,6 +39,10 @@ module.exports = { { test: /\.(png|svg|jpg|jpeg|gif)$/i, type: "asset/resource", + loader: "file-loader", + options: { + name: "[name].[ext]", + }, }, ], }, From 82760c2017b8b29597345165a5829f1d846f5e71 Mon Sep 17 00:00:00 2001 From: Dain Lee Date: Tue, 14 Mar 2023 16:35:13 +0900 Subject: [PATCH 04/35] =?UTF-8?q?feat:=20=ED=97=A4=EB=8D=94=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 8 +------- src/components/Header.ts | 20 ++++++++++++++++++++ src/index.ts | 9 +++++++++ 3 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 src/components/Header.ts create mode 100644 src/index.ts diff --git a/index.html b/index.html index 394322bc7..20663f04e 100644 --- a/index.html +++ b/index.html @@ -9,13 +9,7 @@
-
-

MovieList 로고

- -
+

지금 인기 있는 영화

diff --git a/src/components/Header.ts b/src/components/Header.ts new file mode 100644 index 000000000..8a6d6d53d --- /dev/null +++ b/src/components/Header.ts @@ -0,0 +1,20 @@ +class Header extends HTMLElement { + constructor() { + super(); + this.render(); + } + + render() { + this.innerHTML = ` +
+

MovieList 로고

+ +
+ `; + } +} + +export default Header; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 000000000..167e6c7b0 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,9 @@ +import "./css/reset.css"; +import "./css/common.css"; +import "./assets/logo.png"; +import "./assets/search_button.png"; +import "./assets/star_empty.png"; +import "./assets/star_filled.png"; +import Header from "./components/Header"; + +customElements.define("movie-header", Header); From 904e6c075f4fb9de1d43fdea25b0b09a51372809 Mon Sep 17 00:00:00 2001 From: Dain Lee Date: Tue, 14 Mar 2023 16:48:03 +0900 Subject: [PATCH 05/35] =?UTF-8?q?feat:=20=EC=98=81=ED=99=94=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 329 +----------------------------------- src/components/MovieList.ts | 33 ++++ src/index.ts | 2 + 3 files changed, 36 insertions(+), 328 deletions(-) create mode 100644 src/components/MovieList.ts diff --git a/index.html b/index.html index 20663f04e..8e64bde11 100644 --- a/index.html +++ b/index.html @@ -10,334 +10,7 @@ diff --git a/src/components/MovieList.ts b/src/components/MovieList.ts new file mode 100644 index 000000000..0aa9a3460 --- /dev/null +++ b/src/components/MovieList.ts @@ -0,0 +1,33 @@ +export default class MovieList extends HTMLElement { + constructor() { + super(); + this.render(); + } + + render() { + this.innerHTML = ` +
+

지금 인기 있는 영화

+ + +
+ `; + } +} diff --git a/src/index.ts b/src/index.ts index 167e6c7b0..925497270 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,5 +5,7 @@ import "./assets/search_button.png"; import "./assets/star_empty.png"; import "./assets/star_filled.png"; import Header from "./components/Header"; +import MovieList from "./components/MovieList"; customElements.define("movie-header", Header); +customElements.define("movie-list", MovieList); From 509f9f0b83f7d7fd99c755412aa50fbe99125531 Mon Sep 17 00:00:00 2001 From: Dain Lee Date: Tue, 14 Mar 2023 16:48:36 +0900 Subject: [PATCH 06/35] =?UTF-8?q?style:=20export=20=EB=B0=A9=EB=B2=95=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Header.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/Header.ts b/src/components/Header.ts index 8a6d6d53d..06933b2b9 100644 --- a/src/components/Header.ts +++ b/src/components/Header.ts @@ -1,4 +1,4 @@ -class Header extends HTMLElement { +export default class Header extends HTMLElement { constructor() { super(); this.render(); @@ -16,5 +16,3 @@ class Header extends HTMLElement { `; } } - -export default Header; From cbd6e3d0623a2e6e2692adb5d173b0b3c32a5aee Mon Sep 17 00:00:00 2001 From: Dain Lee Date: Tue, 14 Mar 2023 17:14:14 +0900 Subject: [PATCH 07/35] =?UTF-8?q?feat:=20=EC=98=81=ED=99=94=20=EC=95=84?= =?UTF-8?q?=EC=9D=B4=ED=85=9C=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/MovieItem.ts | 27 +++++++++++++++++++++++++++ src/components/MovieList.ts | 31 ++++++++++--------------------- src/css/common.css | 4 ++-- src/css/reset.css | 3 ++- src/index.ts | 2 ++ 5 files changed, 43 insertions(+), 24 deletions(-) create mode 100644 src/components/MovieItem.ts diff --git a/src/components/MovieItem.ts b/src/components/MovieItem.ts new file mode 100644 index 000000000..e87217e7c --- /dev/null +++ b/src/components/MovieItem.ts @@ -0,0 +1,27 @@ +export default class MovieItem extends HTMLElement { + constructor() { + super(); + this.render(); + } + + render() { + this.innerHTML = ` +
  • + +
    + 앤트맨과 와스프: 퀀텀매니아 +

    앤트맨과 와스프: 퀀텀매니아

    +

    + 별점 6.5 +

    +
    +
    +
  • + `; + } +} diff --git a/src/components/MovieList.ts b/src/components/MovieList.ts index 0aa9a3460..124033957 100644 --- a/src/components/MovieList.ts +++ b/src/components/MovieList.ts @@ -7,27 +7,16 @@ export default class MovieList extends HTMLElement { render() { this.innerHTML = `
    -

    지금 인기 있는 영화

    - - -
    +

    지금 인기 있는 영화

    +
      + + + + + +
    + +
    `; } } diff --git a/src/css/common.css b/src/css/common.css index e4f2ff208..0b111aa2a 100644 --- a/src/css/common.css +++ b/src/css/common.css @@ -48,8 +48,8 @@ button { .item-list { display: grid; margin: 48px 0; - grid-template-columns: repeat(4, 180px); - grid-column-gap: 160px; + grid-template-columns: repeat(5, 180px); + grid-column-gap: 76px; grid-row-gap: 48px; } diff --git a/src/css/reset.css b/src/css/reset.css index 3675e6452..51f12d24d 100644 --- a/src/css/reset.css +++ b/src/css/reset.css @@ -109,7 +109,8 @@ body { line-height: 1; } ol, -ul { +ul, +movie-item { list-style: none; } blockquote, diff --git a/src/index.ts b/src/index.ts index 925497270..f496db5e2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,8 @@ import "./assets/star_empty.png"; import "./assets/star_filled.png"; import Header from "./components/Header"; import MovieList from "./components/MovieList"; +import MovieItem from "./components/MovieItem"; customElements.define("movie-header", Header); customElements.define("movie-list", MovieList); +customElements.define("movie-item", MovieItem); From 440d6fec9db03a344f044615915d48cbc25bbd8e Mon Sep 17 00:00:00 2001 From: Dain Lee Date: Tue, 14 Mar 2023 17:50:24 +0900 Subject: [PATCH 08/35] =?UTF-8?q?feat:=20API=20=EC=9A=94=EC=B2=AD=20?= =?UTF-8?q?=EB=B0=8F=20API=20=ED=82=A4=20=EC=9D=80=EB=8B=89=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + package-lock.json | 21 ++++++++++++++++----- package.json | 3 +++ src/components/MovieList.ts | 9 +++++++++ src/domain/movieApi.ts | 9 +++++++++ 5 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 src/domain/movieApi.ts diff --git a/.gitignore b/.gitignore index 3c3629e64..37d7e7348 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules +.env diff --git a/package-lock.json b/package-lock.json index bbbd34bb0..c4c586e3a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "javascript-movie-review", "version": "1.0.0", "license": "ISC", + "dependencies": { + "dotenv": "^16.0.3" + }, "devDependencies": { "@babel/core": "^7.20.12", "@babel/preset-env": "^7.20.2", @@ -5016,12 +5019,11 @@ } }, "node_modules/dotenv": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", - "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", - "dev": true, + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/dotenv-defaults": { @@ -5033,6 +5035,15 @@ "dotenv": "^8.2.0" } }, + "node_modules/dotenv-defaults/node_modules/dotenv": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", + "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/dotenv-webpack": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/dotenv-webpack/-/dotenv-webpack-8.0.1.tgz", diff --git a/package.json b/package.json index fcfdbb191..9d43e4fcb 100644 --- a/package.json +++ b/package.json @@ -47,5 +47,8 @@ "webpack": "^5.75.0", "webpack-cli": "^5.0.1", "webpack-dev-server": "^4.11.1" + }, + "dependencies": { + "dotenv": "^16.0.3" } } diff --git a/src/components/MovieList.ts b/src/components/MovieList.ts index 124033957..915c5e469 100644 --- a/src/components/MovieList.ts +++ b/src/components/MovieList.ts @@ -1,6 +1,15 @@ +import { movieApi } from "../domain/movieApi"; + export default class MovieList extends HTMLElement { + movies: any[]; + constructor() { super(); + this.movies = []; + } + + async connectedCallback() { + this.movies = await movieApi.fetchMovieInfo(); this.render(); } diff --git a/src/domain/movieApi.ts b/src/domain/movieApi.ts new file mode 100644 index 000000000..2aa61d092 --- /dev/null +++ b/src/domain/movieApi.ts @@ -0,0 +1,9 @@ +export const movieApi = { + async fetchMovieInfo() { + let response = await fetch( + `https://api.themoviedb.org/3/movie/popular?api_key=${process.env.API_KEY}&language=ko&page=1` + ); + let data = await response.json(); + return data; + }, +}; From c866b880cb0b537deb0f1dd2fddc240dd93e0718 Mon Sep 17 00:00:00 2001 From: Dain Lee Date: Tue, 14 Mar 2023 20:01:09 +0900 Subject: [PATCH 09/35] =?UTF-8?q?feat:=20API=EC=97=90=EC=84=9C=20=EA=B0=80?= =?UTF-8?q?=EC=A0=B8=EC=98=A8=20=EC=A0=95=EB=B3=B4=20=EB=A0=8C=EB=8D=94?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/MovieItem.ts | 27 ------------------------- src/components/MovieList.ts | 39 ++++++++++++++++++++++++++++--------- src/index.ts | 2 -- 3 files changed, 30 insertions(+), 38 deletions(-) delete mode 100644 src/components/MovieItem.ts diff --git a/src/components/MovieItem.ts b/src/components/MovieItem.ts deleted file mode 100644 index e87217e7c..000000000 --- a/src/components/MovieItem.ts +++ /dev/null @@ -1,27 +0,0 @@ -export default class MovieItem extends HTMLElement { - constructor() { - super(); - this.render(); - } - - render() { - this.innerHTML = ` -
  • - -
    - 앤트맨과 와스프: 퀀텀매니아 -

    앤트맨과 와스프: 퀀텀매니아

    -

    - 별점 6.5 -

    -
    -
    -
  • - `; - } -} diff --git a/src/components/MovieList.ts b/src/components/MovieList.ts index 915c5e469..b938719b2 100644 --- a/src/components/MovieList.ts +++ b/src/components/MovieList.ts @@ -9,23 +9,44 @@ export default class MovieList extends HTMLElement { } async connectedCallback() { - this.movies = await movieApi.fetchMovieInfo(); - this.render(); + const { page, results, total_pages, total_results } = + await movieApi.fetchMovieInfo(); + this.movies = results; + this.renderMovies(); } - render() { + renderMovies() { this.innerHTML = ` -
    +

    지금 인기 있는 영화

      - - - - - + ${this.movies.map((movie) => this.renderMovie(movie)).join("")}
    `; } + + renderMovie(movie: any) { + return ` +
  • + +
    + ${movie.title} +

    ${movie.title}

    +

    + 별점 ${movie.vote_average} +

    +
    +
    +
  • + `; + } } diff --git a/src/index.ts b/src/index.ts index f496db5e2..925497270 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,8 +6,6 @@ import "./assets/star_empty.png"; import "./assets/star_filled.png"; import Header from "./components/Header"; import MovieList from "./components/MovieList"; -import MovieItem from "./components/MovieItem"; customElements.define("movie-header", Header); customElements.define("movie-list", MovieList); -customElements.define("movie-item", MovieItem); From 3947f75fb4f89067d5bd624538d60667d2ee55d5 Mon Sep 17 00:00:00 2001 From: Dain Lee Date: Tue, 14 Mar 2023 21:43:20 +0900 Subject: [PATCH 10/35] =?UTF-8?q?feat:=20=EB=8D=94=EB=B3=B4=EA=B8=B0=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=EC=8B=9C=20=EC=98=81=ED=99=94=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EB=A0=8C=EB=8D=94?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/REQUIREMENTS.md | 6 ++-- index.html | 2 +- src/components/MovieList.ts | 51 +++++++++++++++--------------- src/components/movieListHandler.ts | 11 +++++++ src/domain/movieApi.ts | 23 +++++++++++--- src/utils/eventListener.ts | 11 +++++++ src/utils/selector.ts | 11 +++++++ 7 files changed, 81 insertions(+), 34 deletions(-) create mode 100644 src/components/movieListHandler.ts create mode 100644 src/utils/eventListener.ts create mode 100644 src/utils/selector.ts diff --git a/docs/REQUIREMENTS.md b/docs/REQUIREMENTS.md index db7edeb76..d0af295db 100644 --- a/docs/REQUIREMENTS.md +++ b/docs/REQUIREMENTS.md @@ -1,8 +1,8 @@ ### ✅ 기능 목록 -- [ ] API에게 1페이지를 요청한다. -- [ ] 사용자가 더보기를 누르면 1페이지를 추가 요청한다. - - [ ] 사용자가 더보기를 누르면 더 많은 영화 목록을 보여준다. +- [x] API에게 1페이지를 요청한다. +- [x] 사용자가 더보기를 누르면 1페이지를 추가 요청한다. + - [x] 사용자가 더보기를 누르면 더 많은 영화 목록을 보여준다. - [ ] API의 끝 페이지에 도달하면 더보기 버튼을 화면에서 삭제한다. - [ ] 로딩중에는 스켈레톤 UI를 표시한다. - [ ] 인기순으로 영화를 정렬한다. diff --git a/index.html b/index.html index 8e64bde11..5c4832a98 100644 --- a/index.html +++ b/index.html @@ -10,7 +10,7 @@
    - +
    diff --git a/src/components/MovieList.ts b/src/components/MovieList.ts index b938719b2..fd8bb8adb 100644 --- a/src/components/MovieList.ts +++ b/src/components/MovieList.ts @@ -1,17 +1,14 @@ import { movieApi } from "../domain/movieApi"; +import { onClickMoreButton } from "./movieListHandler"; export default class MovieList extends HTMLElement { - movies: any[]; - constructor() { super(); - this.movies = []; + this.updateMovies(); } - async connectedCallback() { - const { page, results, total_pages, total_results } = - await movieApi.fetchMovieInfo(); - this.movies = results; + async updateMovies() { + await movieApi.fetchMovieInfo(); this.renderMovies(); } @@ -20,33 +17,35 @@ export default class MovieList extends HTMLElement {

    지금 인기 있는 영화

      - ${this.movies.map((movie) => this.renderMovie(movie)).join("")} + ${movieApi.movies.map((movie) => this.renderMovie(movie)).join("")}
    - +
    `; + + onClickMoreButton(); } renderMovie(movie: any) { return `
  • - -
    - ${movie.title} -

    ${movie.title}

    -

    - 별점 ${movie.vote_average} -

    -
    -
    -
  • + +
    + ${movie.title} +

    ${movie.title}

    +

    + 별점 ${movie.vote_average} +

    +
    +
    + `; } } diff --git a/src/components/movieListHandler.ts b/src/components/movieListHandler.ts new file mode 100644 index 000000000..3890201d7 --- /dev/null +++ b/src/components/movieListHandler.ts @@ -0,0 +1,11 @@ +import { movieApi } from "../domain/movieApi"; +import { executeEventListener } from "../utils/eventListener"; +import { $ } from "../utils/selector"; + +export const onClickMoreButton = () => { + executeEventListener( + $("#more-button"), + "click", + async () => await movieApi.fetchMovieInfo() + ); +}; diff --git a/src/domain/movieApi.ts b/src/domain/movieApi.ts index 2aa61d092..5fafe5e0a 100644 --- a/src/domain/movieApi.ts +++ b/src/domain/movieApi.ts @@ -1,9 +1,24 @@ +import MovieList from "../components/MovieList"; +import { $ } from "../utils/selector"; + export const movieApi = { + page: 1, + movies: [], + total_pages: 2, + total_results: 0, + async fetchMovieInfo() { - let response = await fetch( - `https://api.themoviedb.org/3/movie/popular?api_key=${process.env.API_KEY}&language=ko&page=1` + const response = await fetch( + `https://api.themoviedb.org/3/movie/popular?api_key=${process.env.API_KEY}&language=ko&page=${this.page}` ); - let data = await response.json(); - return data; + const { page, results, total_pages, total_results } = await response.json(); + + this.page = page + 1; + this.movies = [...this.movies, ...results] as any; + this.total_pages = total_pages; + this.total_results = total_results; + + const movieList = $("#movie-list") as MovieList; + movieList.renderMovies(); }, }; diff --git a/src/utils/eventListener.ts b/src/utils/eventListener.ts new file mode 100644 index 000000000..2119830c7 --- /dev/null +++ b/src/utils/eventListener.ts @@ -0,0 +1,11 @@ +export const executeEventListener = ( + target: Element, + type: string, + listener: (event: Event) => void +) => { + target?.addEventListener(type, (event) => { + event.preventDefault(); + + listener(event); + }); +}; diff --git a/src/utils/selector.ts b/src/utils/selector.ts new file mode 100644 index 000000000..71018d61a --- /dev/null +++ b/src/utils/selector.ts @@ -0,0 +1,11 @@ +export const $ = (selector: string): E => { + const element = document.querySelector(selector); + if (element) return element; + throw new Error(`존재하지 않는 요소입니다: ${selector}`); +}; + +export const $$ = (selector: string): NodeListOf => { + const elements = document.querySelectorAll(selector); + if (elements.length) return elements as NodeListOf; + throw new Error(`존재하지 않는 요소입니다: ${selector}`); +}; From f77159ef5c7e02b8bda16bb0702d75218792bdc9 Mon Sep 17 00:00:00 2001 From: Dain Lee Date: Tue, 14 Mar 2023 21:55:59 +0900 Subject: [PATCH 11/35] =?UTF-8?q?refactor:=20=EC=98=81=ED=99=94=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20=EA=B4=80=EB=A0=A8=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/MovieList.ts | 4 ---- src/components/movieListHandler.ts | 8 ++++++++ src/domain/movieApi.ts | 6 ++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/components/MovieList.ts b/src/components/MovieList.ts index fd8bb8adb..51d2dd7d7 100644 --- a/src/components/MovieList.ts +++ b/src/components/MovieList.ts @@ -1,5 +1,4 @@ import { movieApi } from "../domain/movieApi"; -import { onClickMoreButton } from "./movieListHandler"; export default class MovieList extends HTMLElement { constructor() { @@ -9,7 +8,6 @@ export default class MovieList extends HTMLElement { async updateMovies() { await movieApi.fetchMovieInfo(); - this.renderMovies(); } renderMovies() { @@ -22,8 +20,6 @@ export default class MovieList extends HTMLElement {
    `; - - onClickMoreButton(); } renderMovie(movie: any) { diff --git a/src/components/movieListHandler.ts b/src/components/movieListHandler.ts index 3890201d7..cd4d9f87e 100644 --- a/src/components/movieListHandler.ts +++ b/src/components/movieListHandler.ts @@ -1,6 +1,7 @@ import { movieApi } from "../domain/movieApi"; import { executeEventListener } from "../utils/eventListener"; import { $ } from "../utils/selector"; +import MovieList from "./MovieList"; export const onClickMoreButton = () => { executeEventListener( @@ -9,3 +10,10 @@ export const onClickMoreButton = () => { async () => await movieApi.fetchMovieInfo() ); }; + +export const updateMovies = () => { + const movieList = $("#movie-list") as MovieList; + movieList.renderMovies(); + onClickMoreButton(); +}; + diff --git a/src/domain/movieApi.ts b/src/domain/movieApi.ts index 5fafe5e0a..c89b3c275 100644 --- a/src/domain/movieApi.ts +++ b/src/domain/movieApi.ts @@ -1,5 +1,4 @@ -import MovieList from "../components/MovieList"; -import { $ } from "../utils/selector"; +import { updateMovies } from "../components/movieListHandler"; export const movieApi = { page: 1, @@ -18,7 +17,6 @@ export const movieApi = { this.total_pages = total_pages; this.total_results = total_results; - const movieList = $("#movie-list") as MovieList; - movieList.renderMovies(); + updateMovies(); }, }; From 8cec0804dbba5e9e32bb868beaa05b1523233b8f Mon Sep 17 00:00:00 2001 From: Dain Lee Date: Wed, 15 Mar 2023 13:13:22 +0900 Subject: [PATCH 12/35] =?UTF-8?q?feat:=20=EC=9D=B8=EA=B8=B0=EC=88=9C?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=98=81=ED=99=94=20=EC=A0=95=EB=A0=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/domain/movieApi.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/domain/movieApi.ts b/src/domain/movieApi.ts index c89b3c275..66b3bc93f 100644 --- a/src/domain/movieApi.ts +++ b/src/domain/movieApi.ts @@ -13,10 +13,13 @@ export const movieApi = { const { page, results, total_pages, total_results } = await response.json(); this.page = page + 1; - this.movies = [...this.movies, ...results] as any; + this.movies = [...this.movies, ...sortMovies(results)] as any; this.total_pages = total_pages; this.total_results = total_results; updateMovies(); }, }; + +const sortMovies = (movies: any) => + movies.sort((a: any, b: any) => b.popularity - a.popularity); From c936bdd6f5ed1c4b352d95edb29af3b6bff875e4 Mon Sep 17 00:00:00 2001 From: Dain Lee Date: Wed, 15 Mar 2023 14:14:00 +0900 Subject: [PATCH 13/35] =?UTF-8?q?fix:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EB=B6=88=EB=9F=AC=EC=98=A4=EA=B8=B0=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit copy-webpack-plugin을 이용한 이미지 로드 문제 해결 --- .gitignore | 1 + package-lock.json | 167 ++++++++++++++++++++++++++++++++++++ package.json | 1 + src/components/Header.ts | 2 +- src/components/MovieList.ts | 2 +- src/index.ts | 4 - webpack.config.js | 12 +-- 7 files changed, 175 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 37d7e7348..8f00ef230 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules .env +dist \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index c4c586e3a..2a75d0d67 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "@types/jest": "^29.4.0", "@types/testing-library__jest-dom": "^5.14.5", "babel-jest": "^29.3.1", + "copy-webpack-plugin": "^11.0.0", "css-loader": "^6.7.3", "cypress": "^12.3.0", "dotenv-webpack": "^8.0.1", @@ -4434,6 +4435,95 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "dev": true }, + "node_modules/copy-webpack-plugin": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", + "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", + "dev": true, + "dependencies": { + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.1", + "globby": "^13.1.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/copy-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/copy-webpack-plugin/node_modules/schema-utils": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/core-js-compat": { "version": "3.27.1", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.27.1.tgz", @@ -4896,6 +4986,18 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", @@ -5907,6 +6009,22 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -6344,6 +6462,37 @@ "node": ">=4" } }, + "node_modules/globby": { + "version": "13.1.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.3.tgz", + "integrity": "sha512-8krCNHXvlCgHDpegPzleMq07yMYTO2sXKASmZmquEYWEmCx6J5UTRbp5RwMJkTJGtcQ44YpiUYUiN0b9mzy8Bw==", + "dev": true, + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -8635,6 +8784,15 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -9186,6 +9344,15 @@ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "dev": true }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", diff --git a/package.json b/package.json index 9d43e4fcb..d03c27af7 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "@types/jest": "^29.4.0", "@types/testing-library__jest-dom": "^5.14.5", "babel-jest": "^29.3.1", + "copy-webpack-plugin": "^11.0.0", "css-loader": "^6.7.3", "cypress": "^12.3.0", "dotenv-webpack": "^8.0.1", diff --git a/src/components/Header.ts b/src/components/Header.ts index 06933b2b9..0f5b3ed71 100644 --- a/src/components/Header.ts +++ b/src/components/Header.ts @@ -7,7 +7,7 @@ export default class Header extends HTMLElement { render() { this.innerHTML = `
    -

    MovieList 로고

    +

    MovieList 로고

    From b362beddc43a7a44a93ca5ab2d9177415f97f900 Mon Sep 17 00:00:00 2001 From: Dain Lee Date: Wed, 15 Mar 2023 15:44:55 +0900 Subject: [PATCH 17/35] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B3=A0=20=ED=81=B4?= =?UTF-8?q?=EB=A6=AD=EC=8B=9C=20=EC=B2=98=EC=9D=8C=20=ED=99=94=EB=A9=B4?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=8F=8C=EC=95=84=EA=B0=80=EB=8A=94=20?= =?UTF-8?q?=EA=B8=B0=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 --- src/components/Header.ts | 5 +++-- .../{searchBoxHandler.ts => headerHandler.ts} | 10 +++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) rename src/components/{searchBoxHandler.ts => headerHandler.ts} (74%) diff --git a/src/components/Header.ts b/src/components/Header.ts index 21119a71e..8e214ee72 100644 --- a/src/components/Header.ts +++ b/src/components/Header.ts @@ -1,16 +1,17 @@ -import { onSubmitSearchBox } from "./searchBoxHandler"; +import { onSubmitSearchBox, onClickLogo } from "./headerHandler"; export default class Header extends HTMLElement { constructor() { super(); this.render(); onSubmitSearchBox(); + onClickLogo(); } render() { this.innerHTML = `
    -

    MovieList 로고

    +