0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Next.js】管理者情報をWebAPIのNextResponse,NextRequestでPOST通信を実施する

Posted at

サンプル

管理者の登録画面からデータを入力します。

管理者1.png

登録が成功するとPostgreSQLにデータが反映されます。

管理者登録Postgres.png

登録済み管理者の場合は、下記のようにサーバ側からメッセージを返却します。

管理者すでにある.png

アラートにて登録済みの管理者を表示する仕様です。

管理者すでにある2.png

スキーマモデル

管理者情報としてAdminUserモデルを追加しました。

schema.prisma
// 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 = "postgresql"
  url      = env("DATABASE_URL")
}

model User{
  userId Int @id @default(autoincrement())
  userName String
  email String @unique
  password String
  createdAt DateTime @default(now())

  orders   Order[]  // 1人のユーザーは複数の注文を持つ
}

model AdminUser{
  adminUserId Int @id @default(autoincrement())
  adminUserName String
  adminEmail String @unique
  adminPassword String
  createdAt DateTime @default(now())
}

model Product{
  productId Int @id @default(autoincrement())
  productName String
  description String
  productImagepath String
  createdAt DateTime @default(now())
  updatedAt DateTime @default(now())

  items   Item[]   // 1つの製品は複数のアイテムに関連付けられる
}

model Item{
  itemId Int @id @default(autoincrement())
  quantity Int
  price Int
  createdAt DateTime @default(now())
  updatedAt DateTime @default(now())

  orderId   Int      // Order と 1対多 のリレーション
  order     Order    @relation(fields: [orderId], references: [orderId])
  productId Int      // Product と 多対1 のリレーション
  product   Product  @relation(fields: [productId], references: [productId])
}

model Order{
  orderId Int @id @default(autoincrement())
  total Int
  createdAt DateTime @default(now())
  updatedAt DateTime @default(now())

  userId    Int      // User と 1対多 のリレーション
  user      User     @relation(fields: [userId], references: [userId])
  items     Item[]   // 1つの注文には複数のアイテムが関連付けられる
}

ディレクトリ構成

NextProject
├─ app
│  ├─ admin
│  │  ├─ userRegister
│  │  │  └─ page.tsx
│  │  └─ adminUserRegister
│  │     └─ page.tsx
│  ├─ api
│  │  ├─ adminUserRegister
│  │  │  └─ route.ts
│  │  └─ userRegister
│  │        └─ route.ts
│  ├─ components
│  │  └─ headers
│  │        └─ navbar
│  │           └─ page.tsx
│  └─ prisma
│     └─ schema.prisma
├─ next.config.ts
├─ package.json
├─ package.lock.json
└─ tailwind.config.mjs

フロント側のコード

app/admin/adminUserRegister/page.tsx
'use client'
import { useForm } from "react-hook-form"
import { useState } from "react";

//付与すること

export default function AdminRegister(){
    //初期値アを設定
    const defaultValues = {
        userName:'管理者太郎',
        email:'authenticater@email.com',
        password:''
    }

    //フォームを初期化する
    const {register,handleSubmit,formState:{errors}} = useForm({
        defaultValues
    });

    const [userName,setUserName] = useState("");
    const [email,setEmail] = useState("");
    const [password,setPassword] = useState("");
    
    //フォーム送信時の実行される関数
    const onSubmit = async(data:any)=>{
        //POSTリクエスト送信
        const response = await fetch('/api/adminUserRegister',{
            method:'POST',
            headers:{
                'Content-Type':'application/json',
                cache:'no-store'
            },
            body:JSON.stringify({
                userName:data.userName,
                email:data.email,
                password:data.password
            })
        });
        //レスポンスデータをJSON変換する
        const returnResponse = await response.json();
        console.log(returnResponse);

        //レスポンスを画面に表示する
        if(response.ok){
            alert('管理者ユーザ登録成功しました');
        }

        if(returnResponse.status === 500){
            alert(returnResponse.existAdminUser.adminUserName + "は、すでに塘路kされています");
        }
    }

    return(
        <div className="flex items-center justify-center min-h-screen rounded-md">
            <form onSubmit={handleSubmit(onSubmit)} className="shadow-md w-96 px-8 py-8 border border-gray-300 rounded-md">
                <div className="w-full">
                    <label className="font-bold">管理者名</label>
                    <input
                        type="text"
                        name="userName"
                        defaultValue={userName}
                        className="block rounded-md w-full text-sm border border-gray-300 text-gray-900 px-2 py-2"
                        placeholder=""
                        {...register('userName',{
                          required:'管理者名は必須です。',
                          maxLength:{
                            value:20,
                            message:'管理者名は20文字以内にしてください。'
                          }  
                        })}
                        onChange={(e)=>setUserName(e.target.value)}
                    />
                    <div className="text-red-500">{errors.userName?.message}</div>
                </div>
                <div className="w-full mt-4">
                    <label className="font-bold">管理者メールアドレス</label>
                    <input
                        type="email"
                        name="email"
                        defaultValue={email}
                        className="block rounded-md w-full text-sm border border-gray-300 text-gray-900 px-2 py-2"                        
                        {...register('email',{
                            required:'管理者メールアドレスは必須です。',
                            pattern:{
                                value:/([a-z\d+\-.]@[a-z\d-]+(?:\.[a-z]+)*)/i,
                                message:'管理写メールアドレスが必須です。'
                            }
                        })}
                        onChange={(e)=>setEmail(e.target.value)}
                    />
                </div>
                <div className="w-full mt-4">
                    <label className="font-bold">管理者パスワード</label>
                    <input
                        type="password"
                        name="password"
                        defaultValue={password}
                        className="block rounded-md w-full text-sm border border-gray-300 text-gray-900 px-2 py-2"
                        {...register('password',{
                            required:'管理者パスワードは必須です。'
                        })}
                        onChange={(e)=>{e.target.value}}
                    />
                </div>
                <div className="flex items-center justify-center mt-4 mb-4">
                    <button type="submit" className="shadow-md bg-blue-500 text-white font-bold rounded-md px-4 py-4">
                        登録
                    </button>
                </div>
            </form>
        </div>
    )
}



サーバ側のコード

app/api/adminUserRegister/route.ts
import { NextRequest,NextResponse } from "next/server";
import { PrismaClient } from "@prisma/client";
import bcrypt from 'bcryptjs'

const prisma = new PrismaClient();

export async function POST(req:NextRequest){
    try{
        let {userName,email,password} = await req.json();
        console.log("受け取った管理者名は," + userName);
        const hashedPassword:String = await bcrypt.hash(password,10);
        
        //リクエストパラメータが不足している場合はエラーレスポンスを変化ykする
        if(!userName || !email || !password){
            return NextResponse.json({error:"全ての項目を入力してください",status:401});
        }

        //登録済みユーザの確認
        const existAdminUser = await prisma.AdminUser.findUnique({
            where:{
                adminEmail: email
            }
        });

        if(existAdminUser){
            return NextResponse.json({message:"すでにこのユーザーは登録されています。",status:500,existAdminUser:existAdminUser},{status:500});
        }

        //管理ユーザを登録する
        const newAdminUser = await prisma.AdminUser.create({
            data:{
                adminUserName: userName,
                adminEmail: email,
                adminPassword: hashedPassword
            }
        });

        //成功レスポンセ鵜を変化yk数ル
        return NextResponse.json({message:'管理者ユーザーを登録しました。',adminUser:newAdminUser});

    }catch(error){
        if(error instanceof Error){
            console.log("エラー詳細:",error);
        }
        return NextResponse.json({error:"ユーザー登録中にエラーが発生しました。",status:500});
    }
}

以上です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?