Added: Livewire, Barcode Printing & Laravel Snappy

This commit is contained in:
Fahim Anzam Dip 2021-07-21 01:06:47 +06:00
parent 1cec992366
commit eff33fd386
18 changed files with 603 additions and 72 deletions

View File

@ -0,0 +1,17 @@
<?php
namespace Modules\Product\Http\Controllers;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Gate;
class BarcodeController extends Controller
{
public function printBarcode() {
abort_if(Gate::denies('print_barcodes'), 403);
return view('product::barcode.index');
}
}

View File

@ -0,0 +1,30 @@
@extends('layouts.app')
@section('title', 'Print Barcode')
@push('page_css')
@livewireStyles
@endpush
@section('breadcrumb')
<ol class="breadcrumb border-0 m-0">
<li class="breadcrumb-item"><a href="{{ route('home') }}">Home</a></li>
<li class="breadcrumb-item active">Print Barcode</li>
</ol>
@endsection
@section('content')
<div class="container-fluid">
<div class="row">
<div class="col-12">
<livewire:barcode.search-product/>
</div>
</div>
<div class="row mt-4">
<div class="col-md-12">
<livewire:barcode.product-table/>
</div>
</div>
</div>
@endsection

View File

@ -3,8 +3,7 @@
@section('title', 'Create Product')
@section('third_party_stylesheets')
<link href="https://unpkg.com/filepond/dist/filepond.css" rel="stylesheet" />
<link href="https://unpkg.com/filepond-plugin-image-preview/dist/filepond-plugin-image-preview.css" rel="stylesheet">
@include('includes.filepond-css')
@endsection
@section('breadcrumb')
@ -75,13 +74,13 @@
<div class="col-md-6">
<div class="form-group">
<label for="product_cost">Cost <span class="text-danger">*</span></label>
<input type="number" class="form-control" name="product_cost" required value="{{ old('product_cost') }}">
<input type="number" class="form-control" min="0" name="product_cost" required value="{{ old('product_cost') }}">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="product_price">Price <span class="text-danger">*</span></label>
<input type="number" class="form-control" name="product_price" required value="{{ old('product_price') }}">
<input type="number" class="form-control" min="0" name="product_price" required value="{{ old('product_price') }}">
</div>
</div>
</div>
@ -128,7 +127,7 @@
<div class="card-body">
<div class="form-group">
<label for="image">Product Image <span class="text-danger">*</span></label>
<input id="image" type="file" name="image" required data-max-file-size="500KB">
<input id="image" type="file" name="image" data-max-file-size="500KB">
</div>
</div>
</div>
@ -138,32 +137,7 @@
</div>
@endsection
@section('third_party_scripts')
<script src="https://unpkg.com/filepond-plugin-image-preview/dist/filepond-plugin-image-preview.js"></script>
<script src="https://unpkg.com/filepond-plugin-file-validate-size/dist/filepond-plugin-file-validate-size.js"></script>
<script src="https://unpkg.com/filepond-plugin-file-validate-type/dist/filepond-plugin-file-validate-type.js"></script>
<script src="https://unpkg.com/filepond/dist/filepond.js"></script>
@endsection
@push('page_scripts')
<script>
FilePond.registerPlugin(
FilePondPluginImagePreview,
FilePondPluginFileValidateSize,
FilePondPluginFileValidateType
);
const fileElement = document.querySelector('input[id="image"]');
const pond = FilePond.create( fileElement, {
acceptedFileTypes: ['image/png', 'image/jpg', 'image/jpeg'],
} );
FilePond.setOptions({
server: {
url: "{{ route('filepond.upload') }}",
headers: {
"X-CSRF-TOKEN": "{{ csrf_token() }}"
}
}
});
</script>
@include('includes.filepond-js')
@endpush

View File

