Resolved conflicts

This commit is contained in:
Jitendra Singh 2020-03-03 15:59:47 +05:30
commit 45ec4532fa
51 changed files with 1518 additions and 473 deletions

View File

@ -565,6 +565,7 @@ return [
'file' => 'File',
'checkbox' => 'Checkbox',
'use_in_flat' => "Create in Product Flat Table",
'is_comparable' => "Attribute is comparable",
'default_null_option' => 'Create default empty option',
],
'families' => [

View File

@ -278,6 +278,18 @@
</select>
</div>
<div class="control-group">
<label for="is_comparable">{{ __('admin::app.catalog.attributes.is_comparable') }}</label>
<select class="control" id="is_comparable" name="is_comparable">
<option value="0" {{ $attribute->is_comparable ? '' : 'selected' }}>
{{ __('admin::app.catalog.attributes.no') }}
</option>
<option value="1" {{ $attribute->is_comparable ? 'selected' : '' }}>
{{ __('admin::app.catalog.attributes.yes') }}
</option>
</select>
</div>
{!! view_render_event('bagisto.admin.catalog.attribute.edit_form_accordian.configuration.controls.after', ['attribute' => $attribute]) !!}
</div>

View File

@ -344,14 +344,11 @@
</tr>
@endif
@php ($taxRates = Webkul\Tax\Helpers\Tax::getTaxRatesWithAmount($order, true))
@foreach ($taxRates as $taxRate => $baseTaxAmount)
<tr {{ $loop->last ? 'class=border' : ''}}>
<td id="taxrate-{{ core()->taxRateAsIdentifier($taxRate) }}">{{ __('admin::app.sales.orders.tax') }} {{ $taxRate }} %</td>
<tr class="border">
<td>{{ __('admin::app.sales.orders.tax') }}</td>
<td>-</td>
<td id="basetaxamount-{{ core()->taxRateAsIdentifier($taxRate) }}">{{ core()->formatBasePrice($baseTaxAmount) }}</td>
<td>{{ core()->formatBasePrice($order->base_tax_amount) }}</td>
</tr>
@endforeach
<tr class="bold">
<td>{{ __('admin::app.sales.orders.grand-total') }}</td>
@ -437,9 +434,8 @@
<tr>
<th>{{ __('admin::app.sales.shipments.id') }}</th>
<th>{{ __('admin::app.sales.shipments.date') }}</th>
<th>{{ __('admin::app.sales.shipments.order-id') }}</th>
<th>{{ __('admin::app.sales.shipments.order-date') }}</th>
<th>{{ __('admin::app.sales.shipments.customer-name') }}</th>
<th>{{ __('admin::app.sales.shipments.carrier-title') }}</th>
<th>{{ __('admin::app.sales.shipments.tracking-number') }}</th>
<th>{{ __('admin::app.sales.shipments.total-qty') }}</th>
<th>{{ __('admin::app.sales.shipments.action') }}</th>
</tr>
@ -451,9 +447,8 @@
<tr>
<td>#{{ $shipment->id }}</td>
<td>{{ $shipment->created_at }}</td>
<td>#{{ $shipment->order->id }}</td>
<td>{{ $shipment->order->created_at }}</td>
<td>{{ $shipment->address->name }}</td>
<td>{{ $shipment->carrier_title }}</td>
<td>{{ $shipment->track_number }}</td>
<td>{{ $shipment->total_qty }}</td>
<td class="action">
<a href="{{ route('admin.sales.shipments.view', $shipment->id) }}">

View File

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddIsComparableColumnInAttributesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('attributes', function (Blueprint $table) {
$table->boolean('is_comparable')->default(0);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('attributes', function (Blueprint $table) {
$table->dropColumn('is_comparable');
});
}
}

View File

@ -36,6 +36,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '2',
'code' => 'name',
@ -54,6 +55,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '1',
], [
'id' => '3',
'code' => 'url_key',
@ -72,6 +74,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '4',
'code' => 'tax_category_id',
@ -90,6 +93,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '5',
'code' => 'new',
@ -108,10 +112,11 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '6',
'code' => 'featured',
'admin_name' => 'Featured',
'admin_name' => 'Featured',
'type' => 'boolean',
'validation' => NULL,
'position' => '6',
@ -126,6 +131,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '7',
'code' => 'visible_individually',
@ -144,6 +150,7 @@ class AttributeTableSeeder extends Seeder
'created_at' => $now,
'use_in_flat' => '1',
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '8',
'code' => 'status',
@ -162,6 +169,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '9',
'code' => 'short_description',
@ -180,6 +188,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '10',
'code' => 'description',
@ -198,6 +207,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '1',
], [
'id' => '11',
'code' => 'price',
@ -216,6 +226,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '1',
], [
'id' => '12',
'code' => 'cost',
@ -234,6 +245,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '13',
'code' => 'special_price',
@ -252,6 +264,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '14',
'code' => 'special_price_from',
@ -270,6 +283,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '15',
'code' => 'special_price_to',
@ -288,6 +302,7 @@ class AttributeTableSeeder extends Seeder
'is_visible_on_front' => '0',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '16',
'code' => 'meta_title',
@ -306,6 +321,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '17',
'code' => 'meta_keywords',
@ -324,6 +340,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '18',
'code' => 'meta_description',
@ -342,6 +359,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '19',
'code' => 'width',
@ -360,6 +378,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '20',
'code' => 'height',
@ -378,6 +397,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '21',
'code' => 'depth',
@ -396,6 +416,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '22',
'code' => 'weight',
@ -414,6 +435,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '23',
'code' => 'color',
@ -432,6 +454,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '24',
'code' => 'size',
@ -450,6 +473,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '25',
'code' => 'brand',
@ -468,6 +492,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
], [
'id' => '26',
'code' => 'guest_checkout',
@ -486,6 +511,7 @@ class AttributeTableSeeder extends Seeder
'use_in_flat' => '1',
'created_at' => $now,
'updated_at' => $now,
'is_comparable' => '0',
]
]);

View File

@ -25,6 +25,7 @@ class Attribute extends TranslatableModel implements AttributeContract
'is_user_defined',
'swatch_type',
'use_in_flat',
'is_comparable',
];
// protected $with = ['options'];

View File

@ -0,0 +1,3 @@
<script>
window.location.href = window.location.href.replace('/comparison', '');
</script>

View File

@ -7,4 +7,6 @@
</form>
@include('shop::products.wishlist')
@include('shop::products.compare')
</div>

View File

@ -0,0 +1,11 @@
{{-- @inject ('wishListHelper', 'Webkul\Customer\Helpers\Wishlist')
@auth('customer')
{!! view_render_event('bagisto.shop.products.wishlist.before') !!}
<a @if ($wishListHelper->getWishlistProduct($product)) class="add-to-wishlist already" @else class="add-to-wishlist" @endif href="{{ route('customer.wishlist.add', $product->product_id) }}" id="wishlist-changer">
<span class="icon wishlist-icon"></span>
</a>
{!! view_render_event('bagisto.shop.products.wishlist.after') !!}
@endauth --}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
{
"/js/velocity.js": "/js/velocity.js?id=5d429b3399bd1ffaefbc",
"/js/velocity.js": "/js/velocity.js?id=edb24f7ab80594df62df",
"/css/velocity-admin.css": "/css/velocity-admin.css?id=612d35e452446366eef7",
"/css/velocity.css": "/css/velocity.css?id=249c3b3462d6a9013c20"
"/css/velocity.css": "/css/velocity.css?id=0c3bbabfcb61f4640459"
}

View File

@ -0,0 +1,43 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCustomerCompareProductsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('velocity_customer_compare_products', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('product_flat_id');
$table->foreign('product_flat_id')
->references('id')
->on('product_flat')
->onUpdate('cascade')
->onDelete('cascade');
$table->unsignedInteger('customer_id');
$table->foreign('customer_id')
->references('id')
->on('customers')
->onUpdate('cascade')
->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('velocity_customer_compare_products');
}
}

View File

@ -143,9 +143,9 @@ class Helper extends Review
/**
* Returns the count rating of the product
*
* @param Product $product
* @param Product $product
* @return array
*/
*/
public function getCountRating($product)
{
$reviews = $product->reviews()
@ -227,5 +227,37 @@ class Helper extends Review
'baseTotal' => core()->currency($item->base_total),
];
}
public function formatProduct($product, $list = false)
{
$reviewHelper = app('Webkul\Product\Helpers\Review');
$productImageHelper = app('Webkul\Product\Helpers\ProductImage');
$totalReviews = $reviewHelper->getTotalReviews($product);
$avgRatings = ceil($reviewHelper->getAverageRating($product));
$galleryImages = $productImageHelper->getGalleryImages($product);
$productImage = $productImageHelper->getProductBaseImage($product)['medium_image_url'];
return [
'avgRating' => $avgRatings,
'totalReviews' => $totalReviews,
'image' => $productImage,
'galleryImages' => $galleryImages,
'name' => $product->name,
'slug' => $product->url_key,
'description' => $product->description,
'shortDescription' => $product->short_description,
'firstReviewText' => trans('velocity::app.products.be-first-review'),
'priceHTML' => view('shop::products.price', ['product' => $product])->render(),
'addToCartHtml' => view('shop::products.add-to-cart', [
'product' => $product,
'showCompare' => true,
'addWishlistClass' => !(isset($list) && $list) ? '' : '',
'addToCartBtnClass' => !(isset($list) && $list) ? 'small-padding' : '',
])->render(),
];
}
}

View File

