02. 발등에 next.js + sanity 떨어짐

0x3den·2023년 6월 11일
0
post-thumbnail

next.js + sanity를 활용한 포트폴리오 사이트를 만들겠다고 얘기한 이후인 2월의 어느날, 포폴을 제출해야 했다. 2월 3째주에 몰아서 작업한 기록을 이제서야 포스팅해본다.


시리즈의 첫번째 포스팅은 1월 말이었는데...벗...그 후로 상황이 많이 달라졌다.

난 분명 야금야금 만들고 싶었는데...
1)포폴 제출 요청이 들어왔고, 2)링크로 포폴을 제출하고 싶었고, 3)제출하려면 만들어야 했다.
🤦‍♀️

제출하려면 해야지!

2월 셋째주에 몰아서 작업했다.
제출하고 지쳐서 한동안 안건드리다가... 저번달부터 다시 야금야금 고쳐보고 있다.

5개월만의 포스팅이니 만큼, 이번 포스팅은
2월 셋째주에 작업한 깃헙 커밋...되새김질이 되겠다.


1. 이력 표시 : month도 표시하기

기존 schema에서 인풋값은 년-월-일-시-분 까지 다 받고 있었으나 아웃풋은 2019 - 2020 처럼 year만 표시하고 있었다. 하지만 난 2020.03 - 2020.11 이렇게 표시하고 싶었지.

그래서 다음과 같이 수정했다.

코드를 들고와서 다시 보자면
(나는 디자이너라 챗 gpt의 도움을 받았다...^^)

  • date object의 month0부터 시작하므로 +1을 더해서 표시한다.
  • duration 이 존재하지 않으면 undefined로 표시
  • duration.start 가 존재하지 않는다면 undefined로 표시
  • duration.end 가 존재하지 않는다면, endYearNow로, endMonthundefined로 표시
  • startYearendYear가 모두 존재할 때만 렌더링, startMonthendMonthundefined인 경우는 월을 표시하지 않음
const startYear = new Date(duration?.start).getFullYear()
const startMonth = duration?.start? new Date(duration.start).getMonth() + 1 : undefined
const endYear = duration?.end? new Date(duration?.end).getFullYear() : 'Now'
const endMonth = duration?.end? new Date(duration.end).getMonth() + 1 : undefined
  
  return (
    <div>
      <div className="mb-20">
...
            {!!(startYear && endYear) && (
              <div className="p-3 lg:p-4">
                <div className="text-xs md:text-sm">Duration</div>
                <div className="text-md md:text-lg">{`${startYear}.${startMonth} -  ${endYear}.${endMonth}`}</div>
              </div>
            )}

스위프트 배울 시절 옵셔널 체이닝에 정신이 아득해졌던 기억이 있는데, 타입스크립트에도... 있네....!

2. Navbar mobile 버전 추가

next.js + sanity의 다른 템플릿을 참고해서 작업했던 것 같은데 아니었다. 챗gpt랑 작업했네.

the navbar that I code like this. but I want to add responsible menu for mobile, like hamburger menu. my code is like this. could you edit it? = 지금 내코드 이런데 모바일 대응하게 수정해줄래?

그래서 챗gpt랑 합의 본 코드는 다음과 같다.

  • 'use client' & useState 넣기
    : 왜 넣었는지 기억이 안나서 다시 빼봤는데 다음과 같은 에러가 떴다.
    You're importing a component that needs useState. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.

    공식 설명 링크
    -> next.js는 SSR(서버 사이드 렌더링)과 CSR(클라이언트 사이드 렌더링)을 처리를 다르게 하는데, SSR되는 컴포넌트 중에 CSR로 되어야하는 부분이 생긴다면 (e.g. useState) 파일의 맨 위에 'use client'를 정의해서 클라이언트 번들의 일부로 인식되게끔 한다.

  • isMenuOpen 으로 상태 관리
    :

'use client'

import { MenuIcon, CloseIcon } from '@sanity/icons'
import { resolveHref } from 'lib/sanity.links'
import Link from 'next/link'
import { useState } from 'react'
import { MenuItem } from 'types'

interface NavbarProps {

export function Navbar({ menuItems }: NavbarProps) {
  const [isMenuOpen, setIsMenuOpen] = useState(false)

  return (
	...

      {/* Hamburger menu for mobile*/}
      <div className="flex md:hidden">
        <button
          type="button"
          className="text-gray-600 hover:text-black focus:outline-none"
          onClick={() => setIsMenuOpen(!isMenuOpen)}
        >
          {isMenuOpen ? (
            <CloseIcon className="h-6 w-6" />
          ) : (
            <MenuIcon className="h-6 w-6" />
          )}
        </button>
      </div>
      
      {/* Menu items */}
      <div
        className={`${
          isMenuOpen ? 'block' : 'hidden'
        } md:flex md:items-center w-full md:w-auto`}
      >
        {menuItems &&
          menuItems.map((menuItem, key) => {
            const href = resolveHref(menuItem?._type, menuItem?.slug)
            if (!href || menuItem?._type === 'home') {
              return null
            }
            return (
              ...
            )
          })}
      </div>
    </div>
  )
}

앞으로 얘기할 수 있는 것들

  • iframe : 비교적 최근에 오류 수정을 끝냄
    • vimeo autoplay 적용되지 않는 에러 해결
    • studio preview에서 iframe 미리보기 (하는중)
  • font : 최근에 어도비 폰트도 적용함
    • 어도비 폰트 적용
    • 로컬 폰트 적용
profile
Web3 Product Designer

0개의 댓글