Next.jsでのカルーセル機能の実装

## はじめに
**カルーセル**とは、まるでページをめくるように、複数のコンテンツをスライド形式で楽しむことができる機能のことです。
← 1/20 → みたいなやつです
**ページネーション**とも言います。

今回は、**Next.js**を用いて、そんなカルーセル形式でブログ記事を表示する機能を実装してみました。

## データの準備
まずは、展示するブログの記事データを用意します。タイトルやURL、日付、そして説明文を含むオブジェクトの配列を作成しました。これらのデータは、まるで個々のストーリーが集まった小さな宇宙のように、カルーセルの中で輝きます。
```javascript
export const blogs = [
  {
    title: "ブログタイトル1",
    url: "https://example.com/blog1",
    date: "2024-01-01",
    description: "ブログ1の説明文",
  },
  // 他のブログデータ...
];

```
## Blogコンポーネントの実装
次に、実際にカルーセル機能を持ったBlogコンポーネントを作成します。
```javascript
"use client";
import React, { useState } from "react";
import { AiFillBook } from "react-icons/ai";
import BlogCard from "./BlogCard"; // ブログカードを表示するコンポーネント
import { blogs } from "../constants/blogs"; // ブログデータ
import { AnimatePresence } from "framer-motion";
import { AiOutlineLeft, AiOutlineRight } from "react-icons/ai"; // 矢印アイコン

function Blog() {
  const blogsPerPage = 4; // 1ページに表示するブログの数
  const [currentPage, setCurrentPage] = useState(1); // 現在のページ番号

  const totalPages = Math.ceil(blogs.length / blogsPerPage); // 全ページ数

  // 現在のページに表示するブログを取得
  const startIndex = (currentPage - 1) * blogsPerPage;
  const currentBlogs = blogs.slice(startIndex, startIndex + blogsPerPage);

  // ページ変更のハンドラー
  const handleNextPage = () => {
    if (currentPage < totalPages) {
      setCurrentPage(currentPage + 1);
    }
  };

  const handlePrevPage = () => {
    if (currentPage > 1) {
      setCurrentPage(currentPage - 1);
    }
  };

  return (
    <section className="w-full h-fit px-[40px] py-10 max-xs:px[20px] relative bg-white" id="blog">
      <div className="max-w-7xl mx-auto">
        <div className="inline-block pb-4 pt-4">
          <p className="bg-hotpink text-white text-sm font-medium py-3 px-5 rounded-full flex items-center gap-2">
            <span><AiFillBook className="w-4 h-4" /></span>
            ブログ
          </p>
        </div>

        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 max-w-[1200px] mx-auto">
          <AnimatePresence>
            {currentBlogs.map((blog, index) => (
              <BlogCard
                key={index}
                title={blog.title}
                url={blog.url}
                date={blog.date}
                description={blog.description}
              />
            ))}
          </AnimatePresence>
        </div>

        <div className="flex justify-between items-center mt-4">
          <button
            onClick={handlePrevPage}
            disabled={currentPage === 1}
            className={`${currentPage === 1 ? "opacity-50 cursor-not-allowed" : ""} bg-gray-300 text-gray-700 px-3 py-1 rounded-md`}
          >
            <AiOutlineLeft />
          </button>

          <div className="text-center">
            <p className="text-sm">Page {currentPage} of {totalPages}</p>
          </div>

          <button
            onClick={handleNextPage}
            disabled={currentPage === totalPages}
            className={`${currentPage === totalPages ? "opacity-50 cursor-not-allowed" : ""} bg-gray-300 text-gray-700 px-3 py-1 rounded-md`}
          >
            <AiOutlineRight />
          </button>
        </div>
      </div>
    </section>
  );
}

export default Blog;
```
このコードでは、1ページあたり4つのブログ記事を表示し、ページネーションを通じてユーザーが簡単に次の記事にアクセスできるようにしています。

## まとめ
今回は、Next.jsを用いてブログ記事をカルーセル形式で表示する機能を実装しました。これにより、ユーザーはスムーズに情報を探し出し、新たなインスピレーションを受け取ることができます。