@ -0,0 +1,169 @@
<?php
namespace Webkul\Velocity\Http\Controllers\Shop;
use Cart;
use Webkul\Velocity\Helpers\Helper;
use Webkul\Checkout\Contracts\Cart as CartModel;
use Webkul\Product\Repositories\ProductRepository;
/**
* Cart controller
*
* @author Shubham Mehrotra <shubhammehrotra.symfony@webkul.com> @shubhwebkul
* @copyright 2020 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class CartController extends Controller
{
/**
* Webkul\Velocity\Helpers\Helper object
*
* @var Helper
*/
protected $velocityHelper;
/**
* Webkul\Product\Repositories\ProductRepository object
*
* @var ProductRepository
*/
protected $productRepository;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct(
Helper $velocityHelper,
ProductRepository $productRepository
) {
$this->_config = request('_config');
$this->velocityHelper = $velocityHelper;
$this->productRepository = $productRepository;
}
/**
* Retrives the mini cart details
*
* @return Response
*/
public function getMiniCartDetails()
{
$cart = cart()->getCart();
if ($cart) {
$items = $cart->items;
$cartItems = $items->toArray();
$cartDetails = [];
$cartDetails['base_sub_total'] = core()->currency($cart->base_sub_total);
foreach ($items as $index => $item) {
$images = $item->product->getTypeInstance()->getBaseImage($item);
$cartItems[$index]['images'] = $images;
$cartItems[$index]['url_key'] = $item->product->url_key;
$cartItems[$index]['base_total'] = core()->currency($item->base_total);
}
$response = [
'status' => true,
'mini_cart' => [
'cart_items' => $cartItems,
'cart_details' => $cartDetails,
],
];
} else {
$response = [
'status' => false,
];
}
return response()->json($response, 200);
}
/**
* Function for guests user to add the product in the cart.
*
* @return Mixed
*/
public function addProductToCart()
{
try {
$cart = Cart::getCart();
$id = request()->get('product_id');
$cart = Cart::addProduct($id, request()->all());
if (is_array($cart) && isset($cart['warning'])) {
$response = [
'status' => 'warning',
'message' => $cart['warning'],
];
}
if ($cart instanceof CartModel) {
$items = $cart->items;
$formattedItems = [];
foreach ($items as $item) {
array_push($formattedItems, $this->velocityHelper->formatCartItem($item));
}
$response = [
'status' => 'success',
'totalCartItems' => sizeof($items),
'message' => trans('shop::app.checkout.cart.item.success'),
];
if ($customer = auth()->guard('customer')->user()) {
app('Webkul\Customer\Repositories\WishlistRepository')->deleteWhere(['product_id' => $id, 'customer_id' => $customer->id]);
}
if (request()->get('is_buy_now')) {
return redirect()->route('shop.checkout.onepage.index');
}
}
} catch(\Exception $exception) {
$product = $this->productRepository->find($id);
$response = [
'status' => 'danger',
'message' => trans($exception->getMessage()),
'redirectionRoute' => route('shop.productOrCategory.index', $product->url_key),
];
}
return $response ?? [
'status' => 'danger',
'message' => trans('velocity::app.error.something_went_wrong'),
];
}
/**
* Removes the item from the cart if it exists
*
* @param integer $itemId
* @return Response
*/
public function removeProductFromCart($itemId)
{
$result = Cart::removeItem($itemId);
if ($result) {
$response = [
'status' => 'success',
'label' => trans('velocity::app.shop.general.alert.success'),
'message' => trans('shop::app.checkout.cart.item.success-remove'),
];
}
return response()->json($response ?? [
'status' => 'danger',
'label' => trans('velocity::app.shop.general.alert.error'),
'message' => trans('velocity::app.error.something_went_wrong'),
], 200);
}
}

View File

@ -0,0 +1,185 @@
<?php
namespace Webkul\Velocity\Http\Controllers\Shop;
use Webkul\Velocity\Helpers\Helper;
use Webkul\Product\Repositories\ProductRepository;
use Webkul\Velocity\Repositories\VelocityCustomerCompareProductRepository;
/**
* Comparison controller
*
* @author Shubham Mehrotra <shubhammehrotra.symfony@webkul.com> @shubhwebkul
* @copyright 2020 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class ComparisonController extends Controller
{
/**
* Webkul\Velocity\Helpers\Helper object
*
* @var Helper
*/
protected $velocityHelper;
/**
* Webkul\Product\Repositories\ProductRepository object
*
* @var ProductRepository
*/
protected $productRepository;
/**
* Webkul\Velocity\Repositories\VelocityCustomerCompareProductRepository object of repository
*
* @var VelocityCustomerCompareProductRepository
*/
protected $velocityCompareProductsRepository;
/**
* Create a new controller instance.
*
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
* @param \Webkul\Velocity\Repositories\VelocityCustomerCompareProductRepository $velocityCompareProductsRepository
*
* @return void
*/
public function __construct(
Helper $velocityHelper,
ProductRepository $productRepository,
VelocityCustomerCompareProductRepository $velocityCompareProductsRepository
) {
$this->_config = request('_config');
$this->velocityHelper = $velocityHelper;
$this->productRepository = $productRepository;
$this->velocityCompareProductsRepository = $velocityCompareProductsRepository;
}
/**
* function for customers to get products in comparison.
*
* @return Mixed
*/
public function getComparisonList()
{
if (request()->get('data')) {
$productSlugs = null;
$productCollection = [];
if (auth()->guard('customer')->user()) {
$productCollection = $this->velocityCompareProductsRepository
->leftJoin(
'product_flat',
'velocity_customer_compare_products.product_flat_id',
'product_flat.id'
)
->where('customer_id', auth()->guard('customer')->user()->id)
->get()
->toArray();
foreach ($productCollection as $index => $customerCompare) {
$product = $this->productRepository->find($customerCompare['product_id']);
$formattedProduct = $this->velocityHelper->formatProduct($product);
$productCollection[$index]['image'] = $formattedProduct['image'];
$productCollection[$index]['priceHTML'] = $formattedProduct['priceHTML'];
$productCollection[$index]['addToCartHtml'] = $formattedProduct['addToCartHtml'];
}
} else {
// for product details
if ($items = request()->get('items')) {
$productSlugs = explode('&', $items);
foreach ($productSlugs as $slug) {
$product = $this->productRepository->findBySlug($slug);
$formattedProduct = $this->velocityHelper->formatProduct($product);
$productMetaDetails = [];
$productMetaDetails['image'] = $formattedProduct['image'];
$productMetaDetails['priceHTML'] = $formattedProduct['priceHTML'];
$productMetaDetails['addToCartHtml'] = $formattedProduct['addToCartHtml'];
$product = array_merge($product->toArray(), $productMetaDetails);
array_push($productCollection, $product);
}
}
}
$response = [
'status' => 'success',
'products' => $productCollection,
];
} else {
$response = view($this->_config['view']);
}
return $response;
}
/**
* function for customers to add product in comparison.
*
* @return json
*/
public function addCompareProduct()
{
$productId = request()->get('productId');
$customerId = auth()->guard('customer')->user()->id;
$compareProduct = $this->velocityCompareProductsRepository->findOneByField([
'customer_id' => $customerId,
'product_flat_id' => $productId,
]);
if (! $compareProduct) {
// insert new row
$this->velocityCompareProductsRepository->create([
'customer_id' => $customerId,
'product_flat_id' => $productId,
]);
return response()->json([
'status' => 'success',
'message' => trans('velocity::app.customer.compare.added'),
'label' => trans('velocity::app.shop.general.alert.success'),
], 201);
} else {
return response()->json([
'status' => 'success',
'label' => trans('velocity::app.shop.general.alert.success'),
'message' => trans('velocity::app.customer.compare.already_added'),
], 200);
}
}
/**
* function for customers to delete product in comparison.
*
* @return json
*/
public function deleteComparisonProduct()
{
// either delete all or individual
if (request()->get('productId') == 'all') {
// delete all
$customerId = auth()->guard('customer')->user()->id;
$this->velocityCompareProductsRepository->deleteWhere([
'customer_id' => auth()->guard('customer')->user()->id,
]);
} else {
// delete individual
$this->velocityCompareProductsRepository->deleteWhere([
'product_flat_id' => request()->get('productId'),
'customer_id' => auth()->guard('customer')->user()->id,
]);
}
return [
'status' => 'success',
'message' => trans('velocity::app.customer.compare.removed'),
'label' => trans('velocity::app.shop.general.alert.success'),
];
}
}

View File