@ -3,8 +3,7 @@
@section('title', 'Edit Product')
@section('third_party_stylesheets')
<link href="https://unpkg.com/filepond/dist/filepond.css" rel="stylesheet" />
<link href="https://unpkg.com/filepond-plugin-image-preview/dist/filepond-plugin-image-preview.css" rel="stylesheet">
@include('includes.filepond-css')
@endsection
@section('breadcrumb')
@ -75,13 +74,13 @@
<div class="col-md-6">
<div class="form-group">
<label for="product_cost">Cost <span class="text-danger">*</span></label>
<input type="number" class="form-control" name="product_cost" required value="{{ $product->product_cost }}">
<input type="number" class="form-control" min="0" name="product_cost" required value="{{ $product->product_cost }}">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="product_price">Price <span class="text-danger">*</span></label>
<input type="number" class="form-control" name="product_price" required value="{{ $product->product_price }}">
<input type="number" class="form-control" min="0" name="product_price" required value="{{ $product->product_price }}">
</div>
</div>
</div>
@ -139,32 +138,7 @@
</div>
@endsection
@section('third_party_scripts')
<script src="https://unpkg.com/filepond-plugin-image-preview/dist/filepond-plugin-image-preview.js"></script>
<script src="https://unpkg.com/filepond-plugin-file-validate-size/dist/filepond-plugin-file-validate-size.js"></script>
<script src="https://unpkg.com/filepond-plugin-file-validate-type/dist/filepond-plugin-file-validate-type.js"></script>
<script src="https://unpkg.com/filepond/dist/filepond.js"></script>
@endsection
@push('page_scripts')
<script>
FilePond.registerPlugin(
FilePondPluginImagePreview,
FilePondPluginFileValidateSize,
FilePondPluginFileValidateType
);
const fileElement = document.querySelector('input[id="image"]');
const pond = FilePond.create( fileElement, {
acceptedFileTypes: ['image/png', 'image/jpg', 'image/jpeg'],
} );
FilePond.setOptions({
server: {
url: "{{ route('filepond.upload') }}",
headers: {
"X-CSRF-TOKEN": "{{ csrf_token() }}"
}
}
});
</script>
@include('includes.filepond-js')
@endpush

View File

@ -12,16 +12,25 @@
@section('content')
<div class="container-fluid mb-4">
<div class="row mb-3">
<div class="col-md-12">
{!! \Milon\Barcode\Facades\DNS1DFacade::getBarCodeSVG($product->product_code, $product->product_barcode_symbology, 2, 110) !!}
</div>
</div>
<div class="row">
<div class="col-lg-7">
<div class="card h-100">
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered table-hover">
<table class="table table-bordered table-striped mb-0">
<tr>
<th>Product Code</th>
<td>{{ $product->product_code }}</td>
</tr>
<tr>
<th>Barcode Symbology</th>
<td>{{ $product->product_barcode_symbology }}</td>
</tr>
<tr>
<th>Name</th>
<td>{{ $product->product_name }}</td>

View File

