개발일지 17 - 상세 페이지에서 찜하기 구현, 찜과 평점 UX 개선

tk7580·2025년 6월 16일

찜하기 기능 구현

1. 초기 화면 렌더링 (Backend → Frontend)

사용자가 작품 상세 페이지에 접근했을 때, WorkController이 작업 수행

  • 현재 로그인한 사용자인지 확인
  • 로그인 상태라면 UserActivityServiceisWorkWishlisted() 메소드를 호출,
    해당 작품에 대한 찜 상태(boolean)를 조회
  • 조회된 boolean 값을 isWishlisted라는 이름으로 Model에 담아 detail.html 뷰(View)로 전달

2. 아이콘 상태 표시 (Frontend - Thymeleaf & CSS)

detail.html은 컨트롤러로부터 받은 isWishlisted 값을 사용

  • th:classappend 속성을 통해, isWishlistedtrue일 경우에만 '찜하기' 버튼(<a> 태그)에 wish-active 라는 CSS 클래스를 추가
  • CSS는 .wish-active 클래스를 가진 버튼 내부의 svg 아이콘에 fill 속성을 적용하여, 아이콘 내부를 채운다.

3. 사용자 클릭 이벤트 처리 (Frontend - JavaScript)

사용자가 '찜하기' 버튼을 클릭하면, detail.html의 JavaScript가 작업 수행

  • 버튼에 wish-active 클래스가 있는지 여부로 현재 찜 상태를 판단
  • 상태에 따라 백엔드의 UserActivityControllerPOST (찜하기) 또는 DELETE (찜 취소) 요청을 비동기(fetch)로 전송
  • 서버로부터 성공적인 응답(response.ok)을 받으면, 버튼의 wish-active 클래스를 toggle (있으면 제거, 없으면 추가)하여 아이콘의 채워진 상태를 즉시 반전

4. UX 개선

  • 기존
    찜을 하지 않은 상태에서는
    아이콘이 비워져 있고 '찜하기'
    찜을 한 상태에서는
    아이콘이 채워져 있고 '찜 취소' 라고 출력된다.

글자 수가 달라서 상태가 바뀔때마다 버튼 크기가 바뀌는 것이 시각적으로 좋지 못하다고 판단하였고,
평소 GS편의점택배 택배 예약 페이지를 보면서 주의사항 부분에 '인지하였습니다' 등 문구가
눌려있는 상태인지 안 눌려있는 상태인지 구분하기 힘들다고 생각해 온 점을 반영하여
'찜하기' 라는 글자는 그대로 유지하고
아이콘의 fill만 조정하여 표시하는 방식으로 결정하였다.

평점 매기기 UX 개선

평점 매기기의 경우는 원래
시청 완료한 작품을 기록,
사용자들의 평점을 기반으로 작품의 평점을 계산,
그리고 사용자가 준 평점을 기반으로 작품을 추천하는 기능을 구현하려고 짜놓은 계획인데

개발일지 14의 상태처럼 평점 매기기가 먼저 나와 있으면 시청 완료가 선행되고 평점을 매기는 구조의 의미가 전달되지 않을 것 같다고 생각하였다.
감상 완료를 해야먄 평점을 남길 수 있어야 하지만
현실적으로 서비스 내에서 감상을 하는 것은 불가능하기에
봤다고 치고 넘어간다고 하더라도 감상 완료는 먼저 와야 한다.

그런 차원에서 시청 완료 버튼을 먼저 준비하고
시청 완료 버튼을 누르면 그때 평점 매기기 버튼이 나오는 방식으로 구현하기로 결정하였다.

0개의 댓글