article

Thursday, April 17, 2025

Laravel 12 Livewire Starter Kit CRUD (Create, Read, Update and Delete) | FluxUI

Laravel 12 Livewire Starter Kit CRUD (Create, Read, Update and Delete) | FluxUI



Download Laravel App

https://laravel.com/docs/12.x/installation

Connecting our Database

open .env file root directory.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=8889
DB_DATABASE=laravel12dev
DB_USERNAME=root
DB_PASSWORD=root

Database Migration
php artisan migrate

myapp>php artisan migrate
Migration table created successfully.
check database table

Create tables Model php artisan make:model Product -m myapp>php artisan make:model Product -m Open new products migrations yourproject/database/migrations laravelproject\database\migrations\_create_products_table.php
//laravelproject\database\migrations\_create_products_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.
     */
    public function up(): void
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->string('price');
            $table->text('description');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('products');
    }
};
run
myapp>php artisan migrate
update Product Model
app/models/Product.php
//app/models/Product.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    protected $fillable = [
        'title',
        'price',
        'description'
    ];
}
Create livewire Component Products
php artisan make:livewire Products
livewire_crud\app\Livewire\Products.php
//livewire_crud\app\Livewire\Products.php
<?php

namespace App\Livewire;

use Livewire\Component;
use Livewire\WithPagination;
use App\Models\Product;
use Flux\Flux;

class Products extends Component
{

    use WithPagination;
    public $productID;

    public function render()
    {
        $products = Product::orderByDesc('created_at')->paginate(3);
        return view('livewire.product', [
            'products' => $products
        ]);
    }

    public function edit($id)
    {
        //dd($id);
        $this->dispatch('edit-product', $id); //livewire laravel com/docs/events#dispatching-events
    }

    public function delete($id)
    {
        //dd($id);
        $this->productID = $id;
        Flux::modal('delete-product')->show();
    }

    public function deleteProduct()
    {
        Product::find($this->productID)->delete();
        //display flash message
        session()->flash("success", "Product successfully Deleted");
        //redirect to product
        $this->redirectRoute('products', navigate: true);

        Flux::modal('delete-product')->close();
    }
}
Update routes web.phpp
use App\Livewire\Products;
Route::middleware(['auth'])->group(function () {
Route::get('products', Products::class)->name('products');
}

update sidebar view

livewire_crud\resources\views\components\layouts\app\sidebar.blade.php

//livewire_crud\resources\views\components\layouts\app\sidebar.blade.php
        <flux:navlist variant="outline">
            <flux:navlist.group :heading="__('Platform')" class="grid">
                <flux:navlist.item icon="home" :href="route('dashboard')" :current="request()->routeIs('dashboard')" wire:navigate>{{ __('Dashboard') }}</flux:navlist.item>
                <flux:navlist.item icon="home" :href="route('products')" :current="request()->routeIs('products')" wire:navigate>{{ __('Products') }}</flux:navlist.item>
            </flux:navlist.group>
        </flux:navlist>
Create Product Component
php artisan make:livewire CreateProduct
update with the following code
livewire_crud\app\Livewire\CreateProduct.php
//livewire_crud\app\Livewire\CreateProduct.php
<?php

namespace App\Livewire;

use Livewire\Component;
use Flux\Flux;
use App\Models\Product;

class CreateProduct extends Component
{
    public $title;
    public $price;
    public $description;

    protected function rules () 
    {
        return[
            'title' => 'required|string|max:255',
            'price' => 'required|string',
            'description' => 'required|string'
        ];
    }

    public function save() 
    {
        $this->validate();
        //dd('success');
        
        Product::create([
            "title" => $this->title,
            "price" => $this->price,
            "description" => $this->description,
        ]);
        //reset form
        $this->reset();
        //clode modal
        Flux::modal('create-product')->close();

        //display flash message
        session()->flash("success", "Product successfully added");

        //redirect to product
        $this->redirectRoute('products', navigate: true);
    }

    public function render()
    {
        return view('livewire.create-product');
    }
}
Edit Product Component
php artisan make:livewire EditProduct
update with the following code
livewire_crud\app\Livewire\EditProduct.php
//livewire_crud\app\Livewire\EditProduct.php
<?php

namespace App\Livewire;

use App\Models\Product;
use Flux\Flux;
use Livewire\Component;
use Livewire\Attributes\On;

class EditProduct extends Component
{
    public $title, $price, $description, $productID;

    #[On('edit-product')] //livewire laravel com/docs/events#dispatching-events

    public function edit($id)
    {
        //dd("edit product id {$id}");

        $product = Product::findOrFail($id);
        $this->productID = $id;
        $this->title = $product->title;
        $this->price = $product->price;
        $this->description = $product->description;
        Flux::modal('edit-product')->show();
    }

    public function update() 
    {
        $this->validate(([
            'title' => ['required', 'string', 'max:255'],
            'price' => ['required'],
            'description' => ['required'],
        ]));

        $product = Product::find($this->productID);
        $product->title = $this->title;
        $product->price = $this->price;
        $product->description = $this->description;
        $product->save();

        //display flash message
        session()->flash("success", "Product successfully updated");
        
        //redirect to product
        $this->redirectRoute('products', navigate: true);
        Flux::modal('edit-product')->close();
    }

    public function render()
    {
        return view('livewire.edit-product');
    }
}
copy header from livewire_crud\resources\views\partials\settings-heading.blade.php copy header to livewire_crud\resources\views\livewire\product.blade.php
add modal components flux ui - fluxui_dev/components/modal copy modal code to livewire_crud\resources\views\livewire\create-product.blade.php
//livewire_crud\resources\views\livewire\create-product.blade.php
<div>
    <flux:modal name="create-product" class="md:w-800">
        <div class="space-y-6">
            <div>
                <flux:heading size="lg">Create Product</flux:heading>
                <flux:text class="mt-2">Make changes to your Product.</flux:text>
            </div>

            <flux:input label="Title" wire:model="title" placeholder="Product Title" />
            <flux:input label="Price" wire:model="price" placeholder="Product Price" />
            <flux:textarea label="Description" wire:model="description" placeholder="Product Description" />

            <div class="flex">
                <flux:spacer />

                <flux:button type="submit" variant="primary" wire:click="save">Save</flux:button>
            </div>
        </div>
    </flux:modal>
</div>
Edit View
livewire_crud\resources\views\livewire\edit-product.blade.php
//livewire_crud\resources\views\livewire\edit-product.blade.php
<div>
    <flux:modal name="edit-product" class="md:w-800">
        <div class="space-y-6">
            <div>
                <flux:heading size="lg">Update Product</flux:heading>
                <flux:text class="mt-2">Update your Product.</flux:text>
            </div>

            <flux:input label="Title" wire:model="title" placeholder="Product Title" />
            <flux:input label="Price" wire:model="price" placeholder="Product Price" />
            <flux:textarea label="Description" wire:model="description" placeholder="Product Description" />

            <div class="flex">
                <flux:spacer />

                <flux:button type="submit" variant="primary" wire:click="update">Update</flux:button>
            </div>
        </div>
    </flux:modal>
</div>
Product View
livewire_crud\resources\views\livewire\product.blade.php
//livewire_crud\resources\views\livewire\product.blade.php
<div class="relative mb-6 w-full">
    <flux:heading size="xl" level="1">{{ __('Products') }}</flux:heading>
    <flux:subheading size="lg" class="mb-6">{{ __('Manage your Products') }}</flux:subheading>
    <flux:separator variant="subtle" />

    <flux:modal.trigger name="create-product">
        <flux:button class="mt-4">Create Product</flux:button>
    </flux:modal.trigger>

    @session('success')
    <div
        x-data="{show: true}"
        x-show="show"
        x-init="setTimeout(() => { show = false }, 3000)"
        class="fixed top-5 right-5 bg-green-600 text-white text-sm p-4 rounded-lg shadow-lg z-50"
        role="alert">
        <p>{{ $value }}</p>
    </div>
    @endsession('success')

    <livewire:create-product />
    <livewire:edit-product />

    <div class="relative overflow-x-auto mt-5">
        <table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
            <thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
                <tr>
                    <th scope="col" class="px-6 py-3">
                        Product name
                    </th>
                    <th scope="col" class="px-6 py-3">
                        Price
                    </th>
                    <th scope="col" class="px-6 py-3">
                        Description
                    </th>
                    <th scope="col" class="px-6 py-3">
                        Action
                    </th>
                </tr>
            </thead>
            <tbody>
                @forelse ($products as $rs)
                <tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 border-gray-200">
                    <th scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
                        {{ $rs->title }}
                    </th>
                    <td class="px-6 py-4">
                        {{ $rs->price }}
                    </td>
                    <td class="px-6 py-4">
                        {{ $rs->description }}
                    </td>
                    <td class="px-6 py-4">
                        <flux:button wire:click="edit({{ $rs->id }})">Edit</flux:button>
                        <flux:button variant="danger" wire:click="delete({{ $rs->id }})">Delete</flux:button>
                    </td>
                </tr>
                @empty
                <tr>
                    <td colspan="3">
                        No record
                    </td>
                </tr>
                @endforelse
            </tbody>
        </table>

        <div class="mt-4">
            {{ $products->links() }}
        </div>

        <flux:modal name="delete-product" class="min-w-[22rem]">
            <div class="space-y-6">
                <div>
                    <flux:heading size="lg">Delete Product?</flux:heading>

                    <flux:text class="mt-2">
                        <p>You're about to delete this Product.</p>
                        <p>This action cannot be reversed.</p>
                    </flux:text>
                </div>

                <div class="flex gap-2">
                    <flux:spacer />

                    <flux:modal.close>
                        <flux:button variant="ghost">Cancel</flux:button>
                    </flux:modal.close>

                    <flux:button type="submit" variant="danger" wire:click="deleteProduct()">Delete product</flux:button>
                </div>
            </div>
        </flux:modal>

    </div>

</div>
Run php artisan serve and npm run dev myapp>composer run dev
Starting Laravel development server: http://127.0.0.1:8000

Related Post