@ -7,6 +7,8 @@
*/
Route::group(['middleware' => 'auth'], function () {
//Print Barcode
Route::get('/products/print-barcode', 'BarcodeController@printBarcode')->name('barcode.print');
//Product
Route::resource('products', 'ProductController');
//Product Category

View File

@ -13,10 +13,6 @@ class UploadController extends Controller
{
public function filepondUpload(Request $request) {
if (!$request->ajax()) {
return back();
}
$request->validate([
'image' => 'required|image|mimes:png,jpeg,jpg'
]);
@ -42,10 +38,6 @@ class UploadController extends Controller
}
public function filepondDelete(Request $request) {
if (!$request->ajax()) {
return back();
}
$upload = Upload::where('folder', $request->getContent())->first();
Storage::deleteDirectory('public/temp/' . $upload->folder);

View File

@ -0,0 +1,45 @@
<?php
namespace App\Http\Livewire\Barcode;
use Livewire\Component;
use Milon\Barcode\Facades\DNS1DFacade;
use Modules\Product\Entities\Product;
class ProductTable extends Component
{
public $product;
public $quantity;
public $barcodes;
protected $listeners = ['productSelected'];
public function mount() {
$this->product = '';
$this->quantity = 0;
$this->barcodes = [];
}
public function render() {
return view('livewire.barcode.product-table');
}
public function productSelected(Product $product) {
$this->product = $product;
$this->quantity = 1;
$this->barcodes = [];
}
public function generateBarcodes(Product $product, $quantity) {
$this->barcodes = [];
for ($i = 1; $i <= $quantity; $i++) {
$barcode = DNS1DFacade::getBarCodeSVG($product->product_code, $product->product_barcode_symbology,2 , 60);
array_push($this->barcodes, $barcode);
}
}
public function updatedQuantity() {
$this->barcodes = [];
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace App\Http\Livewire\Barcode;
use Illuminate\Support\Collection;
use Livewire\Component;
use Modules\Product\Entities\Product;
class SearchProduct extends Component
{
public $query;
public $searchResults;
public function mount() {
$this->query = '';
$this->searchResults = Collection::empty();
}
public function render() {
return view('livewire.barcode.search-product');
}
public function updatedQuery() {
$this->searchResults = Product::where('product_name', 'like', '%' . $this->query . '%')
->orWhere('product_code', 'like', '%' . $this->query . '%')
->get();
}
public function resetQuery() {
$this->query = '';
$this->searchResults = Collection::empty();
}
public function selectProduct($product) {
$this->emit('productSelected', $product);
}
}

View File

@ -6,12 +6,15 @@
"license": "MIT",
"require": {
"php": "^7.3|^8.0",
"barryvdh/laravel-snappy": "^0.4.8",
"fideloper/proxy": "^4.4",
"fruitcake/laravel-cors": "^2.0",
"guzzlehttp/guzzle": "^7.0.1",
"infyomlabs/laravel-ui-coreui": "^3.0",
"laravel/framework": "^8.40",
"laravel/tinker": "^2.5",
"livewire/livewire": "^2.5",
"milon/barcode": "^8.0",
"nwidart/laravel-modules": "^8.2",
"realrashid/sweet-alert": "^4.0",
"spatie/laravel-medialibrary": "^9.0.0",

283
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "0529f25855530902932a9ae4f2f8d0ba",
"content-hash": "53badb2a324d9caf89ceed410177f49b",
"packages": [
{
"name": "asm89/stack-cors",
@ -62,6 +62,71 @@
},
"time": "2021-03-11T06:42:03+00:00"
},
{
"name": "barryvdh/laravel-snappy",
"version": "v0.4.8",
"source": {
"type": "git",
"url": "https://github.com/barryvdh/laravel-snappy.git",
"reference": "1903ab84171072b6bff8d98eb58d38b2c9aaf645"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-snappy/zipball/1903ab84171072b6bff8d98eb58d38b2c9aaf645",
"reference": "1903ab84171072b6bff8d98eb58d38b2c9aaf645",
"shasum": ""
},
"require": {
"illuminate/filesystem": "^5.5|^6|^7|^8",
"illuminate/support": "^5.5|^6|^7|^8",
"knplabs/knp-snappy": "^1",
"php": ">=7"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.4-dev"
},
"laravel": {
"providers": [
"Barryvdh\\Snappy\\ServiceProvider"
],
"aliases": {
"PDF": "Barryvdh\\Snappy\\Facades\\SnappyPdf",
"SnappyImage": "Barryvdh\\Snappy\\Facades\\SnappyImage"
}
}
},
"autoload": {
"psr-4": {
"Barryvdh\\Snappy\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Barry vd. Heuvel",
"email": "barryvdh@gmail.com"
}
],
"description": "Snappy PDF/Image for Laravel",
"keywords": [
"image",
"laravel",
"pdf",
"snappy",
"wkhtmltoimage",
"wkhtmltopdf"
],
"support": {
"issues": "https://github.com/barryvdh/laravel-snappy/issues",
"source": "https://github.com/barryvdh/laravel-snappy/tree/master"
},
"time": "2020-09-07T12:33:10+00:00"
},
{
"name": "brick/math",
"version": "0.9.2",
@ -1095,6 +1160,76 @@
],
"time": "2021-07-06T13:35:54+00:00"
},
{
"name": "knplabs/knp-snappy",
"version": "v1.2.1",
"source": {
"type": "git",
"url": "https://github.com/KnpLabs/snappy.git",
"reference": "7bac60fb729147b7ccd8532c07df3f52a4afa8a4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/KnpLabs/snappy/zipball/7bac60fb729147b7ccd8532c07df3f52a4afa8a4",
"reference": "7bac60fb729147b7ccd8532c07df3f52a4afa8a4",
"shasum": ""
},
"require": {
"php": ">=7.1",
"psr/log": "^1.0",
"symfony/process": "~3.4||~4.3||~5.0"
},
"require-dev": {
"phpunit/phpunit": "~7.4"
},
"suggest": {
"h4cc/wkhtmltoimage-amd64": "Provides wkhtmltoimage-amd64 binary for Linux-compatible machines, use version `~0.12` as dependency",
"h4cc/wkhtmltoimage-i386": "Provides wkhtmltoimage-i386 binary for Linux-compatible machines, use version `~0.12` as dependency",
"h4cc/wkhtmltopdf-amd64": "Provides wkhtmltopdf-amd64 binary for Linux-compatible machines, use version `~0.12` as dependency",
"h4cc/wkhtmltopdf-i386": "Provides wkhtmltopdf-i386 binary for Linux-compatible machines, use version `~0.12` as dependency",
"wemersonjanuario/wkhtmltopdf-windows": "Provides wkhtmltopdf executable for Windows, use version `~0.12` as dependency"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"Knp\\Snappy\\": "src/Knp/Snappy"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "KnpLabs Team",
"homepage": "http://knplabs.com"
},
{
"name": "Symfony Community",
"homepage": "http://github.com/KnpLabs/snappy/contributors"
}
],
"description": "PHP5 library allowing thumbnail, snapshot or PDF generation from a url or a html page. Wrapper for wkhtmltopdf/wkhtmltoimage.",
"homepage": "http://github.com/KnpLabs/snappy",
"keywords": [
"knp",
"knplabs",
"pdf",
"snapshot",
"thumbnail",
"wkhtmltopdf"
],
"support": {
"issues": "https://github.com/KnpLabs/snappy/issues",
"source": "https://github.com/KnpLabs/snappy/tree/master"
},
"time": "2020-01-20T08:30:30+00:00"
},
{
"name": "laravel/framework",
"version": "v8.50.0",
@ -1845,6 +1980,78 @@
],
"time": "2021-01-18T20:58:21+00:00"
},
{
"name": "livewire/livewire",
"version": "v2.5.5",
"source": {
"type": "git",
"url": "https://github.com/livewire/livewire.git",
"reference": "de192292d68276d831e5fd9824c80c3b78a21ddf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/livewire/livewire/zipball/de192292d68276d831e5fd9824c80c3b78a21ddf",
"reference": "de192292d68276d831e5fd9824c80c3b78a21ddf",
"shasum": ""
},
"require": {
"illuminate/database": "^7.0|^8.0",
"illuminate/support": "^7.0|^8.0",
"illuminate/validation": "^7.0|^8.0",
"php": "^7.2.5|^8.0",
"symfony/http-kernel": "^5.0"
},
"require-dev": {
"calebporzio/sushi": "^2.1",
"laravel/framework": "^7.0|^8.0",
"mockery/mockery": "^1.3.1",
"orchestra/testbench": "^5.0|^6.0",
"orchestra/testbench-dusk": "^5.2|^6.0",
"phpunit/phpunit": "^8.4|^9.0",
"psy/psysh": "@stable"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Livewire\\LivewireServiceProvider"
],
"aliases": {
"Livewire": "Livewire\\Livewire"
}
}
},
"autoload": {
"files": [
"src/helpers.php"
],
"psr-4": {
"Livewire\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Caleb Porzio",
"email": "calebporzio@gmail.com"
}
],
"description": "A front-end framework for Laravel.",
"support": {
"issues": "https://github.com/livewire/livewire/issues",
"source": "https://github.com/livewire/livewire/tree/v2.5.5"
},
"funding": [
{
"url": "https://github.com/calebporzio",
"type": "github"
}
],
"time": "2021-07-13T05:03:28+00:00"
},
{
"name": "maatwebsite/excel",
"version": "3.1.32",
@ -2163,6 +2370,80 @@
},
"time": "2021-05-25T15:42:17+00:00"
},
{
"name": "milon/barcode",
"version": "8.0.1",
"source": {
"type": "git",
"url": "https://github.com/milon/barcode.git",
"reference": "a1b1ee1a743c1368597f1742e6ee4765333a15a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/milon/barcode/zipball/a1b1ee1a743c1368597f1742e6ee4765333a15a1",
"reference": "a1b1ee1a743c1368597f1742e6ee4765333a15a1",
"shasum": ""
},
"require": {
"illuminate/support": "^8.0",
"php": "^7.3 | ^8.0"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Milon\\Barcode\\BarcodeServiceProvider"
],
"aliases": {
"DNS1D": "Milon\\Barcode\\Facades\\DNS1DFacade",
"DNS2D": "Milon\\Barcode\\Facades\\DNS2DFacade"
}
}
},
"autoload": {
"psr-0": {
"Milon\\Barcode": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0"
],
"authors": [
{
"name": "Nuruzzaman Milon",
"email": "contact@milon.im"
}
],
"description": "Barcode generator like Qr Code, PDF417, C39, C39+, C39E, C39E+, C93, S25, S25+, I25, I25+, C128, C128A, C128B, C128C, 2-Digits UPC-Based Extention, 5-Digits UPC-Based Extention, EAN 8, EAN 13, UPC-A, UPC-E, MSI (Variation of Plessey code)",
"keywords": [
"CODABAR",
"CODE 128",
"CODE 39",
"barcode",
"datamatrix",
"ean",
"laravel",
"pdf417",
"qr code",
"qrcode"
],
"support": {
"issues": "https://github.com/milon/barcode/issues",
"source": "https://github.com/milon/barcode/tree/8.0.1"
},
"funding": [
{
"url": "https://paypal.me/tomilon",
"type": "custom"
},
{
"url": "https://github.com/milon",
"type": "github"
}
],
"time": "2021-01-08T11:36:07+00:00"
},
{
"name": "monolog/monolog",
"version": "2.3.0",

View File

@ -167,6 +167,8 @@ return [
*/
RealRashid\SweetAlert\SweetAlertServiceProvider::class,
Spatie\Permission\PermissionServiceProvider::class,
Milon\Barcode\BarcodeServiceProvider::class,
Barryvdh\Snappy\ServiceProvider::class,
/*
* Application Service Providers...
*/
@ -230,6 +232,10 @@ return [
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
'Alert' => RealRashid\SweetAlert\Facades\Alert::class,
'DNS1D' => Milon\Barcode\Facades\DNS1DFacade::class,
'DNS2D' => Milon\Barcode\Facades\DNS2DFacade::class,
'PDF' => Barryvdh\Snappy\Facades\SnappyPdf::class,
'SnappyImage' => Barryvdh\Snappy\Facades\SnappyImage::class,
],
];

52
config/snappy.php Normal file
View File

@ -0,0 +1,52 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Snappy PDF / Image Configuration
|--------------------------------------------------------------------------
|
| This option contains settings for PDF generation.
|
| Enabled:
|
| Whether to load PDF / Image generation.
|
| Binary:
|
| The file path of the wkhtmltopdf / wkhtmltoimage executable.
|
| Timout:
|
| The amount of time to wait (in seconds) before PDF / Image generation is stopped.
| Setting this to false disables the timeout (unlimited processing time).
|
| Options:
|
| The wkhtmltopdf command options. These are passed directly to wkhtmltopdf.
| See https://wkhtmltopdf.org/usage/wkhtmltopdf.txt for all options.
|
| Env:
|
| The environment variables to set while running the wkhtmltopdf process.
|
*/
'pdf' => [
'enabled' => true,
'binary' => env('WKHTML_PDF_BINARY', '"C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe"'),
'timeout' => false,
'options' => [],
'env' => [],
],
'image' => [
'enabled' => true,
'binary' => env('WKHTML_IMG_BINARY', '"C:\Program Files\wkhtmltopdf\bin\wkhtmltoimage.exe"'),
'timeout' => false,
'options' => [],
'env' => [],
],
];