@ -2,11 +2,15 @@
namespace Webkul\Velocity\Http\Controllers\Shop;
use Illuminate\Http\Request;
use Cart;
use Webkul\Product\Helpers\ProductImage;
use Webkul\Velocity\Http\Shop\Controllers;
use Webkul\Checkout\Contracts\Cart as CartModel;
use Webkul\Product\Repositories\SearchRepository;
use Webkul\Product\Repositories\ProductRepository;
use Webkul\Category\Repositories\CategoryRepository;
use Webkul\Velocity\Repositories\Product\ProductRepository as VelocityProductRepository;
/**
@ -15,7 +19,7 @@ use Webkul\Velocity\Repositories\Product\ProductRepository as VelocityProductRep
* @author Shubham Mehrotra <shubhammehrotra.symfony@webkul.com> @shubhwebkul
* @copyright 2019 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class ShopController extends Controller
class ShopController extends Controller
{
/**
* Contains route related configuration
@ -24,6 +28,13 @@ use Webkul\Velocity\Repositories\Product\ProductRepository as VelocityProductRep
*/
protected $_config;
/**
* Webkul\Product\Helpers\ProductImage object
*
* @var ProductImage
*/
protected $productImageHelper;
/**
* SearchRepository object
*
@ -35,7 +46,7 @@ use Webkul\Velocity\Repositories\Product\ProductRepository as VelocityProductRep
* ProductRepository object
*
* @var ProductRepository
*/
*/
protected $productRepository;
/**
@ -45,15 +56,28 @@ use Webkul\Velocity\Repositories\Product\ProductRepository as VelocityProductRep
*/
protected $velocityProductRepository;
/**
* CategoryRepository object of velocity package
*
* @var CategoryRepository
*/
protected $categoryRepository;
/**
* Create a new controller instance.
*
* @param \Webkul\Product\Helpers\ProductImage $productImageHelper
* @param \Webkul\Product\Repositories\SearchRepository $searchRepository
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
* @param \Webkul\Category\Repositories\CategoryRepository $categoryRepository
* @param \Webkul\Velocity\Repositories\Product\ProductRepository $velocityProductRepository
* @return void
*/
public function __construct(
ProductImage $productImageHelper,
SearchRepository $searchRepository,
ProductRepository $productRepository,
CategoryRepository $categoryRepository,
VelocityProductRepository $velocityProductRepository
) {
$this->_config = request('_config');
@ -62,6 +86,10 @@ use Webkul\Velocity\Repositories\Product\ProductRepository as VelocityProductRep
$this->productRepository = $productRepository;
$this->productImageHelper = $productImageHelper;
$this->categoryRepository = $categoryRepository;
$this->velocityProductRepository = $velocityProductRepository;
}
@ -83,10 +111,8 @@ use Webkul\Velocity\Repositories\Product\ProductRepository as VelocityProductRep
if ($product) {
$productReviewHelper = app('Webkul\Product\Helpers\Review');
$productImageHelper = app('Webkul\Product\Helpers\ProductImage');
$galleryImages = $productImageHelper->getProductBaseImage($product);
$galleryImages = $this->productImageHelper->getProductBaseImage($product);
$response = [
'status' => true,
@ -102,7 +128,7 @@ use Webkul\Velocity\Repositories\Product\ProductRepository as VelocityProductRep
} else {
$response = [
'status' => false,
'slug' => $slug,
'slug' => $slug,
];
}
@ -138,7 +164,7 @@ use Webkul\Velocity\Repositories\Product\ProductRepository as VelocityProductRep
break;
default:
$categoryDetails = app('Webkul\Category\Repositories\CategoryRepository')->findByPath($slug);
$categoryDetails = $this->categoryRepository->findByPath($slug);
if ($categoryDetails) {
$list = false;
@ -149,6 +175,7 @@ use Webkul\Velocity\Repositories\Product\ProductRepository as VelocityProductRep
$productDetails = [];
$productDetails = array_merge($productDetails, $this->formatProduct($product));
array_push($customizedProducts, $productDetails);
}
@ -156,7 +183,7 @@ use Webkul\Velocity\Repositories\Product\ProductRepository as VelocityProductRep
'status' => true,
'list' => $list,
'categoryDetails' => $categoryDetails,
'categoryProducts' => $customizedProducts
'categoryProducts' => $customizedProducts,
];
}
@ -171,7 +198,7 @@ use Webkul\Velocity\Repositories\Product\ProductRepository as VelocityProductRep
public function fetchCategories()
{
$formattedCategories = [];
$categories = app('Webkul\Category\Repositories\CategoryRepository')->getVisibleCategoryTree(core()->getCurrentChannel()->root_category_id);
$categories = $this->categoryRepository->getVisibleCategoryTree(core()->getCurrentChannel()->root_category_id);
foreach ($categories as $category) {
array_push($formattedCategories, $this->getCategoryFilteredData($category));
@ -185,7 +212,7 @@ use Webkul\Velocity\Repositories\Product\ProductRepository as VelocityProductRep
public function fetchFancyCategoryDetails($slug)
{
$categoryDetails = app('Webkul\Category\Repositories\CategoryRepository')->findByPath($slug);
$categoryDetails = $this->categoryRepository->findByPath($slug);
if ($categoryDetails) {
$response = [
@ -202,6 +229,7 @@ use Webkul\Velocity\Repositories\Product\ProductRepository as VelocityProductRep
private function getCategoryFilteredData($category)
{
$formattedChildCategory = [];
foreach ($category->children as $child) {
array_push($formattedChildCategory, $this->getCategoryFilteredData($child));
}
@ -218,100 +246,32 @@ use Webkul\Velocity\Repositories\Product\ProductRepository as VelocityProductRep
private function formatProduct($product, $list = false)
{
$reviewHelper = app('Webkul\Product\Helpers\Review');
$productImageHelper = app('Webkul\Product\Helpers\ProductImage');
$totalReviews = $reviewHelper->getTotalReviews($product);
$avgRatings = ceil($reviewHelper->getAverageRating($product));
$galleryImages = $productImageHelper->getGalleryImages($product);
$productImage = $productImageHelper->getProductBaseImage($product)['medium_image_url'];
$galleryImages = $this->productImageHelper->getGalleryImages($product);
$productImage = $this->productImageHelper->getProductBaseImage($product)['medium_image_url'];
return [
'avgRating' => $avgRatings,
'totalReviews' => $totalReviews,
'image' => $productImage,
'galleryImages' => $galleryImages,
'name' => $product->name,
'slug' => $product->url_key,
'image' => $productImage,
'description' => $product->description,
'shortDescription' => $product->meta_description,
'galleryImages' => $galleryImages,
'priceHTML' => view('shop::products.price', ['product' => $product])->render(),
'totalReviews' => $totalReviews,
'avgRating' => $avgRatings,
'shortDescription' => $product->short_description,
'firstReviewText' => trans('velocity::app.products.be-first-review'),
'priceHTML' => view('shop::products.price', ['product' => $product])->render(),
'addToCartHtml' => view('shop::products.add-to-cart', [
'product' => $product,
'showCompare' => true,
'addWishlistClass' => ! (isset($list) && $list) ? '' : '',
'addToCartBtnClass' => ! (isset($list) && $list) ? $addToCartBtnClass ?? '' : ''
'addToCartBtnClass' => ! (isset($list) && $list) ? 'small-padding' : '',
])->render(),
];
}
/**
* Function for guests user to add the product in the cart.
*
* @return Mixed
*/
public function addProductToCart()
{
try {
$cart = Cart::getCart();
$formattedBeforeItems = [];
$id = request()->get('product_id');
$velocityHelper = app('Webkul\Velocity\Helpers\Helper');
if ($cart) {
$beforeItems = $cart->items;
foreach ($beforeItems as $item) {
array_push($formattedBeforeItems, $velocityHelper->formatCartItem($item));
}
}
$cart = Cart::addProduct($id, request()->all());
if (is_array($cart) && isset($cart['warning'])) {
$response = [
'status' => 'warning',
'message' => $cart['warning'],
];
}
if ($cart instanceof CartModel) {
$items = $cart->items;
$formattedItems = [];
foreach ($items as $item) {
array_push($formattedItems, $velocityHelper->formatCartItem($item));
}
$response = [
'status' => 'success',
'totalCartItems' => sizeof($items),
'addedItems' => array_slice($formattedItems, sizeof($formattedBeforeItems)),
'message' => trans('shop::app.checkout.cart.item.success'),
];
if ($customer = auth()->guard('customer')->user()) {
$this->wishlistRepository->deleteWhere(['product_id' => $id, 'customer_id' => $customer->id]);
}
if (request()->get('is_buy_now')) {
return redirect()->route('shop.checkout.onepage.index');
}
}
} catch(\Exception $exception) {
$product = $this->productRepository->find($id);
$response = [
'status' => 'false',
'message' => trans($exception->getMessage()),
'redirectionRoute' => route('shop.productOrCategory.index', $product->url_key),
];
}
return $response ?? [
'status' => 'error',
'message' => trans('velocity::app.error.something-went-wrong'),
];
}
}

View File

@ -15,6 +15,20 @@ Route::group(['middleware' => ['web', 'locale', 'theme', 'currency']], function
Route::get('/fancy-category-details/{slug}', 'ShopController@fetchFancyCategoryDetails')->name('velocity.fancy.category.details');
Route::post('/cart/add', 'ShopController@addProductToCart')->name('velocity.cart.add.product');
Route::get('/mini-cart', 'CartController@getMiniCartDetails')->name('velocity.cart.get.details');
Route::post('/cart/add', 'CartController@addProductToCart')->name('velocity.cart.add.product');
Route::delete('/cart/remove/{id}', 'CartController@removeProductFromCart')->name('velocity.cart.remove.product');
Route::get('/comparison', 'ComparisonController@getComparisonList')
->name('velocity.product.compare')
->defaults('_config', [
'view' => 'shop::compare.index'
]);
Route::put('/comparison', 'ComparisonController@addCompareProduct')->name('customer.product.add.compare');
Route::delete('/comparison', 'ComparisonController@deleteComparisonProduct')->name('customer.product.delete.compare');
});
});

View File

@ -0,0 +1,10 @@
<?php
namespace Webkul\Velocity\Models;
use Illuminate\Database\Eloquent\Model;
class VelocityCustomerCompareProduct extends Model
{
protected $guarded = [];
}

View File

@ -0,0 +1,18 @@
<?php
namespace Webkul\Velocity\Repositories;
use Webkul\Core\Eloquent\Repository;
class VelocityCustomerCompareProductRepository extends Repository
{
/**
* Specify Model class name
*
* @return mixed
*/
function model()
{
return 'Webkul\Velocity\Models\VelocityCustomerCompareProduct';
}
}

View File

@ -2,7 +2,7 @@
<form method="POST" @submit.prevent="addToCart">
<button
type="submit"
:disabled="isButtonEnable == 'false'"
:disabled="isButtonEnable == 'false' || isButtonEnable == false"
:class="`btn btn-add-to-cart ${addClassToBtn}`">
<i class="material-icons text-down-3" v-if="showCartIcon">shopping_cart</i>
@ -26,8 +26,8 @@
data: function () {
return {
'qtyText': this.__('checkout.qty'),
'isButtonEnable': this.isEnable,
'qtyText': this.__('checkout.qty'),
}
},
@ -44,45 +44,20 @@
.then(response => {
this.isButtonEnable = true;
if (response.data.status) {
response.data.addedItems.forEach(item => {
let cartItemHTML = `<div class="row small-card-container">
<div class="col-3 product-image-container mr15">
<a href="${this.$root.baseUrl}/checkout/cart/remove/${item.itemId}">
<span class="rango-close"></span>
</a>
if (response.data.status == 'success') {
this.$root.miniCartKey++;
<a
href="${this.$root.baseUrl}/${item.url_key}"
class="unset">
window.showAlert(`alert-success`, this.__('shop.general.alert.success'), response.data.message);
} else {
window.showAlert(`alert-${response.data.status}`, response.data.label ? response.data.label : this.__('shop.general.alert.error'), response.data.message);
<div class="product-image"
style="background-image: url('${item.images['small_image_url']}');">
</div>
</a>
</div>
<div class="col-9 no-padding card-body align-vertical-top">
<div class="no-padding">
<div class="fs16 text-nowrap fw6">${item.name}</div>
<div class="fs18 card-current-price fw6">
<div class="display-inbl">
<label class="fw5">${this.qtyText}</label>
<input type="text" disabled value="${item.quantity}" class="ml5" />
</div>
<span class="card-total-price fw6">${item.baseTotal}</span>
</div>
</div>
</div>
</div>`;
$('#cart-modal-content .mini-cart-container').append(cartItemHTML);
$('.mini-cart-container .badge').text(response.data.totalCartItems);
});
if (response.data.redirectionRoute) {
window.location.href = response.data.redirectionRoute;
}
}
})
.catch(error => {
console.log("something went wrong");
console.log(this.__('error.something_went_wrong'));
})
}
}

View File

@ -0,0 +1,123 @@
<template>
<div :class="`dropdown ${cartItems.length > 0 ? '' : 'disable-active'}`">
<cart-btn :item-count="cartItems.length"></cart-btn>
<div
id="cart-modal-content"
v-if="cartItems.length > 0"
class="modal-content sensitive-modal cart-modal-content hide">
<!--Body-->
<div class="mini-cart-container">
<div class="row small-card-container" :key="index" v-for="(item, index) in cartItems">
<div class="col-3 product-image-container mr15">
<a @click="removeProduct(item.id)">
<span class="rango-close"></span>
</a>
<a class="unset" :href="`${$root.baseUrl}/${item.url_key}`">
<div
class="product-image"
:style="`background-image: url(${item.images.medium_image_url});`">
</div>
</a>
</div>
<div class="col-9 no-padding card-body align-vertical-top">
<div class="no-padding">
<div class="fs16 text-nowrap fw6" v-html="item.name"></div>
<div class="fs18 card-current-price fw6">
<div class="display-inbl">
<label class="fw5">{{ __('checkout.qty') }}</label>
<input type="text" disabled :value="item.quantity" class="ml5" />
</div>
<span class="card-total-price fw6">
{{ item.base_total }}
</span>
</div>
</div>
</div>
</div>
</div>
<!--Footer-->
<div class="modal-footer">
<h2 class="col-6 text-left fw6">
{{ subtotalText }}
</h2>
<h2 class="col-6 text-right fw6 no-padding">{{ cartInformation.base_sub_total }}</h2>
</div>
<div class="modal-footer">
<a class="col text-left fs16 link-color remove-decoration" :href="viewCart">{{ cartText }}</a>
<div class="col text-right no-padding">
<a :href="checkoutUrl">
<button
type="button"
class="theme-btn fs16 fw6">
{{ checkoutText }}
</button>
</a>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: [
'cartText',
'viewCart',
'checkoutUrl',
'checkoutText',
'subtotalText',
],
data: function () {
return {
cartItems: [],
cartInformation: [],
}
},
mounted: function () {
this.getMiniCartDetails();
},
watch: {
'$root.miniCartKey': function () {
this.getMiniCartDetails();
}
},
methods: {
getMiniCartDetails: function () {
this.$http.get(`${this.$root.baseUrl}/mini-cart`)
.then(response => {
if (response.data.status) {
this.cartItems = response.data.mini_cart.cart_items;
this.cartInformation = response.data.mini_cart.cart_details;
}
})
.catch(exception => {
console.log(this.__('error.something_went_wrong'));
});
},
removeProduct: function (productId) {
this.$http.delete(`${this.$root.baseUrl}/cart/remove/${productId}`)
.then(response => {
this.cartItems = this.cartItems.filter(item => item.id != productId);
window.showAlert(`alert-${response.data.status}`, response.data.label, response.data.message);
})
.catch(exception => {
console.log(this.__('error.something_went_wrong'));
});
}
}
}
</script>

View File

@ -67,7 +67,7 @@
<span class="fs14" v-text="product.firstReviewText"></span>
</div>
<vnode-injector :nodes="getAddToCartHtml()"></vnode-injector>
<vnode-injector :nodes="$root.getDynamicHTML(product.addToCartHtml)"></vnode-injector>
</div>
</div>
</template>
@ -88,22 +88,5 @@
'showTestClass': 'sdfsdf',
}
},
methods: {
getAddToCartHtml: function () {
const { render, staticRenderFns } = Vue.compile(this.product.addToCartHtml);
const _staticRenderFns = this.$options.staticRenderFns = staticRenderFns;
try {
var output = render.call(this, this.$createElement)
} catch (exception) {
debugger
}
this.$options.staticRenderFns = _staticRenderFns
return output
}
},
}
</script>

View File

@ -0,0 +1,64 @@
<template>
<a class="unset compare-icon text-right" @click="addProductToCompare">
<i class="material-icons">compare_arrows</i>
</a>
</template>
<script>
export default {
props: ['slug', 'customer', 'productId'],
methods: {
addProductToCompare: function () {
if (this.customer == "true") {
this.$http.put(
`${this.$root.baseUrl}/comparison`, {
productId: this.productId,
}
).then(response => {
window.showAlert(`alert-${response.data.status}`, response.data.label, response.data.message);
}).catch(error => {
window.showAlert(
'alert-danger',
this.__('shop.general.alert.error'),
this.__('error.something_went_wrong')
);
});
} else {
let updatedItems = [this.slug];
let existingItems = window.localStorage.getItem('compared_product');
if (existingItems) {
existingItems = JSON.parse(existingItems);
if (existingItems.indexOf(this.slug) == -1) {
updatedItems = existingItems.concat([this.slug]);
window.localStorage.setItem('compared_product', JSON.stringify(updatedItems));
window.showAlert(
`alert-success`,
this.__('shop.general.alert.success'),
`${this.__('customer.compare.added')}`
);
} else {
window.showAlert(
`alert-success`,
this.__('shop.general.alert.success'),
`${this.__('customer.compare.already_added')}`
);
}
} else {
window.localStorage.setItem('compared_product', JSON.stringify([this.slug]));
window.showAlert(
`alert-success`,
this.__('shop.general.alert.success'),
`${this.__('customer.compare.added')}`
);
}
}
}
}
}
</script>

View File

@ -43,7 +43,7 @@
<p class="pt14 fs14 description-text" v-html="product.shortDescription"></p>
<vnode-injector :nodes="getAddToCartHtml()"></vnode-injector>
<vnode-injector :nodes="$root.getDynamicHTML(product.addToCartHtml)"></vnode-injector>
</div>
<div
@ -93,7 +93,7 @@
},
mounted: function () {
// console.log(this.quickViewDetails, this.quickView);
$('.compare-icon').click(this.closeQuickView);
},
methods: {
@ -106,21 +106,6 @@
changeImage: function (imageIndex) {
this.currentlyActiveImage = imageIndex;
},
getAddToCartHtml: function () {
const { render, staticRenderFns } = Vue.compile(this.product.addToCartHtml);
const _staticRenderFns = this.$options.staticRenderFns = staticRenderFns;
try {
var output = render.call(this, this.$createElement)
} catch (exception) {
console.log("something went wrong");
}
this.$options.staticRenderFns = _staticRenderFns
return output;
}
}
}
</script>

View File

@ -11,9 +11,9 @@
:key="categoryIndex"
:id="`category-${category.id}`"
class="category-content cursor-pointer"
v-for="(category, categoryIndex) in slicedCategories"
@mouseout="toggleSidebar(id, $event, 'mouseout')"
@mouseover="toggleSidebar(id, $event, 'mouseover')">
@mouseover="toggleSidebar(id, $event, 'mouseover')"
v-for="(category, categoryIndex) in slicedCategories">
<a
:class="`category unset ${(category.children.length > 0) ? 'fw6' : ''}`"
@ -28,7 +28,9 @@
v-if="category.category_icon_path"
:src="`${$root.baseUrl}/storage/${category.category_icon_path}`" />
</div>
<span class="category-title">{{ category['name'] }}</span>
<i
class="rango-arrow-right pr15 pull-right"
@mouseout="toggleSidebar(id, $event, 'mouseout')"
@ -41,18 +43,23 @@
class="sub-category-container"
v-if="category.children.length && category.children.length > 0">
<div :class="`sub-categories sub-category-${sidebarLevel+categoryIndex}`">
<div
@mouseout="toggleSidebar(id, $event, 'mouseout')"
@mouseover="remainBar(`sidebar-level-${sidebarLevel+categoryIndex}`)"
:class="`sub-categories sub-category-${sidebarLevel+categoryIndex} cursor-default`">
<nav
class="sidebar"
@mouseover="remainBar(`sidebar-level-${sidebarLevel+categoryIndex}`)"
:id="`sidebar-level-${sidebarLevel+categoryIndex}`">
:id="`sidebar-level-${sidebarLevel+categoryIndex}`"
@mouseover="remainBar(`sidebar-level-${sidebarLevel+categoryIndex}`)">
<ul type="none">
<li
:key="`${subCategoryIndex}-${categoryIndex}`"
v-for="(subCategory, subCategoryIndex) in category.children">
<a
:class="`category unset ${(subCategory.children.length > 0) ? 'fw6' : ''}`"
:class="`category sub-category unset ${(subCategory.children.length > 0) ? 'fw6' : ''}`"
:href="`${$root.baseUrl}/${category.slug}/${subCategory.slug}`">
<div
@ -143,7 +150,7 @@
slicedCategories['parentSlug'] = this.parentSlug;
this.slicedCategories = slicedCategories;
}
},
}
}
</script>

View File

@ -0,0 +1,53 @@
<template>
<div :class="`stars mr5 fs${size ? size : '16'} ${pushClass ? pushClass : ''}`">
<input
v-if="editable"
type="number"
:value="showFilled"
name="rating"
class="hidden" />
<i
:class="`material-icons ${editable ? 'cursor-pointer' : ''}`"
v-for="(rating, index) in parseInt((showFilled != 'undefined') ? showFilled : 3)"
:key="`${index}${Math.random()}`"
@click="updateRating(index + 1)">
star
</i>
<template v-if="!hideBlank">
<i
:class="`material-icons ${editable ? 'cursor-pointer' : ''}`"
v-for="(blankStar, index) in (5 - ((showFilled != 'undefined') ? showFilled : 3))"
:key="`${index}${Math.random()}`"
@click="updateRating(showFilled + index + 1)">
star_border
</i>
</template>
</div>
</template>
<script type="text/javascript">
export default {
props: [
'size',
'ratings',
'editable',
'hideBlank',
'pushClass',
],
data: function () {
return {
showFilled: this.ratings,
}
},
methods: {
updateRating: function (index) {
index = Math.abs(index);
this.editable ? this.showFilled = index : '';
}
},
}
</script>

View File

@ -1,20 +1,41 @@
<template>
<i
v-if="isCustomer == 'true'"
:class="`material-icons ${addClass ? addClass : ''}`"
@mouseover="isActive ? isActive = !isActive : ''"
@mouseout="active !== '' && !isActive ? isActive = !isActive : ''">
{{ isActive ? 'favorite_border' : 'favorite' }}
</i>
<a
v-else
@click="addProductWishlist(productId)"
:href="`${$root.baseUrl}/customer/login`"
:class="`unset wishlist-icon ${addClass ? addClass : ''} text-right`">
<i
:class="`material-icons ${addClass ? addClass : ''}`"
@mouseover="isActive ? isActive = !isActive : ''"
@mouseout="active !== '' && !isActive ? isActive = !isActive : ''">
{{ isActive ? 'favorite_border' : 'favorite' }}
</i>
</a>
</template>
<script type="text/javascript">
export default {
props: ['active', 'addClass'],
props: ['active', 'addClass', 'isCustomer', 'productId'],
data: function () {
return {
isActive: this.active
isActive: this.active,
}
},
methods: {
addProductWishlist: function () {
}
}
}
</script>

View File

@ -31,8 +31,10 @@ window.Carousel = VueCarousel;
// UI components
Vue.component("vue-slider", require("vue-slider-component"));
Vue.component('mini-cart', require('./UI/components/mini-cart'));
Vue.component('modal-component', require('./UI/components/modal'));
Vue.component("add-to-cart", require("./UI/components/add-to-cart"));
Vue.component('star-ratings', require('./UI/components/star-rating'));
Vue.component('quantity-btn', require('./UI/components/quantity-btn'));
Vue.component('sidebar-component', require('./UI/components/sidebar'));
Vue.component("product-card", require("./UI/components/product-card"));
@ -41,6 +43,7 @@ Vue.component('carousel-component', require('./UI/components/carousel'));
Vue.component('child-sidebar', require('./UI/components/child-sidebar'));
Vue.component('card-list-header', require('./UI/components/card-header'));
Vue.component('magnify-image', require('./UI/components/image-magnifier'));
Vue.component('compare-component', require('./UI/components/product-compare'));
Vue.component('responsive-sidebar', require('./UI/components/responsive-sidebar'));
Vue.component('product-quick-view', require('./UI/components/product-quick-view'));
Vue.component('product-quick-view-btn', require('./UI/components/product-quick-view-btn'));
@ -50,6 +53,7 @@ window.eventBus = new Vue();
$(document).ready(function () {
// define a mixin object
Vue.mixin(require('./UI/components/trans'));
Vue.mixin({
data: function () {
return {
@ -67,6 +71,12 @@ $(document).ready(function () {
route ? window.location.href = route : '';
},
debounceToggleSidebar: function (id, {target}, type) {
// setTimeout(() => {
this.toggleSidebar(id, target, type);
// }, 500);
},
toggleSidebar: function (id, {target}, type) {
if (
Array.from(target.classList)[0] == "main-category"
@ -81,11 +91,11 @@ $(document).ready(function () {
}
}
} else if (
Array.from(target.classList)[0] == "category"
|| Array.from(target.classList)[0] == "category-icon"
|| Array.from(target.classList)[0] == "category-title"
|| Array.from(target.classList)[0] == "category-content"
|| Array.from(target.classList)[0] == "rango-arrow-right"
Array.from(target.classList)[0] == "category"
|| Array.from(target.classList)[0] == "category-icon"
|| Array.from(target.classList)[0] == "category-title"
|| Array.from(target.classList)[0] == "category-content"
|| Array.from(target.classList)[0] == "rango-arrow-right"
) {
let parentItem = target.closest('li');
if (target.id || parentItem.id.match('category-')) {
@ -154,6 +164,27 @@ $(document).ready(function () {
return false
}
},
getDynamicHTML: function (input) {
var _staticRenderFns;
const { render, staticRenderFns } = Vue.compile(input);
if (this.$options.staticRenderFns.length > 0) {
_staticRenderFns = this.$options.staticRenderFns;
} else {
_staticRenderFns = this.$options.staticRenderFns = staticRenderFns;
}
try {
var output = render.call(this, this.$createElement);
} catch (exception) {
console.log(this.__('error.something_went_wrong'));
}
this.$options.staticRenderFns = _staticRenderFns;
return output;
}
}
});
@ -164,6 +195,7 @@ $(document).ready(function () {
data: function () {
return {
modalIds: {},
miniCartKey: 0,
quickView: false,
productDetails: [],
}
@ -265,6 +297,7 @@ $(document).ready(function () {
this.$http.get(`${this.baseUrl}/categories`)
.then(response => {
this.sharedRootCategories = response.data.categories;
$(`<style type='text/css'> .sub-categories{ min-height:${response.data.categories.length * 30}px;} </style>`).appendTo("head");
})
.catch(error => {
console.log('failed to load categories');
@ -280,7 +313,7 @@ $(document).ready(function () {
}
})
});
}
},
}
});
@ -291,5 +324,5 @@ $(document).ready(function () {
render(h, {props}) {
return props.nodes;
}
})
});
});

View File

@ -509,6 +509,21 @@ header {
}
}
}
// transform: scale(1) rotateZ(-180deg);
// transition: transform .15s,opacity .15s;
}
~ .compare-btn {
height: 50px;
float: right;
font-size: 18px;
font-weight: 600;
padding: 10px 16px 6px 16px;
i {
vertical-align: middle;
}
}
}

View File

@ -255,6 +255,8 @@
}
.card-body {
cursor: default;
> div:last-child {
margin-top: 10px;
}
@ -274,17 +276,6 @@
}
}
.wishlist-icon {
height: 38px;
display: table;
text-align: right;
> i {
display: table-cell;
vertical-align: middle;
}
}
.add-to-cart-btn {
width: 100%;
position: relative;
@ -298,11 +289,24 @@
}
}
~ .wishlist-icon {
~ a {
right: 0;
margin: 0;
padding: 0;
height: 38px;
display: table;
cursor: pointer;
text-align: right;
position: absolute;
&.compare-icon {
right: 27px;
}
> i {
display: table-cell;
vertical-align: middle;
}
}
}
}
@ -340,6 +344,26 @@
#quick-view-btn-container {
display: block;
}
.product-image-container {
overflow: hidden;
img {
transition: 0.5s all;
transform: scale(1.1);
}
}
}
.lg-card-container:hover {
.product-image {
overflow: hidden;
img {
transition: 0.5s all;
transform: scale(1.1);
}
}
}
.quantity {
@ -708,9 +732,7 @@
.customer-sidebar {
border-right: 1px solid $border-general;
}
.customer-sidebar {
.account-details {
text-align: center;
padding: 25px 20px;
@ -775,6 +797,10 @@
&.downloadables::before {
content: "\e926";
}
&.compare::before {
content: "\e93b";
}
}
}
@ -1494,7 +1520,7 @@
span:nth-child(1),
.special-price,
.price-from > span:not(:nth-child(2)) {
font-size: 20px;
font-size: 20px !important;
font-weight: 600;
}
@ -2196,6 +2222,18 @@
@extend .small-padding;
}
}
.VueCarousel-slide {
cursor: default;
}
#new-products-carousel {
.add-to-cart-btn {
~ a {
position: static;
}
}
}
}
.vue-slider {
@ -2205,3 +2243,63 @@
.profile-update-form {
width: 800px;
}
.compare-products {
.col,
.col-2 {
padding-left: 0;
max-width: 20%;
}
.image-wrapper {
width: 100%;
}
.stars {
i {
font-size: 16px;
}
}
.action {
position: relative;
.close-btn {
right: 0;
top: 6px;
position: absolute;
display: inline-block;
&:hover {
font-weight: 600;
}
}
.compare-icon {
display: none;
}
}
.product-price {
span {
font-size: 24px !important
}
}
.material-icons {
&.cross {
top: 5px;
right: 20px;
cursor: pointer;
position: absolute;
}
}
.wishlist-icon {
top: 5px;
right: 60px;
position: absolute;
display: inline-block;
}
}

View File

@ -643,9 +643,11 @@ body::after {
}
}
.compare-icon,
.wishlist-icon {
height: 38px;
display: table;
cursor: pointer;
margin-left: 10px;
i {

View File

@ -159,26 +159,38 @@
display: none;
}
.cart-wish-wrap {
.add-to-cart-btn {
padding: 0;
display: table;
.add-to-cart-btn {
padding: 0;
display: table;
.btn-add-to-cart {
.small-padding {
&.btn-add-to-cart {
padding: 3px 14px !important;
}
.btn-add-to-cart {
.small-padding {
&.btn-add-to-cart {
padding: 3px 14px !important;
}
}
}
.wishlist-icon {
padding: 0;
max-width: 25px;
~ a {
position: relative;
&.compare-icon {
right: 0;
}
&.wishlist-icon {
padding: 0;
left: 10px;
max-width: 25px;
}
}
}
}
#quick-view-btn-container {
display: none;
}
}
}
@ -450,6 +462,11 @@
&.vc-small-screen {
display: block !important;
}
+ .recently-viewed {
top: 0;
position: static;
}
}
.reviews-container {
@ -485,6 +502,10 @@
padding: 0px;
position: relative;
margin-bottom: 20px;
.vc-small-product-image {
width: 100%;
}
}
.right {
@ -559,7 +580,7 @@
.filters-container {
left: 0px;
top: 40px;
top: 30px;
padding: 0;
width: 100%;
z-index: 9;
@ -613,9 +634,9 @@
.category-title {
width: 100%;
display: none;
display: table;
padding-left: 10px;
display: none;
margin : 13px 0px 13px 0px;
> i {
@ -665,9 +686,10 @@
li {
font-size: 16px;
padding: 10px 0px 10px 20px;
a {
padding: 10px 0px 10px 20px;
// padding: 10px 0px 10px 20px;
}
&:hover {
@ -868,4 +890,18 @@
margin-left: 0;
}
}
.compare-products {
padding: 0 !important;
.col,
.col-2 {
max-width: unset;
}
}
.compare-icon,
.wishlist-icon {
margin-left: 0;
}
}

View File

@ -6,6 +6,7 @@
.magnifier {
> img {
max-width: 100%;
min-height: 450px;
max-height: 530px;
}
@ -219,9 +220,11 @@
}
}
.compare-icon,
.wishlist-icon {
height: 46px;
display: table;
cursor: pointer;
padding-left: 10px;
i {

View File

@ -124,7 +124,7 @@
margin-top: 10px;
}
.mt15 {
margin-top: 15px;
margin-top: 15px !important;
}
.mr5 {
margin-right: 5px;
@ -486,13 +486,19 @@
.wishlist-icon {
height: 40px;
display: table;
padding-left: 0 !important;
i {
display: table-cell;
vertical-align: middle;
padding-left: 0 !important;
}
}
.compare-icon {
padding-left: 0;
}
.add-to-cart-btn {
max-width: 150px;
}
@ -876,4 +882,16 @@ button[disabled] {
z-index: 5000;
position: fixed;
background: rgba(255, 255, 255, 0.9);
}
.compare-icon,
.wishlist-icon {
height: 38px;
display: table;
margin-left: 10px;
i {
display: table-cell;
vertical-align: middle;
}
}

View File

@ -8,6 +8,14 @@ return [
],
'customer' => [
'compare' => [
'text' => 'قارن',
'compare_similar_items' => 'مقارنة العناصر المماثلة',
'added' => 'تمت إضافة العنصر بنجاح لمقارنة القائمة',
'removed' => 'تمت إزالة العنصر بنجاح من قائمة المقارنة',
'already_added' => 'تمت إضافة العنصر بالفعل لمقارنة القائمة',
'empty-text' => "ليس لديك أي عناصر في قائمة المقارنة الخاصة بك",
],
'login-form' => [
'sign-up' => 'سجل',
'new-customer' => 'عميل جديد',
@ -50,7 +58,7 @@ return [
'error' => [
'go-to-home' => 'الذهاب إلى المنزل',
'page-lost-short' => 'الصفحة فقدت المحتوى',
'something-went-wrong' => 'هناك خطأ ما',
'something_went_wrong' => 'هناك خطأ ما',
'page-lost-description' => "الصفحة التي تبحث عنها غير متوفرة. حاول البحث مرة أخرى أو استخدم زر العودة للخلف أدناه.",
],

View File

@ -191,6 +191,14 @@ return [
],
'customer' => [
'compare' => [
'text' => 'Compare',
'compare_similar_items' => 'Compare Similar Items',
'added' => 'Item successfully added to compare list',
'already_added' => 'Item already added to compare list',
'removed' => 'Item successfully removed from compare list',
'empty-text' => "You don't have any items in your compare list",
],
'login-form' => [
'sign-up' => 'Sign up',
'new-customer' => 'New Customer',
@ -216,7 +224,7 @@ return [
'error' => [
'go-to-home' => 'Go to home',
'page-lost-short' => 'Page lost content',
'something-went-wrong' => 'something went wrong',
'something_went_wrong' => 'something went wrong',
'page-lost-description' => "The page you're looking for isn't available. Try to search again or use the Go Back button below.",
],

View File

@ -212,7 +212,7 @@ return [
'error' => [
'go-to-home' => 'Ga naar de startpagina',
'page-lost-short' => 'Page lost content',
'something-went-wrong' => 'something went wrong',
'something_went_wrong' => 'something went wrong',
'page-lost-description' => "The page you're looking for isn't available. Try to search again or use the Go Back button below.",
],

View File

@ -8,6 +8,14 @@ return [
],
'customer' => [
'compare' => [
'text' => 'Comparar',
'compare_similar_items' => 'Comparar itens semelhantes',
'already_added' => 'Item já adicionado à lista de comparação',
'added' => 'Item adicionado com sucesso à lista de comparação',
'removed' => 'Item removido com sucesso da lista de comparação',
'empty-text' => "Você não possui nenhum item na sua lista de comparação",
],
'login-form' => [
'sign-up' => 'inscrever-se',
'new-customer' => 'Novo cliente',
@ -49,7 +57,7 @@ return [
'error' => [
'go-to-home' => 'Vá para casa',
'something-went-wrong' => 'algo deu errado',
'something_went_wrong' => 'algo deu errado',
'page-lost-short' => 'Conteúdo perdido da página',
'page-lost-description' => "A página que você está procurando não está disponível. Tente pesquisar novamente ou use o botão Voltar atrás abaixo.",
],

View File

@ -1,32 +1,3 @@
<script type="text/x-template" id="star-ratings-template">
<div :class="`stars mr5 fs${size ? size : '16'} ${pushClass ? pushClass : ''}`">
<input
v-if="editable"
type="number"
:value="showFilled"
name="rating"
class="hidden" />
<i
:class="`material-icons ${editable ? 'cursor-pointer' : ''}`"
v-for="(rating, index) in parseInt(showFilled ? showFilled : 3)"
:key="`${index}${Math.random()}`"
@click="updateRating(index + 1)">
star
</i>
<template v-if="!hideBlank">
<i
:class="`material-icons ${editable ? 'cursor-pointer' : ''}`"
v-for="(blankStar, index) in (5 - (showFilled ? showFilled : 3))"
:key="`${index}${Math.random()}`"
@click="updateRating(showFilled + index + 1)">
star_border
</i>
</template>
</div>
</script>
<script type="text/x-template" id="cart-btn-template">
<button
type="button"
@ -147,6 +118,13 @@
{!! view_render_event('bagisto.shop.layout.header.cart-item.before') !!}
@include('shop::checkout.cart.mini-cart')
{!! view_render_event('bagisto.shop.layout.header.cart-item.after') !!}
{!! view_render_event('bagisto.shop.layout.header.compare.before') !!}
<a class="compare-btn unset" href="{{ route('velocity.product.compare') }}">
<i class="material-icons">compare_arrows</i>
<span>Compare</span>
</a>
{!! view_render_event('bagisto.shop.layout.header.compare.after') !!}
</div>
</div>
</script>
@ -162,11 +140,15 @@
<i class="material-icons">perm_identity</i>
<span>
@guest('customer')
<a class="unset" href="{{ route('customer.session.index') }}">
{{ __('velocity::app.responsive.header.greeting', ['customer' => 'Guest']) }}
</a>
@endguest
@auth('customer')
{{ __('velocity::app.responsive.header.greeting', ['customer' => auth()->guard('customer')->user()->first_name]) }}
<a class="unset" href="{{ route('customer.profile.index') }}">
{{ __('velocity::app.responsive.header.greeting', ['customer' => auth()->guard('customer')->user()->first_name]) }}
</a>
@endauth
<i
class="material-icons pull-right"
@ -211,7 +193,7 @@
</ul>
<ul type="none" class="category-wrapper">
<li v-for="(category, index) in JSON.parse(categories)">
<li v-for="(category, index) in $root.sharedRootCategories">
<a
class="unset"
:href="`${$root.baseUrl}/${category.slug}`">
@ -285,10 +267,10 @@
<img
class="language-logo"
src="{{ asset('/storage/' . $locale->locale_image) }}" />
@else
@elseif ($locale->code == "en")
<img
class="language-logo"
src="{{ asset($locale->locale_image) }}" />
src="{{ asset('/themes/velocity/assets/images/flags/en.png') }}" />
@endif
</div>
<span>{{ $locale->name }}</span>
@ -524,31 +506,6 @@
<script type="text/javascript">
(() => {
Vue.component('star-ratings', {
props: [
'ratings',
'size',
'hideBlank',
'pushClass',
'editable'
],
template: '#star-ratings-template',
data: function () {
return {
showFilled: this.ratings,
}
},
methods: {
updateRating: function (index) {
index = Math.abs(index);
this.editable ? this.showFilled = index : '';
}
},
})
Vue.component('cart-btn', {
template: '#cart-btn-template',
@ -729,7 +686,7 @@
} else {
event.preventDefault();
let categories = this.sharedRootCategories;
let categories = this.$root.sharedRootCategories;
this.rootCategories = false;
this.subCategory = categories[index];
}

View File

@ -1,108 +1,9 @@
@inject ('productImageHelper', 'Webkul\Product\Helpers\ProductImage')
@php
$cart = cart()->getCart();
@endphp
<div class="mini-cart-container pull-right">
@if ($cart)
@php
Cart::collectTotals();
$items = $cart->items;
@endphp
<div class="dropdown">
<cart-btn item-count="{{ $cart->items->count() }}"></cart-btn>
<div class="modal-content sensitive-modal cart-modal-content hide" id="cart-modal-content">
<!--Body-->
<div class="mini-cart-container">
@foreach ($items as $item)
@php
$images = $item->product->getTypeInstance()->getBaseImage($item);
@endphp
<div class="row small-card-container">
<div class="col-3 product-image-container mr15">
<a href="{{ route('shop.checkout.cart.remove', ['id' => $item->id]) }}">
<span class="rango-close"></span>
</a>
<a
href="{{ route('shop.productOrCategory.index', $item->product->url_key) }}"
class="unset">
<div class="product-image"
style="background-image: url('{{ $images['small_image_url'] }}');">
</div>
</a>
</div>
<div class="col-9 no-padding card-body align-vertical-top">
<div class="no-padding">
{!! view_render_event('bagisto.shop.checkout.cart-mini.item.name.before', ['item' => $item]) !!}
<div class="fs16 text-nowrap fw6">{{ $item->name }}</div>
{!! view_render_event('bagisto.shop.checkout.cart-mini.item.name.after', ['item' => $item]) !!}
{!! view_render_event('bagisto.shop.checkout.cart-mini.item.price.before', ['item' => $item]) !!}
<div class="fs18 card-current-price fw6">
<div class="display-inbl">
<label class="fw5">{{ __('velocity::app.checkout.qty') }}</label>
{!! view_render_event('bagisto.shop.checkout.cart-mini.item.quantity.before', ['item' => $item]) !!}
<input type="text" disabled value="{{ $item->quantity }}" class="ml5" />
{!! view_render_event('bagisto.shop.checkout.cart-mini.item.quantity.after', ['item' => $item]) !!}
</div>
<span class="card-total-price fw6">
{{ core()->currency($item->base_total) }}
</span>
</div>
{!! view_render_event('bagisto.shop.checkout.cart-mini.item.price.after', ['item' => $item]) !!}
</div>
</div>
</div>
@endforeach
</div>
<!--Footer-->
<div class="modal-footer">
<h2 class="col-6 text-left fw6">
{{ __('shop::app.checkout.cart.cart-subtotal') }}
</h2>
{!! view_render_event('bagisto.shop.checkout.cart-mini.subtotal.before', ['cart' => $cart]) !!}
<h2 class="col-6 text-right fw6 no-padding">{{ core()->currency($cart->base_sub_total) }}</h2>
{!! view_render_event('bagisto.shop.checkout.cart-mini.subtotal.after', ['cart' => $cart]) !!}
</div>
<div class="modal-footer">
<a class="col text-left fs16 link-color remove-decoration" href="{{ route('shop.checkout.cart.index') }}">
{{ __('shop::app.minicart.view-cart') }}
</a>
<div class="col text-right no-padding">
<a href="{{ route('shop.checkout.onepage.index') }}">
<button
type="button"
class="theme-btn fs16 fw6">
{{ __('shop::app.minicart.checkout') }}
</button>
</a>
</div>
</div>
</div>
</div>
@else
<div class="dropdown disable-active">
<cart-btn item-count="{{ __('shop::app.minicart.zero') }}"></cart-btn>
</div>
@endif
<mini-cart
view-cart="{{ route('shop.checkout.cart.index') }}"
cart-text="{{ __('shop::app.minicart.view-cart') }}"
checkout-text="{{ __('shop::app.minicart.checkout') }}"
checkout-url="{{ route('shop.checkout.onepage.index') }}"
subtotal-text="{{ __('shop::app.checkout.cart.cart-subtotal') }}">
</mini-cart>
</div>

View File

@ -0,0 +1,181 @@
@extends('shop::layouts.master')
@section('page_title')
{{ __('velocity::app.customer.compare.compare_similar_items') }}
@endsection
@section('content-wrapper')
@php
$attributeRepository = app('\Webkul\Attribute\Repositories\AttributeRepository');
$comparableAttributes = $attributeRepository->findByField('is_comparable', 1);
@endphp
<compare-product></compare-product>
@endsection
@push('scripts')
<script type="text/x-template" id="compare-product-template">
<section class="cart-details row no-margin col-12">
<h1 class="fw6 col-6">
{{ __('velocity::app.customer.compare.compare_similar_items') }}
</h1>
<div class="col-6" v-if="products.length > 0">
<button class="theme-btn light pull-right" @click="removeProductCompare('all')">Clear All</button>
</div>
{!! view_render_event('bagisto.shop.customers.account.compare.view.before') !!}
<div class="row compare-products col-12 ml0">
<template v-if="products.length > 0">
@php
$comparableAttributes = $comparableAttributes->toArray();
array_splice($comparableAttributes, 1, 0, [[
'code' => 'image',
'admin_name' => 'Product Image'
]]);
array_splice($comparableAttributes, 2, 0, [[
'code' => 'addToCartHtml',
'admin_name' => 'Actions'
]]);
@endphp
@foreach ($comparableAttributes as $attribute)
<div class="row col-12 pr-0 mt15">
<div class="col-2">
<span class="fs16">{{ $attribute['admin_name'] }}</span>
</div>
<div class="col" :key="`title-${index}`" v-for="(product, index) in products">
@if ($attribute['code'] == 'name')
<a :href="`${$root.baseUrl}/${product.url_key}`" class="unset">
<h1 class="fw6 fs18" v-text="product['{{ $attribute['code'] }}']"></h1>
</a>
@elseif ($attribute['code'] == 'image')
<a :href="`${$root.baseUrl}/${product.url_key}`" class="unset">
<img :src="product['{{ $attribute['code'] }}']" class="image-wrapper"></span>
</a>
@elseif ($attribute['code'] == 'price')
<span v-html="product['priceHTML']"></span>
@elseif ($attribute['code'] == 'addToCartHtml')
<div class="action">
<vnode-injector :nodes="$root.getDynamicHTML(product.addToCartHtml)"></vnode-injector>
<i
class="material-icons cross fs16"
@click="removeProductCompare(isCustomer ? product.id : product.slug)">
close
</i>
</div>
@elseif ($attribute['code'] == 'color')
<span v-html="product.color_label"></span>
@elseif ($attribute['code'] == 'size')
<span v-html="product.size_label"></span>
@elseif ($attribute['code'] == 'size')
<span v-html="product.size_label"></span>
@else
<span v-html="product['{{ $attribute['code'] }}']"></span>
@endif
</div>
</div>
@endforeach
</template>
<span v-if="isProductListLoaded && products.length == 0">
@{{ __('customer.compare.empty-text') }}
</span>
</div>
{!! view_render_event('bagisto.shop.customers.account.compare.view.after') !!}
</section>
</script>
<script>
Vue.component('compare-product', {
template: '#compare-product-template',
data: function () {
return {
'products': [],
'isProductListLoaded': false,
'isCustomer': '{{ auth()->guard('customer')->user() ? "true" : "false" }}' == "true",
}
},
mounted: function () {
this.getComparedProducts();
},
methods: {
'getComparedProducts': function () {
if (this.isCustomer) {
var data = {
params: {
data: true,
}
};
} else {
let items = JSON.parse(window.localStorage.getItem('compared_product'));
items = items ? items.join('&') : '';
var data = {
params: {
items,
data: true,
}
};
}
this.$http.get(`${this.$root.baseUrl}/comparison`, data)
.then(response => {
this.isProductListLoaded = true;
this.products = response.data.products;
})
.catch(error => {
console.log(this.__('error.something_went_wrong'));
});
},
'removeProductCompare': function (productId) {
if (this.isCustomer) {
this.$http.delete(`${this.$root.baseUrl}/comparison?productId=${productId}`)
.then(response => {
if (productId == 'all') {
this.$set(this, 'products', this.products.filter(product => false));
} else {
this.$set(this, 'products', this.products.filter(product => product.id != productId));
}
window.showAlert(`alert-${response.data.status}`, response.data.label, response.data.message);
})
.catch(error => {
console.log(this.__('error.something_went_wrong'));
});
} else {
let existingItems = window.localStorage.getItem('compared_product');
existingItems = JSON.parse(existingItems);
if (productId == "all") {
updatedItems = [];
this.$set(this, 'products', []);
} else {
updatedItems = existingItems.filter(item => item != productId);
this.$set(this, 'products', this.products.filter(product => product.slug != productId));
}
window.localStorage.setItem('compared_product', JSON.stringify(updatedItems));
window.showAlert(
`alert-success`,
this.__('shop.general.alert.success'),
`${this.__('customer.compare.removed')}`
);
}
},
}
});
</script>
@endpush

View File

@ -18,6 +18,11 @@
$subMenuCollection['orders'] = $menuItem['children']['orders'];
$subMenuCollection['downloadables'] = $menuItem['children']['downloadables'];
$subMenuCollection['wishlist'] = $menuItem['children']['wishlist'];
$subMenuCollection['compare'] = [
'key' => 'account.compare',
'url' => route('velocity.product.compare'),
'name' => 'velocity::app.customer.compare.text',
];
$subMenuCollection['reviews'] = $menuItem['children']['reviews'];
$subMenuCollection['address'] = $menuItem['children']['address'];
} catch (\Exception $exception) {
@ -26,7 +31,7 @@
@endphp
@foreach ($subMenuCollection as $index => $subMenuItem)
<li class="{{ $menu->getActive($subMenuItem) }}">
<li class="{{ $menu->getActive($subMenuItem) }}" title="{{ trans($subMenuItem['name']) }}">
<a class="unset fw6 full-width" href="{{ $subMenuItem['url'] }}">
<i class="icon {{ $index }} text-down-3"></i>
<span>{{ trans($subMenuItem['name']) }}<span>

View File

@ -44,8 +44,6 @@
{{ __('shop::app.customer.account.profile.index.edit') }}
</a>
</span>
<div class="horizontal-rule"></div>
</div>
{!! view_render_event('bagisto.shop.customers.account.profile.view.before', ['customer' => $customer]) !!}

View File

@ -132,25 +132,23 @@
<script type="text/javascript">
(() => {
var showAlert = (messageType, messageLabel, message) => {
window.showAlert = (messageType, messageLabel, message) => {
if (messageType && message !== '') {
let html = `<div class="alert ${messageType} alert-dismissible" id="alert">
<a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</a>
<strong>${messageLabel} !</strong> ${message}.
<strong>${messageLabel ? messageLabel + '!' : ''} </strong> ${message}.
</div>`;
document.body.innerHTML += html;
$('body').append(html);
window.setTimeout(() => {
$(".alert").fadeTo(500, 0).slideUp(500, () => {
$(this).remove();
});
$(".alert").remove();
}, 5000);
}
}
let messageType = 'alert-success';
let messageLabel = 'dsfghjkl';
let messageType = '';
let messageLabel = '';
@if ($message = session('success'))
messageType = 'alert-success';
@ -167,7 +165,7 @@
@endif
if (messageType && '{{ $message }}' !== '') {
showAlert(messageType, messageLabel, '{{ $message }}');
window.showAlert(messageType, messageLabel, '{{ $message }}');
}
window.serverErrors = [];

View File

@ -86,6 +86,10 @@
<a href="{{ route('customer.wishlist.index') }}" class="unset">{{ __('shop::app.header.wishlist') }}</a>
</li>
<li>
<a href="{{ route('velocity.product.compare') }}" class="unset">{{ __('velocity::app.customer.compare.text') }}</a>
</li>
<li>
<a href="{{ route('customer.session.destroy') }}" class="unset">{{ __('shop::app.header.logout') }}</a>
</li>

View File

@ -1,30 +1,8 @@
{!! view_render_event('bagisto.shop.products.add_to_cart.before', ['product' => $product]) !!}
<div class="row mx-0 col-12 no-padding">
<div class="add-to-cart-btn pl0">
@if (isset($form) && !$form)
<button
type="submit"
{{ ! $product->isSaleable() ? 'disabled' : '' }}
class="btn btn-add-to-cart {{ $addToCartBtnClass ?? '' }}">
@if (! (isset($showCartIcon) && !$showCartIcon))
<i class="material-icons text-down-3">shopping_cart</i>
@endif
<span class="fs14 fw6 text-uppercase text-up-4">
{{ __('shop::app.products.add-to-cart') }}
</span>
</button>
@else
<form
method="POST"
action="{{ route('cart.add', $product->product_id) }}">
@csrf
<input type="hidden" name="product_id" value="{{ $product->product_id }}">
<input type="hidden" name="quantity" value="1">
<div class="row mx-0 col-12 no-padding">
<div class="add-to-cart-btn pl0">
@if (isset($form) && !$form)
<button
type="submit"
{{ ! $product->isSaleable() ? 'disabled' : '' }}
@ -35,28 +13,42 @@
@endif
<span class="fs14 fw6 text-uppercase text-up-4">
{{ $btnText ?? __('shop::app.products.add-to-cart') }}
{{ __('shop::app.products.add-to-cart') }}
</span>
</button>
</form>
@else
<add-to-cart
form="true"
csrf-token='{{ csrf_token() }}'
product-id="{{ $product->product_id }}"
add-class-to-btn="{{ $addToCartBtnClass ?? '' }}"
is-enable={{ ! $product->isSaleable() ? 'false' : 'true' }}
show-cart-icon={{ !(isset($showCartIcon) && !$showCartIcon) }}
btn-text="{{ $btnText ?? __('shop::app.products.add-to-cart') }}">
</add-to-cart>
@endif
</div>
{{-- <add-to-cart
form="true"
csrf-token='{{ csrf_token() }}'
product-id="{{ $product->product_id }}"
add-class-to-btn="{{ $addToCartBtnClass ?? '' }}"
is-enable={{ ! $product->isSaleable() ? 'false' : 'true' }}
show-cart-icon={{ !(isset($showCartIcon) && !$showCartIcon) }}
btn-text="{{ $btnText ?? __('shop::app.products.add-to-cart') }}">
</add-to-cart> --}}
@if (isset($showCompare) && $showCompare)
<compare-component
@auth('customer')
customer="true"
@endif
@guest('customer')
customer="false"
@endif
slug="{{ $product->url_key }}"
product-id="{{ $product->id }}"
></compare-component>
@endif
@if (! (isset($showWishlist) && !$showWishlist))
@include('shop::products.wishlist', [
'addClass' => $addWishlistClass ?? ''
])
@endif
</div>
@if (! (isset($showWishlist) && !$showWishlist))
@include('shop::products.wishlist', [
'addClass' => $addWishlistClass ?? ''
])
@endif
</div>
{!! view_render_event('bagisto.shop.products.add_to_cart.after', ['product' => $product]) !!}

View File

@ -18,7 +18,7 @@
font-size: 18px;
font-weight: 600;
}
@media only screen and (max-width: 992px) {
.main-content-wrapper .vc-header {
box-shadow: unset;
@ -61,7 +61,7 @@
@endif
</div>
<div class="col-12">
<div class="col-12 no-padding">
<div class="hero-image">
@if (!is_null($category->image))
<img class="logo" src="{{ $category->image_url }}" />

View File

@ -65,6 +65,7 @@
<div class="cart-wish-wrap mt5">
@include ('shop::products.add-to-cart', [
'product' => $product,
'showCompare' => true,
'addWishlistClass' => 'pl10',
'addToCartBtnClass' => 'medium-padding'
])
@ -120,6 +121,7 @@
@include ('shop::products.add-to-cart', [
'product' => $product,
'addWishlistClass' => 'col-lg-4 col-md-4 col-sm-12 offset-lg-4 pr0',
'showCompare' => true,
'addToCartBtnClass' => $addToCartBtnClass ?? '',
'btnText' => $btnText ?? null
])

View File

@ -2,12 +2,21 @@
@inject ('reviewHelper', 'Webkul\Product\Helpers\Review')
@inject ('customHelper', 'Webkul\Velocity\Helpers\Helper')
@inject ('productImageHelper', 'Webkul\Product\Helpers\ProductImage')
@php
$total = $reviewHelper->getTotalReviews($product);
$avgRatings = $reviewHelper->getAverageRating($product);
$avgStarRating = ceil($avgRatings);
$productImages = [];
$images = $productImageHelper->getGalleryImages($product);
foreach ($images as $key => $image) {
array_push($productImages, $image['medium_image_url']);
}
@endphp
@section('page_title')
@ -24,7 +33,7 @@
.related-products {
width: 100%;
}
.recently-viewed {
margin-top: 20px;
}
@ -88,6 +97,7 @@
@include ('shop::products.add-to-cart', [
'form' => false,
'product' => $product,
'showCompare' => true,
'showCartIcon' => false,
])
</div>
@ -162,10 +172,18 @@
@endsection
@push('scripts')
<script type='text/javascript' src='https://unpkg.com/spritespin@4.1.0/release/spritespin.js'></script>
<script type="text/x-template" id="product-view-template">
<form method="POST" id="product-form" action="{{ route('cart.add', $product->product_id) }}" @click="onSubmit($event)">
<input type="hidden" name="is_buy_now" v-model="is_buy_now">
<slot></slot>
<slot v-if="slot"></slot>
<div v-else>
<div class="spritespin"></div>
</div>
</form>
</script>
@ -175,11 +193,14 @@
template: '#product-view-template',
data: function() {
return {
slot: true,
is_buy_now: 0,
}
},
mounted: function () {
// this.open360View();
let currentProductId = '{{ $product->url_key }}';
let existingViewed = window.localStorage.getItem('recentlyViewed');
if (! existingViewed) {
@ -217,27 +238,58 @@
e.preventDefault();
var this_this = this;
this.$validator.validateAll().then(function (result) {
this.$validator.validateAll().then(result => {
if (result) {
this_this.is_buy_now = e.target.classList.contains('buynow') ? 1 : 0;
this.is_buy_now = e.target.classList.contains('buynow') ? 1 : 0;
setTimeout(function() {
document.getElementById('product-form').submit();
}, 0);
}
});
},
open360View: function () {
this.slot = false;
setTimeout(() => {
$('.spritespin').spritespin({
source: SpriteSpin.sourceArray('http://shubham.webkul.com/3d-image/sample-{lane}-{frame}.jpg', {
lane: [0,5],
frame: [0,5],
digits: 2
}),
// width and height of the display
width: 400,
height: 225,
// the number of lanes (vertical angles)
lanes: 12,
// the number of frames per lane (per vertical angle)
frames: 24,
// interaction sensitivity (and direction) modifier for horizontal movement
sense: 1,
// interaction sensitivity (and direction) modifier for vertical movement
senseLane: -2,
// the initial lane number
lane: 6,
// the initial frame number (within the lane)
frame: 0,
// disable autostart of the animation
animate: false,
plugins: [
'progress',
'360',
'drag'
]
});
}, 0);
}
}
});
$(document).ready(function() {
var addTOButton = document.getElementsByClassName('add-to-buttons')[0];
// document.getElementById('loader').style.display="none";
// addTOButton.style.display="flex";
});
window.onload = function() {
var thumbList = document.getElementsByClassName('thumb-list')[0];
var thumbFrame = document.getElementsByClassName('thumb-frame');

View File

@ -16,15 +16,16 @@
title="{{ __('velocity::app.shop.wishlist.remove-wishlist-text') }}"
@endif>
<wishlist-component active="{{ !$isWished }}"></wishlist-component>
<wishlist-component active="{{ !$isWished }}" is-customer="true"></wishlist-component>
</a>
@endauth
@guest('customer')
<a
href="{{ route('customer.session.index') }}"
class="unset wishlist-icon {{ $addWishlistClass ?? '' }} text-right">
<wishlist-component active="false"></wishlist-component>
</a>
<wishlist-component
active="false"
is-customer="false"
product-id="{{ $product->product_id }}"
add-class="{{ $addWishlistClass ?? '' }}">
</wishlist-component>
@endauth
{!! view_render_event('bagisto.shop.products.wishlist.after') !!}