Laravel E-Commerce Project

Laravel 8 E-Commerce - Admin Add New Product


Video Thumbnail

In this video, we will learn about how to add a new product.

Let's see how we can add a new product. First, we need to create a new Livewire component for adding a new product.

Switch to the command prompt and run the command:


php artisan make:livewire admin/AdminAddProductComponent

Next, switch to the project and create a route for the AdminAddProductComponent. Open the web.php file and, inside the admin route group, add the route:


Route::get('/admin/product/add',AdminAddProductComponent::class)->name('admin.addproduct');

Now, open the AdminAddProductComponent.php class file and write the following code:


<?php
namespace AppHttpLivewireAdmin;
use AppModelsCategory;
use AppModelsProduct;
use CarbonCarbon;
use LivewireComponent;
use IlluminateSupportStr;
use LivewireWithFileUploads;
class AdminAddProductComponent extends Component
{
    use WithFileUploads;
    public $name;
    public $slug;
    public $short_description;
    public $description;
    public $regular_price;
    public $sale_price;
    public $SKU;
    public $stock_status;
    public $featured;
    public $quantity;
    public $image;
    public $category_id;  
    public $images;     
    public function mount()
    {
        $this->stock_status = 'instock';
        $this->featured = 0;
    }
    public function generateSlug()
    {
        $this->slug = Str::slug($this->name,'-');
    }
    public function updated($fields)
    {
        $this->validateOnly($fields,[
            'name' => 'required',
            'slug' => 'required|unique:products',
            'short_description' => 'required',
            'description' => 'required',
            'regular_price' => 'required|numeric',
            'sale_price' => 'numeric',
            'SKU' => 'required',
            'stock_status' => 'required',            
            'quantity' => 'required|numeric',
            'image' => 'required|mimes:jpeg,png',
            'category_id' => 'required'            
        ]);
    }
    public function addProduct()
    {
        $this->validate([
            'name' => 'required',
            'slug' => 'required|unique:products',
            'short_description' => 'required',
            'description' => 'required',
            'regular_price' => 'required|numeric',
            'sale_price' => 'numeric',
            'SKU' => 'required',
            'stock_status' => 'required',            
            'quantity' => 'required|numeric',
            'image' => 'required|mimes:jpeg,png',
            'category_id' => 'required'                 
        ]);
        $product = new Product();
        $product->name = $this->name;
        $product->slug = $this->slug;
        $product->short_description = $this->short_description;
        $product->description = $this->description;
        $product->regular_price = $this->regular_price;
        $product->sale_price = $this->sale_price;
        $product->SKU = $this->SKU;
        $product->stock_status = $this->stock_status;
        $product->featured = $this->featured;
        $product->quantity = $this->quantity;
        $imageName = Carbon::now()->timestamp. '.' . $this->image->extension();
        $this->image->storeAs('products',$imageName);
        $product->image = $imageName;     
        
        if($this->images)
        {
            $imagesname = '';
            foreach($this->images as $key=>$image)
            {
                $imgName = Carbon::now()->timestamp. $key. '.' . $image->extension();
                $image->storeAs('products',$imgName);
                $imagesname = $imagesname . ',' . $imgName;
            }
            $product->images = $imagesname;
        }
        $product->category_id = $this->category_id;
        $product->save();
        session()->flash('message','Product has been created successfully!');
    }
    public function render()
    {
        $categories = Category::all();
        return view('livewire.admin.admin-add-product-component',['categories'=>$categories])->layout('layouts.base');
    }
}

Open the admin-add-product-component.blade.php view file and write the following code:


