Laravel 8 E-Commerce - Admin Add New Product
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 App\Http\Livewire\Admin;
use App\Models\Category;
use App\Models\Product;
use Carbon\Carbon;
use Livewire\Component;
use Illuminate\Support\Str;
use Livewire\WithFileUploads;
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.