📖 Next.js 도서 추천 페이지 상세 설명

2025. 2. 24. 15:11프론트엔드/Next JS

728x90

📖 Next.js 도서 추천 페이지 상세 설명

📂 src/
│── 📂 components/
│    ├── 📄 global-layout.tsx       // 전역 레이아웃 컴포넌트
│    ├── 📄 searchable-layout.tsx   // 검색 기능이 포함된 레이아웃
│    ├── 📄 book-item.tsx           // 개별 도서 아이템 UI
│── 📂 pages/
│    ├── 📄 _app.tsx                // Next.js 앱 전체 레이아웃 적용
│    ├── 📄 index.tsx               // 메인 페이지 (도서 목록)
│── 📂 styles/
│    ├── 📄 globals.css             // 전역 CSS
│    ├── 📄 book-item.module.css     // 도서 UI 스타일
│── 📂 mock/
│    ├── 📄 books.json               // 더미 데이터 (책 정보)
│── 📂 types/
│    ├── 📄 index.ts                 // 데이터 타입 정의

2. index.tsx (메인 페이지) 분석

📌 pages/index.tsx

이 파일은 메인 페이지 역할을 하며, SearchableLayout을 적용하여 검색 기능이 포함된 UI를 구성합니다.

🔹 코드

// 필요한 모듈 및 컴포넌트 import
import SearchableLayout from "@/components/searchable-layout"; 
import style from "./index.module.css";
import { ReactNode } from "react";
import books from "@/mock/books.json";  // 도서 더미 데이터
import BookItem from "@/components/book-item"; // 도서 아이템 컴포넌트

export default function Home() {
  return (
    <div className={style.container}>
      <section>
        <h3>지금 추천하는 도서</h3>
        {books.map((book) => (
          <BookItem key={book.id} {...book} />
        ))}
      </section>
      <section>
        <h3>등록된 모든 도서</h3>
        {books.map((book) => (
          <BookItem key={book.id} {...book} />
        ))}
      </section>
    </div>
  );
}

// 특정 페이지에서만 적용될 레이아웃 정의
Home.getLayout = (page: ReactNode) => {
  return <SearchableLayout>{page}</SearchableLayout>;
};

🔹 코드 설명

  1. SearchableLayout 적용
    • Home.getLayout을 통해 SearchableLayout을 index.tsx에만 적용함.
    • SearchableLayout은 검색창을 포함한 레이아웃을 제공.
  2. 더미 데이터(books.json) 활용
    • mock/books.json에 저장된 도서 데이터를 가져와서 화면에 렌더링.
    • books.map((book) => <BookItem key={book.id} {...book} />)를 사용하여 각 도서를 BookItem 컴포넌트로 표시.
  3. 추천 도서 & 전체 도서 목록을 분리
    • <section> 태그를 사용하여 추천 도서전체 도서 목록을 구분.

3. book-item.tsx (도서 아이템 컴포넌트) 분석

각 도서를 개별적으로 BookItem 컴포넌트를 사용하여 표시합니다.

📌 components/book-item.tsx

import type { BookData } from "@/types";
import Link from "next/link";
import style from "./book-item.module.css";

// BookData 타입 정의
export default function BookItem({
  id,
  title,
  subTitle,
  description,
  author,
  publisher,
  coverImgUrl,
}: BookData) {
  return (
    <Link href={`/book/${id}`} className={style.container}>
      <img src={coverImgUrl} />
      <div>
        <div className={style.title}>{title}</div>
        <div className={style.subTitle}>{subTitle}</div>
        <br />
        <div className={style.author}>
          {author} | {publisher}
        </div>
      </div>
    </Link>
  );
}

🔹 코드 설명

  1. BookData 타입을 사용하여 안전한 데이터 전달
    • title, subTitle, author, publisher 등의 데이터를 props로 받아 사용.
  2. Next.js의 Link 컴포넌트를 활용하여 도서 상세 페이지 연결
    • href={/book/${id}}를 사용하여 개별 도서 상세 페이지로 이동.
  3. 책 표지 이미지 표시
    • <img src={coverImgUrl} />로 도서 표지를 렌더링.
  4. 제목과 부제목 스타일링
    • .title, .subTitle, .author 클래스를 사용하여 스타일을 적용.

4. book-item.module.css (도서 UI 스타일) 분석

각 도서의 디자인을 결정하는 CSS 모듈입니다.

📌 styles/book-item.module.css

.container {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.cover_img_container {
  display: flex;
  justify-content: center;
  padding: 20px;
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  position: relative;
}

.cover_img_container::before {
  position: absolute;
  top: 0px;
  left: 0px;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.7);
  content: "";
} 
/* 가상 요소를 사용하여 배경 어둡게 처리 */

.cover_img_container > img {
  z-index: 1;
  max-height: 350px;
  height: 100%;
}

.title {
  font-size: large;
  font-weight: bold;
}

.subTitle {
  color: gray;
}

.author {
  color: gray;
}

.description {
  background-color: rgb(245, 245, 245);
  padding: 15px;
  line-height: 1.3;
  white-space: pre-line;
  border-radius: 5px;
}

🔹 스타일 설명

  1. container
    • 도서 아이템을 세로로 정렬(flex-direction: column)하고, 아이템 간격을 조정(gap: 10px).
  2. 책 표지 이미지 스타일링 (cover_img_container)
    • background-size: cover로 배경 이미지를 화면에 맞게 조정.
    • ::before 가상 요소를 사용하여 반투명 검정 배경 효과 추가.
    • position: absolute; top: 0; left: 0;를 사용하여 배경이 이미지 위를 덮도록 설정.
  3. 제목 및 서브타이틀 스타일 (.title, .subTitle)
    • .title은 크고 굵게 스타일 적용.
    • .subTitle과 .author는 회색 글씨로 가독성을 높임.
  4. 책 설명 스타일 (.description)
    • 배경 색상을 밝은 회색(rgb(245, 245, 245))으로 설정.
    • white-space: pre-line;을 사용하여 줄바꿈(\n)을 반영.

5. 마무리

정리

  • index.tsx: 책 목록을 표시하는 메인 페이지, getLayout을 활용하여 SearchableLayout 적용.
  • book-item.tsx: 각 도서 정보를 렌더링하는 컴포넌트, Next.js Link를 사용해 상세 페이지 연결.
  • book-item.module.css: 책 아이템의 UI 스타일을 담당, 반투명 배경 및 텍스트 스타일 적용.

이제 검색 기능을 추가하면, 더 완성도 높은 도서 추천 웹사이트가 될 수 있습니다! 🚀

728x90