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 개선하기] 가브리엘(윤주현) 미션 제출합니다. #81

Merged
merged 118 commits into from
Mar 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
118 commits
Select commit Hold shift + click to select a range
5db1c55
docs: 기능 목록과 요구 사항 작성
feb-dain Mar 14, 2023
281a479
chore: 폴더 정리 및 프리티어 적용
feb-dain Mar 14, 2023
fbc7b98
fix: 이미지 업로드 문제 해결
feb-dain Mar 14, 2023
82760c2
feat: 헤더 컴포넌트화
feb-dain Mar 14, 2023
904e6c0
feat: 영화 목록 컴포넌트화
feb-dain Mar 14, 2023
509f9f0
style: export 방법 변경
feb-dain Mar 14, 2023
cbd6e3d
feat: 영화 아이템 컴포넌트화
feb-dain Mar 14, 2023
440d6fe
feat: API 요청 및 API 키 은닉화
feb-dain Mar 14, 2023
c866b88
feat: API에서 가져온 정보 렌더링
feb-dain Mar 14, 2023
3947f75
feat: 더보기 클릭시 영화 목록 추가 및 렌더링
feb-dain Mar 14, 2023
f77159e
refactor: 영화 목록 관련 함수 분리
feb-dain Mar 14, 2023
8cec080
feat: 인기순으로 영화 정렬
feb-dain Mar 15, 2023
c936bdd
fix: 이미지 불러오기 문제 해결
feb-dain Mar 15, 2023
7197252
feat: 검색 기능 구현 및 정렬 기능 삭제
feb-dain Mar 15, 2023
cfa5193
feat: 목록 이름 대신 검색 결과 표시하는 기능 추가
feb-dain Mar 15, 2023
658cc76
feat: 별점을 소수점 1자리까지만 표시는
feb-dain Mar 15, 2023
b362bed
feat: 로고 클릭시 처음 화면으로 돌아가는 기능 구현
feb-dain Mar 15, 2023
ae6383e
feat: 요청한 API 상태 코드에 따라 오류 메시지 출력
feb-dain Mar 15, 2023
17a4af6
feat: 검색 결과가 없을 경우 결과 없음 안내 페이지 렌더링
feb-dain Mar 15, 2023
eb55b7c
fix: 페이지 초기화 문제 해결
feb-dain Mar 15, 2023
1efa111
refactor: any 타입 제거
feb-dain Mar 15, 2023
e0a59bb
refactor: movie API와 movieStore 분리
feb-dain Mar 16, 2023
95c26c3
feat: 스켈레톤 로딩 기능 추가 및 빈 이미지일 경우 대체 이미지 추가
feb-dain Mar 16, 2023
beea5fc
test: e2e 테스트 진행
feb-dain Mar 16, 2023
f639cfd
docs: README 작성
feb-dain Mar 16, 2023
2e96a14
chore: 필요 없는 파일 삭제
feb-dain Mar 16, 2023
c0fb798
chore: index.html 스크립트 추가
gabrielyoon7 Mar 16, 2023
32305bc
fix: 웹팩 설정을 통한 웹팩 배포 버그 수정
gabrielyoon7 Mar 19, 2023
3da8c40
refactor: 불필요한 옵셔널 체이닝 제거
gabrielyoon7 Mar 19, 2023
d37a516
refactor: 인터페이스 네이밍 개선 및 위치 변경
gabrielyoon7 Mar 19, 2023
ca17994
refactor: 불필요한 css 코드 제거
gabrielyoon7 Mar 19, 2023
48d601c
refactor: event type과 prevent 여부를 추가로 줄 수 있는 형태로 개선
gabrielyoon7 Mar 19, 2023
296c767
refactor: URL 생성 함수 제거 및 상수화
gabrielyoon7 Mar 19, 2023
84eaa12
refactor: 에러 핸들링 개선
gabrielyoon7 Mar 20, 2023
061293b
refactor: 오류 발생 시 서버에서 준 메시지를 출력하도록 개선
gabrielyoon7 Mar 20, 2023
a65de38
refactor: page와 api 레이어 분리
gabrielyoon7 Mar 20, 2023
5b5f426
refactor: 관련 있는 파일끼리 묶는 작업
gabrielyoon7 Mar 20, 2023
e5ec3ff
refactor: 함수 이동
gabrielyoon7 Mar 20, 2023
65f6674
chore: 깃허브 자동 배포 파일 추가
gabrielyoon7 Mar 20, 2023
64e3294
.
gabrielyoon7 Mar 20, 2023
a6b7e69
refactor: 싱글턴 패턴을 활용하여 Store 클래스 제작
gabrielyoon7 Mar 20, 2023
0c76576
refactor: 각종 값을 저장/갱신하는 과정을 Store에 통합
gabrielyoon7 Mar 20, 2023
2b7e9fd
refactor: 영화 호출 및 리프레시 구조 개편
gabrielyoon7 Mar 21, 2023
e9aebc3
style: 공백 개선 및 미사용 메서드 제거
gabrielyoon7 Mar 21, 2023
9a431db
refactor: 인터페이스 명 변경
gabrielyoon7 Mar 23, 2023
60a1848
refactor: 불필요한 체이닝 제거
gabrielyoon7 Mar 23, 2023
cad96a7
feat: 그리드 반응형 기능 추가
gabrielyoon7 Mar 23, 2023
f2c32f4
feat: 무한 스크롤 기능 구현
gabrielyoon7 Mar 23, 2023
4486189
chore: 자동 배포 패치
gabrielyoon7 Mar 24, 2023
80966a6
refactor: CustomEvent를 이용하여 MovieItem과 MovieList 분리
gabrielyoon7 Mar 24, 2023
c23695d
fix: 헤더의 검색창이 고정되어있던 버그 수정
gabrielyoon7 Mar 24, 2023
e08aa5b
refactor: 무한 스크롤 옵저버 로직 개선
gabrielyoon7 Mar 24, 2023
75d1f9f
refactor: 일부 메서드 네이밍 개선
gabrielyoon7 Mar 24, 2023
6c7b21d
feat: 모달 열리는 기능 제작
gabrielyoon7 Mar 24, 2023
732c505
chore: genres fixture 추가
gabrielyoon7 Mar 24, 2023
b946e09
chore: eslint 플러그인 설치
gabrielyoon7 Mar 25, 2023
97931e2
refactor: 이벤트 리스너 내장 기능으로 복구구
gabrielyoon7 Mar 25, 2023
c1457af
feat: 모바일용 헤더 추가
gabrielyoon7 Mar 25, 2023
7704f49
refactor: 헤더 이름 변경
gabrielyoon7 Mar 25, 2023
d9a747c
feat: 반응형 헤더 검색창 추가
gabrielyoon7 Mar 25, 2023
96e8876
fix: 모바일 헤더가 제대로 동작하지 않던 버그 수정
gabrielyoon7 Mar 25, 2023
3db2bcc
refactor: 모달을 정 중앙에 위치하도록 개선
gabrielyoon7 Mar 25, 2023
e89b88f
fix: 모달의 최소 너비가 너무 크게 적용되는 문제 수정
gabrielyoon7 Mar 25, 2023
59e3ce7
refactor: 장르 파일 위치 수정
gabrielyoon7 Mar 25, 2023
4b5f1f2
feat: 모달에서 영화의 이미지를 띄우는 기능 구현
gabrielyoon7 Mar 25, 2023
1b80827
feat: 영화 줄거리와 장르를 받는 기능 구현
gabrielyoon7 Mar 25, 2023
b050c0c
feat: 영화 모달에 추가 정보 렌더링
gabrielyoon7 Mar 25, 2023
b80213d
refactor: 불필요한 함수 제거
gabrielyoon7 Mar 25, 2023
c8d2923
refactor: genres 파일 위치 변경
gabrielyoon7 Mar 25, 2023
c73af67
style: eslint 적용
gabrielyoon7 Mar 25, 2023
42375ad
feat: 모달 종료 버튼 디자인 구현
gabrielyoon7 Mar 25, 2023
3f4c734
feat: 모달 디자인 구현
gabrielyoon7 Mar 25, 2023
43eaa78
fix: 빈 별 사이즈 오류 수정
gabrielyoon7 Mar 25, 2023
778b4cb
fix: 모달 오픈 시 백그라운드 스크롤이 되는 문제 수정, 모달 오픈 시 리스트가 마음대로 이동하는 문제 해결
gabrielyoon7 Mar 25, 2023
68fb87b
feat: 디자인 일부 개선
gabrielyoon7 Mar 25, 2023
452c0bf
feat: 유저 별점 저장 및 조회하는 기능 구현
gabrielyoon7 Mar 25, 2023
aa6d2a5
feat: 모달 설명 디자인 개선
gabrielyoon7 Mar 25, 2023
ead6ab4
fix: 별점 저장이 제대로 되지 않던 문제 수정
gabrielyoon7 Mar 25, 2023
22b23ce
feat: 별점에 따른 안내 문구 출력
gabrielyoon7 Mar 25, 2023
71fffa7
feat: 모달 이미지 반응형 구현
gabrielyoon7 Mar 25, 2023
9cc516a
refactor: 메서드명 변경
gabrielyoon7 Mar 26, 2023
d566b12
feat: 반응형으로 별점 설명이 뜨지 않는 기능 구현
gabrielyoon7 Mar 26, 2023
b51b776
refactor: 엘리먼트 간격 조정
gabrielyoon7 Mar 26, 2023
1131a83
refactor: 메서드 분리
gabrielyoon7 Mar 26, 2023
1cf396d
refactor: 모달 이미지 스켈레톤 적용
gabrielyoon7 Mar 26, 2023
f5fbd52
feat: 모바일용 모달 디자인 적용
gabrielyoon7 Mar 26, 2023
ceedb64
fix: 계산된 유저 별점이 제대로 연동이 되지 않는 문제 수정
gabrielyoon7 Mar 26, 2023
25fc4fe
docs: 오탈자 수정
gabrielyoon7 Mar 26, 2023
f262807
fix: 오탈자 수정
gabrielyoon7 Mar 26, 2023
60bde4f
refactor: 일부 엘리먼트 아이디 지정
gabrielyoon7 Mar 26, 2023
7ada9b1
test: 테스트 케이스 작성
gabrielyoon7 Mar 26, 2023
b68e9a8
Merge branch 'main' of https://github.com/gabrielyoon7/javascript-mov…
gabrielyoon7 Mar 26, 2023
aa2c8c2
refactor: 잘못된 merged files 제거
gabrielyoon7 Mar 27, 2023
7953bc8
fix: 테스트가 mac 환경에서 되지 않는 문제 해결
gabrielyoon7 Mar 27, 2023
83fbf55
refactor: 불필요한 파일 제거
gabrielyoon7 Mar 27, 2023
7e64121
fix: 오탈자 수정
gabrielyoon7 Mar 27, 2023
5cc3f41
fix: skeleton이 빠진 문제 수정
gabrielyoon7 Mar 27, 2023
6394ea0
refactor: 이미지 태그 개선
gabrielyoon7 Mar 27, 2023
81064f6
fix: 과도한 무한스크롤 시 alert 로 인해 다음 동작이 안되는 오류 수정
gabrielyoon7 Mar 27, 2023
0874431
refactor: 별점 설명 메서드 제거
gabrielyoon7 Mar 28, 2023
c308c2b
refactor: 모바일/PC 헤더 통합
gabrielyoon7 Mar 28, 2023
ce88b92
fix:모바일 화면에서 검색 버튼이 펼쳐지지 않던 버그 수정
gabrielyoon7 Mar 28, 2023
9645f90
refactor: 미사용 코드 제거
gabrielyoon7 Mar 28, 2023
208a908
refactor: 파일 구조 개선
gabrielyoon7 Mar 28, 2023
77e00dc
refactor: 헤더 구조 개선
gabrielyoon7 Mar 28, 2023
d3881c3
refactor: 리스너의 콜백 함수를 기명 함수로 수정
gabrielyoon7 Mar 28, 2023
8e9a82e
refactor: 파일 구조 개선
gabrielyoon7 Mar 28, 2023
ccceddd
refactor: 무한 스크롤 관련 코드 함수 이동 (임시)
gabrielyoon7 Mar 28, 2023
78ab1ec
refactor: observeIntersection 유틸화
gabrielyoon7 Mar 29, 2023
f344bee
refactor: api 에러 핸들링 수정
gabrielyoon7 Mar 29, 2023
eb473df
refactor: UserRating 구조 개선
gabrielyoon7 Mar 29, 2023
acdbaa9
refactor: 변수명 개선
gabrielyoon7 Mar 29, 2023
4b79ff6
refactor: 화살표 함수 분리를 통한 네이밍
gabrielyoon7 Mar 29, 2023
4e37e7a
style: 불필요한 공백 제거
gabrielyoon7 Mar 29, 2023
835b147
fix: 헤더 버그 수정
gabrielyoon7 Mar 29, 2023
e40bdd8
refactor: 불필요한 함수 제거
gabrielyoon7 Mar 29, 2023
a286ecf
refactor: 함수 순서 변경
gabrielyoon7 Mar 29, 2023
acb082d
fix: 코드 변경으로 인한 테스트 케이스 수정
gabrielyoon7 Mar 29, 2023
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: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: NodeJS with Webpack
on:
# step1브랜치에 커밋을 push할 때마다 실행
push:
branches: ["step1"]
branches: ["step2"]

