Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2단계 - 상세 정보 & UI/UX 개선하기] 초코(강다빈) 미션 제출합니다. #171

Merged
merged 105 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from 81 commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
58a3ce0
feat: eslint와 prettier 기본 세팅
00kang Mar 19, 2024
5661a8a
feat: eslint, prettier 패키지 설치
Jaymyong66 Mar 19, 2024
022dbf2
feat: eslint error를 warn으로 설정 변경
00kang Mar 19, 2024
f3135ea
chore: ts-eslint parse 설정
00kang Mar 19, 2024
52f9c3a
feat: image 소스 파일 추가
00kang Mar 19, 2024
553471b
feat : css - common.css, reset.css 추가
00kang Mar 19, 2024
a9e23b3
feat: index.html 템플릿 설정
00kang Mar 19, 2024
a12194e
docs: 기능 요구 사항 정리
00kang Mar 19, 2024
40846a2
feat: mockingData 설정
00kang Mar 19, 2024
00f7a69
feat: MovieCard 컴포넌트 구현
00kang Mar 19, 2024
dab4109
chore: eslint - browser env : true로 변경
Jaymyong66 Mar 19, 2024
c67458d
feat: mockingData 20개로 업데이트
Jaymyong66 Mar 19, 2024
716b456
chore: webpack-dev-server - 설정 및 이미지 파일 경로
Jaymyong66 Mar 19, 2024
4e07ad5
refactor: MovieCard 메서드 분리
Jaymyong66 Mar 19, 2024
5057566
feat: index.js에 css import
Jaymyong66 Mar 19, 2024
2bbc6f4
feat: MoreButton 컴포넌트
Jaymyong66 Mar 19, 2024
da29495
feat: API에서 받아온 데이터 렌더링
Jaymyong66 Mar 20, 2024
f74a933
feat: MovieCard 영화 데이터 주입
Jaymyong66 Mar 20, 2024
0b51801
feat: 더보기 버튼 클릭 시, 다음 페이지 영화 렌더링
Jaymyong66 Mar 20, 2024
568b3c4
feat: 영화 검색 기능
Jaymyong66 Mar 20, 2024
e2b5ccc
feat: skeleton UI 적용
Jaymyong66 Mar 20, 2024
5622b4c
feat: 영화 검색 기능 추가, page가 더 있을 때에만 더보기 버튼 렌더링
Jaymyong66 Mar 21, 2024
0696960
feat: 검색 결과가 없을때, UI 표시
Jaymyong66 Mar 21, 2024
04750f0
feat: 현재 영화 리스트에 따른 리스트 Title 변경
Jaymyong66 Mar 21, 2024
1ca0616
feat: 응답에 따른 에러 처리
Jaymyong66 Mar 21, 2024
97c0763
fix: 검색어 입력 후 Enter 누를 시, 두번 event가 발생하는 버그 수정
Jaymyong66 Mar 21, 2024
98ee73b
fix: 검색어 입력마다 presentPage count 리셋
Jaymyong66 Mar 21, 2024
22dc6ad
fix: skeleton li element가 완전히 제거되지 않는 버그 수정
Jaymyong66 Mar 21, 2024
b09291f
feat: 검색 후 home으로 돌아올 시, 기존 가져온 인기 영화 render
Jaymyong66 Mar 21, 2024
3755207
style: 영화 평점 css
Jaymyong66 Mar 21, 2024
8cf6096
chore: cypress 설정
Jaymyong66 Mar 21, 2024
fa81b18
chore: gitignore - dist,, env 추가
Jaymyong66 Mar 21, 2024
6d4fef8
chore: tsconfig 옵션 추가
Jaymyong66 Mar 21, 2024
4273068
test: 인기순 영화 페이지 E2E 테스트
Jaymyong66 Mar 21, 2024
a817135
chore: gitignore에 cypress.env.json 추가
Jaymyong66 Mar 21, 2024
a96aac3
test: TMDB에서 인기순 영화 GET요청 API 테스트
Jaymyong66 Mar 21, 2024
11532ab
test: TMDB에서 영화 검색 GET요청 API 테스트
Jaymyong66 Mar 21, 2024
02db706
test: Fixture를 이용한 인기순 영화 목록 테스트
Jaymyong66 Mar 21, 2024
75004f9
test: Fixture를 이용한 영화 검색 결과 렌더링 테스트
Jaymyong66 Mar 21, 2024
28af29a
test: fixture - search 데이터 업데이트
Jaymyong66 Mar 21, 2024
88c2cc7
chore: output Path 수정
00kang Mar 21, 2024
acda9b6
refactor: image 디렉토리 위치 변
00kang Mar 23, 2024
b27638f
refactor: css 디렉토리 위칭 이동 및 css variables 생성
00kang Mar 23, 2024
ea1b8a3
refactor: 매직넘버 상수화
00kang Mar 23, 2024
7b4d067
refactor: ErrorRender로 클래스명 수정
00kang Mar 23, 2024
2094ff8
refactor: SearchBox 컴포넌트 내 함수 이름 변경 및 메서드 분리
00kang Mar 23, 2024
83c4cd4
refactor: MovieStore와 SearchMovieStore에서 API 호출 로직 분리
00kang Mar 25, 2024
24db597
refactor: DocumentFragement 사용으로 DOM 접근 줄이기
00kang Mar 25, 2024
9cb0f27
refactor: early return으로 depth 줄이기
00kang Mar 25, 2024
e2f6ecd
refactor: #genereateMovieList와 #generateSearchMovieList의 중복 코드 메서드 분리
00kang Mar 25, 2024
5399034
refctor: 헤더 고정, 포스터 이미지 없는 데이터 이미지 삽입
00kang Mar 25, 2024
64dd479
refactor: 검색결과에 검색어(해리)가 포함되어 있는지 test 코드 추가
00kang Mar 25, 2024
065f2c6
feat: deploy 디렉토리에 css와 png 추가
00kang Mar 25, 2024
a6111ca
chore: eslint, package, tsconfig 설정
00kang Mar 25, 2024
cefc87f
docs: 구현 기능 목록 작성
00kang Mar 26, 2024
f109faa
feat: 스켈레톤의 <a> 태그 제거
00kang Mar 26, 2024
2cc746c
feat: 임의 데이터를 활용한 모달창 오픈
00kang Mar 26, 2024
1b4ea09
feat: 모달 클로즈 기능 구현
00kang Mar 27, 2024
0fbc146
feat: movieDetail API로부터 데이터 받아와서 모달에 보여주기
00kang Mar 28, 2024
1c2c72e
fix: 이미지 영역 고정
00kang Mar 28, 2024
af8d8e8
fix: 모달 내 텍스트 영역 조정
00kang Mar 28, 2024
b1e8768
fix: 모달 클로즈 오류 비동기 키워드 사용으로 해결
00kang Mar 29, 2024
28af320
feat: 클릭한 무비카드에 맞는 데이터 모달에 띄우기
00kang Mar 31, 2024
5569bdb
feat: API 요청 메서드 분리
00kang Apr 1, 2024
ccb81ff
feat: 더보기 버튼 대신 무한 스크롤 기능 구현
00kang Apr 1, 2024
afa3b94
refactor: 데이터 로드시 스켈레톤 ui 확인을 위한 딜레이 메서드 삭제
00kang Apr 1, 2024
0148e13
feat: 모달 내 별점 0으로 세팅
00kang Apr 1, 2024
7207d52
feat: 모달 내 별점 클릭 이벤트 구현
00kang Apr 1, 2024
5fb1acf
feat: 모달 내 평점 소수점 2자리까지 표현
00kang Apr 1, 2024
73a10cf
feat: tablet size 반응형 디자인 적용
00kang Apr 1, 2024
2d77149
feat: tablet size 일 때 스켈레톤 ui 6개로 변경
00kang Apr 1, 2024
c1a406b
feat: mobile size일 때 그리드 조절
00kang Apr 1, 2024
46943e3
feat: mobile size일 때 스켈레톤 4개로 조정
00kang Apr 1, 2024
15111d6
feat: mobile size일 때 모달 사이즈 수정
00kang Apr 1, 2024
2dc4077
feat: npm run build
00kang Apr 1, 2024
779cebb
feat: 스크립트 추가 후 npm run build
00kang Apr 1, 2024
485910f
Merge branch '00kang' into step2
00kang Apr 1, 2024
7e3748e
feat: npm run build
00kang Apr 1, 2024
de041e3
feat: npm run build
00kang Apr 1, 2024
dc31890
Merge branch 'deploy-step2' into step2
00kang Apr 1, 2024
8209206
feat: import문 삽입
00kang Apr 1, 2024
1c9ff19
refactor: mobile, tablet 사이즈 기준 상수화
00kang Apr 2, 2024
6c861dd
refactor: let 연산자 삭제
00kang Apr 2, 2024
4eaa732
refactor: moviesData의 타입 명확히 Movie[]로 지정
00kang Apr 2, 2024
6707341
feat: 무한 스크롤 구현!
00kang Apr 2, 2024
b64fdfc
refactor: 반응형 디자인 수정
00kang Apr 2, 2024
6864ff6
feat: 모달 내 별점 localstorage에 반영 및 localstorage에 저장된 결과 보여주기
00kang Apr 3, 2024
4dac6b6
feat: ESC key 로 모달 클로즈
00kang Apr 3, 2024
0330025
docs: 업데이트
00kang Apr 3, 2024
973037a
feat: 영화 포스터와 검색창 hover시 border 디자인
00kang Apr 3, 2024
9709602
feat: 최상단으로 이동하는 버튼
00kang Apr 3, 2024
a1a8443
refactor: 모달 디테일 수정
00kang Apr 3, 2024
9858971
fix: 모달 오픈시 무비리스트의 스크롤이 최상단으로 가는 문제 해결
00kang Apr 3, 2024
8cc5075
refactor: store 코드 메서드 분리
00kang Apr 3, 2024
06cad8e
fix: 없는 데이터에 forEach() 를 사용하는 문제
00kang Apr 3, 2024
48726d8
refactor: response 반환
00kang Apr 3, 2024
5cdec22
refactor: 메서드 분리
00kang Apr 3, 2024
4e169ca
refactor: return new Error
00kang Apr 3, 2024
bff9d97
refactor: 스크립트 파일 제거
00kang Apr 3, 2024
c846053
fix: 초기 세팅 시 별 이미지 안 뜨는 문제
00kang Apr 4, 2024
4542fb2
refactor: movieCard 클래스 메서드 분리
00kang Apr 4, 2024
722cb70
refactor: Modal 클래스 메서드 분리
00kang Apr 4, 2024
2fadb45
refactor: Modal 클래스 분리 : Modal, MovieInfo, VoteHandler
00kang Apr 4, 2024
cb164ab
feat: 모달에 skeleton UI 추가
00kang Apr 4, 2024
fa80a28
refactor: 반응형 디자인 수정 및 모달 스켈레톤 UI 적용
00kang Apr 4, 2024
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
2 changes: 2 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"no-promise-executor-return": "off",
"consistent-return": "off",
"no-return-await": "off",
"no-plusplus": "off",

},
"env": {
"es6": true,
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
node_modules
dist
.env
cypress.env.json
Binary file added deploy/images/modal_close_button.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added dist/06f0f15cfcb8d681b62c.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added dist/2e162b4fefb34cd7ed8d.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added dist/6328741810b732410eec.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added dist/6c9611deedf4b85849c9.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
484 changes: 484 additions & 0 deletions dist/bundle.js

Large diffs are not rendered by default.

Binary file added dist/e9a379619c759f886f7c.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added dist/f1bd4269f4446ceae306.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions dist/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!doctype html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<title>영화관</title>
<script defer type="module" src="./dist/bundle.js"></script>
<script defer src="bundle.js"></script></head>
<body>
<div id="app">
<header>
<h1>
<button id="home-button"></button>
</h1>
</header>
<main>
<section class="item-view">
<h2></h2>
<ul class="item-list"></ul>
</section>
</main>
</div>
</body>
</html>
28 changes: 27 additions & 1 deletion docs/REQUIREMENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
- 실제 동작하는 API를 통한 비동기 통신
- UX 경험 개선을 위한 더 보기(페이징) 구현

## 구현할 기능 목록

## STEP1 구현할 기능 목록


### 1. 🎬 영화 목록 조회 (인기순)

Expand Down Expand Up @@ -32,3 +34,27 @@
- [x] 검색 결과가 없을 경우 (응답은 있으나)
- [x] HTTP 4xx 오류일 때 (클라이언트 오류)
- [x] HTTP 5xx 오류일 때 (서버 오류)


## STEP2 구현할 기능 목록

### 1. 📺 영화 상세정보 조회

- [ ] 영화 포스터나 제목을 클릭하면 자세한 예고편이나 줄거리 등의 정보를 보여준다.
- [ ] API에서 제공하는 항목을 활용하여 상세 정보를 보여주는 모달 창을 구현한다.
- [ ] 키보드의 ESC 키를 누르면 모달 창을 닫을 수 있는 등 사용성을 고려한다.

### 2. ⭐️ 별점 매기기

- [ ] TMDB API 요청과는 관련 없습니다.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 누구에게 전달하는 메세지인가용

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

완료된 기능은 체크해줘도 좋을거 같네요 ㅎㅎ

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

급하게 제출하느라고 놓쳤네요,,ㅎ 리뷰 재요청하기 전에 정리하도록 하겠습니다.

- [ ] 사용자는 영화에 대해 별점을 줄 수 있다.
- [ ] 새로고침하더라도 사용자가 남긴 별점은 유지되어야 한다.
- [ ] 별점은 5개로 구성되어 있으며 한 개당 2점이며 1점 단위는 고려하지 않는다.
- 2점, 4점, 6점, 8점, 10점

### 3. 📐 UI⁄UX 개선하기

- [ ] 영화 목록과 영화 상세 정보가 뜨는 모달창에 대한 반응형 레이아웃을 구성한다.
- [ ] 영화 목록의 더보기 버튼을 무한 스크롤 방식으로 변경한다.
- 검색 결과 화면에서 사용자가 브라우저 화면의 끝에 도달하면 그 다음 20개의 목록을 서버에 요청하여 추가로 불러올 수 있다.

6 changes: 2 additions & 4 deletions index.html
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

배포한 사이트에 들어갔을 때 load 되지 않는 이미지들이 있는데 확인해보시면 좋을거 같네요~

image image image

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여긴 아직 수정이 안 된거 같네요 ㅎㅎ

image

Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<link rel="stylesheet" href="./css/reset.css" type="text/css" />
<link rel="stylesheet" href="./css/common.css" type="text/css" />

<title>영화관</title>
<script defer type="module" src="./dist/bundle.js"></script>
</head>
<body>
<div id="app">
<header>
<h1>
<button id="home-button"><img src="./images/logo.png" alt="MovieList 로고" /></button>
<button id="home-button"></button>
</h1>
</header>
<main>
Expand Down
140 changes: 105 additions & 35 deletions src/App.ts
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제 local에서 코드를 실행했을 때 아래와 같은 에러가 나오는데 이 에러가 어디에서 왜 발생하는지 찾아서 고쳐보시면 좋겠네요 ㅎㅎ

image

Original file line number Diff line number Diff line change
@@ -1,22 +1,57 @@
import { Movie } from './index.d';

import { SKELETON_UI_FIXED } from './constants';
import { SKELETON_UI_PC, SKELETON_UI_TABLET, SKELETON_UI_MOBILE } from './constants';

import MoreButton from './components/MoreButton';
import MovieCard from './components/MovieCard';
import movieStore from './store/MovieStore';
import SearchBox from './components/SearchBox';
import searchMovieStore from './store/SearchMovieStore';

import SearchBox from './components/SearchBox';
import MovieCard from './components/MovieCard';
import Modal from './components/Modal';

import Logo from './images/logo.png';

type Tpage = 'popular' | 'search';

export default class App {
#pageType: Tpage = 'popular';

#observer: IntersectionObserver | null = null;

#isLoading: boolean = false;

#skeletonBySize: number = SKELETON_UI_PC;

async run() {
this.#insertLogo();
this.#generateMovieList();
this.#generateSearchBox();
this.#addHomeButtonEvent();
this.#initEventListeners();
this.#setupIntersectionObserver();
}

#insertLogo() {
const homeButton = document.getElementById('home-button');
const imgElement = document.createElement('img');

imgElement.src = Logo;
imgElement.alt = 'MovieList 로고';

homeButton?.appendChild(imgElement);
}

#getSkeletonCount() {
const width = window.innerWidth;
let skeletonCount = this.#skeletonBySize;

if (width <= 390) {
skeletonCount = SKELETON_UI_MOBILE;
} else if (width <= 834) {
skeletonCount = SKELETON_UI_TABLET;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반응형을 위해 이런 조건이 추가된거 같은데 매직 넘버 대신 상수를 사용해보시면 좋을거 같아요

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

매직 넘버 대신 상수 사용하기!
매번 리뷰 코멘트에 달리는데 매 미션마다 하나씩 놓치는 제 자신이 부끄럽네요,,ㅎ


return skeletonCount;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 로직을 let을 사용하지 않도록 변경해보셔도 좋을거 같아요 ㅎㅎ


#generateMovieList() {
Expand All @@ -35,13 +70,19 @@ export default class App {
async #generateItemList(title: string, fetchData: () => Promise<Movie[]>, store: any) {
this.#changeTitle(title);
this.#removePreviousError();

const ulElement = document.querySelector('ul.item-list');

if (ulElement) {
this.#generateSkeletonUI(ulElement as HTMLElement);
const skeletonCount = this.#getSkeletonCount();
this.#generateSkeletonUI(ulElement as HTMLElement, skeletonCount);

const newData = await fetchData();

this.#removeSkeletonUI();
this.#appendMovieCard(newData, ulElement as HTMLElement);

this.#observeSentinel();
}
}

Expand All @@ -61,17 +102,12 @@ export default class App {

ulElement?.appendChild(card.element);
});

this.#generateMoreButton();
}

