article

Friday, July 19, 2024

Next.js 14 CRUD (Create Read Update and Delete) with PHP MySQL

Next.js 14 CRUD (Create Read Update and Delete) with PHP MySQL

Install nextjs
https://nextjs.org/
npx create-next-app@latest

install axios
npm install axios
https://www.npmjs.com/package/axios
app\page.js
//app\page.js
import ListUser from '@/components/ListUser'
import { Suspense } from "react";
import Link from "next/link";

export default function Home() {
  return (
    <div className="w-screen py-20 flex justify-center flex-col items-center">
      <div className="flex items-center justify-between gap-1 mb-5">
        <h1 className="text-4xl font-bold">Next.js 14 CRUD (Create Read Update and Delete) with PHP MySQL</h1>
      </div>    
      <div className="overflow-x-auto">
          <div className="mb-2 w-full text-right">
            <Link
              href="/users/create"
              className="btn btn-primary">
              Add New User
            </Link>
          </div>
        <Suspense fallback="Loading...">
            <ListUser/>
          </Suspense>
      </div>  
    </div>
  );
}
components\ListUser.jsx
//components\ListUser.jsx
"use client";

import axios from 'axios';
import { useEffect, useState } from "react";
import Link from "next/link";

export default function ListUser() {

    const [users, setUsers] = useState([]);

    useEffect(() => {
        getUsers();
    }, []);
 
    function getUsers() { 
        axios.get('http://localhost:8888/devproject/nexjsphpmysl/api/').then(function(response) {
            console.log(response.data);
            setUsers(response.data);
        });
    }

    const deleteUser = (id) => {
        axios.delete(`http://localhost:8888/devproject/nexjsphpmysl/api/${id}/delete`).then(function(response){
            console.log(response.data);
            getUsers();
        });
    }
    
    return (
        <table className="table table-zebra">
            <thead className="text-sm text-gray-700 uppercase bg-gray-50">
                <tr>
                    <th className="py-3 px-6">#</th>
                    <th className="py-3 px-6">Name</th>
                    <th className="py-3 px-6">Email</th>
                    <th className="py-3 px-6">Mobile</th>
                    <th className="py-3 px-6 text-center">Actions</th>
                </tr>
            </thead>
            <tbody>
                {users.map((user, key) =>
                    <tr key={key} className="bg-white border-b">
                        <td className="py-3 px-6">{user.id}</td>
                        <td className="py-3 px-6">{user.name}</td>
                        <td className="py-3 px-6">{user.email}</td>
                        <td className="py-3 px-6">{user.mobile}</td>
                        <td className="flex justify-center gap-1 py-3">
                            <Link
                                href={`/users/view/${user.id}`} 
                                className="btn btn-success">
                                View
                            </Link>
                            <Link className="btn btn-info" href={`users/edit/${user.id}/`}>
                                Edit
                            </Link>
                            <button onClick={() => deleteUser(user.id)} className="btn btn-error">Delete</button>
                        </td>
                    </tr>
                )}
            </tbody>
        </table>
    )
}
app\users\create\page.jsx
//app\users\create\page.jsx
"use client";

import React, { useState } from "react";
import axios from 'axios' //npm install axios https://www.npmjs.com/package/axios

const Addnewuser = () => {
    const [inputs, setInputs] = useState([]);
 
    const handleChange = (event) => {
        const name = event.target.name;
        const value = event.target.value;
        setInputs(values => ({...values, [name]: value}));
    }

    const handleSubmit = (event) => {
        event.preventDefault();

        axios.post('http://localhost:8888/devproject/nexjsphpmysl/api/save', inputs).then(function(response){
            console.log(response.data);
            window.location.href = '/';
        });
    }

    return (
    <div className="max-w-md mx-auto mt-5">
        <h1 className="text-2xl text-center mb-2">Add New User</h1>
        <div>
        <form onSubmit={handleSubmit}>
        <div className="mb-5">
          <label htmlFor="name" className="block text-sm font-medium text-gray-900">
            Name
          </label>
          <input
            type="text"
            name="name"
            id="name"
            className="input input-bordered input-primary w-full max-w-xs"
            placeholder="Name..."
            onChange={handleChange}
          />
        </div>
        <div className="mb-5">
          <label htmlFor="email" className="block text-sm font-medium text-gray-900">
            Email
          </label>
          <input
            type="email"
            name="email"
            id="email"
            className="input input-bordered input-primary w-full max-w-xs"
            placeholder="email..."
            onChange={handleChange}
          />
        </div>
        <div className="mb-5">
          <label htmlFor="mobile" className="block text-sm font-medium text-gray-900">
            Mobile
          </label>
          <input
            type="text"
            name="mobile"
            id="mobile"
            className="input input-bordered input-primary w-full max-w-xs"
            placeholder="mobile..."
            onChange={handleChange}
          />
        </div>
        <button type="submit" className="btn btn-primary">Add New User</button> 
      </form>
    </div>
    </div>
  );
};
   
