epiday

개발 개요

Project Name

Epiday (에피데이)

Overview

감정 상태를 기록하고 명언과 글귀를 공유하며 소통할 수 있는 서비스

Development Period

2024년 9월 ~ 10월

Link

개발 방식

코드잇(주)에서 제공받은 기획안, 디자인 시안, 백엔드 서버 스웨거 문서를 기반으로 프론트엔드 개발 진행
(프론트엔드 개발 기여도 100%)

  • 기획안

    기획안

    Notion
  • 디자인 시안

    디자인 시안

    Figma
  • 백엔드 스웨거

    백엔드 스웨거

    Swagger

프론트엔드 개발

기여도 100%

기술 스택

Routing & Rendering

  • Next.js

    App Router를 사용하여 SSR와 CSR을 혼합해 페이지 렌더링과 네비게이션 최적화

  • TypeScript

    정적 타입 시스템을 도입하여 코드의 가독성과 유지보수성 강화

Authentication

  • NextAuth

    사용자 인증 관리 및 보안성 강화

State Management

  • React Query

    API 데이터 호출 및 캐싱, 상태 관리

  • Zustand

    전역 상태 관리 (모달과 토스트)

  • React Hook Form

    사용자 입력 검증 및 상태 관리 (로그인, 회원가입 및 Epiday 작성 폼)

Styling

  • Tailwind CSS

    유틸리티 기반의 CSS 프레임워크로 빠르고 효율적인 스타일링 구현

  • Heroicons

    Next.js 페이지에 아이콘 추가

Functional Components

  • react-calendar

    달력 컴포넌트

  • recharts

    감정 차트 데이터 시각화

  • react-avatar-editor

    프로필 이미지 편집 (확대 및 위치 조정 가능)

Deployment

  • Vercel

    프로젝트 배포 및 관리

주요 기능

Centralized Query Key Management

  • Query Key 관리를 한 곳에서 통일성 있게 유지해 혼동을 방지하고, 재사용성을 높임
  • export const queryKeys = {
      epiday: {
        allEpidays: ['epidays'],
        epidays: (limit: number) => ['epidays', { limit }],
        epidayForToday: (date: string) => ['epidays', 'today', { date }],
        epidaysBySearchKeyword: (keyword: string) => ['epidays', 'search', { keyword }],
        epidayDetails: (id: number) => ['epidays', 'detail', { id }],
        myEpidays: ['epidays', 'my'],
      },
      emotionLog: {
        allEmotionLogs: ['emotionLogs'],
        emotionLogForToday: ['emotionLogs', 'today'],
        emotionLogsForMonth: (year: number, month: number) => ['emotionLogs', 'month', { year, month }],
      },
      comment: {
        allComments: ['comments'],
        comments: (limit: number) => ['comments', { limit }],
        commentsForEpiday: (epidayId: number) => ['comments', 'epiday', { epidayId }],
        myComments: ['comments', 'my'],
      },
    };
    

Optimistic Updates

  • '좋아요' 클릭과 댓글 삭제 작업에 React Query의 onMutate를 사용해 낙관적 업데이트를 적용, 즉각적인 UI 반응을 통해 사용자 경험을 개선
  • const likeMutation = useMutation({
      mutationFn: () => {
        return isLiked ? deleteLike(session, id) : postLike(session, id);
      },
      onMutate: async () => {
        await queryClient.cancelQueries({ queryKey: queryKeys.epiday.epidayDetails(id) });
        const prevEpidayDetails = queryClient.getQueryData(queryKeys.epiday.epidayDetails(id));
        queryClient.setQueryData(queryKeys.epiday.epidayDetails(id), (oldData: GetEpidayData) => ({
          ...oldData,
          likeCount: oldData.isLiked ? oldData.likeCount - 1 : oldData.likeCount + 1,
          isLiked: !oldData.isLiked,
        }));
        return { prevEpidayDetails };
      },
      onError: (error, _, context) => {
        showToast({ message: error.message, type: 'error' });
        queryClient.setQueryData(queryKeys.epiday.epidayDetails(id), context.prevEpidayDetails);
      },
      onSettled: () => {
        queryClient.invalidateQueries({ queryKey: queryKeys.epiday.epidayDetails(id) });
      },
    });

Loading Skeletons

  • API 데이터 로딩 중 로딩 스켈레톤을 표시하여 화면 깨짐 방지
skeleton2

Smooth Responsive Design

  • 다양한 화면 크기에서도 문제없이 표시되도록 정밀한 CSS 작업을 통해 모바일에서 PC까지 유연한 반응형 디자인을 구현
responsive

페이지 소개

랜딩 페이지

  • SEO 최적화를 위해 서버 사이드 렌더링(SSR) 구현
  • 최신 에피데이 데이터를 서버에서 미리 API로 불러옴
  • 상단 프로필 버튼과 '시작하기' 버튼 클릭 시 로그인 페이지로 이동
landing

로그인/회원가입 페이지

  • React Hook Form의 useForm으로 폼 상태 및 에러 메시지 관리
  • NextAuth의 signIn을 활용한 사용자 인증 관리
  • 사이트 둘러보기용 계정 제공:
    ID: daeun@gmail.com
    PW: dhekdms123 (오다은123)
login

메인 페이지

  • 오늘의 에피데이가 있을 경우 표시, 없으면 미표시
  • 오늘의 감정 선택 기능
  • 최신 에피데이와 댓글이 보여지며, '더보기' 클릭 시 3개씩 추가 로드
  • 새로고침 버튼으로 최신 상태 동기화
epidays

피드 페이지

  • 최신순 에피데이 나열, '더보기' 클릭 시 8개씩 추가 로드
  • 새로고침 버튼으로 최신 상태 동기화
feed

검색 페이지

  • 키워드 검색 시 해당 단어가 포함된 에피데이 리스트 표시
  • 검색어를 localStorage에 저장해 최근 검색어로 표시, '모두 지우기' 버튼으로 삭제 가능
  • 에피데이 리스트는 8개씩 무한 스크롤로 표시
search

에피데이 상세 페이지

  • 본인 작성 글에는 수정/삭제 가능한 케밥 메뉴 표시
  • 좋아요 기능 및 URL 복사 기능 제공
  • 댓글은 7개씩 무한 스크롤로 표시
epidays-detail

에피데이 작성/수정 페이지

  • React Hook Form의 useForm으로 폼 상태 및 에러 메시지 관리
  • 라디오 버튼 선택에 따라 input 필드 표시 여부 조정
  • 태그는 입력 후 Enter로 추가하고, X 버튼으로 삭제 가능
  • 필수 항목 작성 시 완료 버튼 활성화
form

마이 페이지

  • 프로필과 오늘의 감정, 감정 캘린더, 감정 차트, 작성한 에피데이와 댓글 표시
  • '프로필 편집' 클릭 시 닉네임과 프로필 이미지를 수정할 수 있는 모달 창 표시
  • 감정 캘린더에는 일별 감정 이모지 기록이 표시되며, 화살표로 월 변경 가능
  • 감정 차트는 선택한 월의 감정 비율을 시각화
  • 내 에피데이/댓글은 최신 3개만 표시, '더보기' 클릭 시 3개씩 추가 로드
mypage