Laravel 9 React js CRUD

Laravel 9 React installation with Laravel Breeze:

  • laravel new project-name
  • cd project-name
  • composer require laravel/breeze --dev
  • php artisan breeze:install react
  • npm install
  • npm run dev

CRUD Operation:

  • php artisan make:model Post -mcr

database/migrations/2022_07_13_115218_create_posts_table.php

  • <?php
     
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;
     
    return new class extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            Schema::create('posts', function (Blueprint $table) {
                $table->id();
                $table->string('title');
                $table->text('description');
                $table->timestamps();
            });
        }
     
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::dropIfExists('posts');
        }
    }

App/Models/Post.php

  • <?php

    namespace App\Models;

    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;

    class Post extends Model
    {
        use HasFactory;

        protected $fillable = [
            'title', 'description'
        ];
    }

routes/web.php

  • <?php

    use Illuminate\Foundation\Application;
    use Illuminate\Support\Facades\Route;
    use Inertia\Inertia;
    use App\Http\Controllers\PostController;

    /*
    |--------------------------------------------------------------------------
    | Web Routes
    |--------------------------------------------------------------------------
    |
    | Here is where you can register web routes for your application. These
    | routes are loaded by the RouteServiceProvider within a group which
    | contains the "web" middleware group. Now create something great!
    |
    */

    Route::get('/', function () {
        return Inertia::render('Welcome', [
            'canLogin' => Route::has('login'),
            'canRegister' => Route::has('register'),
            'laravelVersion' => Application::VERSION,
            'phpVersion' => PHP_VERSION,
        ]);
    });

    Route::get('/dashboard', function () {
        return Inertia::render('Dashboard');
    })->middleware(['auth', 'verified'])->name('dashboard');

    require __DIR__.'/auth.php';

    //
    Route::resource('post', PostController::class);

app/Http/Controllers/PostController.php

  • <?php

    namespace App\Http\Controllers;

    use App\Models\Post;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Validator;
    use Inertia\Inertia;

    class PostController extends Controller
    {
        /**
         * Display a listing of the resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function index()
        {
            $post = Post::all();
            return Inertia::render('Posts/Index', ['post' => $post]);
        }

        /**
         * Show the form for creating a new resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function create()
        {
            return Inertia::render('Posts/Create');
        }

        /**
         * Store a newly created resource in storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return \Illuminate\Http\Response
         */
        public function store(Request $request)
        {
            Validator::make($request->all(), [
                'title' => ['required'],
                'description' => ['required'],
            ])->validate();

            Post::create($request->all());

            return redirect()->route('post.index');
        }

        /**
         * Display the specified resource.
         *
         * @param  \App\Models\Post  $post
         * @return \Illuminate\Http\Response
         */
        public function show(Post $post)
        {
            return response()->json([
                'post'=>$post
            ]);
        }

        /**
         * Show the form for editing the specified resource.
         *
         * @param  \App\Models\Post  $post
         * @return \Illuminate\Http\Response
         */
        public function edit(Post $post)
        {
            return Inertia::render('Posts/Edit', ['post' => $post]);
        }

        /**
         * Update the specified resource in storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \App\Models\Post  $post
         * @return \Illuminate\Http\Response
         */
        public function update($id, Request $request)
        {
            Validator::make($request->all(), [
                'title' => ['required'],
                'description' => ['required'],
            ])->validate();

            Post::find($id)->update($request->all());
            return redirect()->route('post.index');
        }

        /**
         * Remove the specified resource from storage.
         *
         * @param  \App\Models\Post  $post
         * @return \Illuminate\Http\Response
         */
        public function destroy($id)
        {
            Post::find($id)->delete();
            return redirect()->route('post.index');
        }
    }

Create React Pages:

In resources/js/Pages:

  • Index.jsx
  • Create.jsx
  • Edit.jsx