// eslint-disable-next-line max-lines-per-function
#generateSkeletonUI(ulElement: HTMLElement) {
this.#removeMoreButton();

#generateSkeletonUI(ulElement: HTMLElement, skeletonCount: number) {
const fragment = new DocumentFragment();

for (let i = 0; i < SKELETON_UI_FIXED; i++) {
for (let i = 0; i < skeletonCount; i++) {
const card = new MovieCard({
classes: ['skeleton-container'],
});
Expand All @@ -92,34 +128,49 @@ export default class App {
}
}

/* eslint-disable max-lines-per-function */
#generateMoreButton() {
this.#removeMoreButton();
#setupIntersectionObserver() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

무한스크롤 역시 이번에 처음 구현해보았습니다!
이렇게 intersection Oberserver API를 사용해서 무한 스크롤을 적용해보려고 했는데 안되는 문제가 있습니다!
어디를 놓치고 있는지 힌트를 얻을 수 있을까요?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API key가 없어 직접 코드를 구현해서 확인하지는 못 했네요 😅

const options = {
root: null,
rootMargin: '0px',
threshold: 0.8,
};

this.#observer = new IntersectionObserver(this.#handleIntersection, options);
const sentinel = document.createElement('li');
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기에서 만든 sentinel(li tag)를 DOM에 넣어주는 부분이 없는게 원인이지 않을까 싶은데

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맞네요,,ㅎ intersection obersever API에 대한이해가 덜 된 상태에서 하려다보니 놓쳤던 것 같습니다.

sentinel.classList.add('sentinel');
this.#observer.observe(sentinel);
}