export default Addnewuser;
app\users\edit\[id]\page.jsx
//app\users\edit\[id]\page.jsx
"use client";
  
import React, { useState, useEffect } from 'react';
import axios from 'axios' //npm install axios https://www.npmjs.com/package/axios
import { useParams } from 'next/navigation'
 
export default function Edituser() {
    const [inputs, setInputs] = useState([]);
    const {id}=useParams();
    console.log(id);
 
    useEffect(() => {
        getUser();
    }, []);
 
    function getUser() {
        axios.get(`http://localhost:8888/devproject/nexjsphpmysl/api/${id}`).then(function(response) {
            console.log(response.data);
            setInputs(response.data);
        });
    }

    const handleChange = (event) => {
        const name = event.target.name;
        const value = event.target.value;
        setInputs(values => ({...values, [name]: value}));
    }

    const handleSubmit = (event) => {
        event.preventDefault();
 
        axios.put(`http://localhost:8888/devproject/nexjsphpmysl/api/${id}/edit`, inputs).then(function(response){
            console.log(response.data);
            window.location.href = '/';
        });
         
    }
    return (
    <div className="max-w-md mx-auto mt-5">
      <h1 className="text-2xl text-center mb-2">Edit Form</h1>
            <form onSubmit={handleSubmit}> 
                <div className="mb-3 mt-3">
                    <label className="block text-sm font-medium text-gray-900"> ID:</label>
                    <input type="text" id="id" name="id" value={id} disabled />
                </div>
                <div className="mb-3 mt-3">
                    <label className="block text-sm font-medium text-gray-900"> Full Name:</label>
                    <input type="text" className="input input-bordered input-primary w-full max-w-xs" placeholder="Enter Your Full Name" name="name"
                    value={inputs.name || ''} 
                    onChange={handleChange}/>
                </div>
                <div className="mb-3 mt-3">
                    <label className="block text-sm font-medium text-gray-900">Email:</label>
                    <input type="text" className="input input-bordered input-primary w-full max-w-xs" id="email" placeholder="Enter email" name="email"
                    value={inputs.email || ''} 
                    onChange={ handleChange}/>
                </div>
                <div className="mb-3 mt-3">
                    <label className="block text-sm font-medium text-gray-900">Mobile:</label>
                    <input type="text" className="input input-bordered input-primary w-full max-w-xs" id="mobile" placeholder="Enter mobile" name="mobile"
                    value={inputs.mobile || ''} 
                    onChange={ handleChange}/>
                </div>
                <button type="submit" name="update"  className="btn btn-primary">Update</button>
            </form>
    </div>
  );
}
app\users\view\[id]\page.jsx
//app\users\view\[id]\page.jsx
"use client";
  
import React, { useState, useEffect } from 'react';
import axios from 'axios' //npm install axios https://www.npmjs.com/package/axios
import { useParams } from 'next/navigation'
 
export default function ViewUser() {
    const {id}=useParams();
  
    console.log(id);
  
    const[user,setUser]=useState([]);
   
    useEffect(()=>{
        fetchUser();
    },[id]);
   
    const fetchUser=async()=>{
        try{
        const result=await axios.get("http://localhost:8888/devproject/nexjsphpmysl/api/"+id);
          console.log(result.data);
          setUser(result.data)
   
        }catch(err){
            console.log("Something Wrong");
        }
    }
  
    return (
    <div className="max-w-2xl mx-auto mt-5">
      <h1 className="text-2xl text-center mb-2">View User</h1>
      <table className="table table-zebra">
          <thead className="text-sm text-gray-700 uppercase bg-gray-50">
            <tr>
              <th>S No.</th>
              <th>Name</th>
              <th>Email</th>         
              <th>Mobile</th>      
            </tr>
          </thead>
          <tbody>
            <tr>
                <td>{user.id}</td>
                <td>{user.name}</td>
                <td>{user.email}</td>
                <td>{user.mobile}</td>
            </tr>
          </tbody>
      </table>
    </div>
  );
}
devproject/nexjsphpmysl/api/index.php
//devproject/nexjsphpmysl/api/index.php
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: *");
header("Access-Control-Allow-Methods: *");

