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

KDT5_양준용_2차 과제 제출 RE_4조 #68

Open
wants to merge 59 commits into
base: main
Choose a base branch
from
Open

Conversation

azure0929
Copy link

🎬 2차 과제 : API를 활용한 영화 검색 사이트 만들기


작성자 : 양준용 - 4조
제출 날짜 : (1차) 05.04, (2차:피어 리뷰 후 수정) 5월 7일


결과물


HTML, CSS, SCSS, JS 활용



필수 요구사항

  • 영화 제목으로 검색이 가능해야 합니다!
  • 검색된 결과의 영화 목록이 출력돼야 합니다!
  • 단일 영화의 상세정보(제목, 개봉연도, 평점, 장르, 감독, 배우, 줄거리, 포스터 등)를 볼 수 있어야 합니다!
  • 실제 서비스로 배포하고 접근 가능한 링크를 추가해야 합니다.

선택 요구사항

  • 한 번의 검색으로 영화 목록이 20개 이상 검색되도록 만들어보세요.
  • 영화 개봉연도로 검색할 수 있도록 만들어보세요.
  • 영화 목록을 검색하는 동안 로딩 애니메이션이 보이도록 만들어보세요.
  • 무한 스크롤 기능을 추가해서 추가 영화 목록을 볼 수 있도록 만들어보세요.
  • 영화 포스터가 없을 경우 대체 이미지를 출력하도록 만들어보세요.
  • 영화 상세정보가 출력되기 전에 로딩 애니메이션이 보이도록 만들어보세요.
  • 영화 상세정보 포스터를 고해상도로 출력해보세요. (실시간 이미지 리사이징)
  • 차별화가 가능하도록 프로젝트를 최대한 예쁘게 만들어보세요.
  • 영화와 관련된 기타 기능도 고려해보세요.



화면구성

Home
Search
Movie



주요기능


1. 한 번의 검색으로 20개 출력

  • if 함수를 활용하여 searchMovies(2)를 추가하여 .btn 클릭 시 영화 리스트가 더 출력이 되도록 설정
const btnEl = this.el.querySelector('.btn')
btnEl.addEventListener('click', () => {
  if (movieStore.state.searchText.trim()) {
    searchMovies(1)
    searchMovies(2)
    }
  })



2. 영화 포스터가 없을 경우 대체 이미지를 출력

  • src에 ${movie.Poster}를 입력하여 포스터를 불러오고, onerror 속성을 사용하여 '스즈메의 문단속' 포스터로 이미지를 대체
<img src="${movie.Poster}"  onerror="this.src='https://img.cgv.co.kr/Movie/Thumbnail/Poster/000086/86815/86815_1000.jpg'" />



3. 영화 상세정보 포스터를 고해상도로 출력

  • replace라는 메서드를 활용하여 'SX1000'을 추가하여 고해상도로 출력
const bigPoster = movie.Poster.replace('SX300', 'SX1000')




어려웠던 점

  • Intersection Observer API에 대한 지식 부족
  • 개봉연도로 검색할 수 있도록 하는 Js 문법 지식 부족

궁금한 점

  • img 태그를 활용하여 onerror 속성을 통해 대체 이미지를 출력하는 방법 이외에 다른 방법이 있는지 궁금합니다.

Copy link
Member

@iamidlek iamidlek left a comment

Choose a reason for hiding this comment

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

고생하셨습니다.
전체적으로 잘 구현해 주셨습니다.
UI도 보기 좋게 잘 구현해 주신 것 같습니다.
readme도 잘 작성해 주시고
commit 도 잘 나누어서 작성해 주셔서 좋습니다.
commit message 등 조금 더 고려가 되면 더욱 좋을 것 같습니다.

core 폴더 내부 assets.js, src의 script.js 는 파일명이 어떤 것을 의미하는지 애매한 것 같습니다.

<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Oswald:wght@600&family=Roboto:wght@400;700&display=swap" rel="stylesheet" />

<link rel="stylesheet" href="./src/css/style.css" />
Copy link
Member

Choose a reason for hiding this comment

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

reset css 와 겹치는 내용이 많은 것 같습니다.
scss파일과 따로 관리하는 이유도 있으신지 궁금한 부분입니다.

movieStore.subscribe('movies', () => {
this.render()
})
movieStore.subscribe('loading', () => {
Copy link
Member

Choose a reason for hiding this comment

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

subscribe로 store의 값이 변화 될 때 재렌더링을 위해 작성하신 부분인데
구독하는 대상이 3개나 있는데 loading 하나로 하여도 충분하지 않을까요?
(data fetch 시작과 종료에 따라 재렌더링이 이루어지면 될 것 같습니다.)

super({
tagName: 'button'
})
movieStore.subscribe('pageMax', () => {
Copy link
Member

Choose a reason for hiding this comment

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

구조상 pageMax 값이 동일하더라도
할당이 이루어져 재렌더링이 일어나지만
의미적으로는 page 의 변화를 바라보고 있어야 할 것 같습니다.

현재 구조에서는 아래처럼 될 것 같아요.

Suggested change
movieStore.subscribe('pageMax', () => {
movieStore.subscribe("page", () => {
const { page, pageMax } = movieStore.state;
if (page === 1) {
this.el.classList.remove("hide");
return;
}

<a href="#/search"><button class="btn btn-primary"><i class="fa-solid fa-magnifying-glass"></i></button></a>
`
const inputEl = this.el.querySelector('input')
inputEl.addEventListener('input', () => {
Copy link
Member

Choose a reason for hiding this comment

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

event 받아서 처리하는 방법도 있을 것 같습니다.

Suggested change
inputEl.addEventListener('input', () => {
inputEl.addEventListener("input", (event) => {
movieStore.state.searchText = event.target.value;
});

btnEl.addEventListener('click', () => {
if (movieStore.state.searchText.trim()) {
searchMovies(1)
searchMovies(2)
Copy link
Member

@iamidlek iamidlek May 10, 2023

Choose a reason for hiding this comment

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

1, 2 페이지를 동시에 요청하시는 경우 이하 사항에 대한 처리가 필요할 것 같습니다.
EX) zozo 검색 시 총 결과가 10개 미만이라 2page 요청 이후 not found 처리되는 문제가 있습니다.


this.el.innerHTML = /* html */ `
<div
style="background-image: url(${bigPoster});"
Copy link
Member

Choose a reason for hiding this comment

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

인라인 스타일을 사용하지 않고 구현 할 수 있는 방법을 고려해 보시면 좋을 것 같습니다.

img {
display: block;
width: 100%;
cursor: pointer;
Copy link
Member

Choose a reason for hiding this comment

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

cursor pointer를 img 태그에 주면
Home 의 BEST SCENE 의 이미지의 경우
클릭 시 아무 동작이 없기 때문에 좋지 않을 것 같습니다.

store.state.message = Error
}
} catch (error) {
console.log('searchMovies error:', error)
Copy link
Member

Choose a reason for hiding this comment

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

console.error 사용해 보시면 좋을 것 같습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants