🔥딱 8일간! 인프런x토스x허먼밀러 역대급 혜택

[인프런 워밍업 클럽 3기 풀스택] 1주차 발자국

[인프런 워밍업 클럽 3기 풀스택] 1주차 발자국

학습 내용

1주차에는 주로 사용할 기술들에 대한 소개와 기본 문법을 배우고 이를 이용해 TODO List를 만들었다.

  • Firebase 이후 등장한 Supabase에 대해서 배웠다.

    오픈소스 프로젝트여서 자체 서버구축이 가능하고 특히 개인/소규모 풀스택 개발에 필요한 것이 대부분 갖춰져 있다는 장점이 있어 앞으로 진행할 프로젝트에 적절한 서비스임을 느꼈다. 부족한 문서 한글화가 단점이라고 하셨는데 강의에서 설정 방법을 자세히 알려주셔서 초보인 나도 쉽게 적용시킬 수 있었다.

  • Next.js는 풀스택 개발에 최적화된 프레임워크로, SSR을 지원하고 별도 서버 구축 없이도 API 구축이 가능하다.

  • 이외에도 TailwindCSS(+MaterialUI), Recoil, React Query(TanStack Query)에 대해 배우고 사용해보았다.

    기존에 GraphQL을 써봤는데, 이번 기회에 궁금했던 React Query의 장점과 기본 문법을 알게 되어서 좋았다. 사용법 자체는 비슷하기도 해서 금방 적응할 수 있을 것 같았다.
    나는 프론트엔드만 더듬더듬 배운 적이 있고 제공되는 백엔드 API를 사용하기만 했었는데(만드는 걸 아주 간단하게 배운 적 있는데 엄청 어려웠다) Server Action 함수 만들고 호출하기만 해도 백엔드 없이 직접 DB를 조작할 수 있다는 게 신기했다.

     

 

미션

생성된 TODO의 생성 시간을 저장하고 이를 표시하는 기능을 추가하세요.

  • TODO 항목 옆에 생성 시간을 표시하기

    • 날짜 포맷 함수 만들기

      // utils/formatDate.ts
      export const formatDate = (dateString?: string): string => {
        if (!dateString) return "";
      
        const date = new Date(dateString);
      
        const yyyy = date.getFullYear();
        const mm = String(date.getMonth() + 1).padStart(2, "0");
        const dd = String(date.getDate()).padStart(2, "0");
        const hh = String(date.getHours()).padStart(2, "0");
        const min = String(date.getMinutes()).padStart(2, "0");
        const ss = String(date.getSeconds()).padStart(2, "0");
      
        return `${yyyy}-${mm}-${dd} ${hh}:${min}:${ss}`;
      };
    • 생성 시각은 이미 supabase에 있으므로 created_at 필드 값을 가져와 사용


      나중에 완료 시각이 추가되어도 생성 시간은 위치가 바뀌지 않게 위쪽에 배치

      <>
        <p className={`flex-1 ${completed && "line-through"}`}>{title}</p>
        <div className="grid grid-rows-2 items-end pr-1">
          <p className="text-xs text-right text-gray-500">
            <i className="fas fa-pen pr-1" />
            {formatDate(todo.created_at)}
          </p>
          <p className="text-xs text-right text-gray-500"></p>
        </div>
      </>
  • completed_at 필드를 추가하여 완료한 시간도 함께 저장하기

    • created_at과 같이 supabase에 completed_at 필드부터 추가(Allow Nullable 체크)


      이후 npm run generate-types 실행해 타입 파일도 수정

    • todo가 체크되어 completed가 true일 때는, completed_at에 완료 시각을 저장하도록 updateTodo Server Action을 수정

      export async function updateTodo(todo: TodoRowUpdate) {
        const supabase = await createServerSupabaseClient();
      
        const { data, error } = await supabase
          .from("todo")
          .update({
            ...todo,
            updated_at: new Date().toISOString(),
            completed_at: todo.completed ? new Date().toISOString() : null,
          })
          .eq("id", todo.id);
      
        if (error) {
          handleError(error);
        }
      
        return data;
      }
    • 마지막으로 completed_at도 포맷팅하여 완료 시각을 표시하고, 조건부 렌더링을 적용해 완료 시각이 없을 때는 아이콘과 시각 모두 표시하지 않도록 작성

      <>
        <p className={`flex-1 ${completed && "line-through"}`}>{title}</p>
        <div className="grid grid-rows-2 items-end pr-1">
          <p className="text-xs text-right text-gray-500">
            <i className="fas fa-pen pr-1" />
            {formatDate(todo.created_at)}
          </p>
          <p className="text-xs text-right text-gray-500">
            {todo.completed_at ? (
              <>
                <i className="fas fa-check mr-2" />
                {formatDate(todo.completed_at)}
              </>
            ) : null}
          </p>
        </div>
      </>

image

마무리

이번 주 학습에서는 스스로 부족한 점을 많이 느꼈던 것 같다... 처음 배운 것, 지금까지 잘 몰랐던 것도 많았고 버전 문제 등 사소한 이슈를 많이 겪어서 시간이 꽤 들었다.

그래도 생각보다 간단하게 Todo List가 만들어지는 걸 보면서, 완강할 때쯤 되면 나만의 프로젝트도 만들 수 있겠다는 자신감이 생기고 있다🙂 아직 너무나 익숙하지 않지만 클론하다 보면 조금씩 감이 잡힐 것 같다.

미션을 진행하면서 발전시킬 수 있는 부분도 많을 것 같은데 이번 주에는 시간을 거의 내지 못해 아쉬웠다. 다음 주에는 더 열심히 따라가고 싶다!

댓글을 작성해보세요.

채널톡 아이콘