Index.jsx

  • import Navbar from '@/Components/Navbar'
    import React from 'react'
    import { Inertia } from "@inertiajs/inertia";
    import { usePage, Link } from '@inertiajs/inertia-react';

    function Index() {

      const { post } = usePage().props

      function destroy(e) {
        if (confirm("Are you sure you want to delete this user?")) {
          Inertia.delete(route("post.destroy", e.currentTarget.id));
        }
      }

      return (
        <>
          <Navbar />
          <div className="py-12">
            <div className="max-w-7xl mx-auto sm:px-6 lg:px-8">
              <div className="bg-white overflow-hidden shadow-sm sm:rounded-lg">
                <div className="p-6 bg-white border-b border-gray-200">

                  <div className="flex items-center justify-between mb-6">
                    <Link className="px-6 py-2 text-white bg-green-500 rounded-md focus:outline-none" href={route("post.create")}>
                      Create Post
                    </Link>
                  </div>

                  <table className="table-fixed w-full">
                    <thead>
                      <tr className="bg-gray-100">
                        <th className="px-4 py-2 w-20">Id</th>
                        <th className="px-4 py-2 w-20">Title</th>
                        <th className="px-4 py-2 w-20">Description</th>
                        <th className="px-4 py-2 w-20">Action</th>
                      </tr>
                    </thead>
                    <tbody>
                      {post.map(({ id, title, description }) => (
                        <tr>
                          <td className="border px-4 py-2">{id}</td>
                          <td className="border px-4 py-2">{title}</td>
                          <td className="border px-4 py-2">{description}</td>
                          <td className="border px-4 py-2">
                            <Link tabIndex="1" className="px-4 py-2 text-sm text-white bg-blue-500 rounded" href={route("post.edit", id)}>
                              Edit
                            </Link>
                            <button onClick={destroy} id={id} tabIndex="-1" type="button" className="mx-1 px-4 py-2 text-sm text-white bg-red-500 rounded">
                              Delete
                            </button>
                          </td>
                        </tr>
                      ))}

                      {post.length === 0 && (
                        <tr>
                          <td className="px-6 py-4 border-t" colSpan="4">
                            <h1>No data found!</h1>
                          </td>
                        </tr>
                      )}
                    </tbody>
                  </table>
                </div>
              </div>
            </div>
          </div>
        </>
      )
    }

    export default Index

Create.jsx

  • import React from 'react'
    import Navbar from '@/Components/Navbar'
    import swal from 'sweetalert';
    import { useForm } from '@inertiajs/inertia-react';

    function Create() {

      document.title = "Laravel | Create - Form"

      const { data, setData, errors, post } = useForm({
        title: "",
        description: "",
      });

      function handleSubmit(e) {
        e.preventDefault()
        post(route("post.store"));
        swal({
          title: "Good job!",
          text: "Created",
          icon: "success",
          button: "Ok!",
        });
      }

      return (
        <>
          <Navbar />
          <div style={{ width: '500px', margin: '0 auto' }}>
            <h1 className="text-center my-4">Basic Form</h1>
            <form className='form-control' onSubmit={handleSubmit}>
             
              <div className="mb-3">
                <label className="form-label">Title</label>
                <input type="text" name="title" value={data.title} onChange={(e) => setData("title", e.target.value)} className="form-control" />
              </div>

              <span className="text-red-600">{errors.title}</span>

              <div className="mb-3">
                <label className="form-label">Description</label>
                <textarea type="text" className="w-full rounded form-control" label="description" name="description" errors={errors.description} value={data.description} onChange={(e) => setData("description", e.target.value)} rows="5" />
              </div>

              <span className="text-red-600">{errors.description}</span>

              <button className="btn btn-primary">Create</button>
            </form>
          </div>
        </>
      )
    }

    export default Create

Edit.jsx

  • import Navbar from '@/Components/Navbar'
    import React from 'react'
    import { useForm, usePage, Link } from '@inertiajs/inertia-react';

    function Edit() {

      const { post } = usePage().props;

      const { data, setData, put, errors } = useForm({
        title: post.title || "",
        description: post.description || "",
      });

      function handleSubmit(e) {
        e.preventDefault();
        put(route("post.update", post.id));
      }

      return (
        <>
          <Navbar />
          <div style={{ width: '500px', margin: '0 auto' }}>
            <h1 className="text-center my-4">Basic Form</h1>
            <form className='form-control' onSubmit={handleSubmit}>

              <div className="mb-3">
                <label className="form-label">Title</label>
                <input type="text" name="title" value={data.title} onChange={(e) => setData("title", e.target.value)} className="form-control" />
              </div>

              <span className="text-red-600">{errors.title}</span>

              <div className="mb-3">
                <label className="form-label">Description</label>
                <textarea type="text" value={data.description} onChange={(e) => setData("description", e.target.value)} className="w-full rounded form-control" label="description" name="description" rows="5" />
              </div>

              <span className="text-red-600">{errors.description}</span>

              <button className="btn btn-success">Update</button>
            </form>
          </div>
        </>
      )
    }

    export default Edit
































































Comments

Popular posts from this blog

Create a Connection in Node js and make an API

React JS | Store form data in localStorage

React Redux Toolkit