# Lesson 6 - Create BookCard.jsx Component

## Explanation and Step-by-Step Procedure for `BookCard` and `BookList` Integration

### **Step 1: Create `BookCard.jsx`**

The `BookCard` component displays individual book details in a card layout.

**Key Features of `BookCard.jsx`:**

1. **Props**:
   * The `book` prop contains all the book details.
2. **Two-Column Layout**:
   * **Left Column**: Displays the book's thumbnail image.
   * **Right Column**: Shows the book title, authors, description, and published year.
3. **Reusable Component**:
   * Uses the `ReadMore` component for expandable descriptions.
4. **Prop Validation**:
   * Ensures that `book` prop matches the expected structure.

***

```graphql
// Layout Design of BookCard Component
BookCard Component
│
├── Props
│   └── book (object) - Contains book information
│       └── volumeInfo (object)
│           ├── title (string)
│           ├── authors (array of strings)
│           ├── description (string)
│           ├── publishedDate (string)
│           └── imageLinks (object)
│               └── thumbnail (string)
│
└── Render Structure
    └── <div> (card mb-3, maxWidth: '540px')
        └── <div> (row g-0)
            ├── Left Column: <div> (col-md-4) - Book Thumbnail
            │   └── <img> (img-fluid rounded-start)
            │       ├── src={imageLinks?.thumbnail || 'https://via.placeholder.com/128x200'}
            │       └── alt={title || 'No Thumbnail'}
            │
            └── Right Column: <div> (col-md-8) - Book Details
                └── <div> (card-body)
                    ├── <h5> (card-title) - Book title
                    │   └── {title || 'No Title Available'}
                    │
                    ├── <p> (card-text) - Authors
                    │   ├── <strong>Authors:</strong>
                    │   └── Conditional: {authors ? authors.join(', ') : 'Unknown'}
                    │
                    ├── <p> (card-text) - Description
                    │   ├── <strong>Description:</strong>
                    │   └── Conditional: {description ? <ReadMoreUpdate book={book} /> : 'No Description Available'}
                    │
                    └── <p> (card-text) - Published Year
                        └── <small> (text-muted)
                            ├── <strong>Published Year:</strong>
                            └── {publishedDate || 'Unknown'}

```

### **Step 2: Modify `BookList.jsx`**

Integrate the `BookCard` component into `BookList` for displaying each book's details.

**Key Changes in `BookList.jsx`:**

1. **Import `BookCard`:**

   ```jsx
   import BookCard from './BookCard';
   ```

   * This allows `BookList` to use the `BookCard` component.
2. **Replace Card Rendering Logic:**

   ```jsx
   {books.map((book) => (
     <BookCard key={book.id} book={book} />
   ))}
   ```

   * For each book, render a `BookCard` component and pass the `book` object as a prop.
3. **Flexible Layout:**
   * Books are displayed using a `d-flex flex-wrap justify-content-center` class for responsive alignment.

***

#### **How It Works Together**

* `BookList`:
  * Iterates over the list of books and renders a `BookCard` for each.
* `BookCard`:
  * Takes a single `book` object and displays its content in a card layout.
* **Advantages**:
  * **Reusability**: The `BookCard` component can be reused in other contexts.
  * **Separation of Concerns**: Cleanly separates rendering logic for individual books.

***

#### **Benefits for Students**

1. **Component Hierarchy**:
   * Understand how to compose larger components from smaller, reusable components.
2. **Bootstrap Layout**:
   * Learn to use `d-flex` and `flex-wrap` for responsive layouts.
3. **Reusable Patterns**:
   * Create modular components (`BookCard`) that simplify main component logic.

### Step-by-Step Explanation of `BookCard.jsx` Implementation

The `BookCard` component displays detailed information about a book in a card-style layout.

***

#### **Step 1. Import Necessary Libraries**

```jsx
import React from 'react';
import PropTypes from 'prop-types';
import ReadMore from './ReadMore';
```

* **React**: Provides the base framework for building the component.
* **PropTypes**: Ensures the props passed to the component are well-defined.
* **Bootstrap**: Provides ready-to-use styles for the layout.
* **ReadMore**: A component to manage expandable descriptions.

***

#### **Step 2. Destructure Props**

```jsx
const { title, authors, description, publishedDate, imageLinks } = book.volumeInfo;
```

* Extracts specific fields from the `book.volumeInfo` object for easy access.

***

#### **Step 3. BookCard Layout**

```jsx
<div className="card mb-3" style={{ maxWidth: '540px' }}>
  <div className="row g-0">
    {/* Left Column: Thumbnail */}
    <div className="col-md-4">
      <img
        src={imageLinks?.thumbnail || 'https://via.placeholder.com/128x200'}
        alt={title || 'No Thumbnail'}
        className="img-fluid rounded-start"
      />
    </div>

    {/* Right Column: Book Details */}
    <div className="col-md-8">
      <div className="card-body">
        <h5 className="card-title">{title || 'No Title Available'}</h5>
        <p className="card-text">
          <strong>Authors:</strong> {authors ? authors.join(', ') : 'Unknown'}
        </p>
        <p className="card-text">
          <strong>Description:</strong> {description ? <ReadMore text={description} /> : 'No Description Available'}
        </p>
        <p className="card-text">
          <small className="text-muted">
            <strong>Published Year:</strong> {publishedDate || 'Unknown'}
          </small>
        </p>
      </div>
    </div>
  </div>
</div>
```

* **Left Column**:
  * Displays the book's thumbnail image.
  * If the image is unavailable, a placeholder is used.
* **Right Column**:
  * Contains details such as title, authors, description, and published year.
  * Uses `ReadMore` for expandable descriptions.

***

#### **Step 4. Prop Validation**

```jsx
BookCard.propTypes = {
  book: PropTypes.shape({
    volumeInfo: PropTypes.shape({
      title: PropTypes.string,
      authors: PropTypes.arrayOf(PropTypes.string),
      description: PropTypes.string,
      publishedDate: PropTypes.string,
      imageLinks: PropTypes.shape({
        thumbnail: PropTypes.string,
      }),
    }).isRequired,
  }).isRequired,
};
```

* Ensures the `book` prop contains all necessary fields with correct types.

***

#### **5. Export the Component**

```jsx
export default BookCard;
```

* Makes `BookCard` reusable across the application.

***

#### **Integration with `BookList`**

* The `BookList` component uses `BookCard` to render individual book details.
* For each book in the list, a `BookCard` is created with the book object as a prop.

***

#### **Benefits for Students**

1. **Reusability**:
   * The modular `BookCard` can be reused wherever book details need to be displayed.
2. **Responsive Design**:
   * The Bootstrap-based layout adapts to different screen sizes.
3. **Clean Code**:
   * Prop validation ensures better maintainability and error checking.

This implementation completes the integration of `BookCard` with the app.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://reactjs.koida.tech/restful-apis-build-a-booksearch-app-ver-2.0/lesson-6-create-bookcard.jsx-component.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