jobs:
# deploy라는 job에 배포에 필요한 과정 기술
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@

### 📝 실행 방법

- <a href="https://feb-dain.github.io/javascript-/javascript-movie-review">앱 바로 실행하기</a>
- <a href="https://gabrielyoon7.github.io/javascript-movie-review/">앱 바로 실행하기</a>

- 터미널에서 npm 설치(`npm install`) 후 `npm run start` 커맨드로 앱을 실행할 수 있다.

Expand Down
31 changes: 24 additions & 7 deletions cypress/e2e/movie.spec.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,40 @@ describe("영화관 앱 테스트.", () => {
cy.visit("http://localhost:8080/");
});

it("더보기를 클릭하면 영화 목록이 20개씩 추가된다.", () => {
cy.get("#more-button").click();
it("스크롤이 바닥에 터치할 때 마다 20개씩 추가된다.", () => {
// cy.get('#loading-trigger').click();
cy.get('#loading-trigger').scrollIntoView();
cy.get(".item-list").children().should("have.length", "40");
cy.get("#more-button").click();
cy.wait(1000);
cy.get('#loading-trigger').scrollIntoView();
cy.get(".item-list").children().should("have.length", "60");
cy.wait(1000);
cy.get('#loading-trigger').scrollIntoView();
cy.get(".item-list").children().should("have.length", "80");
});

it("키워드를 검색하면 해당 키워드가 포함된 영화 목록을 보여준다.", () => {
cy.get("input[name='search-bar']").type("고양이");
cy.get("#search-bar").submit();
cy.get(".item-list > li").each((li: HTMLElement) => {
cy.get("#search-input").type("고양이");
cy.wait(1000);
cy.get("#search-button").click();
cy.wait(1000);
cy.get(".item-list > movie-item > li").each((li: HTMLElement) => {
expect(li).to.contain.text("고양이");
});
});

it("로고를 클릭하면 처음 화면으로 이동한다.", () => {
cy.get("#search-input").type("고양이");
cy.wait(1000);
cy.get("#search-button").click();
cy.wait(1000);
cy.get("#logo").click();
cy.get(".item-view > h2").should("contain.text", "지금 인기 있는 영화");
cy.get(".sub-title > h2").should("contain.text", "지금 인기 있는 영화");
});

it("별점을 3점 준다.", () => {
cy.get('ul.item-list movie-item:first-child').click();
cy.get('.rating-star:nth-child(3)').click();
cy.get('#rating-point').should("contain.text", "6");
});
});
5 changes: 0 additions & 5 deletions cypress/fixtures/example.json

This file was deleted.

2 changes: 1 addition & 1 deletion docs/REQUIREMENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
- [x] 사용자가 더보기를 누르면 1페이지를 추가 요청한다.
- [x] 사용자가 더보기를 누르면 더 많은 영화 목록을 보여준다.
- [x] API의 끝 페이지에 도달하면 더보기 버튼을 화면에서 삭제한다.
- [ ] 로딩중에는 스켈레톤 UI를 표시한다.
- [x] 로딩중에는 스켈레톤 UI를 표시한다.
- [x] 인기순으로 영화를 정렬한다.

- [x] 사용자는 보고 싶은 영화를 검색할 수 있다.
Expand Down
5 changes: 4 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@

<body>
<div id="app">
<movie-header></movie-header>
<div id="movie-header">
<movie-header></movie-header>
</div>
<movie-list id="movie-list"></movie-list>
<movie-modal id="movie-modal"></movie-modal>
</div>
</body>

Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"webpack-dev-server": "^4.11.1"
},
"dependencies": {
"dotenv": "^16.0.3"
"dotenv": "^16.0.3",
"eslint-plugin-prettier": "^4.2.1"
}
}
}
Binary file modified src/assets/star_empty.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 0 additions & 35 deletions src/components/Header/headerHandler.ts

