🍿Component Guide

이 가이드는 gomdolbook 프론트엔드 프로젝트에서 사용되는 주요 리액트 컴포넌트들에 대한 설명을 제공합니다. 각 컴포넌트의 목적, 주요 Props, 그리고 사용 예시를 통해 프로젝트의 이해를 돕고 컴포넌트 재사용성을 높이는 것을 목표로 합니다.

📁 UI 컴포넌트 (src/ui)

애플리케이션 전반에 사용되는 기본적인 UI 요소들입니다.

  • 경로: src/ui/Modal.tsx

  • 설명: 재사용 가능한 모달 다이얼로그 컴포넌트입니다. 오버레이 및 닫기 버튼 로직을 포함하며, 컨텐츠를 내부에 표시합니다. createPortal 사용하여 #modal DOM 요소에 렌더링됩니다.

  • Props:

    • children: ReactNode (필수) - 모달 내부에 표시될 컨텐츠입니다.

    • innerWidth: string (필수) - 모달의 너비입니다. (예: "500px", "80%")

    • innerHeight: string (필수) - 모달의 높이입니다. (예: "300px", "fit-content")

    • bgc?: string (선택, 기본값: #fafafa) - 모달의 배경색입니다.

    • color?: string (선택, 기본값: #262627) - 모달의 텍스트 색상입니다.

    • onClose: () => void (필수) - 모달을 닫을 때 호출될 함수입니다.

  • 주요 기능:

    • Escape 키를 누르거나 오버레이를 클릭하여 모달을 닫을 수 있습니다.

    • scale-in, scale-out CSS 클래스를 사용한 애니메이션 효과가 적용됩니다.

  • 사용 예시:

const [isModalOpen, setIsModalOpen] = useState(false);
// ...
{isModalOpen && (
  <Modal innerWidth="400px" innerHeight="200px" onClose={() => setIsModalOpen(false)}>
    <p>모달 내용입니다.</p>
  </Modal>
)}

LoginRequireModal

  • 경로: src/ui/LoginRequireModal.tsx

  • 설명: 사용자에게 로그인이 필요함을 알리는 특정 목적의 모달입니다. Modal 컴포넌트를 기반으로 구현되었습니다.

  • Props:

    • onClose: () => void (필수) - 모달을 닫을 때 호출될 함수입니다.

  • 사용 예시:

const [showLoginModal, setShowLoginModal] = useState(false);
// ...
// 사용자가 로그인 없이 특정 기능에 접근하려고 할 때
// setShowLoginModal(true);
// ...
{showLoginModal && <LoginRequireModal onClose={() => setShowLoginModal(false)} />}

BookPublisher

  • 경로: src/ui/BookPublisher.tsx

  • 설명: 책의 저자, 출판사, 출판일을 표시하는 컴포넌트입니다.

  • Props:

    • author: string (필수) - 저자 이름입니다.

    • publisher: string (필수) - 출판사 이름입니다.

    • date: string (필수) - 출판일입니다.

    • align?: string (선택, 기본값: center) - 컨텐츠 정렬 방식 (justify-content 값) 입니다.

  • 사용 예시:

<BookPublisher author="김곰돌" publisher="곰돌출판사" date="2024-01-01" align="flex-start" />

ThreeDotMenu

  • 경로: src/ui/ThreeDotMenu.tsx

  • 설명: 세 개의 점 아이콘으로 트리거되는 드롭다운 메뉴입니다. 주로 '삭제하기'와 같은 추가 작업을 제공하며, Framer Motion을 사용한 애니메이션이 적용되어 있습니다. ModalTypes.DELETE 타입의 확인 모달을 내부적으로 사용합니다.

  • Props:

    • onRemove: () => void (필수) - '삭제하기' 메뉴 아이템 클릭 후, 확인 모달에서 '삭제' 버튼을 눌렀을 때 실행될 함수입니다.

    • statusUpdate?: () => void (선택) - (현재 코드에는 직접적인 사용처가 명시되어 있지 않으나, 추후 상태 변경 등의 추가 메뉴를 위해 존재할 수 있습니다.)

    • isLoading: boolean (필수) - onRemove 함수 실행 시 '삭제' 버튼의 비활성화 상태를 제어합니다.

    • children?: ReactNode (선택) - 드롭다운 메뉴에 추가적인 DropdownLink 아이템을 넣을 수 있습니다.

  • 주요 기능:

    • Framer Motion을 사용한 드롭다운 애니메이션 (open/closed, itemVariants).

    • useModal 커스텀 훅을 사용하여 모달 상태를 관리합니다.

  • 사용 예시:

// 아이템 삭제 함수
const handleDeleteItem = () => { /* ... */ };
// 로딩 상태
const isLoading = false;

<ThreeDotMenu onRemove={handleDeleteItem} isLoading={isLoading}>
  <DropdownLink variants={itemVariants} onClick={() => alert('추가 액션!')}>
    추가 액션
  </DropdownLink>
</ThreeDotMenu>

Toast

  • 경로: src/ui/Toast.tsx

  • 설명: 작업 완료 후 사용자에게 성공 또는 오류 메시지를 잠시 보여주는 알림 컴포넌트입니다. createPortal을 사용하여 #modal DOM 요소에 렌더링됩니다.

  • Props:

    • onShow: boolean (필수) - 토스트 메시지의 표시 여부를 제어합니다.

    • onError: boolean (필수) - true이면 오류 메시지 스타일, false이면 성공 메시지 스타일을 적용합니다.

    • onClose: () => void (필수) - 토스트 메시지가 닫힐 때 호출될 함수입니다.

    • message: { success: string; error: string } (필수) - 성공 및 오류 상황에 표시될 메시지 객체입니다.

  • 주요 기능:

    • 3초 후 자동으로 사라지며, 애니메이션 효과가 적용됩니다.

  • 사용 예시:

// useToast 훅 사용 예시
// const { isToastVisible, hasToastError, openToast, openErrorToast, closeToast } = useToast();
// ...
// openToast(); 또는 openErrorToast(); 호출로 표시
// ...
<Toast
  onShow={isToastVisible}
  onError={hasToastError}
  onClose={closeToast}
  message={{
    success: "작업이 성공적으로 완료되었습니다.",
    error: "오류가 발생했습니다. 다시 시도해주세요.",
  }}
/>

StatusTapNavigation

  • 경로: src/ui/StatusTapNavigation.tsx

  • 설명: 상태 기반의 탭 네비게이션을 제공하는 제네릭 컴포넌트입니다. react-router-domuseNavigate를 사용하여 라우팅을 처리합니다.

  • Props:

    • statusOption: TapOption<T>[] (필수) - 각 탭의 정보를 담는 배열입니다. TapOption 객체는 label (탭에 표시될 문자열), status (탭의 상태 값), path (클릭 시 이동할 경로)를 포함합니다.

    • initialStatus: T (필수) - 초기에 선택될 탭의 상태 값입니다.

  • 타입 파라미터:

    • T extends string: status 값의 타입을 나타내는 제네릭 파라미터입니다.

  • 사용 예시:

type BookReadStatus = "reading" | "finished" | "to_read";

const libraryStatusOptions: { label: string; status: BookReadStatus; path: string }[] = [
  { label: "읽는 중", status: "reading", path: "/library/reading" },
  { label: "읽기 완료", status: "finished", path: "/library/finished" },
  { label: "읽을 예정", status: "to_read", path: "/library/to_read" },
];

<StatusTapNavigation
  statusOption={libraryStatusOptions}
  initialStatus="reading"
/>

Skeleton Loaders

  • 데이터 로딩 중에 표시되는 플레이스홀더 UI 컴포넌트들입니다. 다양한 컨텐츠 영역에 맞춰 여러 종류가 제공됩니다.

  • SimpleSkeletonLoader: 일반적인 목록 아이템 형태의 스켈레톤 로더.

    • 경로: src/ui/SimpleSkeletonLoader.tsx

    • Props: $width: string (전체 너비), $n: number (반복할 아이템 수).

  • BookListSkeletonLoader: 책 목록 페이지용 스켈레톤 로더.

  • BookDetailSkeletonLoader: 책 상세 정보 페이지용 스켈레톤 로더.

  • CollectionSkeletonLoader: 컬렉션 목록 페이지용 스켈레톤 로더.

  • IndexPageSkeletonLoader: 메인 인덱스 페이지용 스켈레톤 로더.

  • ReadingLogSkeletonLoader: 독서 기록 페이지용 스켈레톤 로더.

  • 공통 스타일: src/styles/common.styled.tsLineSkeleton, SquareSkeleton을 기반으로 합니다.

frameMotion/ImageMotion

  • 경로: src/ui/frameMotion/ImageMotion.tsx

  • 설명: 마우스 움직임에 따라 3D 틸트 및 그림자 효과를 보여주는 이미지 컴포넌트입니다. Framer Motion 라이브러리를 사용하며, createPortal을 사용하여 #motion DOM 요소에 렌더링됩니다. 현재는 특정 고양이 이미지를 사용합니다.

  • Props: 없음 (내부적으로 이미지 소스 및 애니메이션 값 관리)

  • 주요 기능:

    • 마우스 진입(onMouseEnter), 이동(onMouseMove), 이탈(onMouseLeave) 이벤트에 반응하여 이미지의 rotateX, rotateY, x, yfilter (drop-shadow) 스타일을 동적으로 변경합니다.

    • Framer Motion의 useSpring, useMotionTemplate, transform 등을 활용합니다.

  • 사용 예시: 주로 비어 있는 상태나 시각적 강조가 필요한 부분에 사용될 수 있습니다. (예: BookListView.tsx에서 책 목록이 비어 있을 때)


🔩 레이아웃 컴포넌트 (src/components/layout)

애플리케이션의 전체적인 구조와 페이지 레이아웃을 담당하는 컴포넌트들입니다.

Layout

  • 경로: src/components/layout/Layout.tsx

  • 설명: 애플리케이션의 메인 레이아웃입니다. Header, Footer를 포함하며, react-router-domuseOutlet을 통해 현재 라우트에 해당하는 페이지 컴포넌트를 렌더링합니다. Vercel Analytics도 이 컴포넌트에서 초기화합니다.

  • Props: 없음

  • 사용 예시: App.tsx에서 최상위 라우트의 element로 사용됩니다.

<Routes>
  <Route path="/" element={<Layout />}>
    {/* ... nested routes ... */}
  </Route>
</Routes>

  • 경로: src/components/layout/header/Header.tsx

  • 설명: 애플리케이션의 상단 헤더입니다. 사이트 로고, 주요 네비게이션 링크(Library, Collections, Analytics), 사용자 인증 관련 UI(로그인 버튼 또는 사용자 메뉴)를 포함합니다. 스크롤에 따라 높이가 동적으로 변하는 애니메이션 효과가 적용되어 있습니다.

  • Props: 없음

  • 주요 기능:

    • useKeycloak 훅을 사용하여 사용자 인증 상태를 확인하고 UI를 다르게 렌더링합니다.

    • 인증되지 않은 사용자가 특정 네비게이션 링크 클릭 시 LoginRequireModal을 표시합니다.

    • Framer Motion의 useScroll, useTransform을 사용하여 스크롤 기반 애니메이션을 구현합니다.

  • 하위 컴포넌트:

    • UserMenu.tsx

    • LoginModal.tsx

UserMenu

  • 경로: src/components/layout/header/UserMenu.tsx

  • 설명: 인증된 사용자를 위한 드롭다운 메뉴입니다. 'My Library', 'My Collection', 'Log out' 등의 링크를 제공합니다. Framer Motion을 사용한 애니메이션이 적용되어 있습니다.

  • Props:

    • onLoggedOut: () => void (필수) - 'Log out' 메뉴 클릭 시 실행될 로그아웃 처리 함수입니다.

  • 주요 기능:

    • itemVariants를 사용한 Framer Motion 애니메이션.

    • useNavigate를 사용하여 페이지 이동을 처리합니다.

LoginModal

  • 경로: src/components/layout/header/LoginModal.tsx

  • 설명: 소셜 로그인(Kakao, GitHub, Google) 옵션을 제공하는 모달입니다. Modal 컴포넌트를 기반으로 구현되었습니다.

  • Props:

    • isModalOpened: boolean (필수) - 모달의 표시 여부를 제어합니다.

    • onClose: () => void (필수) - 모달을 닫을 때 호출될 함수입니다.

    • github: () => void (필수) - GitHub 로그인 시도 시 호출될 함수입니다.

    • kakao: () => void (필수) - Kakao 로그인 시도 시 호출될 함수입니다.

    • google: () => void (필수) - Google 로그인 시도 시 호출될 함수입니다.

  • 경로: src/components/layout/footer/Footer.tsx

  • 설명: 애플리케이션의 하단 푸터입니다. 간단한 저작권 정보를 표시합니다.

  • Props: 없음


🧩 기능별 컴포넌트 (src/components)

각 페이지 또는 특정 기능과 관련된 컴포넌트들입니다.

홈페이지 (src/components/homepage)

ReadingBooksView

  • 경로: src/components/homepage/ReadingBooksView.tsx

  • 설명: 애플리케이션의 메인 페이지 (인덱스 페이지) 컨텐츠입니다. SearchBar와 현재 읽고 있는 책 목록 (BookListView)을 표시합니다. 사용자가 로그인하지 않은 경우, ImageMotion 컴포넌트를 포함한 빈 라이브러리 화면을 표시할 수 있습니다.

  • Props: 없음

  • 주요 의존성:

    • SearchBar 컴포넌트

    • BookListView 컴포넌트

    • useKeycloak 훅 (인증 상태 확인)

    • useBook 훅 (읽고 있는 책 목록 조회)

    • IndexPageSkeletonLoader (로딩 중 UI)

  • 경로: src/components/homepage/SearchBar.tsx

  • 설명: 책 검색을 위한 입력 필드를 제공합니다. 사용자가 검색어를 입력하고 Enter 키를 누르면 SearchResult 모달을 표시합니다.

  • Props: 없음

  • 주요 의존성:

    • SearchResult 컴포넌트

    • useBookSearch 훅 (검색어 상태 관리)

    • useKeycloak 훅 (인증 상태 확인)

    • LoginRequireModal (로그인 필요 시)

SearchResult

  • 경로: src/components/homepage/SearchResult.tsx

  • 설명: Modal 컴포넌트 내에서 책 검색 결과를 목록 형태로 표시합니다. 각 아이템 클릭 시 BookDetail 컴포넌트를 통해 책의 상세 정보를 보여줍니다.

  • Props:

    • text: string (필수) - 초기 검색어입니다.

    • onClose: () => void (필수) - 검색 결과 모달을 닫을 때 호출될 함수입니다.

  • 주요 의존성:

    • BookDetail 컴포넌트

    • BookPublisher UI 컴포넌트

    • SimpleSkeletonLoader (로딩 중 UI)

    • useBookSearch 훅 (검색어 관리 및 재검색)

    • useBook 훅 (검색 결과 조회)

책 관련 (src/components/book)

BookListView

  • 경로: src/components/book/BookListView.tsx

  • 설명: 책 목록을 표지 이미지와 제목으로 표시합니다. 책 상태(status)에 따라 클릭 시 ReadingLogPage로 이동하거나 BookDetail 모달을 엽니다. 책 목록이 비어있을 경우, "책을 추가해 독서기록을 시작해보세요." 메시지와 함께 ImageMotion 컴포넌트를 표시할 수 있습니다.

  • Props:

    • bookList: LibraryResponse[] (필수) - 화면에 표시할 책들의 정보 배열입니다. LibraryResponse 타입은 cover, title, isbn, status를 포함합니다.

  • 주요 의존성:

    • Modal UI 컴포넌트

    • BookDetail 컴포넌트

    • ImageMotion UI 컴포넌트

    • useKeycloak

BookDetail

  • 경로: src/components/book/BookDetail.tsx

  • 설명: 특정 책의 상세 정보를 표시합니다. 책 표지, 제목, 저자/출판사/출판일, ISBN, 카테고리, 책 소개 등을 포함하며, BookStatusButton을 통해 책 상태를 변경하거나 컬렉션에서 제거하는 등의 작업을 수행할 수 있습니다.

  • Props:

    • isbn: string (필수) - 상세 정보를 조회할 책의 ISBN입니다.

    • onClose: () => void (필수) - (주로 모달로 표시될 때) 상세 정보 뷰를 닫을 때 호출될 함수입니다.

  • 주요 의존성:

    • BookDetailSkeletonLoader, Toast, BookPublisher, ThreeDotMenu UI 컴포넌트

    • BookStatusButton 컴포넌트

    • RefetchContext, CollectionParamContext 컨텍스트

    • useBook, useCollection, useReadingLog, useToast

BookStatusButton

  • 경로: src/components/book/BookStatusButton.tsx

  • 설명: 책의 현재 상태에 따라 다른 버튼들을 렌더링합니다. (예: "읽는 중", "읽을 예정", "읽기 완료" 저장 버튼, 또는 현재 상태 표시, 컬렉션에 추가 버튼). BookDetail 컴포넌트 내에서 사용됩니다.

  • Props:

    • bookData: BookResponse (필수) - 대상 책의 정보입니다.

    • status: string (필수) - 책의 현재 상태 ("NEW", "READING", "EMPTY" 등)입니다.

    • statusRefetch: (options?: RefetchOptions) => Promise<QueryObserverResult<unknown, Error>> (필수) - 책 상태 변경 후 호출될 refetch 함수입니다.

    • showToast: () => void (필수) - 성공 토스트 메시지를 표시하는 함수입니다.

    • showErrorToast: () => void (필수) - 오류 토스트 메시지를 표시하는 함수입니다.

  • 주요 의존성:

    • translateBookStatus 유틸리티 함수

    • RefetchContext, CollectionParamContext 컨텍스트

    • useBook, useCollection

내 서재 (src/components/myLibrary)

LibraryStatusNav

  • 경로: src/components/myLibrary/LibraryStatusNav.tsx

  • 설명: '내 서재' 페이지 상단에 위치하는 네비게이션 바입니다. StatusTapNavigation UI 컴포넌트를 사용하여 "읽는 중", "읽을 예정", "읽기 완료" 탭을 제공합니다.

  • Props: 없음

  • 주요 의존성:

    • StatusTapNavigation UI 컴포넌트

내 컬렉션 (src/components/myCollection)

CollectionListView

  • 경로: src/components/myCollection/CollectionListView.tsx

  • 설명: 사용자가 생성한 컬렉션 목록을 카드 형태로 보여줍니다. 각 카드에는 컬렉션 이름과 포함된 책들의 표지 이미지(최대 4개)가 표시됩니다. '새로 추가하기' 기능을 통해 새로운 컬렉션을 생성할 수 있는 UI도 제공합니다.

  • Props: 없음

  • 주요 의존성:

    • CollectionSkeletonLoader (로딩 중 UI)

    • useCollection 훅 (컬렉션 목록 조회 및 생성)

    • useKeycloak 훅 (인증 상태 확인)

    • useMediaBreakpoints 훅 (모바일 반응형 처리)

CollectionView

  • 경로: src/components/myCollection/CollectionView.tsx

  • 설명: 특정 컬렉션에 속한 책 목록을 표시합니다. BookListView와 유사하게 책 표지, 제목을 보여주며, 클릭 시 CollectionBookMetaDetail 모달을 엽니다.

  • Props:

    • collectionBookList: CollectionBookMetaResponse[] (필수) - 화면에 표시할 컬렉션 내 책 정보 배열입니다.

  • 주요 의존성:

    • Modal UI 컴포넌트

    • CollectionBookMetaDetail 컴포넌트

    • ImageMotion UI 컴포넌트

    • @react-keycloak/web

CollectionBookMetaDetail

  • 경로: src/components/myCollection/CollectionBookMetaDetail.tsx

  • 설명: 컬렉션 내 특정 책 상세 정보를 표시합니다. BookDetail과 비슷한 UI를 가지며, 해당 책이 현재 컬렉션에 포함되어 있는지 여부에 따라 '추가하기' 또는 '제거하기' 버튼을 렌더링합니다.

  • Props:

    • isbn: string (필수) - 상세 정보를 조회할 책의 ISBN입니다.

    • onClose: () => void (필수) - 상세 정보 모달을 닫을 때 호출될 함수입니다.

  • 주요 의존성:

    • BookDetailSkeletonLoader, BookPublisher, Toast UI 컴포넌트

    • CollectionParamContext 컨텍스트

    • useBook, useCollection, useToast

    • Button (BookStatusButton에서 export 된 styled-component)

독서 기록 (src/components/readingLog)

Rating

  • 경로: src/components/readingLog/Rating.tsx

  • 설명: 책에 대한 별점을 표시하고 사용자가 별점을 매길 수 있도록 하는 컴포넌트입니다.

  • Props:

    • isbn?: string (선택, 기본값: "") - 별점을 매길 책의 ISBN입니다.

    • initialRating: number (선택, 기본값: 0) - 초기 별점 값입니다. (0-5 사이)

    • refetch?: (options?: RefetchOptions) => Promise<QueryObserverResult<ApiResponse<ReadingLogResponse> | void, Error>> (선택) - 별점 변경 후 독서 기록 데이터를 다시 불러오기 위한 함수입니다.

  • 주요 의존성:

    • useReadingLog 훅 (별점 업데이트)

    • react-icons/fa6 (별 아이콘)

ReadingLogNote

  • 경로: src/components/readingLog/ReadingLogNote.tsx

  • 설명: 독서 기록의 세 가지 노트("무엇을 다룬 책인지 알아내기", "내용 해석하기", "비평하기")를 각각 표시하고, 각 노트를 수정할 수 있는 버튼을 제공합니다. HTML 내용은 DOMPurify를 사용하여 안전하게 렌더링합니다.

  • Props:

    • noteContentData: NoteContentData[] (필수) - 각 노트의 note (ID), title, text (내용)을 담은 객체 배열입니다.

    • openReadingLogModal: (id: string, title: string, placeholder: string) => void (필수) - 노트 수정 버튼 클릭 시 WYSIWYG 에디터 모달을 열기 위한 함수입니다.

  • 주요 의존성:

    • DOMPurify (HTML 내용 정화)

    • react-icons/fa6 (수정 아이콘)

AutoSaveReadingLogEditor

  • 경로: src/components/readingLog/AutoSaveReadingLogEditor.tsx

  • 설명: 독서 기록 노트 작성을 위한 WYSIWYG 에디터 모달입니다. TinyMCE를 사용하며, 작성 중인 내용을 30초 간격으로 localStorage에 자동 저장하는 기능과, 이전에 저장된 임시 초안이 있을 경우 불러올지 묻는 확인 모달(DraftConfirmModal) 기능을 포함합니다.

  • Props:

    • onClose: () => void (필수) - 에디터 모달을 닫을 때 호출될 함수입니다.

    • modalType: ModalTypes (필수) - 현재 모달의 타입 (주로 ModalTypes.WYSIWYG일 때 표시됨)입니다.

    • note: { id: string; title: string; text: string } (필수) - 현재 편집 중인 노트의 정보 (ID, 제목, 내용)입니다.

    • placeholder: string (필수) - 에디터에 표시될 초기값 또는 플레이스홀더입니다.

    • setPlaceholder: React.Dispatch<React.SetStateAction<string>> (필수) - 플레이스홀더 상태를 업데이트하는 함수입니다 (예: 임시 초안 로드 시).

    • onChangeValue: (text: string) => void (필수) - 에디터 내용 변경 시 호출될 콜백 함수입니다.

    • onSave: () => void (필수) - '저장하기' 버튼 클릭 시 호출될 콜백 함수입니다.

    • isFirstOpened: boolean (필수) - 모달이 처음 열렸는지 여부를 나타내는 상태값입니다 (임시 초안 확인 로직에 사용).

    • setIsFirstOpened: React.Dispatch<React.SetStateAction<boolean>> (필수) - isFirstOpened 상태를 업데이트하는 함수입니다.

  • 주요 의존성:

    • Modal UI 컴포넌트

    • TinyMCE 유틸리티 컴포넌트

    • DraftConfirmModal 컴포넌트

    • DOMPurify (HTML 내용 정화)

DraftConfirmModal

  • 경로: src/components/readingLog/DraftConfirmModal.tsx

  • 설명: AutoSaveReadingLogEditor에서 사용되며, 임시 저장된 노트 내용이 있을 경우 사용자에게 불러올지 여부를 묻는 모달입니다.

  • Props:

    • isOpen: boolean (필수) - 모달의 표시 여부를 제어합니다.

    • onConfirm: () => void (필수) - '불러오기' 버튼 클릭 시 실행될 함수입니다.

    • onDiscard: () => void (필수) - '새로 작성' 버튼 클릭 시 (또는 모달 닫기 시) 실행될 함수입니다.

  • 주요 의존성:

    • Modal UI 컴포넌트

분석 페이지 (src/components/analytics)

AnalyticsNavBar

  • 경로: src/components/analytics/AnalyticsNavBar.tsx

  • 설명: '분석' 페이지 상단에 위치하는 네비게이션 바입니다. StatusTapNavigation UI 컴포넌트를 사용하며, 현재는 "캘린더" 탭만 제공합니다.

  • Props: 없음

  • 주요 의존성:

    • StatusTapNavigation UI 컴포넌트

CalendarMonthly

  • 경로: src/components/analytics/CalendarMonthly.tsx

  • 설명: @fullcalendar/react를 사용하여 월별 달력 형태로 완료된 책들을 표시합니다. 달력의 이벤트를 클릭하면 해당 책의 정보(표지, 제목, 별점)가 담긴 모달이 나타나고, 책 표지 클릭 시 해당 책의 ReadingLogPage로 이동합니다.

  • Props: 없음

  • 주요 의존성:

    • @fullcalendar/react, @fullcalendar/daygrid

    • Modal UI 컴포넌트

    • Rating 컴포넌트

    • useBook 훅 (완료된 책 캘린더 데이터 조회)

    • useMediaBreakpoints 훅 (반응형 높이 조절)

    • useModal


🛠️ 유틸리티 (src/utils)

애플리케이션 전반에서 사용되는 헬퍼 함수 및 유틸리티 컴포넌트입니다.

TranslateBookStatus

  • 경로: src/utils/TranslateBookStatus.ts

  • 설명: 책 상태 코드 문자열(예: "READING", "TO_READ")을 한글 표시 문자열(예: "읽는 중", "읽을 예정")로 변환하는 함수입니다.

  • 함수 시그니처: translateBookStatus(bookStatus: string) => string

  • 사용 예시:TypeScript

    import { TranslateBookStatus } from "@/utils";
    const koreanStatus = TranslateBookStatus("FINISHED"); // "읽기 완료"

TinyMCE

  • 경로: src/utils/TinyMCE.tsx

  • 설명: @tinymce/tinymce-react 라이브러리의 Editor 컴포넌트를 감싼 래퍼 컴포넌트입니다. 독서 기록 작성 등에 사용되는 리치 텍스트 에디터를 제공합니다. API 키는 환경 변수(VITE_TINY_MCE_API_KEY)에서 가져옵니다.

  • Props:

    • placeholder: string (필수) - 에디터의 초기값 또는 플레이스홀더 텍스트입니다.

    • onChangeValue: (text: string) => void (필수) - 에디터 내용이 변경될 때마다 호출되는 콜백 함수이며, 변경된 내용을 인자로 받습니다.

  • 사용 예시: (주로 AutoSaveReadingLogEditor 내에서 사용)TypeScript

    <TinyMCE
      placeholder="<p>여기에 독서 기록을 작성하세요...</p>"
      onChangeValue={(newText) => console.log(newText)}
    />

Last updated