쿠키를 사용한 업데이트 공지사항 팝업 만들기 - 02

부루베릐·2022년 11월 10일
0

TIL

목록 보기
3/23
post-custom-banner

이전 포스트 쿠키를 사용한 업데이트 공지사항 팝업 만들기 - 01

실제 구현 시 이슈

쿠키를 어떻게 만들 것인가

크게 두 가지 경우를 생각해 보았다. 첫번째는 팝업을 보여주는 쿠키를 만드는 경우이고, 두번째는 팝업을 보여주지 않는 쿠키를 만드는 경우이다. 밑에 나름대로 정리해 보았는데, 보면 알겠지만 두 방법 모두 문제점을 가지고 있었다.

  1. SHOW_UPDATE_MODAL 쿠키
    1. 해당 쿠키가 있으면 모달을 보여준다.
    2. 메인 페이지가 mounted될 때 해당 쿠키가 없으면 set해준다.
    3. 7일 후 없어지는 것은 max-age 설정을 사용하여 자동으로 expire되도록 한다.
    4. 클릭 후 사라지는 것은 쿠키를 지우거나 값을 변경하는 것으로 한다.
    5. 문제
      1. 해당 쿠키가 없을 때, 이 쿠키가 expired되어서 없어졌는지, 원래부터 없었는지 판단할 수 있는가?
      2. 다음 업데이트 시에 또 해당 모달이 보여져야 하는데, 이번 업데이트에서 이미 안 보여지도록 처리를 한 상황이다. 어떻게 매 업데이트때마다 다시 보여지도록 처리할 수 있을까?
  1. NOT_SHOW_UPDATE_MODAL 쿠키
    1. 해당 쿠키가 없어야 모달을 보여준다.
    2. 최초 진입 시 쿠키가 없으므로 모달을 보여준다.
    3. 문제
      1. 7일 뒤에는 쿠키가 생성되어서 모달을 안 보여주어야 하는데, expired라면 모를까 없던 쿠키를 일정 시간 후에 생성할 수 있는 방법이 있는가?
      2. 역시 위의 SHOW 쿠키 방법과 똑같이 매 업데이트때마다 모달이 다시 보여지도록 처리할 수 있는 방법이 마땅치 않다.

즉 위의 두 방식 모두

  • 계속되는 버전 업데이트를 어떻게 핸들링해 줄 수 있을 것인지
  • 다시 보지 않기 기능과 7일까지만 보이는 기능 둘 다를 만족시킬 방법이 있을 것인지

모두 커버해주는 해결책이 아니라는 것이다. 단순하게 모달이 보여지는지에 대한 여부만을 판단하기에는 고려해야 하는 조건이 많아지게 되었다.
따라서 업데이트에 대한 정보 + 모달을 언제까지 보여줄 수 있을지에 대한 것 모두 쿠키를 사용하여 커버하고 싶다면, 이에 대한 정보를 쿠키 안에 저장하는 것이 최선의 선택이라 판단하였다.

해결책

  • 쿠키는 모달이 보여지고 안 보여지고에 대한 것만 판단할 수 없다. 업데이트에 대한 정보 역시 쿠키 안에 들어 있어야 한다.
  • 쿠키에는 업데이트 버전 정보에 관한 값과 모달을 보여줄 날짜 기한에 대한 값이 들어간다.
  • 쿠키의 유효시간은 없다.
  • 현재 업데이트 정보가 쿠키 값과 일치하지 않는다면 해당 모달은 보여지지 않는다.
  • 사용법
    • 메인 페이지로 진입 시 쿠키가 없거나 쿠키 안의 업데이트 버전 정보 값이 현재 업데이트보다 뒤쳐진다면 쿠키를 현재 업데이트 정보로 새로 생성해준다.
    • mounted 안에서 쿠키의 모달을 보여줄 날짜 기한 값을 매번 현재 날짜와 비교하면서 날짜가 지나면 더 이상 보여주지 않는다.
      • 버전 업데이트 시 쿠키의 모달을 보여줄 날짜 기한 값을 업데이트 시부터 7일 후로 변경한다.
      • 다시 보지 않기를 누르면 쿠키의 모달을 보여줄 날짜 기한 값을 지금으로 변경

코드

이제 위의 계획을 코드로 옮겨보자. 우리 회사는 nuxt.js를 사용하므로, nuxt.js로 해당 기능을 구현한다.

메인 페이지에 공지사항 팝업 div 요소를 만든다. isShowingNotice 플래그와 handleClickUpdateNoti라는 클릭 이벤트 핸들러를 가지고 있다.

<template>
	...
  <div 
		v-if="isShowingNotice" 
		class="update-notice" 
		@click="handleClickUpdateNoti"
	/>
	...
</template>

mounted 로직

먼저 mounted 로직을 살펴보자. 메인 페이지가 마운트될 때마다 쿠키의 값을 확인한다. 쿠키가 없거나 쿠키에 저장된 업데이트 날짜가 최신이 아니라면 새로 쿠키를 만들어 줄 것이다. 그리고 메서드 checkUpdateNotiShow를 호출하여 쿠키 안의 값을 검사해 업데이트 팝업을 보여줄지 말지를 결정할 것이다.