include 'DbConnect.php';
$objDb = new DbConnect;
$conn = $objDb->connect();

$method = $_SERVER['REQUEST_METHOD'];
switch ($method) {
    case "GET":
        $sql = "SELECT * FROM users";
        $path = explode('/', $_SERVER['REQUEST_URI']);
        if (isset($path[4]) && is_numeric($path[4])) {
            $sql .= " WHERE id = :id";
            $stmt = $conn->prepare($sql);
            $stmt->bindParam(':id', $path[4]);
            $stmt->execute();
            $users = $stmt->fetch(PDO::FETCH_ASSOC);
        } else {
            $stmt = $conn->prepare($sql);
            $stmt->execute();
            $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
        }

        echo json_encode($users);
        break;

    case "POST":
        $user = json_decode(file_get_contents('php://input'));
        $sql = "INSERT INTO users(id, name, email, mobile, created_at) VALUES(null, :name, :email, :mobile, :created_at)";
        $stmt = $conn->prepare($sql);
        $created_at = date('Y-m-d');
        $stmt->bindParam(':name', $user->name);
        $stmt->bindParam(':email', $user->email);
        $stmt->bindParam(':mobile', $user->mobile);
        $stmt->bindParam(':created_at', $created_at);

        if ($stmt->execute()) {
            $response = ['status' => 1, 'message' => 'Record created successfully.'];
        } else {
            $response = ['status' => 0, 'message' => 'Failed to create record.'];
        }
        echo json_encode($response);
        break;

    case "PUT":
        $user = json_decode(file_get_contents('php://input'));
        $sql = "UPDATE users SET name= :name, email =:email, mobile =:mobile, updated_at =:updated_at WHERE id = :id";
        $stmt = $conn->prepare($sql);
        $updated_at = date('Y-m-d');
        $stmt->bindParam(':id', $user->id);
        $stmt->bindParam(':name', $user->name);
        $stmt->bindParam(':email', $user->email);
        $stmt->bindParam(':mobile', $user->mobile);
        $stmt->bindParam(':updated_at', $updated_at);

        if ($stmt->execute()) {
            $response = ['status' => 1, 'message' => 'Record updated successfully.'];
        } else {
            $response = ['status' => 0, 'message' => 'Failed to update record.'];
        }
        echo json_encode($response);
        break;

    case "DELETE":
        $sql = "DELETE FROM users WHERE id = :id";
        $path = explode('/', $_SERVER['REQUEST_URI']);

        $stmt = $conn->prepare($sql);
        $stmt->bindParam(':id', $path[4]);

        if ($stmt->execute()) {
            $response = ['status' => 1, 'message' => 'Record deleted successfully. ' . $path[4] . ' '];
        } else {
            $response = ['status' => 0, 'message' => 'Failed to delete record.'];
        }
        echo json_encode($response);
        break;
}
devproject/nexjsphpmysl/api/DbConnect.php
//devproject/nexjsphpmysl/api/DbConnect.php
<?php
class DbConnect
{
    private $server = 'localhost';
    private $dbname = 'nextjsdb';
    private $user = 'root';
    private $pass = 'root';

    public function connect()
    {
        try {
            $conn = new PDO('mysql:host=' . $this->server . ';dbname=' . $this->dbname, $this->user, $this->pass);
            $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            return $conn;
        } catch (\Exception $e) {
            echo "Database Error: " . $e->getMessage();
        }
    }
}

devproject/nexjsphpmysl/api/.htaccess
RewriteEngine On
 
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
Run C:\myapp-js>npm start

Check API Results in Postman
https://www.postman.com/downloads/
POST method : http://localhost/devproject/nexjsphpmysl/api/save
Get method : http://localhost/devproject/nexjsphpmysl/api/
PUT method : http://localhost/devproject/nexjsphpmysl/api/1
DELTE method : http://localhost/devproject/nexjsphpmysl/api/1

Related Post