if (searchMovieStore.presentPage === searchMovieStore.totalPages) return;
#observeSentinel() {
const sentinel = document.querySelector('.sentinel');
if (sentinel && this.#observer) {
this.#observer.observe(sentinel);
}
}

const itemView = document.querySelector('section.item-view');

const moreBtn = new MoreButton({
onClick: () => {
if (this.#pageType === 'popular') {
movieStore.increasePageCount();
this.#generateMovieList();
} else {
searchMovieStore.increasePageCount();
this.#generateSearchMovieList();
}
},
#handleIntersection = (entries: IntersectionObserverEntry[]) => {
entries.forEach((entry) => {
if (entry.isIntersecting && entry.intersectionRatio >= 0.8 && !this.#isLoading) {
this.#loadMoreMovies();
}
});
};

itemView?.appendChild(moreBtn.element);
}
// eslint-disable-next-line max-lines-per-function
async #loadMoreMovies() {
if (searchMovieStore.presentPage === searchMovieStore.totalPages) return;

#removeMoreButton() {
const moreButton = document.getElementById('more-button');
if (moreButton) {
moreButton.parentNode?.removeChild(moreButton);
this.#isLoading = true;

if (this.#pageType === 'popular') {
await movieStore.increasePageCount();
await this.#generateMovieList();
} else {
await searchMovieStore.increasePageCount();
await this.#generateSearchMovieList();
}

this.#isLoading = false;
}

#removePreviousError() {
Expand All @@ -130,6 +181,7 @@ export default class App {
}
}

// eslint-disable-next-line max-lines-per-function
#generateSearchBox() {
const header = document.querySelector('header');
const ulElement = document.querySelector('ul.item-list');
Expand All @@ -154,7 +206,6 @@ export default class App {
this.#pageType = 'popular';
this.#changeTitle('지금 인기 있는 영화');
this.#removePreviousError();
this.#removeMoreButton();
this.#renderAllMovieList();
});
}
Expand All @@ -169,5 +220,24 @@ export default class App {

ulElement.innerHTML = '';
this.#appendMovieCard(movieDatas, ulElement as HTMLElement);
this.#observeSentinel();
}

#initEventListeners() {
const itemList = document.querySelector('ul.item-list');

if (itemList) {
itemList.addEventListener('click', this.#handleMovieCardClick.bind(this));
}
}

#handleMovieCardClick(event: any) {
const clickedElement = event.target.closest('.item-card');

if (clickedElement) {
const movieId = Number(clickedElement.dataset.movieid);
const modal = Modal.getInstance(movieId);
modal.openModal();
}
}
}
Loading