View File

@ -19,7 +19,8 @@ class SuperUserSeeder extends Seeder
$user = User::create([
'name' => 'Administrator',
'email' => 'admin@gmail.com',
'password' => Hash::make(12345678)
'password' => Hash::make(12345678),
'is_active' => 1
]);
$superAdmin = Role::create([

View File

@ -14,6 +14,7 @@
@stack('page_css')
@livewireStyles
<style>
div.dataTables_wrapper div.dataTables_length select {
width: 65px;
@ -51,5 +52,7 @@
@yield('third_party_scripts')
@stack('page_scripts')
@livewireScripts
</body>
</html>

View File

@ -29,6 +29,13 @@
<i class="c-sidebar-nav-icon bi bi-journals" style="line-height: 1;"></i> All Products
</a>
</li>
@can('print_barcodes')
<li class="c-sidebar-nav-item">
<a class="c-sidebar-nav-link {{ request()->routeIs('barcode.print') ? 'c-active' : '' }}" href="{{ route('barcode.print') }}">
<i class="c-sidebar-nav-icon bi bi-printer" style="line-height: 1;"></i> Print Barcode
</a>
</li>
@endcan
</ul>
</li>
@endcan

View File

@ -0,0 +1,48 @@
<div>
<div class="card">
<div class="card-body">
<div class="table-responsive-md">
<table class="table table-bordered mb-0">
<thead>
<tr class="align-middle">
<th class="align-middle">Product Name</th>
<th class="align-middle">Code</th>
<th class="align-middle">Quantity</th>
</tr>
</thead>
<tbody>
<tr>
@if(!empty($product))
<td class="align-middle">{{ $product->product_name }}</td>
<td class="align-middle">{{ $product->product_code }}</td>
<td class="align-middle text-center" style="width: 200px;">
<input wire:model="quantity" class="form-control" type="number" min="1" value="{{ $quantity }}">
</td>
@else
<td colspan="3" class="text-center">
<span class="text-danger">Please search & select a product!</span>
</td>
@endif
</tr>
</tbody>
</table>
</div>
<div class="mt-3">
<button {{ empty($product) ? 'disabled' : '' }} wire:click="generateBarcodes({{ $product }}, {{ $quantity }})" type="button" class="btn btn-primary"><i class="bi bi-upc-scan"></i> Generate Barcodes
</button>
</div>
</div>
</div>
@if(!empty($barcodes))
<div class="card">
<div class="card-body d-flex flex-wrap justify-content-center align-items-center pt-5">
@foreach($barcodes as $barcode)
<div class="mr-5 mb-5">
{!! $barcode !!}
</div>
@endforeach
</div>
</div>
@endif
</div>

View File

@ -0,0 +1,49 @@
<div class="position-relative">
<div class="card mb-0">
<div class="card-body">
<div class="form-group mb-0">
<div class="input-group">
<div class="input-group-prepend">
<div class="input-group-text">
<i class="bi bi-search"></i>
</div>
</div>
<input wire:keydown.escape="resetQuery" wire:model.debounce.500ms="query" type="text" class="form-control" placeholder="Type product name or code...." wire:key.="">
</div>
</div>
</div>
</div>
<div wire:loading class="card position-absolute mt-1" style="z-index: 1;left: 0;right: 0;">
<div class="card-body">
<strong class="text-primary">Searching.......</strong>
</div>
</div>
@if(!empty($query))
<div wire:click="resetQuery" class="position-fixed w-100 h-100" style="left: 0; top: 0; right: 0; bottom: 0;z-index: 1;"></div>
@if($searchResults->isNotEmpty())
<div class="card position-absolute mt-1" style="z-index: 2;left: 0;right: 0;">
<div class="card-body">
<ul class="list-group list-group-flush">
@foreach($searchResults as $result)
<li class="list-group-item list-group-item-action">
<a wire:click="resetQuery" wire:click.prevent="selectProduct({{$result}})" href="#">
{{ $result->product_name }} | {{ $result->product_code }}
</a>
</li>
@endforeach
</ul>
</div>
</div>
@else
<div class="card position-absolute mt-1" style="z-index: 1;left: 0;right: 0;">
<div class="card-body">
<div class="alert alert-warning mb-0">
No Results....
</div>
</div>
</div>
@endif
@endif
</div>