# Lesson 9 - Show Book Details in a Modal - Working



### Step-by-Step Implementation of Modal for Book Details

**Objective**

To create a modal that displays detailed book information using the `BookDetail` component. The modal is triggered when the "Read More" button in the `ReadMore` component is clicked.

***

#### **Step 1. Modify `ReadMore.jsx`**

* **Objective**: Trigger the modal when the "Read More" button is clicked.
* **Key Changes**:
  * Added state `isModalOpen` to track the modal's visibility.
  * Added methods `handleOpenModal` and `handleCloseModal` to control the modal.
  * Included the `BookDetail` component conditionally.

**Explanation:**

* **State Management**:
  * `isModalOpen` ensures the modal only appears when needed.
* **Dynamic Rendering**:
  * `BookDetail` is only rendered when `isModalOpen` is `true`.

***

### ReadMore.jsx Component Update

{% tabs %}
{% tab title="Before Modal Display" %}
```jsx
// ReadMore.jsx - before modal display
// Import necessary libraries
import React, { useState } from 'react'
import PropTypes from 'prop-types'

const ReadMore = ({ text }) => {
  const [isExpanded, setIsExpanded] = useState(false)

  // Toggle the expanded state
  const toggleExpanded = () => {
    setIsExpanded(!isExpanded)
  }

  return (
    <div>
      {isExpanded ? (
        <>
          <p>{text}</p>
          <button className="btn btn-secondary btn-sm" onClick={toggleExpanded}>
            Close
          </button>
        </>
      ) : (
        <>
          <p>{text.length > 100 ? `${text.substring(0, 100)}...` : text}</p>
          {text.length > 100 && (
            <button className="btn btn-primary btn-sm" onClick={toggleExpanded}>
              Read More
            </button>
          )}
        </>
      )}
    </div>
  )
}

// Define PropTypes for the component
ReadMore.propTypes = {
  text: PropTypes.string.isRequired,
}

export default ReadMore

```
{% endtab %}

{% tab title="After Modal Display" %}
````jsx
// ReadMoreUpdate.jsx - after modal display

// Import necessary libraries
import React, { useState } from 'react'
import PropTypes from 'prop-types'
import BookDetail from './BookDetail.jsx'

const ReadMore = ({ book }) => {
  const [isModalOpen, setIsModalOpen] = useState(false)

  // Open modal
  const handleOpenModal = () => {
    setIsModalOpen(true)
  }

  // Close modal
  const handleCloseModal = () => {
    setIsModalOpen(false)
  }

  return (
    <div>
      <button className="btn btn-primary btn-sm" onClick={handleOpenModal}>
        Read More
      </button>

      {isModalOpen && <BookDetail book={book} onClose={handleCloseModal} />}
    </div>
  )
}

ReadMore.propTypes = {
  book: PropTypes.shape({
    title: PropTypes.string,
    authors: PropTypes.arrayOf(PropTypes.string),
    description: PropTypes.string,
    publishedDate: PropTypes.string,
    publisher: PropTypes.string,
  }).isRequired,
}

export default ReadMore

```
````
{% endtab %}
{% endtabs %}

#### **2. Create `BookDetail.jsx`**

* **Objective**: A modal component that displays detailed book information with a "Close" button.
* **Bootstrap Modal Classes**:
  * **`modal`**: Styles the modal dialog.
  * **`modal-dialog`**: Centers the modal content.
  * **`modal-content`**: Contains the modal structure (header, body, footer).
  * **`btn-close`**: Provides a styled close button.

**Structure of `BookDetail`:**

1. **Header**:
   * Displays the book title.
   * Includes a close button to exit the modal.
2. **Body**:
   * Shows book details like authors, published date, description, and publisher.
3. **Footer**:
   * Includes a "Close" button to exit the modal.

**Code Highlights:**

* **Props**:
  * `book`: Contains the book data to display.
  * `onClose`: A callback function to handle modal closure.

***

### Creation of BookDetail.jsx Component

{% tabs %}
{% tab title="BookDetail.jsx" %}
```jsx
// BookDetai;jsx
// Import necessary libraries
import React from 'react'
import PropTypes from 'prop-types'
import 'bootstrap/dist/css/bootstrap.min.css'

const BookDetail = ({ book, onClose }) => {
  const { title, authors, publishedDate, description, publisher } = book.volumeInfo

  return (
    <div className="modal show d-block" tabIndex="-1" role="dialog">
      <div className="modal-dialog" role="document">
        <div className="modal-content">
          <div className="modal-header">
            <h5 className="modal-title">{title || 'No Title Available'}</h5>
            <button
              type="button"
              className="btn-close"
              onClick={onClose}></button>
          </div>
          <div className="modal-body">
            <p>
              <strong>Authors:</strong>{' '}
              {authors ? authors.join(', ') : 'Unknown'}
            </p>
            <p>
              <strong>Published Date:</strong> {publishedDate || 'Unknown'}
            </p>
            <p>
              <strong>Description:</strong>{' '}
              {description || 'No Description Available'}
            </p>
            <p>
              <strong>Publisher:</strong> {publisher || 'Unknown'}
            </p>
          </div>
          <div className="modal-footer">
            <button
              type="button"
              className="btn btn-secondary"
              onClick={onClose}>
              Close
            </button>
          </div>
        </div>
      </div>
    </div>
  )
}

BookDetail.propTypes = {
  book: PropTypes.shape({
    title: PropTypes.string,
    authors: PropTypes.arrayOf(PropTypes.string),
    description: PropTypes.string,
    publishedDate: PropTypes.string,
    publisher: PropTypes.string,
  }).isRequired,
  onClose: PropTypes.func.isRequired,
}

export default BookDetail

```
{% endtab %}

{% tab title="Second Tab" %}

{% endtab %}
{% endtabs %}

#### **3. How It Works**

1. When the user clicks "Read More" in `ReadMore.jsx`:
   * `isModalOpen` is set to `true`, rendering `BookDetail`.
2. `BookDetail` displays the book's details in a Bootstrap-styled modal.
3. Clicking the "Close" button triggers the `onClose` callback:
   * This sets `isModalOpen` to `false`, hiding the modal.

***

#### **Benefits of This Approach**

1. **Reusability**:
   * The `BookDetail` component can be used in other parts of the app for similar functionality.
2. **Separation of Concerns**:
   * Modal logic is encapsulated in `BookDetail`, keeping `ReadMore` clean.
3. **Responsive Design**:
   * Bootstrap ensures the modal adapts to different screen sizes.

***

This implementation enhances the user experience by allowing detailed book information to be viewed without navigating away from the main page.