This file was deleted.

23 changes: 0 additions & 23 deletions src/components/Header/index.ts

This file was deleted.

63 changes: 0 additions & 63 deletions src/components/MovieList/index.ts

This file was deleted.

39 changes: 0 additions & 39 deletions src/components/MovieList/movieListHandler.ts

This file was deleted.

42 changes: 42 additions & 0 deletions src/components/movie-header/Header.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { onClickLogo, onClickSearchButton, onClickSearchFormTrigger, searchInputEnterListener } from "./headerHandler";

export default class Header extends HTMLElement {

constructor() {
super();
this.render();
onClickLogo();
onClickSearchFormTrigger();
onClickSearchButton();
searchInputEnterListener();
}

render() {
this.innerHTML = `
<header id="header" class="d-flex justify-content-between">
<div id="logo">
<h1><img id="logo" src="./assets/logo.png" alt="MovieList 로고" /></h1>
</div>

<div id="search-box" class="search-box d-flex justify-content-between">
<div id="search-form" class="search-box d-flex justify-content-between">
<input
id="search-input"
type="text"
placeholder="검색"
name="search-bar"
class=""
/>
<button
id="search-button"
class="search-button"
>
검색
</button>
</div>
<button id="search-form-trigger" class="search-button">검색</button>
</div>
</header>
`;
}
}
51 changes: 51 additions & 0 deletions src/components/movie-header/headerHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { searchMovieByKeyword, updateMovies } from "../../domain/movies";
import Store from "../../domain/Store";
import { $ } from "../../utils/selector";

