Re:SALOON & VBA

Next.js14 + Prisma + MySQL で読書履歴管理システム(BOOKLOG)

Node.jsベースのVue系のフレームワークのNUXT.JSで、
Nuxt3で読書履歴管理システム(BOOKLOG)
を作成してみていたのだが、Nuxt2が、Nuxt3になり(ヴ―ジョンアップ)、
CSSのVuetifyの対応(対応したサンプルサイトの登場)を待っていたのだけれど
中々、簡単なのがネット検索でHITしなく、Nuxt2から、Nuxt3への移行が中々に難しい。数が少ない。

で、
Node.jsベースのフレームワーク
といえば、React系のフレームワークのNEXT.JSは、どうなんだろうか?

NEXT.JSは、ver.14で、NUXT.JS より導入数は多いという話(寧ろ本筋か!)
実際、ネット検索でも、関連ページのHIT数は段違いの感がある。

中々、私生活の方が暇になったので、
何か目標のようなものになればと
読書履歴管理システム(BOOKLOG)
の、NEXT.JS版を作ってみようかというのが、この投稿である。




【前提】
・Node.js
・MySql

①.Nuxt 3プロジェクトの作成
コマンドを実行すると TypeScript や ESLint などを利用するか訊かれるが src ディレクトリを除いてすべて”Yes”を設定した。

% npx create-next-app@latest nextjs-14-booklog
% cd nextjs-14-booklog

②.Prismaのインストール
% npm install prisma --save-dev
% npx prisma init --datasource-provider mysql
% npm install @prisma/client

■prisma/schema.prisma を修正(DB Modelsを③でテーブル作成してくれる)


// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
generator client {
 provider = "prisma-client-js"
}
datasource db {
 provider = "mysql"
 url   = env("DATABASE_URL")
}
model booklog {
 isbn13   String @id @db.VarChar(13)
 isbn10   String?  @db.VarChar(10)
 bookname  String   @db.VarChar(50)
 author   String?  @db.VarChar(25)
 publisher  String?  @db.VarChar(25)
 genre    String?  @db.VarChar(25)
 issuedate  DateTime  @default(now()) @db.Timestamp(0)
 getdate   DateTime? @db.Timestamp(0)
 readdate  DateTime? @db.Timestamp(0)
 ownership  Int?
 purchase  Int?
 library   String?  @db.VarChar(25)
 overview  String?  @db.VarChar(255)
 impressions String?  @db.Text
 state    String?  @db.VarChar(10)
 coverimg  String?  @db.VarChar(40)
}



■.env の「DATABASE_URL」をMYSQL用に以下のように修正(ご自分の環境に合わせて)
DATABASE_URL="mysql://root:password@127.0.0.1:3306/Prisma?schema=public"

③.booklogテーブルの作成
% npx prisma db push

■\app\booklogs/page.tsx ※< >は化けるので< >に替えています。


import prisma from '@/lib/prisma';
import Link from 'next/link';
import { revalidatePath } from 'next/cache';
const Page = async () => {
 const booklog = await prisma.booklog.findMany();
 return (
  <div className="m-8">
   <h1 className="text-xl font-bold">BOOKLOG一覧</h1>
   <div class="h-96 overflow-scroll">
    <table className="table-auto">
     <thead className="sticky top-0 z-10">
      <tr className="bg-gray-200">
       <th className="sticky left-0 bg-white border">ISBN13</th>
       <th className="px-4 py-2 border">書名</th>
       <th className="px-4 py-2 border">著者名</th>
       <th className="px-4 py-2 border">発行</th>
       <th className="px-4 py-2 border">分類</th>
       <th className="px-4 py-2 border">削除</th>
      </tr>
     </thead>
     <tbody>
      {booklog.map((booklog) => (
       <tr key={booklog.isbn13}>
        <td className=" px-4 py-2 sticky left-0 z-[2] bg-slate-100 border ">
         <Link href={`/booklogs/${booklog.isbn13}`}>{booklog.isbn13}</Link>
        </td>
        <td className=" px-4 py-2 border">{booklog.bookname}</td>
        <td className=" px-4 py-2 border">{booklog.author}</td>
        <td className=" px-4 py-2 border">{booklog.publisher}</td>
        <td className=" px-4 py-2 border">{booklog.genre}</td>
        <td className=" px-4 py-2 border">
           <form action={async (data: FormData) => {
            'use server';
            const isbn13 = data.get('isbn13') as string;
            await prisma.booklog.delete({ where: { isbn13 } });
            revalidatePath('/booklogs');
            }}
           >
            <input type="hidden" name="isbn13" value={booklog.isbn13} />
            <button type="submit"
             className="bg-red-500 px-2 py-1 rounded-lg text-sm text-white">
             Del
            </button>
           </form>
        </td>
       </tr>
      ))}
     </tbody>
    </table>
   </div>
   <form className="flex items-center mt-4"
    action={async (data: FormData) => {
     'use server';
     const isbn13 = data.get('isbn13') as string;
     const bookname = data.get('bookname') as string;
     await prisma.booklog.create({ data: { isbn13, bookname } });
     revalidatePath('/booklogs');
    }}
   >
    <label htmlFor="isbn13">ISBN13:</label>
    <input type="text" name="isbn13" className="border mx-2 p-1" />
    <label htmlFor="bookname">書名:</label>
    <input type="text" name="bookname" className="border mx-2 p-1" />
    <button
     type="submit"
     className="bg-blue-600 px-2 py-1 rounded-lg text-sm text-white"
    >
     Add Book
    </button>
   </form>
  </div>
 );
};
export default Page;


④.起動確認
% npm_run_dev

ブラウザで http://localhost:3000/booklogs

■GITHUB
https://github.com/frontflg/BOOKLOG_NEXTJS14

検索・登録・変更・削除は可能ですが、
エラーチェックが出来ていない。(データ型、文字長、必須)
日付の入力が、手入力(カレンダーでない)
更新・削除後、一覧ページへ自動遷移しない
等、不完全極まりない状態です。
機能拡張して頂ける方がいましたら、お願いしたいです。

 

名前:
コメント:

※文字化け等の原因になりますので顔文字の投稿はお控えください。

コメント利用規約に同意の上コメント投稿を行ってください。

 

※ブログ作成者から承認されるまでコメントは反映されません。

  • Xでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

最新の画像もっと見る

最近の「Node.js」カテゴリーもっと見る

最近の記事
バックナンバー
2024年
2023年
人気記事