<div>
    <div class=`container` style=`padding:30px 0;`>
        <div class=`row`>
            <div class=`col-md-12`>
                <div class=`panel panel-default`>
                    <div class=`panel-heading`>
                        <div class=`row`>
                            <div class=`col-md-6`>
                                Add New Product
                            </div>
                            <div class=`col-md-6`>
                                <a href=`{{route('admin.products')}}` class=`btn btn-success pull-right`>All Products</a>
                            </div>
                        </div>
                    </div>
                    <div class=`panel-body`>
                        @if(Session::has('message'))
                            <div class=`alert alert-success` role=`alert`>{{Session::get('message')}}</div>
                        @endif
                        <form class=`form-horizontal` enctype=`multipart/form-data` wire:submit.prevent=`addProduct`>
                            <div class=`form-group`>
                                <label class=`col-md-4 control-label`>Product Name</label>
                                <div class=`col-md-4`>
                                    <input type=`text` placeholder=`Product Name` class=`form-control input-md` wire:model=`name` wire:keyup=`generateSlug` />
                                    @error('name')  <p class=`text-danger`>{{$message}}</p> @enderror
                                </div>
                            </div>
                            <div class=`form-group`>
                                <label class=`col-md-4 control-label`>Product Slug</label>
                                <div class=`col-md-4`>
                                    <input type=`text` placeholder=`Product Slug` class=`form-control input-md` wire:model=`slug` />
                                    @error('slug')  <p class=`text-danger`>{{$message}}</p> @enderror
                                </div>
                            </div>
                            <div class=`form-group`>
                                <label class=`col-md-4 control-label`>Short Description</label>
                                <div class=`col-md-4` wire:ignore>
                                    <textarea class=`form-control` id=`short_description` placeholder=`Short Description`  wire:model=`short_description`></textarea>
                                    @error('short_description')  <p class=`text-danger`>{{$message}}</p> @enderror
                                </div>
                            </div>
                            <div class=`form-group`>
                                <label class=`col-md-4 control-label`>Description</label>
                                <div class=`col-md-4` wire:ignore>
                                    <textarea class=`form-control` id=`description` placeholder=`Description`  wire:model=`description`></textarea>
                                    @error('description')  <p class=`text-danger`>{{$message}}</p> @enderror
                                </div>
                            </div>
                            <div class=`form-group`>
                                <label class=`col-md-4 control-label`>Regular Price</label>
                                <div class=`col-md-4`>
                                    <input type=`text` placeholder=`Regular Price` class=`form-control input-md`  wire:model=`regular_price`/>                                    
                                    @error('regular_price')  <p class=`text-danger`>{{$message}}</p> @enderror
                                </div>
                            </div>
                            <div class=`form-group`>
                                <label class=`col-md-4 control-label`>Sale Price</label>
                                <div class=`col-md-4`>
                                    <input type=`text` placeholder=`Sale Price` class=`form-control input-md` wire:model=`sale_price` />  
                                    @error('sale_price')  <p class=`text-danger`>{{$message}}</p> @enderror                                 
                                </div>
                            </div>
                            <div class=`form-group`>
                                <label class=`col-md-4 control-label`>SKU</label>
                                <div class=`col-md-4`>
                                    <input type=`text` placeholder=`SKU` class=`form-control input-md` wire:model=`SKU` />
                                    @error('SKU')  <p class=`text-danger`>{{$message}}</p> @enderror  
                                </div>
                            </div>
                            <div class=`form-group`>
                                <label class=`col-md-4 control-label`>Stock</label>
                                <div class=`col-md-4`>
                                    <select class=`form-control` wire:model=`stock_status`>
                                        <option value=`instock`>InStock</option>
                                        <option value=`outofstock`>Out of Stock</option>
                                    </select>
                                    @error('stock_status')  <p class=`text-danger`>{{$message}}</p> @enderror  
                                </div>
                            </div>
                            <div class=`form-group`>
                                <label class=`col-md-4 control-label`>Featured</label>
                                <div class=`col-md-4`>
                                    <select class=`form-control` wire:model=`featured`>
                                        <option value=`0`>No</option>
                                        <option value=`1`>Yes</option>
                                    </select>
                                </div>
                            </div>
                            <div class=`form-group`>
                                <label class=`col-md-4 control-label`>Quantity</label>
                                <div class=`col-md-4`>
                                    <input type=`text` placeholder=`Quantity` class=`form-control input-md` wire:model=`quantity`/>
                                    @error('quantity')  <p class=`text-danger`>{{$message}}</p> @enderror  
                                </div>
                            </div>
                            <div class=`form-group`>
                                <label class=`col-md-4 control-label`>Product Image</label>
                                <div class=`col-md-4`>
                                    <input type=`file` class=`input-file` wire:model=`image` />
                                    @if($image)
                                        <img src=`{{$image->temporaryUrl()}}` width=`120` />
                                    @endif  
                                    @error('image')  <p class=`text-danger`>{{$message}}</p> @enderror                                    
                                </div>
                            </div>      
                            
                            <div class=`form-group`>
                                <label class=`col-md-4 control-label`>Product Gallery</label>
                                <div class=`col-md-4`>
                                    <input type=`file` class=`input-file` wire:model=`images` multiple />
                                    @if($images)
                                        @foreach($images as $image)
                                            <img src=`{{$image->temporaryUrl()}}` width=`120` />
                                        @endforeach
                                    @endif  
                                    @error('images')  <p class=`text-danger`>{{$message}}</p> @enderror                                    
                                </div>
                            </div>    
                            
                            
                            <div class=`form-group`>
                                <label class=`col-md-4 control-label`>Category</label>
                                <div class=`col-md-4`>
                                    <select class=`form-control` wire:model=`category_id`>
                                        <option value=``>Select Category</option>
                                        @foreach ($categories as $category)
                                            <option value=`{{$category->id}}`>{{$category->name}}</option>
                                        @endforeach                                        
                                    </select>
                                    @error('category_id')  <p class=`text-danger`>{{$message}}</p> @enderror  
                                </div>
                            </div>
                            <div class=`form-group`>
                                <label class=`col-md-4 control-label`></label>
                                <div class=`col-md-4`>
                                    <button type=`submit` class=`btn btn-primary`>Submit</button>                                    
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
@push('scripts')
    <script>
        $(function(){
            tinymce.init({
                selector:'#short_description',
                setup:function(editor){
                    editor.on('Change',function(e){
                        tinyMCE.triggerSave();
                        var sd_data = $('#short_description').val();
                        @this.set('short_description',sd_data);
                    });
                }
            });
            tinymce.init({
                selector:'#description',
                setup:function(editor){
                    editor.on('Change',function(e){
                        tinyMCE.triggerSave();
                        var d_data = $('#description').val();
                        @this.set('description',d_data);
                    });
                }
            });
        });
    </script>
@endpush

To configure the image directory, go to the config directory and open the filesystem.php file. Inside the disk array, set the root path as follows:


 'disks' => [
        'local' => [
            'driver' => 'local',
            //'root' => storage_path('app'),            
            'root' => public_path('assets/images'),
        ],

Finally, open the Admin ProductComponent view file and add the `Add Product` link to the header:


<div class=`panel-heading`>
	<div class=`row`>
		<div class=`col-md-6`>
			All Products
		</div>
		<div class=`col-md-6`>
			<a href=`{{route('admin.addproduct')}}` class=`btn btn-success pull-right`>Add New</a>
		</div>
	</div>
</div>

Now, everything is set up. Let's check it. Switch to the browser and refresh the page.

You can see the `Add Product` link. Click on it, and you will see the form. Enter the product details, select the product image, and click on submit.

You will see a success message indicating that the product has been added successfully. Go to the `All Products` page, and you will see the newly added product. You can also check the product on the shop page.

So, in this way, you can add a new product. That's all about adding a new product.

Written by Surfside Media

Senior Full Stack Developer specializing in Web Technologies.