export const onClickLogo = () => {
const store: Store = Store.getInstance();
$("#logo").addEventListener("click", function resetApp() {
store.resetMoviesAndPages();
store.setLastKeyword("");

updateMovies();
})
};

export const onClickSearchFormTrigger = () => {
$("#search-form-trigger").addEventListener("click", function openSearchForm() {
$('#logo').classList.add('display-none');
$('#search-form-trigger').remove();
($('#search-box') as HTMLElement).style.width = '100%';
($('#search-form') as HTMLElement).style.display = 'flex';
($('#search-form') as HTMLElement).style.width = '100%';
($('#search-input') as HTMLElement).style.width = '100%';
})
}

export const onClickSearchButton = () => {
$('#search-button').addEventListener('click', function submitKeyword() {
searchMoviesAndResetHeader();
});
}

export const searchInputEnterListener = () => {
const input = $('#search-input') as HTMLInputElement;
input.addEventListener("keydown", function submitKeyword(event) {
if (event.key === "Enter") {
searchMoviesAndResetHeader();
}
})
}

export const readSearchInputKeyword = () => {
const input = $('#search-input') as HTMLInputElement;
const keyword = input.value;
return keyword;
}

const searchMoviesAndResetHeader = () => {
const keyword = readSearchInputKeyword();
searchMovieByKeyword(keyword);
$('#movie-header').innerHTML = '<movie-header></movie-header>';
}
Loading