<script lang="ts">
import { defineComponent } from '@nuxtjs/composition-api'
import Cookies from 'js-cookie'
  
export default defineComponent({
  mounted() {
    const nowDate = new Date()
    const updatedDate = new Date(UPDATED_DATE)
    const updateNotiCookie = Cookies.get('UPDATE_NOTICE') as string

    if (updateNotiCookie === undefined || this.checkIfRefreshUpdateDateNeeded()) {
      const updateInfo = {
        updatedDate,
        removeNotiDate: new Date(new Date().setDate(nowDate.getDate() + this.MAX_NOTI_REMAINING_DAYS))
      }
      Cookies.set('UPDATE_NOTICE', JSON.stringify(updateInfo), { expires: 365 })
    }

    this.checkUpdateNotiShow()
  },
  data() {
    return {
      MAX_NOTI_REMAINING_DAYS: 7,
      isShowingNotice: false,
    }
  },
...

이 때 좀 유심히 봐야 하는 로직은 팝업을 언제까지 보여줄지 그 기한을 저장하는 removeNotiDate이다. 쿠키가 생성되었을 때부터 7일 후로 기간이 설정되어야 하므로, Date 객체를 다음과 같이 설정하여 사용할 수 있다.

removeNotiDate: new Date(new Date().setDate(nowDate.getDate() + this.MAX_NOTI_REMAINING_DAYS))

nowDate는 마운트되었을 때(로그인하여 처음으로 메인 페이지에 들어왔을 때)의 날짜를 이야기한다. Date 객체에서 day를 가져오기 위해서는 getDate() 메서드를 활용하면 된다. MAX_NOTI_REMAINING_DAYS의 값은 상수로써 관리해주기 위해 data 속성에 대문자로 설정해두었다.

nowDate부터 7일이 지난 날을 설정해주기 위해 new Date()setDate() 메서드를 활용한다.

methods 로직

메서드 로직을 하나하나씩 살펴보도록 하자.

checkUpdateNotiShow

일단 가장 중요한, 업데이트 팝업을 보여줄지 말지를 결정하는 메서드이다. 컴포넌트가 매번 마운트될 때와 팝업을 클릭하였을 때 호출된다.

checkUpdateNotiShow() {
  const updateNotiCookie = Cookies.get('UPDATE_NOTICE') as string

  if (updateNotiCookie === undefined) return

  const removeNotiDate = JSON.parse(updateNotiCookie).removeNotiDate
  this.isShowingNotice = new Date() < new Date(removeNotiDate)
},

isShowingNotice의 값을 boolean으로 정해주는 것이 핵심이고, 현재 시간과 쿠키에 들어 있는 removeNotiDate 시간을 비교한다. stringify하여 스트링화 된 Date 객체는 string으로 나오기 때문에 new Date() 인자로 넣어주어 Date 객체로 다시 만들어준다.


handleClickUpdateNoti

팝업을 클릭했을 때의 이벤트 핸들러이다. 쿠키를 가지고 와 removeNotiDate를 클릭한 시점으로 변경한다. 그리고 바로 checkUpdateNotiShow를 호출하여 팝업을 화면에서 없앤다.

팝업 클릭 시 팝업이 없어지면서 공지사항 페이지가 새 탭에 열려야 한다. 따라서 window.open의 두 번째 인자를 ‘_blank’로 설정한다.

handleClickUpdateNoti() {
  const updateNotiCookie = Cookies.get('UPDATE_NOTICE') as string

  if (updateNotiCookie === undefined) return

  const updateInfo = JSON.parse(updateNotiCookie)
  updateInfo.removeNotiDate = new Date()
  Cookies.set('UPDATE_NOTICE', JSON.stringify(updateInfo), { expires: 365 })
  this.checkUpdateNotiShow()

  window.open(UPDATE_INFO_URL], '_blank')
},

checkIfRefreshUpdateDateNeeded

mounted될 때, 쿠키에 등록된 업데이트 날짜가 최신인지 판단하는 메서드이다.

checkIfRefreshUpdateDateNeeded() {
    const updateNotiCookie = Cookies.get('UPDATE_NOTICE') as string

    if (updateNotiCookie === undefined) return

    const cookieUpdatedDate = new Date(JSON.parse(updateNotiCookie).updatedDate)
    const actualUpdatedDate = new Date(this.$config.UPDATED_DATE)

    return cookieUpdatedDate < actualUpdatedDate
  }
}

이렇게 해서 구현이 끝났다!
아래와 같이 쿠키가 만들어졌고, 이 쿠키를 통해 업데이트 공지사항 팝업을 보여줄 수 있게 되었다.

좀 부족한 코드고 앞으로도 수정하거나 최적화를 진행하여야 하지만, 얕더라도 직접 쿠키를 사용해보는 경험을 한 것으로도 좋은 경험을 했다 생각한다.
이제 다음 포스팅으로는 내가 이 기능을 구현하면서 고민했던 부분들에 대해 이야기하려 한다!

post-custom-banner

0개의 댓글