Jasa Setting Mikrotik

Belajar NextJs Terbaru 16.0.1 Error Saat install Prisma dan prisma-client next-auth bcrypt

Belajar belum selesai dan khatam nextjs 14, 15 sudah naik aja tuh versi next js ke versi NextJs Terbaru 16.0.1, saat saya coba pakai nextjs 16.0.1 ada Error Saat install Prisma dan prisma-client next-aut bcrypt, namun saat installasi file-file berikut, muncul error. error nextjs saat install prisma prisma-client nextauth bcrypt
$ npm install @prisma/client next-auth bcrypt
npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
npm error
npm error While resolving: my-app@0.1.0
npm error Found: nodemailer@6.10.1
npm error node_modules/nodemailer
npm error   peerOptional nodemailer@"^6.8.0" from @auth/core@0.34.2
npm error   node_modules/@auth/core
npm error     peerOptional @auth/core@"0.34.2" from next-auth@4.24.12
npm error     node_modules/next-auth
npm error       next-auth@"*" from the root project
npm error
npm error Could not resolve dependency:
npm error peerOptional nodemailer@"^7.0.7" from next-auth@4.24.12
npm error node_modules/next-auth
npm error   next-auth@"*" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.
npm error
npm error
npm error For a full report see:
npm error C:\Users\HAPESINDO\AppData\Local\npm-cache\_logs\2025-10-29T03_37_18_844Z-eresolve-report.txt
npm error A complete log of this run can be found in: C:\Users\HAPESINDO\AppData\Local\npm-cache\_logs\2025-10-29T03_37_18_844Z-debug-0.log
Solusinya, Install nodemailer@latest $ npm install nodemailer@latest
added 1 package, and audited 428 packages in 3s

172 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
Jika sudah lanjutkan install Prisma dan prisma-client next-aut bcrypt dengan perintah install menggunakan npm npm install @prisma/client next-auth bcrypt Setelah itu install prisma dengan perintah npm install prisma --save-dev Dan jalankan init prisma untuk membuat file .env dan generate prisma npx prisma init Kalau kita ingin cek versi Next.js dan NextAuth biar cocok sepenuhnya (versi yang stabil dan tanpa konflik). Kita bisa buat perintah seperti ini npm list next next-auth nodemailer Selanjutnya ada error saat generate prisma dev npx prisma migrate dev --name init error seperti ini
$ npx prisma migrate dev
Failed to load config file "D:\laragon\www\my-app\prisma.config.ts" as a 
TypeScript/JavaScript module. Error: Error: Cannot find module 'prisma/config'
Require stack:
- D:\laragon\www\my-app\prisma.config.ts
Solusinya tambahkan ini
import "dotenv/config";
di file
prisma.config.ts 
lalu generete ulang. Jangan lupa install juga prisma npm install prisma Berikut beberapa settingan untuk membuat crud dengan Nextjs 16.0.1, file
schema.prisma
berikut isinya : generator client { provider = "prisma-client" output = "../app/generated/prisma" } datasource db { provider = "mysql" url = env("DATABASE_URL") } model Product { id Int @id @default(autoincrement()) nama String harga Float stok Int image String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } File
prisma.config.ts
berikut isinya setelah di tambahin code
import "dotenv/config";
import { defineConfig, env } from "prisma/config"; import "dotenv/config"; export default defineConfig({ schema: "prisma/schema.prisma", migrations: { path: "prisma/migrations", }, engine: "classic", datasource: { url: env("DATABASE_URL"), }, }); Langkah selanjutnya membuat server action, dimana file
ProductAction.tsx
kita buat didalam directory
/app/actions
dengan isi 

"use server"

import prisma from "@/lib/prisma"
import { revalidatePath } from "next/cache"
import fs from "fs";
import path from "path";
import { redirect } from "next/navigation";

async function saveImage(file: File): Promise<string> {
    const uploadDir = path.join(process.cwd(), "public", "uploads");

    if (!fs.existsSync(uploadDir)) fs.mkdirSync(uploadDir, { recursive: true });

    const buffer = Buffer.from(await file.arrayBuffer());
    const filename = Date.now() + "-" + file.name.replace(/\s+/g, "_");
    const filepath = path.join(uploadDir, filename);

    await fs.promises.writeFile(filepath, buffer);
    return "/uploads/" + filename;
}


export async function addProduct(formData: FormData) {
    const nama = formData.get("nama") as string;
    const harga = Number(formData.get("harga"));
    const stok = Number(formData.get("stok"));
    const file = formData.get("image") as File | null;

    let imagePath: string | undefined;
    if (file && file.size > 0) {
        imagePath = await saveImage(file);
    }

    if (!nama || isNaN(harga) || isNaN(stok)) {
        throw new Error("data tidak valid")
    }

    await prisma.product.create({
        data: { nama, harga, stok, image: imagePath }
    })

    revalidatePath("/products")
    redirect("/products");
}
// Edit Produk
export async function updateProduct(id: number, formData: FormData) {
    const nama = formData.get("nama") as string;
    const harga = Number(formData.get("harga"));
    const stok = Number(formData.get("stok"));
    const file = formData.get("image") as File | null;
    // const description = formData.get("description") as string | null;

    let imagePath: string | undefined;
    if (file && file.size > 0) {
        imagePath = await saveImage(file);
    }


    await prisma.product.update({
        where: { id },
        data: { nama, harga, stok, ...(imagePath ? { image: imagePath } : {}) },
    });

    revalidatePath("/products");
    redirect("/products");
}

//Hapus Produk
export async function deleteProduct(id: number) {
    await prisma.product.delete({ where: { id } });
    revalidatePath("/products");
    redirect("/products");
}
Selanjutnya kita buat folder
/app/products
yang didalamnya ada file
page.tsx
dengan isi berikut  


import prisma from "@/lib/prisma";
import DeleteButton from "@/componens/DeleteButton";
import Link from "next/link";


export default async function ProductPage() {

    const products = await prisma.product.findMany({
        orderBy: { id: "desc" }
    })


    return (
        <div>
            <div className="flex justify-between mb-6">
                <h1 className="text-2xl font-bold">Daftar Produk</h1>
                <Link href="/products/new" className="bg-blue-600 text-white px-4 py-2 rounded-lg">+ Tambah Produk</Link>
            </div>

            <table className="w-full border-collapse border">
                <thead>
                    <tr className="bg-gray-100">
                        <th className="border p-2">#</th>
                        <th className="border p-2">Gambar</th>
                        <th className="border p-2">Nama</th>
                        <th className="border p-2">Harga</th>
                        <th className="border p-2">Stok</th>
                        <th className="border p-2">Action</th>
                    </tr>
                </thead>
                <tbody>
                    {products.map((p: { id: number, nama: string, harga: number, stok: number, image?: string | null }, index) => (
                        <tr key={p.id}>
                            <td className="border p-2">{index + 1}</td>
                            <td className="border p-2">
                                {p.image ? (
                                    <img
                                        src={p.image}
                                        alt={p.nama}
                                        className="w-16 h-16 object-cover rounded"
                                    />
                                ) : (
                                    <span className="text-gray-400 italic">No image</span>
                                )}
                            </td>
                            <td className="border p-2">{p.nama}</td>
                            <td className="border p-2">Rp.{p.harga.toLocaleString("id-ID")}</td>
                            <td className="border p-2">{p.stok}</td>
                            <td className="border p-2">
                                <div className="flex justify-center gap-2">
                                    <Link
                                        href={`/products/edit/${p.id}`}
                                        className="bg-blue-500 text-white px-2 py-1 rounded"
                                    >
                                        Edit
                                    </Link>
                                    <DeleteButton id={p.id} />
                                </div>

                            </td>
                        </tr>
                    ))}
                </tbody>
            </table>
        </div>
    )
}

Komentar