¨4.0.1¨
This commit is contained in:
@@ -12,8 +12,8 @@ use Modules\Media\Entities\File;
|
||||
use Modules\Brand\Entities\Brand;
|
||||
use Modules\Slider\Entities\Slider;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Modules\Product\Entities\Product;
|
||||
use Modules\FlashSale\Entities\FlashSale;
|
||||
use Modules\Product\Repositories\ProductRepository;
|
||||
|
||||
class StorefrontTabs extends Tabs
|
||||
{
|
||||
@@ -50,6 +50,7 @@ class StorefrontTabs extends Tabs
|
||||
->add($this->oneColumnBanner());
|
||||
}
|
||||
|
||||
|
||||
private function general()
|
||||
{
|
||||
return tap(new Tab('general', trans('storefront::storefront.tabs.general')), function (Tab $tab) {
|
||||
@@ -63,18 +64,21 @@ class StorefrontTabs extends Tabs
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function getPages()
|
||||
{
|
||||
return Page::all()->pluck('name', 'id')
|
||||
->prepend(trans('storefront::storefront.form.please_select'), '');
|
||||
}
|
||||
|
||||
|
||||
private function getSliders()
|
||||
{
|
||||
return Slider::all()->sortBy('name')->pluck('name', 'id')
|
||||
->prepend(trans('storefront::storefront.form.please_select'), '');
|
||||
}
|
||||
|
||||
|
||||
private function logo()
|
||||
{
|
||||
return tap(new Tab('logo', trans('storefront::storefront.tabs.logo')), function (Tab $tab) {
|
||||
@@ -88,6 +92,15 @@ class StorefrontTabs extends Tabs
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function getMedia($fileId)
|
||||
{
|
||||
return Cache::rememberForever(md5("files.{$fileId}"), function () use ($fileId) {
|
||||
return File::findOrNew($fileId);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function menus()
|
||||
{
|
||||
return tap(new Tab('menus', trans('storefront::storefront.tabs.menus')), function (Tab $tab) {
|
||||
@@ -106,12 +119,14 @@ class StorefrontTabs extends Tabs
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function getMenus()
|
||||
{
|
||||
return Menu::all()->pluck('name', 'id')
|
||||
->prepend(trans('storefront::storefront.form.please_select'), '');
|
||||
}
|
||||
|
||||
|
||||
private function footer()
|
||||
{
|
||||
return tap(new Tab('footer', trans('storefront::storefront.tabs.footer')), function (Tab $tab) {
|
||||
@@ -123,9 +138,10 @@ class StorefrontTabs extends Tabs
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function newsletter()
|
||||
{
|
||||
if (! setting('newsletter_enabled')) {
|
||||
if (!setting('newsletter_enabled')) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -137,12 +153,6 @@ class StorefrontTabs extends Tabs
|
||||
});
|
||||
}
|
||||
|
||||
private function getMedia($fileId)
|
||||
{
|
||||
return Cache::rememberForever(md5("files.{$fileId}"), function () use ($fileId) {
|
||||
return File::findOrNew($fileId);
|
||||
});
|
||||
}
|
||||
|
||||
private function features()
|
||||
{
|
||||
@@ -152,6 +162,7 @@ class StorefrontTabs extends Tabs
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function productPage()
|
||||
{
|
||||
return tap(new Tab('product_page', trans('storefront::storefront.tabs.product_page')), function (Tab $tab) {
|
||||
@@ -162,6 +173,7 @@ class StorefrontTabs extends Tabs
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function socialLinks()
|
||||
{
|
||||
return tap(new Tab('social_links', trans('storefront::storefront.tabs.social_links')), function (Tab $tab) {
|
||||
@@ -181,6 +193,7 @@ class StorefrontTabs extends Tabs
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function sliderBanners()
|
||||
{
|
||||
return tap(new Tab('slider_banners', trans('storefront::storefront.tabs.slider_banners')), function (Tab $tab) {
|
||||
@@ -191,6 +204,7 @@ class StorefrontTabs extends Tabs
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function threeColumnFullWidthBanners()
|
||||
{
|
||||
return tap(new Tab('three_column_full_width_banners', trans('storefront::storefront.tabs.three_column_full_width_banners')), function (Tab $tab) {
|
||||
@@ -201,6 +215,7 @@ class StorefrontTabs extends Tabs
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function featuredCategories()
|
||||
{
|
||||
return tap(new Tab('featured_categories', trans('storefront::storefront.tabs.featured_categories')), function (Tab $tab) {
|
||||
@@ -216,6 +231,13 @@ class StorefrontTabs extends Tabs
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function getProductListFromSetting($key)
|
||||
{
|
||||
return ProductRepository::list(setting($key, []));
|
||||
}
|
||||
|
||||
|
||||
private function productTabsOne()
|
||||
{
|
||||
return tap(new Tab('product_tabs_one', trans('storefront::storefront.tabs.product_tabs_one')), function (Tab $tab) {
|
||||
@@ -229,9 +251,10 @@ class StorefrontTabs extends Tabs
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function topBrands()
|
||||
{
|
||||
if (! auth()->user()->hasAccess(['admin.brands.index'])) {
|
||||
if (!auth()->user()->hasAccess(['admin.brands.index'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -243,6 +266,7 @@ class StorefrontTabs extends Tabs
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function flashSaleAndVerticalProducts()
|
||||
{
|
||||
return tap(new Tab('flash_sale_and_vertical_products', trans('storefront::storefront.tabs.flash_sale_and_vertical_products')), function (Tab $tab) {
|
||||
@@ -256,12 +280,14 @@ class StorefrontTabs extends Tabs
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function getFlashSales()
|
||||
{
|
||||
return FlashSale::all()->pluck('campaign_name', 'id')
|
||||
->prepend(trans('admin::admin.form.please_select'), '');
|
||||
}
|
||||
|
||||
|
||||
private function twoColumnBanners()
|
||||
{
|
||||
return tap(new Tab('two_column_banners', trans('storefront::storefront.tabs.two_column_banners')), function (Tab $tab) {
|
||||
@@ -272,6 +298,7 @@ class StorefrontTabs extends Tabs
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function productGrid()
|
||||
{
|
||||
return tap(new Tab('product_grid', trans('storefront::storefront.tabs.product_grid')), function (Tab $tab) {
|
||||
@@ -285,6 +312,7 @@ class StorefrontTabs extends Tabs
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function threeColumnBanners()
|
||||
{
|
||||
return tap(new Tab('three_column_banners', trans('storefront::storefront.tabs.three_column_banners')), function (Tab $tab) {
|
||||
@@ -295,6 +323,7 @@ class StorefrontTabs extends Tabs
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function productTabsTwo()
|
||||
{
|
||||
return tap(new Tab('product_tabs_two', trans('storefront::storefront.tabs.product_tabs_two')), function (Tab $tab) {
|
||||
@@ -308,6 +337,7 @@ class StorefrontTabs extends Tabs
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function oneColumnBanner()
|
||||
{
|
||||
return tap(new Tab('one_column_banner', trans('storefront::storefront.tabs.one_column_banner')), function (Tab $tab) {
|
||||
@@ -317,9 +347,4 @@ class StorefrontTabs extends Tabs
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
private function getProductListFromSetting($key)
|
||||
{
|
||||
return Product::list(setting($key, []));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,57 +11,20 @@ class Banner
|
||||
public $call_to_action_url;
|
||||
public $open_in_new_window;
|
||||
|
||||
|
||||
public function __construct($image, $call_to_action_url, $open_in_new_window)
|
||||
{
|
||||
$this->image = $image;
|
||||
$this->call_to_action_url = $call_to_action_url;
|
||||
$this->open_in_new_window = (bool) $open_in_new_window;
|
||||
$this->open_in_new_window = (bool)$open_in_new_window;
|
||||
}
|
||||
|
||||
|
||||
public static function getProductPageBanner()
|
||||
{
|
||||
return self::findByName('storefront_product_page_banner');
|
||||
}
|
||||
|
||||
public static function getSliderBanners()
|
||||
{
|
||||
return [
|
||||
'banner_1' => self::findByName('storefront_slider_banner_1'),
|
||||
'banner_2' => self::findByName('storefront_slider_banner_2'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getThreeColumnFullWidthBanners()
|
||||
{
|
||||
return [
|
||||
'background' => self::findByName('storefront_three_column_full_width_banners_background'),
|
||||
'banner_1' => self::findByName('storefront_three_column_full_width_banners_1'),
|
||||
'banner_2' => self::findByName('storefront_three_column_full_width_banners_2'),
|
||||
'banner_3' => self::findByName('storefront_three_column_full_width_banners_3'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getTwoColumnBanners()
|
||||
{
|
||||
return [
|
||||
'banner_1' => self::findByName('storefront_two_column_banners_1'),
|
||||
'banner_2' => self::findByName('storefront_two_column_banners_2'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getThreeColumnBanners()
|
||||
{
|
||||
return [
|
||||
'banner_1' => self::findByName('storefront_three_column_banners_1'),
|
||||
'banner_2' => self::findByName('storefront_three_column_banners_2'),
|
||||
'banner_3' => self::findByName('storefront_three_column_banners_3'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getOneColumnBanner()
|
||||
{
|
||||
return self::findByName('storefront_one_column_banner');
|
||||
}
|
||||
|
||||
public static function findByName($name)
|
||||
{
|
||||
@@ -74,4 +37,49 @@ class Banner
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public static function getSliderBanners()
|
||||
{
|
||||
return [
|
||||
'banner_1' => self::findByName('storefront_slider_banner_1'),
|
||||
'banner_2' => self::findByName('storefront_slider_banner_2'),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public static function getThreeColumnFullWidthBanners()
|
||||
{
|
||||
return [
|
||||
'background' => self::findByName('storefront_three_column_full_width_banners_background'),
|
||||
'banner_1' => self::findByName('storefront_three_column_full_width_banners_1'),
|
||||
'banner_2' => self::findByName('storefront_three_column_full_width_banners_2'),
|
||||
'banner_3' => self::findByName('storefront_three_column_full_width_banners_3'),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public static function getTwoColumnBanners()
|
||||
{
|
||||
return [
|
||||
'banner_1' => self::findByName('storefront_two_column_banners_1'),
|
||||
'banner_2' => self::findByName('storefront_two_column_banners_2'),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public static function getThreeColumnBanners()
|
||||
{
|
||||
return [
|
||||
'banner_1' => self::findByName('storefront_three_column_banners_1'),
|
||||
'banner_2' => self::findByName('storefront_three_column_banners_2'),
|
||||
'banner_3' => self::findByName('storefront_three_column_banners_3'),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public static function getOneColumnBanner()
|
||||
{
|
||||
return self::findByName('storefront_one_column_banner');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ class Feature
|
||||
public $title;
|
||||
public $subtitle;
|
||||
|
||||
|
||||
public function __construct($icon, $title, $subtitle)
|
||||
{
|
||||
$this->icon = $icon;
|
||||
@@ -17,9 +18,10 @@ class Feature
|
||||
$this->subtitle = $subtitle;
|
||||
}
|
||||
|
||||
|
||||
public static function all()
|
||||
{
|
||||
if (! setting('storefront_features_section_enabled')) {
|
||||
if (!setting('storefront_features_section_enabled')) {
|
||||
return collect();
|
||||
}
|
||||
|
||||
@@ -28,6 +30,7 @@ class Feature
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private static function getFeatureFor($number)
|
||||
{
|
||||
return new self(
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Themes\Storefront\Http\Controllers\Admin;
|
||||
|
||||
use Illuminate\Http\Response;
|
||||
use Modules\Admin\Ui\Facades\TabManager;
|
||||
use Themes\Storefront\Http\Requests\SaveStorefrontRequest;
|
||||
|
||||
@@ -10,7 +11,7 @@ class StorefrontController
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return Response
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
@@ -20,15 +21,16 @@ class StorefrontController
|
||||
return view('admin.storefront.edit', compact('settings', 'tabs'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return Response
|
||||
*/
|
||||
public function update(SaveStorefrontRequest $request)
|
||||
{
|
||||
setting($request->except('_token', '_method'));
|
||||
|
||||
return back()->withSuccess(trans('admin::messages.resource_saved', ['resource' => trans('setting::settings.settings')]));
|
||||
return back()->withSuccess(trans('admin::messages.resource_updated', ['resource' => trans('setting::settings.settings')]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,13 +2,16 @@
|
||||
|
||||
namespace Themes\Storefront\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Response;
|
||||
|
||||
class FeaturedCategoryProductController extends ProductIndexController
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param int $categoryNumber
|
||||
* @return \Illuminate\Http\Response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index($categoryNumber)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Themes\Storefront\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Response;
|
||||
use Modules\FlashSale\Entities\FlashSale;
|
||||
|
||||
class FlashSaleProductController
|
||||
@@ -9,7 +10,7 @@ class FlashSaleProductController
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@ class NewsletterPopup
|
||||
return response('')->withCookie($cookie);
|
||||
}
|
||||
|
||||
|
||||
public function destroy()
|
||||
{
|
||||
$cookie = cookie()->forever('show_newsletter_popup', false);
|
||||
|
||||
@@ -2,13 +2,16 @@
|
||||
|
||||
namespace Themes\Storefront\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Response;
|
||||
|
||||
class ProductGridController extends ProductIndexController
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param int $tabNumber
|
||||
* @return \Illuminate\Http\Response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index($tabNumber)
|
||||
{
|
||||
|
||||
@@ -11,18 +11,20 @@ class ProductIndexController
|
||||
{
|
||||
private $recentlyViewed;
|
||||
|
||||
|
||||
public function __construct(RecentlyViewed $recentlyViewed)
|
||||
{
|
||||
$this->recentlyViewed = $recentlyViewed;
|
||||
}
|
||||
|
||||
|
||||
protected function getProducts($settingPrefix)
|
||||
{
|
||||
$type = setting("{$settingPrefix}_product_type", 'custom_products');
|
||||
$limit = setting("{$settingPrefix}_products_limit");
|
||||
|
||||
if ($type === 'category_products') {
|
||||
return $this->categoryProducts($settingPrefix,$limit);
|
||||
return $this->categoryProducts($settingPrefix, $limit);
|
||||
}
|
||||
|
||||
if ($type === 'recently_viewed_products') {
|
||||
@@ -37,7 +39,8 @@ class ProductIndexController
|
||||
->clean();
|
||||
}
|
||||
|
||||
private function categoryProducts($settingPrefix,$limit)
|
||||
|
||||
private function categoryProducts($settingPrefix, $limit)
|
||||
{
|
||||
return Category::findOrNew(setting("{$settingPrefix}_category_id"))
|
||||
->products()
|
||||
@@ -46,33 +49,36 @@ class ProductIndexController
|
||||
->get();
|
||||
}
|
||||
|
||||
|
||||
private function recentlyViewedProducts($limit)
|
||||
{
|
||||
return collect($this->recentlyViewed->products())
|
||||
->reverse()
|
||||
->when(! is_null($limit), function (Collection $products) use ($limit) {
|
||||
->when(!is_null($limit), function (Collection $products) use ($limit) {
|
||||
return $products->take($limit);
|
||||
})
|
||||
->values();
|
||||
}
|
||||
|
||||
|
||||
private function latestProductsCallback($limit)
|
||||
{
|
||||
return function ($query) use ($limit) {
|
||||
$query->latest()
|
||||
->when(! is_null($limit), function ($q) use ($limit) {
|
||||
->when(!is_null($limit), function ($q) use ($limit) {
|
||||
$q->limit($limit);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private function customProductsCallback($settingPrefix)
|
||||
{
|
||||
return function ($query) use ($settingPrefix) {
|
||||
$productIds = setting("{$settingPrefix}_products", []);
|
||||
|
||||
$query->whereIn('id', $productIds)
|
||||
->when(! empty($productIds), function ($q) use ($productIds) {
|
||||
->when(!empty($productIds), function ($q) use ($productIds) {
|
||||
$productIdsString = collect($productIds)->filter()->implode(',');
|
||||
|
||||
$q->orderByRaw("FIELD(id, {$productIdsString})");
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Themes\Storefront\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Response;
|
||||
|
||||
class TabProductController extends ProductIndexController
|
||||
{
|
||||
/**
|
||||
@@ -9,7 +11,8 @@ class TabProductController extends ProductIndexController
|
||||
*
|
||||
* @param int $sectionNumber
|
||||
* @param int $tabNumber
|
||||
* @return \Illuminate\Http\Response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index($sectionNumber, $tabNumber)
|
||||
{
|
||||
|
||||
@@ -2,13 +2,16 @@
|
||||
|
||||
namespace Themes\Storefront\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Response;
|
||||
|
||||
class VerticalProductController extends ProductIndexController
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param int $columnNumber
|
||||
* @return \Illuminate\Http\Response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index($columnNumber)
|
||||
{
|
||||
|
||||
@@ -38,6 +38,7 @@ class SaveStorefrontRequest extends Request
|
||||
'storefront_product_tabs_2_section_tab_4_products',
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Get data to be validated from the request.
|
||||
*
|
||||
@@ -46,7 +47,7 @@ class SaveStorefrontRequest extends Request
|
||||
public function validationData()
|
||||
{
|
||||
foreach ($this->shouldCheck as $attribute) {
|
||||
if (! $this->has($attribute)) {
|
||||
if (!$this->has($attribute)) {
|
||||
$this->merge([$attribute => null]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Themes\Storefront\Http\ViewComposers;
|
||||
|
||||
use Illuminate\View\View;
|
||||
use Themes\Storefront\Banner;
|
||||
use Themes\Storefront\Feature;
|
||||
use Modules\Brand\Entities\Brand;
|
||||
@@ -15,7 +16,8 @@ class HomePageComposer
|
||||
/**
|
||||
* Bind data to the view.
|
||||
*
|
||||
* @param \Illuminate\View\View $view
|
||||
* @param View $view
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function compose($view)
|
||||
@@ -37,9 +39,10 @@ class HomePageComposer
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
private function featuredCategoriesSection()
|
||||
{
|
||||
if (! setting('storefront_featured_categories_section_enabled')) {
|
||||
if (!setting('storefront_featured_categories_section_enabled')) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -50,10 +53,11 @@ class HomePageComposer
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
private function getFeaturedCategories()
|
||||
{
|
||||
$categoryIds = Collection::times(6, function ($number) {
|
||||
if (! is_null(setting("storefront_featured_categories_section_category_{$number}_product_type"))) {
|
||||
if (!is_null(setting("storefront_featured_categories_section_category_{$number}_product_type"))) {
|
||||
return setting("storefront_featured_categories_section_category_{$number}_category_id");
|
||||
}
|
||||
})->filter();
|
||||
@@ -72,6 +76,7 @@ class HomePageComposer
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function threeColumnFullWidthBanners()
|
||||
{
|
||||
if (setting('storefront_three_column_full_width_banners_enabled')) {
|
||||
@@ -79,22 +84,24 @@ class HomePageComposer
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function productTabsOne()
|
||||
{
|
||||
if (! setting('storefront_product_tabs_1_section_enabled')) {
|
||||
if (!setting('storefront_product_tabs_1_section_enabled')) {
|
||||
return;
|
||||
}
|
||||
|
||||
return Collection::times(4, function ($number) {
|
||||
if (! is_null(setting("storefront_product_tabs_1_section_tab_{$number}_product_type"))) {
|
||||
if (!is_null(setting("storefront_product_tabs_1_section_tab_{$number}_product_type"))) {
|
||||
return setting("storefront_product_tabs_1_section_tab_{$number}_title");
|
||||
}
|
||||
})->filter();
|
||||
}
|
||||
|
||||
|
||||
private function topBrands()
|
||||
{
|
||||
if (! setting('storefront_top_brands_section_enabled')) {
|
||||
if (!setting('storefront_top_brands_section_enabled')) {
|
||||
return collect();
|
||||
}
|
||||
|
||||
@@ -103,7 +110,7 @@ class HomePageComposer
|
||||
return Cache::rememberForever(md5('storefront_top_brands:' . serialize($topBrandIds)), function () use ($topBrandIds) {
|
||||
return Brand::with('files')
|
||||
->whereIn('id', $topBrandIds)
|
||||
->when(! empty($topBrandIds), function ($query) use ($topBrandIds) {
|
||||
->when(!empty($topBrandIds), function ($query) use ($topBrandIds) {
|
||||
$topBrandIdsString = collect($topBrandIds)->filter()->implode(',');
|
||||
|
||||
$query->orderByRaw("FIELD(id, {$topBrandIdsString})");
|
||||
@@ -118,6 +125,7 @@ class HomePageComposer
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function flashSaleAndVerticalProducts()
|
||||
{
|
||||
return [
|
||||
@@ -128,6 +136,7 @@ class HomePageComposer
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
private function twoColumnBanners()
|
||||
{
|
||||
if (setting('storefront_two_column_banners_enabled')) {
|
||||
@@ -135,19 +144,21 @@ class HomePageComposer
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function productGrid()
|
||||
{
|
||||
if (! setting('storefront_product_grid_section_enabled')) {
|
||||
if (!setting('storefront_product_grid_section_enabled')) {
|
||||
return;
|
||||
}
|
||||
|
||||
return Collection::times(4, function ($number) {
|
||||
if (! is_null(setting("storefront_product_grid_section_tab_{$number}_product_type"))) {
|
||||
if (!is_null(setting("storefront_product_grid_section_tab_{$number}_product_type"))) {
|
||||
return setting("storefront_product_grid_section_tab_{$number}_title");
|
||||
}
|
||||
})->filter();
|
||||
}
|
||||
|
||||
|
||||
private function threeColumnBanners()
|
||||
{
|
||||
if (setting('storefront_three_column_banners_enabled')) {
|
||||
@@ -155,14 +166,15 @@ class HomePageComposer
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function tabProductsTwo()
|
||||
{
|
||||
if (! setting('storefront_product_tabs_2_section_enabled')) {
|
||||
if (!setting('storefront_product_tabs_2_section_enabled')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$tabs = Collection::times(4, function ($number) {
|
||||
if (! is_null(setting("storefront_product_tabs_2_section_tab_{$number}_product_type"))) {
|
||||
if (!is_null(setting("storefront_product_tabs_2_section_tab_{$number}_product_type"))) {
|
||||
return setting("storefront_product_tabs_2_section_tab_{$number}_title");
|
||||
}
|
||||
})->filter();
|
||||
@@ -173,6 +185,7 @@ class HomePageComposer
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
private function oneColumnBanner()
|
||||
{
|
||||
if (setting('storefront_one_column_banner_enabled')) {
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Themes\Storefront\Http\ViewComposers;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\View\View;
|
||||
use Mexitek\PHPColors\Color;
|
||||
use Modules\Compare\Compare;
|
||||
use Spatie\SchemaOrg\Schema;
|
||||
@@ -18,24 +20,27 @@ use Modules\Product\Entities\SearchTerm;
|
||||
class LayoutComposer
|
||||
{
|
||||
/**
|
||||
* @var \Modules\Compare\Compare
|
||||
* @var Compare
|
||||
*/
|
||||
private $compare;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new view composer instance.
|
||||
*
|
||||
* @param \Modules\Compare\Compare $compare
|
||||
* @param Compare $compare
|
||||
*/
|
||||
public function __construct(Compare $compare)
|
||||
{
|
||||
$this->compare = $compare;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Bind data to the view.
|
||||
*
|
||||
* @param \Illuminate\View\View $view
|
||||
* @param View $view
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function compose($view)
|
||||
@@ -63,29 +68,36 @@ class LayoutComposer
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function footerTagsCallback($tagIds)
|
||||
{
|
||||
return function () use ($tagIds) {
|
||||
return Tag::whereIn('id', $tagIds)
|
||||
->when(!empty($tagIds), function ($query) use ($tagIds) {
|
||||
$tagIdsString = collect($tagIds)->filter()->implode(',');
|
||||
|
||||
$query->orderByRaw("FIELD(id, {$tagIdsString})");
|
||||
})
|
||||
->get();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private function getThemeColor()
|
||||
{
|
||||
try {
|
||||
return new Color(storefront_theme_color());
|
||||
} catch (\Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
return new Color('#0068e1');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function getFavicon()
|
||||
{
|
||||
return $this->getMedia(setting('storefront_favicon'))->path;
|
||||
}
|
||||
|
||||
private function getHeaderLogo()
|
||||
{
|
||||
return $this->getMedia(setting('storefront_header_logo'))->path;
|
||||
}
|
||||
|
||||
private function getNewsletterBgImage()
|
||||
{
|
||||
return $this->getMedia(setting('storefront_newsletter_bg_image'))->path;
|
||||
}
|
||||
|
||||
private function getMedia($fileId)
|
||||
{
|
||||
@@ -94,6 +106,19 @@ class LayoutComposer
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function getHeaderLogo()
|
||||
{
|
||||
return $this->getMedia(setting('storefront_header_logo'))->path;
|
||||
}
|
||||
|
||||
|
||||
private function getNewsletterBgImage()
|
||||
{
|
||||
return $this->getMedia(setting('storefront_newsletter_bg_image'))->path;
|
||||
}
|
||||
|
||||
|
||||
private function getPrivacyPageUrl()
|
||||
{
|
||||
return Cache::tags('settings')->rememberForever('privacy_page_url', function () {
|
||||
@@ -101,11 +126,13 @@ class LayoutComposer
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function getCategories()
|
||||
{
|
||||
return Category::searchable();
|
||||
}
|
||||
|
||||
|
||||
private function getMostSearchedKeywords()
|
||||
{
|
||||
return Cache::remember('most_searched_keywords', now()->addHour(), function () {
|
||||
@@ -113,21 +140,25 @@ class LayoutComposer
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function getPrimaryMenu()
|
||||
{
|
||||
return new MegaMenu(setting('storefront_primary_menu'));
|
||||
}
|
||||
|
||||
|
||||
private function getCategoryMenu()
|
||||
{
|
||||
return new MegaMenu(setting('storefront_category_menu'));
|
||||
}
|
||||
|
||||
|
||||
private function getCart()
|
||||
{
|
||||
return Cart::instance();
|
||||
}
|
||||
|
||||
|
||||
private function getWishlist()
|
||||
{
|
||||
if (auth()->guest()) {
|
||||
@@ -137,15 +168,12 @@ class LayoutComposer
|
||||
return auth()->user()->wishlist()->pluck('product_id');
|
||||
}
|
||||
|
||||
|
||||
private function getFooterMenuOne()
|
||||
{
|
||||
return $this->getFooterMenu(setting('storefront_footer_menu_one'));
|
||||
}
|
||||
|
||||
private function getFooterMenuTwo()
|
||||
{
|
||||
return $this->getFooterMenu(setting('storefront_footer_menu_two'));
|
||||
}
|
||||
|
||||
private function getFooterMenu($menuId)
|
||||
{
|
||||
@@ -155,6 +183,13 @@ class LayoutComposer
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function getFooterMenuTwo()
|
||||
{
|
||||
return $this->getFooterMenu(setting('storefront_footer_menu_two'));
|
||||
}
|
||||
|
||||
|
||||
private function getFooterTags()
|
||||
{
|
||||
$tagIds = setting('storefront_footer_tags', []);
|
||||
@@ -166,18 +201,6 @@ class LayoutComposer
|
||||
);
|
||||
}
|
||||
|
||||
public function footerTagsCallback($tagIds)
|
||||
{
|
||||
return function () use ($tagIds) {
|
||||
return Tag::whereIn('id', $tagIds)
|
||||
->when(! empty($tagIds), function ($query) use ($tagIds) {
|
||||
$tagIdsString = collect($tagIds)->filter()->implode(',');
|
||||
|
||||
$query->orderByRaw("FIELD(id, {$tagIdsString})");
|
||||
})
|
||||
->get();
|
||||
};
|
||||
}
|
||||
|
||||
private function getCopyrightText()
|
||||
{
|
||||
@@ -188,11 +211,13 @@ class LayoutComposer
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
private function getAcceptedPaymentMethodsImage()
|
||||
{
|
||||
return $this->getMedia(setting('storefront_accepted_payment_methods_image'));
|
||||
}
|
||||
|
||||
|
||||
private function getSchemaMarkup()
|
||||
{
|
||||
return Schema::webSite()
|
||||
@@ -200,6 +225,7 @@ class LayoutComposer
|
||||
->potentialAction($this->searchActionSchema());
|
||||
}
|
||||
|
||||
|
||||
private function searchActionSchema()
|
||||
{
|
||||
return Schema::searchAction()
|
||||
|
||||
@@ -2,40 +2,64 @@
|
||||
|
||||
namespace Themes\Storefront\Http\ViewComposers;
|
||||
|
||||
use Illuminate\View\View;
|
||||
use Modules\Support\Money;
|
||||
use Modules\Product\Entities\Product;
|
||||
use Modules\Category\Entities\Category;
|
||||
use Modules\Product\Entities\ProductVariant;
|
||||
|
||||
class ProductIndexPageComposer
|
||||
{
|
||||
/**
|
||||
* Bind data to the view.
|
||||
*
|
||||
* @param \Illuminate\View\View $view
|
||||
* @param View $view
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function compose($view)
|
||||
{
|
||||
$view->with([
|
||||
'categories' => $this->categories(),
|
||||
'minPrice' => $this->minPrice(),
|
||||
'maxPrice' => $this->maxPrice(),
|
||||
'latestProducts' => $this->latestProducts(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
private function categories()
|
||||
{
|
||||
return Category::tree();
|
||||
}
|
||||
|
||||
private function maxPrice()
|
||||
|
||||
private function minPrice()
|
||||
{
|
||||
return Money::inDefaultCurrency(Product::max('selling_price'))
|
||||
$minProductPrice = Product::min('selling_price');
|
||||
$minVariantPrice = ProductVariant::min('selling_price');
|
||||
$minPrice = min($minProductPrice, $minVariantPrice);
|
||||
|
||||
return Money::inDefaultCurrency($minPrice)
|
||||
->convertToCurrentCurrency()
|
||||
->ceil()
|
||||
->amount();
|
||||
}
|
||||
|
||||
|
||||
private function maxPrice()
|
||||
{
|
||||
$maxProductPrice = Product::max('selling_price');
|
||||
$maxVariantPrice = ProductVariant::max('selling_price');
|
||||
$maxPrice = max($maxProductPrice, $maxVariantPrice);
|
||||
|
||||
return Money::inDefaultCurrency($maxPrice)
|
||||
->convertToCurrentCurrency()
|
||||
->ceil()
|
||||
->amount();
|
||||
}
|
||||
|
||||
|
||||
private function latestProducts()
|
||||
{
|
||||
return Product::forCard()->take(5)->latest()->get()->map->clean();
|
||||
|
||||
@@ -15,7 +15,8 @@ class ProductShowPageComposer
|
||||
/**
|
||||
* Bind data to the view.
|
||||
*
|
||||
* @param \Illuminate\View\View $view
|
||||
* @param View $view
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function compose(View $view)
|
||||
@@ -30,6 +31,7 @@ class ProductShowPageComposer
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
private function schemaMarkup(Product $product)
|
||||
{
|
||||
return Schema::product()
|
||||
@@ -43,11 +45,13 @@ class ProductShowPageComposer
|
||||
->offers($this->offersSchema($product));
|
||||
}
|
||||
|
||||
|
||||
private function brandSchema(Product $product)
|
||||
{
|
||||
return Schema::brand()->name($product->brand->name);
|
||||
}
|
||||
|
||||
|
||||
private function aggregateRatingSchema(Product $product)
|
||||
{
|
||||
return Schema::aggregateRating()
|
||||
@@ -55,15 +59,17 @@ class ProductShowPageComposer
|
||||
->ratingCount($product->reviews()->count());
|
||||
}
|
||||
|
||||
|
||||
private function offersSchema(Product $product)
|
||||
{
|
||||
return Schema::offer()
|
||||
->price($product->selling_price->convertToCurrentCurrency()->amount())
|
||||
->price(($product->variant ?? $product)->selling_price->convertToCurrentCurrency()->amount())
|
||||
->priceCurrency(currency())
|
||||
->availability($product->isInStock() ? ItemAvailability::InStock : ItemAvailability::OutOfStock)
|
||||
->url($product->url());
|
||||
}
|
||||
|
||||
|
||||
private function getCategoryBreadCrumb(Collection $categories)
|
||||
{
|
||||
$breadcrumb = '';
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Themes\Storefront\Http\ViewComposers;
|
||||
|
||||
use Illuminate\View\View;
|
||||
use Modules\Category\Entities\Category;
|
||||
|
||||
class StorefrontTabsComposer
|
||||
@@ -9,7 +10,8 @@ class StorefrontTabsComposer
|
||||
/**
|
||||
* Bind data to the view.
|
||||
*
|
||||
* @param \Illuminate\View\View $view
|
||||
* @param View $view
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function compose($view)
|
||||
@@ -19,6 +21,7 @@ class StorefrontTabsComposer
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
private function getCategories()
|
||||
{
|
||||
return ['' => trans('admin::admin.form.please_select')] + Category::treeList();
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace Themes\Storefront\Providers;
|
||||
|
||||
use Illuminate\Pagination\Paginator;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Modules\Support\Traits\AddsAsset;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Modules\Admin\Ui\Facades\TabManager;
|
||||
use Modules\FlashSale\Entities\FlashSale;
|
||||
@@ -17,8 +16,6 @@ use Themes\Storefront\Http\ViewComposers\ProductIndexPageComposer;
|
||||
|
||||
class StorefrontServiceProvider extends ServiceProvider
|
||||
{
|
||||
use AddsAsset;
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
@@ -26,7 +23,7 @@ class StorefrontServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
if (! is_null(setting('storefront_active_flash_sale_campaign'))) {
|
||||
if (!is_null(setting('storefront_active_flash_sale_campaign'))) {
|
||||
FlashSale::activeCampaign(setting('storefront_active_flash_sale_campaign'));
|
||||
}
|
||||
|
||||
@@ -39,9 +36,5 @@ class StorefrontServiceProvider extends ServiceProvider
|
||||
View::composer('admin.storefront.tabs.*', StorefrontTabsComposer::class);
|
||||
|
||||
Paginator::defaultView('public.pagination');
|
||||
|
||||
$this->addAdminAssets('admin.storefront.settings.edit', [
|
||||
'admin.storefront.css', 'admin.media.css', 'admin.storefront.js', 'admin.media.js',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.3.0",
|
||||
"php": "^8.0.2",
|
||||
"mexitek/phpcolors": "^0.4.0"
|
||||
},
|
||||
"autoload": {
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
use Mexitek\PHPColors\Color;
|
||||
use Modules\Menu\MegaMenu\Menu;
|
||||
|
||||
if (! function_exists('resolve_theme_color')) {
|
||||
if (!function_exists('resolve_theme_color')) {
|
||||
/**
|
||||
* Resolve color code by the given theme name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function resolve_theme_color($color)
|
||||
@@ -31,7 +32,7 @@ if (! function_exists('resolve_theme_color')) {
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('storefront_theme_color')) {
|
||||
if (!function_exists('storefront_theme_color')) {
|
||||
function storefront_theme_color()
|
||||
{
|
||||
if (setting('storefront_theme_color') === 'custom_color') {
|
||||
@@ -42,7 +43,7 @@ if (! function_exists('storefront_theme_color')) {
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('mail_theme_color')) {
|
||||
if (!function_exists('mail_theme_color')) {
|
||||
function mail_theme_color()
|
||||
{
|
||||
if (setting('storefront_mail_theme_color') === 'custom_color') {
|
||||
@@ -53,14 +54,14 @@ if (! function_exists('mail_theme_color')) {
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('color2rgba')) {
|
||||
if (!function_exists('color2rgba')) {
|
||||
function color2rgba(Color $color, $opacity)
|
||||
{
|
||||
return sprintf('rgba(%s, %s)', implode(', ', $color->getRgb()), $opacity);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('mega_menu_classes')) {
|
||||
if (!function_exists('mega_menu_classes')) {
|
||||
function mega_menu_classes(Menu $menu, $type = 'category_menu')
|
||||
{
|
||||
$classes = [];
|
||||
@@ -71,7 +72,7 @@ if (! function_exists('mega_menu_classes')) {
|
||||
|
||||
if ($menu->isFluid()) {
|
||||
array_push($classes, 'fluid-menu');
|
||||
} elseif ($menu->hasSubMenus()) {
|
||||
} else if ($menu->hasSubMenus()) {
|
||||
array_push($classes, 'dropdown', 'multi-level');
|
||||
}
|
||||
|
||||
@@ -79,7 +80,7 @@ if (! function_exists('mega_menu_classes')) {
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('products_view_mode')) {
|
||||
if (!function_exists('products_view_mode')) {
|
||||
/**
|
||||
* Get the products view mode.
|
||||
*
|
||||
@@ -91,11 +92,12 @@ if (! function_exists('products_view_mode')) {
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('order_status_badge_class')) {
|
||||
if (!function_exists('order_status_badge_class')) {
|
||||
/**
|
||||
* Get the products view mode.
|
||||
*
|
||||
* @param string $status
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function order_status_badge_class($status)
|
||||
@@ -112,11 +114,12 @@ if (! function_exists('order_status_badge_class')) {
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('social_links')) {
|
||||
if (!function_exists('social_links')) {
|
||||
/**
|
||||
* Get the social links.
|
||||
*
|
||||
* @param string $status
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function social_links()
|
||||
|
||||
@@ -1,30 +1,22 @@
|
||||
{
|
||||
"name": "storefront-theme",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "npm run development",
|
||||
"development": "mix",
|
||||
"watch": "mix watch",
|
||||
"watch-poll": "mix watch -- --watch-options-poll=1000",
|
||||
"hot": "mix watch --hot",
|
||||
"production": "mix --production"
|
||||
},
|
||||
"dependencies": {
|
||||
"animate.css": "^4.1.1",
|
||||
"bootstrap": "4.3.1",
|
||||
"flatpickr": "^4.6.3",
|
||||
"jquery": "^3.4.1",
|
||||
"animate.css": "3.7.2",
|
||||
"blueimp-md5": "^2.19.0",
|
||||
"bootstrap": "4.6.2",
|
||||
"countdown": "^2.6.0",
|
||||
"drift-zoom": "^1.5.1",
|
||||
"flatpickr": "^4.6.13",
|
||||
"glightbox": "^3.2.0",
|
||||
"jquery-nice-select": "^1.1.0",
|
||||
"jquery-zoom": "^1.7.21",
|
||||
"kbw-countdown": "https://github.com/kbwood/countdown.git",
|
||||
"line-awesome": "^1.3.0",
|
||||
"nouislider": "^14.1.1",
|
||||
"popper.js": "^1.15.0",
|
||||
"rtlcss": "^2.4.0",
|
||||
"lodash": "^4.17.21",
|
||||
"nouislider": "^15.7.1",
|
||||
"popper.js": "^1.16.1",
|
||||
"slick-animation": "^0.3.3",
|
||||
"slick-carousel": "^1.8.1",
|
||||
"slick-lightbox": "^0.2.12",
|
||||
"v-click-outside": "^3.0.1",
|
||||
"vue": "2.7.14",
|
||||
"v-click-outside": "^3.2.0",
|
||||
"vue-toast-notification": "0.6.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,116 +1,227 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="570" height="466.011" viewBox="0 0 570 466.011">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="570" height="466.011"
|
||||
viewBox="0 0 570 466.011">
|
||||
<defs>
|
||||
<linearGradient id="linear-gradient" x1="0.5" y1="0.98" x2="0.5" y2="0.034" gradientUnits="objectBoundingBox">
|
||||
<stop offset="0" stop-color="#fff" />
|
||||
<stop offset="1" />
|
||||
<stop offset="0" stop-color="#fff"/>
|
||||
<stop offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Group_146" data-name="Group 146" transform="translate(-26.516 -57.452)">
|
||||
<g id="Group_76" data-name="Group 76" transform="translate(29.78 115.484)">
|
||||
<g id="Group_75" data-name="Group 75">
|
||||
<path id="Path_12" data-name="Path 12" d="M560.936,393.058H110.3c-4.468,0-9.244.5-13.7,0-31.542-3.5-53.1-38.093-62.052-65.553a110.4,110.4,0,0,1-4.759-21.83C27.225,283.024,31.936,259.5,47.634,242.2,61.4,227.039,84.355,224.99,96.778,208.759c9.164-11.924,9.762-28.218,14.989-41.884,3.42-8.938,8.97-17.344,17.021-22.539,6.809-4.388,15-6.212,23.1-6.776a85.133,85.133,0,0,1,37.722,5.986,104.025,104.025,0,0,0,38.609,7.55c15.537.21,30.235-2.339,45.175-6.212,14.617-3.774,30.105-5.146,43.545-12.5,18.989-10.375,32.623-24.588,55.017-27.67,23.943-3.308,50.612,5,66.923,23.233,11,12.311,15.667,28.3,12.2,44.545-2.147,9.988-7.181,21.039.6,29.946,5.13,5.9,13.471,7.808,21.248,8.389,20.99,1.6,39.367,5.825,54.533,21.669,14.973,15.666,16.231,30.832,17.167,51.386a89.989,89.989,0,0,1-1.984,21.8c-.356,1.807-.759,3.615-1.178,5.422-.258,1.1-.517,2.178-.79,3.275-2.243,8.954-6.18,18.312-6.245,27.622-.112,16.681,14.973,25.169,21.781,38.656C556.79,381.8,560.872,393.058,560.936,393.058Z" transform="translate(-29.131 -104)" fill="#d9dffb" />
|
||||
<path id="Path_12" data-name="Path 12"
|
||||
d="M560.936,393.058H110.3c-4.468,0-9.244.5-13.7,0-31.542-3.5-53.1-38.093-62.052-65.553a110.4,110.4,0,0,1-4.759-21.83C27.225,283.024,31.936,259.5,47.634,242.2,61.4,227.039,84.355,224.99,96.778,208.759c9.164-11.924,9.762-28.218,14.989-41.884,3.42-8.938,8.97-17.344,17.021-22.539,6.809-4.388,15-6.212,23.1-6.776a85.133,85.133,0,0,1,37.722,5.986,104.025,104.025,0,0,0,38.609,7.55c15.537.21,30.235-2.339,45.175-6.212,14.617-3.774,30.105-5.146,43.545-12.5,18.989-10.375,32.623-24.588,55.017-27.67,23.943-3.308,50.612,5,66.923,23.233,11,12.311,15.667,28.3,12.2,44.545-2.147,9.988-7.181,21.039.6,29.946,5.13,5.9,13.471,7.808,21.248,8.389,20.99,1.6,39.367,5.825,54.533,21.669,14.973,15.666,16.231,30.832,17.167,51.386a89.989,89.989,0,0,1-1.984,21.8c-.356,1.807-.759,3.615-1.178,5.422-.258,1.1-.517,2.178-.79,3.275-2.243,8.954-6.18,18.312-6.245,27.622-.112,16.681,14.973,25.169,21.781,38.656C556.79,381.8,560.872,393.058,560.936,393.058Z"
|
||||
transform="translate(-29.131 -104)" fill="#d9dffb"/>
|
||||
</g>
|
||||
</g>
|
||||
<path id="Path_13" data-name="Path 13" d="M542.641,305.676H29.79C27.225,283.024,31.936,259.5,47.634,242.2,61.4,227.039,84.355,224.99,96.778,208.759c9.164-11.924,9.762-28.218,14.989-41.884,3.42-8.938,8.97-17.344,17.021-22.539,6.809-4.388,15-6.212,23.1-6.776a85.133,85.133,0,0,1,37.722,5.986,104.025,104.025,0,0,0,38.609,7.55c15.537.21,30.235-2.339,45.175-6.212,14.617-3.774,30.105-5.146,43.545-12.5,18.989-10.375,32.623-24.588,55.017-27.67,23.943-3.308,50.612,5,66.923,23.233,11,12.311,15.667,28.3,12.2,44.545-2.147,9.988-7.181,21.039.6,29.946,5.13,5.9,13.471,7.808,21.248,8.389,20.99,1.6,39.367,5.825,54.533,21.669,14.973,15.666,16.231,30.832,17.167,51.386A89.989,89.989,0,0,1,542.641,305.676Z" transform="translate(0.649 11.484)" opacity="0.2" fill="url(#linear-gradient)" style="mix-blend-mode: screen;isolation: isolate" />
|
||||
<path id="Path_14" data-name="Path 14" d="M199.28,301.828V198.441H154.589l-58.583,83.8L80.679,304.167v32.285h78.588v30.412H199.28V336.451h19.167V301.828Zm-37.2,0H122.789l12.956-19.587,26.331-39.818Z" transform="translate(13.44 34.919)" fill="#1b2c56" />
|
||||
<path id="Path_15" data-name="Path 15" d="M214.178,328.719v11.424H112.516a9.6,9.6,0,0,1,7.49-7.777c4.9-.935,8.441,2.747,8.675,2.981.216-.754,2.354-7.7,9.286-10.165a14.728,14.728,0,0,1,9.573,0,6.841,6.841,0,0,1,8.389-8.982,13.526,13.526,0,0,1,24.535,4.185,6.8,6.8,0,0,1,12.286,1.8,12.545,12.545,0,0,1,21.428,6.538Z" transform="translate(21.341 62.6)" fill="#99a6d6" />
|
||||
<path id="Path_16" data-name="Path 16" d="M266.185,158.292c-48.66,0-65.73,36.495-65.73,86.543,0,17.876,2.146,33.993,7.066,47.368,8.97,24.428,27.218,39.657,58.664,39.657,31.428,0,49.692-15.23,58.663-39.657,4.92-13.375,7.067-29.492,7.067-47.368C331.915,194.787,314.829,158.292,266.185,158.292Zm0,136.138a25.748,25.748,0,0,1-11.15-2.227c-13.439-6.292-15.295-25.281-15.295-47.368,0-26.186,2.807-49.112,26.445-49.112,23.62,0,26.427,22.926,26.427,49.112,0,22.087-1.856,41.06-15.279,47.368A25.793,25.793,0,0,1,266.185,294.43Z" transform="translate(43.162 24.956)" fill="#1b2c56" />
|
||||
<path id="Path_13" data-name="Path 13"
|
||||
d="M542.641,305.676H29.79C27.225,283.024,31.936,259.5,47.634,242.2,61.4,227.039,84.355,224.99,96.778,208.759c9.164-11.924,9.762-28.218,14.989-41.884,3.42-8.938,8.97-17.344,17.021-22.539,6.809-4.388,15-6.212,23.1-6.776a85.133,85.133,0,0,1,37.722,5.986,104.025,104.025,0,0,0,38.609,7.55c15.537.21,30.235-2.339,45.175-6.212,14.617-3.774,30.105-5.146,43.545-12.5,18.989-10.375,32.623-24.588,55.017-27.67,23.943-3.308,50.612,5,66.923,23.233,11,12.311,15.667,28.3,12.2,44.545-2.147,9.988-7.181,21.039.6,29.946,5.13,5.9,13.471,7.808,21.248,8.389,20.99,1.6,39.367,5.825,54.533,21.669,14.973,15.666,16.231,30.832,17.167,51.386A89.989,89.989,0,0,1,542.641,305.676Z"
|
||||
transform="translate(0.649 11.484)" opacity="0.2" fill="url(#linear-gradient)"
|
||||
style="mix-blend-mode: screen;isolation: isolate"/>
|
||||
<path id="Path_14" data-name="Path 14"
|
||||
d="M199.28,301.828V198.441H154.589l-58.583,83.8L80.679,304.167v32.285h78.588v30.412H199.28V336.451h19.167V301.828Zm-37.2,0H122.789l12.956-19.587,26.331-39.818Z"
|
||||
transform="translate(13.44 34.919)" fill="#1b2c56"/>
|
||||
<path id="Path_15" data-name="Path 15"
|
||||
d="M214.178,328.719v11.424H112.516a9.6,9.6,0,0,1,7.49-7.777c4.9-.935,8.441,2.747,8.675,2.981.216-.754,2.354-7.7,9.286-10.165a14.728,14.728,0,0,1,9.573,0,6.841,6.841,0,0,1,8.389-8.982,13.526,13.526,0,0,1,24.535,4.185,6.8,6.8,0,0,1,12.286,1.8,12.545,12.545,0,0,1,21.428,6.538Z"
|
||||
transform="translate(21.341 62.6)" fill="#99a6d6"/>
|
||||
<path id="Path_16" data-name="Path 16"
|
||||
d="M266.185,158.292c-48.66,0-65.73,36.495-65.73,86.543,0,17.876,2.146,33.993,7.066,47.368,8.97,24.428,27.218,39.657,58.664,39.657,31.428,0,49.692-15.23,58.663-39.657,4.92-13.375,7.067-29.492,7.067-47.368C331.915,194.787,314.829,158.292,266.185,158.292Zm0,136.138a25.748,25.748,0,0,1-11.15-2.227c-13.439-6.292-15.295-25.281-15.295-47.368,0-26.186,2.807-49.112,26.445-49.112,23.62,0,26.427,22.926,26.427,49.112,0,22.087-1.856,41.06-15.279,47.368A25.793,25.793,0,0,1,266.185,294.43Z"
|
||||
transform="translate(43.162 24.956)" fill="#1b2c56"/>
|
||||
<g id="Group_78" data-name="Group 78" transform="translate(394.449 377.394)">
|
||||
<g id="Group_77" data-name="Group 77">
|
||||
<path id="Path_17" data-name="Path 17" d="M406.716,329.573v9.6H321.3a8.07,8.07,0,0,1,6.293-6.534c4.12-.785,7.093,2.309,7.289,2.505.181-.634,1.977-6.474,7.8-8.541a12.375,12.375,0,0,1,8.043,0,5.748,5.748,0,0,1,7.048-7.546,11.364,11.364,0,0,1,20.614,3.516,5.714,5.714,0,0,1,10.322,1.509,10.541,10.541,0,0,1,18,5.494Z" transform="translate(-321.299 -313.839)" fill="#99a6d6" />
|
||||
<path id="Path_18" data-name="Path 18" d="M388.19,337.6h31.591a6.8,6.8,0,0,0-11.021-6.5,3.531,3.531,0,0,0-5.785-3.856,9.227,9.227,0,0,0-6.336-6.795c-4.1-1.1-8.806,1.165-10.835,5.6Q387,331.824,388.19,337.6Z" transform="translate(-305.292 -312.268)" fill="#537ec5" />
|
||||
<path id="Path_17" data-name="Path 17"
|
||||
d="M406.716,329.573v9.6H321.3a8.07,8.07,0,0,1,6.293-6.534c4.12-.785,7.093,2.309,7.289,2.505.181-.634,1.977-6.474,7.8-8.541a12.375,12.375,0,0,1,8.043,0,5.748,5.748,0,0,1,7.048-7.546,11.364,11.364,0,0,1,20.614,3.516,5.714,5.714,0,0,1,10.322,1.509,10.541,10.541,0,0,1,18,5.494Z"
|
||||
transform="translate(-321.299 -313.839)" fill="#99a6d6"/>
|
||||
<path id="Path_18" data-name="Path 18"
|
||||
d="M388.19,337.6h31.591a6.8,6.8,0,0,0-11.021-6.5,3.531,3.531,0,0,0-5.785-3.856,9.227,9.227,0,0,0-6.336-6.795c-4.1-1.1-8.806,1.165-10.835,5.6Q387,331.824,388.19,337.6Z"
|
||||
transform="translate(-305.292 -312.268)" fill="#537ec5"/>
|
||||
</g>
|
||||
</g>
|
||||
<path id="Path_19" data-name="Path 19" d="M435.638,301.828V198.441H390.964l-58.6,83.8-15.327,21.926v32.285h78.606v30.412h40V336.451h19.183V301.828Zm-37.189,0h-39.3L372.1,282.24l26.347-39.818Z" transform="translate(72.092 34.919)" fill="#1b2c56" />
|
||||
<path id="Path_20" data-name="Path 20" d="M151.542,198.441h44.691v83.8H92.959Z" transform="translate(16.488 34.919)" opacity="0.2" fill="url(#linear-gradient)" style="mix-blend-mode: screen;isolation: isolate" />
|
||||
<path id="Path_21" data-name="Path 21" d="M331.915,244.835c0,17.876-2.147,33.993-7.067,47.368H207.521c-4.92-13.375-7.066-29.492-7.066-47.368,0-50.048,17.07-86.543,65.73-86.543C314.829,158.292,331.915,194.787,331.915,244.835Z" transform="translate(43.162 24.956)" opacity="0.2" fill="url(#linear-gradient)" style="mix-blend-mode: screen;isolation: isolate" />
|
||||
<path id="Path_22" data-name="Path 22" d="M432.591,198.441v83.8H329.318l58.6-83.8Z" transform="translate(75.139 34.919)" opacity="0.2" fill="url(#linear-gradient)" style="mix-blend-mode: screen;isolation: isolate" />
|
||||
<path id="Path_19" data-name="Path 19"
|
||||
d="M435.638,301.828V198.441H390.964l-58.6,83.8-15.327,21.926v32.285h78.606v30.412h40V336.451h19.183V301.828Zm-37.189,0h-39.3L372.1,282.24l26.347-39.818Z"
|
||||
transform="translate(72.092 34.919)" fill="#1b2c56"/>
|
||||
<path id="Path_20" data-name="Path 20" d="M151.542,198.441h44.691v83.8H92.959Z"
|
||||
transform="translate(16.488 34.919)" opacity="0.2" fill="url(#linear-gradient)"
|
||||
style="mix-blend-mode: screen;isolation: isolate"/>
|
||||
<path id="Path_21" data-name="Path 21"
|
||||
d="M331.915,244.835c0,17.876-2.147,33.993-7.067,47.368H207.521c-4.92-13.375-7.066-29.492-7.066-47.368,0-50.048,17.07-86.543,65.73-86.543C314.829,158.292,331.915,194.787,331.915,244.835Z"
|
||||
transform="translate(43.162 24.956)" opacity="0.2" fill="url(#linear-gradient)"
|
||||
style="mix-blend-mode: screen;isolation: isolate"/>
|
||||
<path id="Path_22" data-name="Path 22" d="M432.591,198.441v83.8H329.318l58.6-83.8Z"
|
||||
transform="translate(75.139 34.919)" opacity="0.2" fill="url(#linear-gradient)"
|
||||
style="mix-blend-mode: screen;isolation: isolate"/>
|
||||
<g id="Group_81" data-name="Group 81" transform="translate(471.515 384.385)">
|
||||
<g id="Group_80" data-name="Group 80">
|
||||
<path id="Path_23" data-name="Path 23" d="M444.886,330.832v6.948H383.044a5.843,5.843,0,0,1,4.556-4.73,6.165,6.165,0,0,1,5.277,1.814,9.616,9.616,0,0,1,5.649-6.185,8.97,8.97,0,0,1,5.824,0,4.162,4.162,0,0,1,5.1-5.463,8.228,8.228,0,0,1,14.925,2.546,4.138,4.138,0,0,1,7.474,1.092,7.631,7.631,0,0,1,13.034,3.978Z" transform="translate(-383.044 -319.441)" fill="#99a6d6" />
|
||||
<path id="Path_23" data-name="Path 23"
|
||||
d="M444.886,330.832v6.948H383.044a5.843,5.843,0,0,1,4.556-4.73,6.165,6.165,0,0,1,5.277,1.814,9.616,9.616,0,0,1,5.649-6.185,8.97,8.97,0,0,1,5.824,0,4.162,4.162,0,0,1,5.1-5.463,8.228,8.228,0,0,1,14.925,2.546,4.138,4.138,0,0,1,7.474,1.092,7.631,7.631,0,0,1,13.034,3.978Z"
|
||||
transform="translate(-383.044 -319.441)" fill="#99a6d6"/>
|
||||
<g id="Group_79" data-name="Group 79" transform="translate(58.291 5.721)">
|
||||
<path id="Path_24" data-name="Path 24" d="M431.475,336.643h22.871a4.921,4.921,0,0,0-7.979-4.708,2.557,2.557,0,0,0-4.189-2.792,6.681,6.681,0,0,0-4.587-4.919,6.9,6.9,0,0,0-7.845,4.055Q430.609,332.461,431.475,336.643Z" transform="translate(-429.746 -324.024)" fill="#bdc9f4" />
|
||||
<path id="Path_24" data-name="Path 24"
|
||||
d="M431.475,336.643h22.871a4.921,4.921,0,0,0-7.979-4.708,2.557,2.557,0,0,0-4.189-2.792,6.681,6.681,0,0,0-4.587-4.919,6.9,6.9,0,0,0-7.845,4.055Q430.609,332.461,431.475,336.643Z"
|
||||
transform="translate(-429.746 -324.024)" fill="#bdc9f4"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Group_82" data-name="Group 82" transform="translate(307.779 356.78)">
|
||||
<rect id="Rectangle_15" data-name="Rectangle 15" width="3.226" height="44.815" fill="#010038" />
|
||||
<rect id="Rectangle_15" data-name="Rectangle 15" width="3.226" height="44.815" fill="#010038"/>
|
||||
</g>
|
||||
<g id="Group_83" data-name="Group 83" transform="translate(243.354 374.838)">
|
||||
<path id="Path_25" data-name="Path 25" d="M297.447,329.7v10.924h-97.2a9.182,9.182,0,0,1,7.161-7.437c4.689-.894,8.072,2.627,8.3,2.851.206-.721,2.25-7.368,8.879-9.721a14.094,14.094,0,0,1,9.154,0,6.54,6.54,0,0,1,8.019-8.587,12.933,12.933,0,0,1,23.46,4,6.5,6.5,0,0,1,11.746,1.717,11.994,11.994,0,0,1,20.488,6.251Z" transform="translate(-200.244 -311.792)" fill="#99a6d6" />
|
||||
<path id="Path_26" data-name="Path 26" d="M276.366,338.833h35.949a7.733,7.733,0,0,0-12.541-7.4,4.02,4.02,0,0,0-6.584-4.39,10.5,10.5,0,0,0-7.209-7.732c-4.668-1.253-10.021,1.327-12.33,6.374Q275.007,332.258,276.366,338.833Z" transform="translate(-182.029 -310.004)" fill="#bdc9f4" />
|
||||
<path id="Path_25" data-name="Path 25"
|
||||
d="M297.447,329.7v10.924h-97.2a9.182,9.182,0,0,1,7.161-7.437c4.689-.894,8.072,2.627,8.3,2.851.206-.721,2.25-7.368,8.879-9.721a14.094,14.094,0,0,1,9.154,0,6.54,6.54,0,0,1,8.019-8.587,12.933,12.933,0,0,1,23.46,4,6.5,6.5,0,0,1,11.746,1.717,11.994,11.994,0,0,1,20.488,6.251Z"
|
||||
transform="translate(-200.244 -311.792)" fill="#99a6d6"/>
|
||||
<path id="Path_26" data-name="Path 26"
|
||||
d="M276.366,338.833h35.949a7.733,7.733,0,0,0-12.541-7.4,4.02,4.02,0,0,0-6.584-4.39,10.5,10.5,0,0,0-7.209-7.732c-4.668-1.253-10.021,1.327-12.33,6.374Q275.007,332.258,276.366,338.833Z"
|
||||
transform="translate(-182.029 -310.004)" fill="#bdc9f4"/>
|
||||
</g>
|
||||
<path id="Path_64" data-name="Path 64" d="M38.669,336.9c14.084,0,17.45,19.241,22.333,28.983,7.016,14,19.65,25.108,35.8,26.187,10.422.7,20.73-2.727,31.176-2.62,52.431.538,77.184,65.574,129.566,64.885,32.211-.423,60.007-19.16,87.59-33.958,14.17-7.6,28.935-14.552,44.807-17.691,20.091-3.974,40.1-.426,60.133,2.136,4.662.6,9.331,1.15,14.017,1.526,40.915,3.288,102.9-16.166,107.215-64.627q.124-1.386.157-2.777.034-1.329-.025-2.66Z" transform="translate(3.016 69.124)" fill="#1b2c56" />
|
||||
<path id="Path_65" data-name="Path 65" d="M594.1,334.09H28.935a2.42,2.42,0,0,0,0,4.84H594.1a2.42,2.42,0,1,0,0-4.84Z" transform="translate(0 68.58)" fill="#1b2c56" />
|
||||
<path id="Path_64" data-name="Path 64"
|
||||
d="M38.669,336.9c14.084,0,17.45,19.241,22.333,28.983,7.016,14,19.65,25.108,35.8,26.187,10.422.7,20.73-2.727,31.176-2.62,52.431.538,77.184,65.574,129.566,64.885,32.211-.423,60.007-19.16,87.59-33.958,14.17-7.6,28.935-14.552,44.807-17.691,20.091-3.974,40.1-.426,60.133,2.136,4.662.6,9.331,1.15,14.017,1.526,40.915,3.288,102.9-16.166,107.215-64.627q.124-1.386.157-2.777.034-1.329-.025-2.66Z"
|
||||
transform="translate(3.016 69.124)" fill="#1b2c56"/>
|
||||
<path id="Path_65" data-name="Path 65"
|
||||
d="M594.1,334.09H28.935a2.42,2.42,0,0,0,0,4.84H594.1a2.42,2.42,0,1,0,0-4.84Z"
|
||||
transform="translate(0 68.58)" fill="#1b2c56"/>
|
||||
<g id="Group_115" data-name="Group 115" transform="translate(82.42 324.638)">
|
||||
<g id="Group_110" data-name="Group 110">
|
||||
<path id="Path_93" data-name="Path 93" d="M71.306,293.216c7.056.422,9.451,7.42,10.029,9.6l7.813,7.815V285.547c-5.622-5.59-1.212-13.976-1.212-13.976,7.134,5.079,3.335,11.864,2.012,13.815v10.149l6.955-6.956c.62-7.886,9.824-9.981,9.824-9.981.768,8.728-6.867,10.239-9.206,10.5L90.009,296.6l-.061-.061V335.51h-.8V311.635l-.061.061-8.215-8.217C71.186,303.552,71.306,293.216,71.306,293.216Z" transform="translate(-71.306 -271.572)" fill="#ff502f" />
|
||||
<path id="Rectangle_17" data-name="Rectangle 17" d="M3.272,0h9.968a3.272,3.272,0,0,1,3.272,3.272V16.688a0,0,0,0,1,0,0H0a0,0,0,0,1,0,0V3.272A3.272,3.272,0,0,1,3.272,0Z" transform="translate(26.764 78.431) rotate(180)" fill="#1b2c56" />
|
||||
<path id="Path_93" data-name="Path 93"
|
||||
d="M71.306,293.216c7.056.422,9.451,7.42,10.029,9.6l7.813,7.815V285.547c-5.622-5.59-1.212-13.976-1.212-13.976,7.134,5.079,3.335,11.864,2.012,13.815v10.149l6.955-6.956c.62-7.886,9.824-9.981,9.824-9.981.768,8.728-6.867,10.239-9.206,10.5L90.009,296.6l-.061-.061V335.51h-.8V311.635l-.061.061-8.215-8.217C71.186,303.552,71.306,293.216,71.306,293.216Z"
|
||||
transform="translate(-71.306 -271.572)" fill="#ff502f"/>
|
||||
<path id="Rectangle_17" data-name="Rectangle 17"
|
||||
d="M3.272,0h9.968a3.272,3.272,0,0,1,3.272,3.272V16.688a0,0,0,0,1,0,0H0a0,0,0,0,1,0,0V3.272A3.272,3.272,0,0,1,3.272,0Z"
|
||||
transform="translate(26.764 78.431) rotate(180)" fill="#1b2c56"/>
|
||||
</g>
|
||||
<g id="Group_114" data-name="Group 114" transform="translate(17.333 30.492)">
|
||||
<g id="Group_113" data-name="Group 113">
|
||||
<g id="Group_112" data-name="Group 112">
|
||||
<g id="Group_111" data-name="Group 111">
|
||||
<path id="Path_94" data-name="Path 94" d="M108.11,314.3l-4.141,3.757V314.04c3.14-1.561,10-7.036,6.415-18.038,0,0-12.47,4.777-8.013,18.044v5.8L98.929,316c-.454-2.982-3.281-10.468-13.736-10.234,0,0,.838,11.454,12.69,11.462l4.488,5.006v7.677h1.6v-9.7l5.165-4.686c10.519.716,12.077-9.431,12.077-9.431C111.847,305.146,108.751,311.63,108.11,314.3Z" transform="translate(-85.193 -296.002)" fill="#49beb7" />
|
||||
<path id="Path_94" data-name="Path 94"
|
||||
d="M108.11,314.3l-4.141,3.757V314.04c3.14-1.561,10-7.036,6.415-18.038,0,0-12.47,4.777-8.013,18.044v5.8L98.929,316c-.454-2.982-3.281-10.468-13.736-10.234,0,0,.838,11.454,12.69,11.462l4.488,5.006v7.677h1.6v-9.7l5.165-4.686c10.519.716,12.077-9.431,12.077-9.431C111.847,305.146,108.751,311.63,108.11,314.3Z"
|
||||
transform="translate(-85.193 -296.002)" fill="#49beb7"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<path id="Path_95" data-name="Path 95" d="M109.56,338.028H94.115l-3.2-17.842h21.837Z" transform="translate(-83.772 -290.001)" fill="#1b2c56" />
|
||||
<path id="Path_95" data-name="Path 95" d="M109.56,338.028H94.115l-3.2-17.842h21.837Z"
|
||||
transform="translate(-83.772 -290.001)" fill="#1b2c56"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Group_121" data-name="Group 121" transform="translate(566.104 325.797)">
|
||||
<g id="Group_120" data-name="Group 120">
|
||||
<g id="Group_119" data-name="Group 119">
|
||||
<g id="Group_116" data-name="Group 116" transform="translate(10.027)">
|
||||
<path id="Path_96" data-name="Path 96" d="M473.088,284.676a71.491,71.491,0,0,1-1.787-11.518l-.026-.658-.457.473a8.051,8.051,0,0,0-2.051,5.195c0,.829.054,1.563.106,2.274a10.016,10.016,0,0,1-.645,5.356c-1.269,2.894-2.107,5.421-.423,9.375l.493,1.146c1.277,2.952,1.8,4.173,1.321,6.538a8.035,8.035,0,0,0,4.487,8.177c-.122,5.367-.277,9.833-.281,9.927l.563.021c.008-.2.711-20.433.292-26.71A71.278,71.278,0,0,0,473.088,284.676Z" transform="translate(-466.861 -272.5)" fill="#ff502f" />
|
||||
<path id="Path_96" data-name="Path 96"
|
||||
d="M473.088,284.676a71.491,71.491,0,0,1-1.787-11.518l-.026-.658-.457.473a8.051,8.051,0,0,0-2.051,5.195c0,.829.054,1.563.106,2.274a10.016,10.016,0,0,1-.645,5.356c-1.269,2.894-2.107,5.421-.423,9.375l.493,1.146c1.277,2.952,1.8,4.173,1.321,6.538a8.035,8.035,0,0,0,4.487,8.177c-.122,5.367-.277,9.833-.281,9.927l.563.021c.008-.2.711-20.433.292-26.71A71.278,71.278,0,0,0,473.088,284.676Z"
|
||||
transform="translate(-466.861 -272.5)" fill="#ff502f"/>
|
||||
</g>
|
||||
<g id="Group_117" data-name="Group 117" transform="translate(0 13.549)">
|
||||
<path id="Path_97" data-name="Path 97" d="M459.718,283.582l-.29-.227-.143.339a6.04,6.04,0,0,0,.7,5.825,7.642,7.642,0,0,1,1.258,4,11.2,11.2,0,0,0,1.94,5.707,13.249,13.249,0,0,0,3.425,3.088c1.286.875,2.214,1.508,2.434,3.082.04.282.072.548.1.8.315,2.49.489,3.872,4.115,5.1,1.051,4.089,1.539,6.94,1.553,7.026l.555-.094C475.325,317.974,470.938,292.372,459.718,283.582Z" transform="translate(-458.828 -283.355)" fill="#ff502f" />
|
||||
<path id="Path_97" data-name="Path 97"
|
||||
d="M459.718,283.582l-.29-.227-.143.339a6.04,6.04,0,0,0,.7,5.825,7.642,7.642,0,0,1,1.258,4,11.2,11.2,0,0,0,1.94,5.707,13.249,13.249,0,0,0,3.425,3.088c1.286.875,2.214,1.508,2.434,3.082.04.282.072.548.1.8.315,2.49.489,3.872,4.115,5.1,1.051,4.089,1.539,6.94,1.553,7.026l.555-.094C475.325,317.974,470.938,292.372,459.718,283.582Z"
|
||||
transform="translate(-458.828 -283.355)" fill="#ff502f"/>
|
||||
</g>
|
||||
<g id="Group_118" data-name="Group 118" transform="translate(18.052 20.487)">
|
||||
<path id="Path_98" data-name="Path 98" d="M481,289.312l-.085-.4-.342.22c-8.631,5.549-7.229,26.607-7.166,27.5l.281-.021h0l.281-.02c0-.064-.134-2.007-.094-4.844.273-.417,1.326-2.023,2.121-3.266a2.889,2.889,0,0,0,.242-2.376,5.912,5.912,0,0,1-.06-2.6,4.742,4.742,0,0,1,1.2-2.423,7.614,7.614,0,0,0,1.309-2.069,6.792,6.792,0,0,0,.448-2.921,3.687,3.687,0,0,1,.741-2.785A4.857,4.857,0,0,0,481,289.312Z" transform="translate(-473.291 -288.914)" fill="#ff502f" />
|
||||
<path id="Path_98" data-name="Path 98"
|
||||
d="M481,289.312l-.085-.4-.342.22c-8.631,5.549-7.229,26.607-7.166,27.5l.281-.021h0l.281-.02c0-.064-.134-2.007-.094-4.844.273-.417,1.326-2.023,2.121-3.266a2.889,2.889,0,0,0,.242-2.376,5.912,5.912,0,0,1-.06-2.6,4.742,4.742,0,0,1,1.2-2.423,7.614,7.614,0,0,0,1.309-2.069,6.792,6.792,0,0,0,.448-2.921,3.687,3.687,0,0,1,.741-2.785A4.857,4.857,0,0,0,481,289.312Z"
|
||||
transform="translate(-473.291 -288.914)" fill="#ff502f"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<path id="Path_99" data-name="Path 99" d="M479.358,339.923h-9.982l-2.764-29.285h15.511Z" transform="translate(-456.896 -263.036)" fill="#1b2c56" />
|
||||
<path id="Path_99" data-name="Path 99" d="M479.358,339.923h-9.982l-2.764-29.285h15.511Z"
|
||||
transform="translate(-456.896 -263.036)" fill="#1b2c56"/>
|
||||
</g>
|
||||
<g id="Group_127" data-name="Group 127" transform="translate(57.242 57.722)">
|
||||
<path id="Path_100" data-name="Path 100" d="M368.515,89.9a11.2,11.2,0,0,0-1.4-4.792l1.39-.775a12.886,12.886,0,0,0-2.685-3.346l-1.058,1.191a11.2,11.2,0,0,0-4.375-2.406l.433-1.524-.02-.005a12.769,12.769,0,0,0-3.495-.487c-.252,0-.5.006-.751.021l.094,1.589a11.22,11.22,0,0,0-4.793,1.4l-.774-1.39a12.835,12.835,0,0,0-3.349,2.682l1.191,1.058a11.187,11.187,0,0,0-2.41,4.374l-1.523-.434-.009.029a12.784,12.784,0,0,0-.487,3.5q0,.371.021.741l1.589-.094a11.221,11.221,0,0,0,1.394,4.794l-1.39.773a12.857,12.857,0,0,0,2.679,3.351l1.061-1.189a11.19,11.19,0,0,0,4.371,2.413l-.437,1.524.04.011a12.825,12.825,0,0,0,3.5.487q.388,0,.771-.024l-.1-1.588a11.225,11.225,0,0,0,4.79-1.407l.776,1.389a12.837,12.837,0,0,0,3.344-2.687l-1.191-1.057a11.2,11.2,0,0,0,2.4-4.377l1.524.432,0-.01a12.819,12.819,0,0,0,.487-3.495c0-.255-.008-.509-.022-.761Zm-13.989,10.509h0l.079-.277Zm9.317-7.988a6.782,6.782,0,1,1,.258-1.852A6.793,6.793,0,0,1,363.843,92.419Z" transform="translate(21.663 -52.751)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<path id="Path_101" data-name="Path 101" d="M338.515,173.9a11.2,11.2,0,0,0-1.4-4.792l1.39-.775a12.884,12.884,0,0,0-2.685-3.346l-1.058,1.191a11.2,11.2,0,0,0-4.375-2.406l.433-1.524-.02,0a12.767,12.767,0,0,0-3.495-.487c-.252,0-.5.006-.751.021l.094,1.589a11.22,11.22,0,0,0-4.793,1.4l-.774-1.39a12.834,12.834,0,0,0-3.349,2.682l1.191,1.058a11.187,11.187,0,0,0-2.41,4.374l-1.523-.434-.009.029a12.785,12.785,0,0,0-.487,3.5q0,.371.021.741l1.589-.094a11.22,11.22,0,0,0,1.394,4.794l-1.39.773a12.859,12.859,0,0,0,2.679,3.351l1.061-1.189a11.19,11.19,0,0,0,4.371,2.413l-.437,1.524.04.011a12.826,12.826,0,0,0,3.5.487q.388,0,.771-.024l-.1-1.588a11.226,11.226,0,0,0,4.79-1.407l.776,1.389a12.837,12.837,0,0,0,3.344-2.687l-1.191-1.057a11.2,11.2,0,0,0,2.4-4.377l1.524.432,0-.01a12.819,12.819,0,0,0,.487-3.495c0-.255-.007-.509-.022-.761Zm-13.989,10.509h0l.079-.277Zm9.317-7.988a6.782,6.782,0,1,1,.258-1.852A6.793,6.793,0,0,1,333.843,176.419Z" transform="translate(14.219 -31.907)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<path id="Path_102" data-name="Path 102" d="M120.262,107.332a6.662,6.662,0,0,0-.836-2.855l.829-.462a7.65,7.65,0,0,0-1.6-1.995l-.63.71a6.66,6.66,0,0,0-2.607-1.434l.258-.909-.011,0a7.612,7.612,0,0,0-2.083-.291c-.15,0-.3,0-.448.014l.056.946a6.687,6.687,0,0,0-2.856.834l-.461-.829a7.646,7.646,0,0,0-2,1.6l.709.63a6.673,6.673,0,0,0-1.435,2.606l-.909-.26,0,.019a7.643,7.643,0,0,0-.29,2.082c0,.149,0,.3.012.442l.947-.055a6.672,6.672,0,0,0,.831,2.857l-.83.461a7.662,7.662,0,0,0,1.6,2l.633-.708a6.662,6.662,0,0,0,2.6,1.437l-.261.909.024.006a7.661,7.661,0,0,0,2.083.291c.154,0,.307,0,.461-.014l-.057-.947a6.665,6.665,0,0,0,2.855-.839l.462.829a7.649,7.649,0,0,0,1.993-1.6l-.71-.63a6.667,6.667,0,0,0,1.432-2.609l.909.258v-.006a7.609,7.609,0,0,0,.29-2.082c0-.152,0-.3-.012-.454Zm-8.336,6.262h0l.047-.165Zm5.553-4.759a4.043,4.043,0,1,1,.154-1.1A4.049,4.049,0,0,1,117.479,108.835Z" transform="translate(-37.531 -47.207)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.322" />
|
||||
<path id="Path_103" data-name="Path 103" d="M75.157,180.381a11.214,11.214,0,0,0-1.4-4.792l1.39-.775a12.885,12.885,0,0,0-2.685-3.346L71.4,172.659a11.2,11.2,0,0,0-4.375-2.406l.433-1.524-.02-.005a12.817,12.817,0,0,0-3.495-.487q-.378,0-.751.021l.094,1.589a11.216,11.216,0,0,0-4.793,1.4l-.774-1.39a12.86,12.86,0,0,0-3.349,2.682l1.189,1.058a11.2,11.2,0,0,0-2.409,4.373l-1.524-.434-.007.03a12.818,12.818,0,0,0-.488,3.495c0,.247.007.5.022.741l1.589-.094a11.208,11.208,0,0,0,1.394,4.8l-1.39.771a12.812,12.812,0,0,0,2.679,3.351l1.061-1.189a11.175,11.175,0,0,0,4.371,2.413l-.437,1.524.04.011a12.826,12.826,0,0,0,3.5.487c.257,0,.515-.008.771-.024l-.1-1.588a11.231,11.231,0,0,0,4.79-1.407l.776,1.389a12.836,12.836,0,0,0,3.344-2.687L72.352,188.5a11.2,11.2,0,0,0,2.4-4.377l1.523.432,0-.01a12.816,12.816,0,0,0,.487-3.495c0-.255-.007-.509-.022-.761ZM61.168,190.891h0l.077-.277Zm9.317-7.988a6.782,6.782,0,1,1,.258-1.852A6.793,6.793,0,0,1,70.486,182.9Z" transform="translate(-51.133 -30.298)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<path id="Path_104" data-name="Path 104" d="M296.644,88.572a5.747,5.747,0,0,0-.721-2.463l.715-.4a6.606,6.606,0,0,0-1.38-1.719l-.544.612a5.732,5.732,0,0,0-2.248-1.237l.222-.783-.01,0a6.618,6.618,0,0,0-1.8-.25c-.13,0-.258,0-.387.011l.049.816a5.755,5.755,0,0,0-2.463.719l-.4-.714a6.582,6.582,0,0,0-1.721,1.378l.612.544a5.75,5.75,0,0,0-1.238,2.248l-.783-.223-.005.015a6.572,6.572,0,0,0-.251,1.8c0,.127,0,.255.011.381l.818-.047a5.752,5.752,0,0,0,.716,2.464l-.715.4a6.59,6.59,0,0,0,1.377,1.722l.545-.61a5.748,5.748,0,0,0,2.247,1.239l-.225.784.021,0a6.571,6.571,0,0,0,1.8.251c.132,0,.265,0,.4-.012l-.05-.816a5.755,5.755,0,0,0,2.463-.723l.4.714a6.6,6.6,0,0,0,1.72-1.382l-.613-.543a5.738,5.738,0,0,0,1.234-2.25l.784.223V90.71a6.52,6.52,0,0,0,.25-1.8c0-.131,0-.261-.011-.391Zm-7.191,5.4h0l.041-.142Zm4.789-4.105a3.491,3.491,0,0,1-3.356,2.541,3.452,3.452,0,0,1-.952-.134,3.5,3.5,0,1,1,4.309-2.408Z" transform="translate(6.726 -51.616)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<path id="Path_105" data-name="Path 105" d="M171.331,99.773a5.776,5.776,0,0,0-.721-2.463l.714-.4a6.586,6.586,0,0,0-1.379-1.72l-.544.612a5.746,5.746,0,0,0-2.248-1.236l.222-.784-.01,0a6.572,6.572,0,0,0-1.8-.251c-.13,0-.258,0-.387.012l.049.816a5.755,5.755,0,0,0-2.464.719l-.4-.715a6.633,6.633,0,0,0-1.721,1.378l.612.545a5.738,5.738,0,0,0-1.238,2.247l-.784-.223,0,.016a6.571,6.571,0,0,0-.251,1.8c0,.127,0,.255.011.381l.816-.047a5.759,5.759,0,0,0,.718,2.464l-.715.4a6.608,6.608,0,0,0,1.377,1.722l.545-.612a5.766,5.766,0,0,0,2.247,1.241l-.225.783.021.006a6.57,6.57,0,0,0,1.8.25q.2,0,.4-.011l-.05-.816a5.773,5.773,0,0,0,2.463-.724l.4.714a6.585,6.585,0,0,0,1.719-1.38l-.612-.544a5.733,5.733,0,0,0,1.234-2.249l.784.222v0a6.619,6.619,0,0,0,.25-1.8c0-.131,0-.262-.011-.392Zm-7.191,5.4h0l.04-.142Zm4.789-4.105a3.491,3.491,0,0,1-6.85-.949,3.453,3.453,0,0,1,.134-.952,3.49,3.49,0,1,1,6.716,1.9Z" transform="translate(-24.37 -48.836)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<path id="Path_106" data-name="Path 106" d="M188.716,170.914a5.775,5.775,0,0,0-.721-2.464l.714-.4a6.628,6.628,0,0,0-1.379-1.72l-.544.613a5.747,5.747,0,0,0-2.249-1.237l.223-.784-.01,0a6.618,6.618,0,0,0-1.8-.25c-.13,0-.258,0-.387.011l.049.816a5.756,5.756,0,0,0-2.464.719l-.4-.715a6.593,6.593,0,0,0-1.721,1.379l.612.544a5.735,5.735,0,0,0-1.238,2.248l-.784-.223,0,.015a6.571,6.571,0,0,0-.251,1.8c0,.127,0,.255.011.381l.816-.047a5.754,5.754,0,0,0,.718,2.464l-.715.4a6.589,6.589,0,0,0,1.377,1.722l.545-.612a5.726,5.726,0,0,0,2.247,1.241l-.225.783.02.006a6.588,6.588,0,0,0,1.8.251c.132,0,.265,0,.4-.012l-.05-.816a5.784,5.784,0,0,0,2.461-.723l.4.714a6.636,6.636,0,0,0,1.719-1.382l-.613-.543a5.756,5.756,0,0,0,1.236-2.25l.783.223v-.006a6.571,6.571,0,0,0,.251-1.8c0-.131,0-.261-.011-.392Zm-7.191,5.4h0l.04-.142Zm4.789-4.105a3.488,3.488,0,1,1,.132-.952A3.492,3.492,0,0,1,186.314,172.21Z" transform="translate(-20.056 -31.183)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<path id="Path_107" data-name="Path 107" d="M399.44,161.581a4.749,4.749,0,0,0-.593-2.026l.587-.327a5.386,5.386,0,0,0-1.135-1.414l-.447.5A4.723,4.723,0,0,0,396,157.3l.183-.644-.009,0a5.445,5.445,0,0,0-1.477-.206c-.106,0-.212,0-.318.01l.04.672a4.752,4.752,0,0,0-2.026.59l-.327-.587a5.424,5.424,0,0,0-1.415,1.133l.5.447a4.725,4.725,0,0,0-1.017,1.849l-.644-.183,0,.012a5.4,5.4,0,0,0-.206,1.477c0,.1,0,.21.009.313l.671-.039a4.745,4.745,0,0,0,.589,2.026l-.588.327a5.435,5.435,0,0,0,1.133,1.417l.448-.5a4.716,4.716,0,0,0,1.847,1.02l-.185.644.017,0a5.445,5.445,0,0,0,1.477.206c.11,0,.218,0,.327-.01l-.041-.671a4.731,4.731,0,0,0,2.025-.6l.328.588a5.405,5.405,0,0,0,1.413-1.136l-.5-.447a4.726,4.726,0,0,0,1.015-1.85l.644.182v0a5.4,5.4,0,0,0,.206-1.478c0-.107,0-.215-.009-.322Zm-5.912,4.441h0l.032-.117Zm3.938-3.376a2.875,2.875,0,0,1-2.761,2.091,2.938,2.938,0,0,1-.783-.11,2.871,2.871,0,0,1,.78-5.633,2.841,2.841,0,0,1,.783.11,2.868,2.868,0,0,1,1.981,3.542Z" transform="translate(32.779 -33.224)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<path id="Path_108" data-name="Path 108" d="M477.106,196.914a4.737,4.737,0,0,0-.593-2.026l.588-.327a5.429,5.429,0,0,0-1.135-1.414l-.448.5a4.727,4.727,0,0,0-1.848-1.017l.183-.644-.009,0a5.444,5.444,0,0,0-1.477-.206c-.107,0-.212,0-.318.01l.04.672a4.731,4.731,0,0,0-2.026.592l-.327-.588a5.427,5.427,0,0,0-1.415,1.133l.5.448a4.729,4.729,0,0,0-1.018,1.849l-.644-.185,0,.012a5.444,5.444,0,0,0-.206,1.478c0,.1,0,.21.01.313l.671-.04a4.739,4.739,0,0,0,.589,2.027l-.588.326a5.429,5.429,0,0,0,1.132,1.417l.448-.5a4.73,4.73,0,0,0,1.849,1.02l-.185.644.016.005a5.4,5.4,0,0,0,1.478.206c.109,0,.217,0,.326-.01l-.04-.672a4.745,4.745,0,0,0,2.025-.594l.327.587a5.411,5.411,0,0,0,1.414-1.136l-.5-.447a4.7,4.7,0,0,0,1.016-1.85l.644.184v-.005a5.4,5.4,0,0,0,.206-1.477c0-.109,0-.216-.01-.322Zm-5.912,4.442h0l.034-.117Zm3.938-3.376a2.871,2.871,0,0,1-2.76,2.089,2.841,2.841,0,0,1-.783-.11,2.874,2.874,0,1,1,3.542-1.98Z" transform="translate(52.051 -24.456)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<path id="Path_109" data-name="Path 109" d="M368.188,213.479a7.05,7.05,0,0,0-.879-3l.87-.486a8.068,8.068,0,0,0-1.681-2.1l-.663.745a7.014,7.014,0,0,0-2.741-1.507l.272-.955-.012,0a8,8,0,0,0-2.189-.306c-.157,0-.315.005-.471.014l.059.995a7.047,7.047,0,0,0-3,.876l-.484-.87a8.068,8.068,0,0,0-2.1,1.679l.745.664a7.02,7.02,0,0,0-1.509,2.74l-.954-.273,0,.019a8,8,0,0,0-.306,2.189c0,.156,0,.311.014.464l.995-.059a7.032,7.032,0,0,0,.874,3l-.871.484a8.022,8.022,0,0,0,1.679,2.1l.664-.744a7,7,0,0,0,2.737,1.51l-.273.955.025.008a8.048,8.048,0,0,0,2.189.3c.162,0,.323,0,.484-.015l-.061-.995a7.007,7.007,0,0,0,3-.881l.487.87a8.039,8.039,0,0,0,2.094-1.683l-.746-.663a7.012,7.012,0,0,0,1.505-2.741l.954.271,0-.006a8.048,8.048,0,0,0,.3-2.189c0-.16,0-.318-.014-.477Zm-8.763,6.581h0l.05-.174Zm5.836-5a4.247,4.247,0,1,1,.162-1.161A4.257,4.257,0,0,1,365.261,215.058Z" transform="translate(23.809 -20.959)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.262" />
|
||||
<path id="Path_110" data-name="Path 110" d="M232.641,121.423a5.4,5.4,0,1,1-5.4-5.4A5.4,5.4,0,0,1,232.641,121.423Z" transform="translate(-8.772 -43.255)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<path id="Path_111" data-name="Path 111" d="M323.119,61.1a3.374,3.374,0,1,1-3.375-3.375A3.375,3.375,0,0,1,323.119,61.1Z" transform="translate(14.685 -57.722)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<path id="Path_112" data-name="Path 112" d="M415.545,127.468a3.374,3.374,0,1,1-3.374-3.375A3.373,3.373,0,0,1,415.545,127.468Z" transform="translate(37.62 -41.252)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<path id="Path_113" data-name="Path 113" d="M428.545,189.134a3.374,3.374,0,1,1-3.374-3.374A3.375,3.375,0,0,1,428.545,189.134Z" transform="translate(40.846 -25.95)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<circle id="Ellipse_11" data-name="Ellipse 11" cx="3.374" cy="3.374" r="3.374" transform="translate(309.897 74.802)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<path id="Path_114" data-name="Path 114" d="M198.044,71.91a3.374,3.374,0,1,1-3.374-3.374A3.373,3.373,0,0,1,198.044,71.91Z" transform="translate(-16.352 -55.039)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<path id="Path_115" data-name="Path 115" d="M97,152.4a3.374,3.374,0,1,1-3.375-3.374A3.375,3.375,0,0,1,97,152.4Z" transform="translate(-41.426 -35.064)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<path id="Path_100" data-name="Path 100"
|
||||
d="M368.515,89.9a11.2,11.2,0,0,0-1.4-4.792l1.39-.775a12.886,12.886,0,0,0-2.685-3.346l-1.058,1.191a11.2,11.2,0,0,0-4.375-2.406l.433-1.524-.02-.005a12.769,12.769,0,0,0-3.495-.487c-.252,0-.5.006-.751.021l.094,1.589a11.22,11.22,0,0,0-4.793,1.4l-.774-1.39a12.835,12.835,0,0,0-3.349,2.682l1.191,1.058a11.187,11.187,0,0,0-2.41,4.374l-1.523-.434-.009.029a12.784,12.784,0,0,0-.487,3.5q0,.371.021.741l1.589-.094a11.221,11.221,0,0,0,1.394,4.794l-1.39.773a12.857,12.857,0,0,0,2.679,3.351l1.061-1.189a11.19,11.19,0,0,0,4.371,2.413l-.437,1.524.04.011a12.825,12.825,0,0,0,3.5.487q.388,0,.771-.024l-.1-1.588a11.225,11.225,0,0,0,4.79-1.407l.776,1.389a12.837,12.837,0,0,0,3.344-2.687l-1.191-1.057a11.2,11.2,0,0,0,2.4-4.377l1.524.432,0-.01a12.819,12.819,0,0,0,.487-3.495c0-.255-.008-.509-.022-.761Zm-13.989,10.509h0l.079-.277Zm9.317-7.988a6.782,6.782,0,1,1,.258-1.852A6.793,6.793,0,0,1,363.843,92.419Z"
|
||||
transform="translate(21.663 -52.751)" fill="none" stroke="#99a6d6" stroke-miterlimit="10"
|
||||
stroke-width="0.541"/>
|
||||
<path id="Path_101" data-name="Path 101"
|
||||
d="M338.515,173.9a11.2,11.2,0,0,0-1.4-4.792l1.39-.775a12.884,12.884,0,0,0-2.685-3.346l-1.058,1.191a11.2,11.2,0,0,0-4.375-2.406l.433-1.524-.02,0a12.767,12.767,0,0,0-3.495-.487c-.252,0-.5.006-.751.021l.094,1.589a11.22,11.22,0,0,0-4.793,1.4l-.774-1.39a12.834,12.834,0,0,0-3.349,2.682l1.191,1.058a11.187,11.187,0,0,0-2.41,4.374l-1.523-.434-.009.029a12.785,12.785,0,0,0-.487,3.5q0,.371.021.741l1.589-.094a11.22,11.22,0,0,0,1.394,4.794l-1.39.773a12.859,12.859,0,0,0,2.679,3.351l1.061-1.189a11.19,11.19,0,0,0,4.371,2.413l-.437,1.524.04.011a12.826,12.826,0,0,0,3.5.487q.388,0,.771-.024l-.1-1.588a11.226,11.226,0,0,0,4.79-1.407l.776,1.389a12.837,12.837,0,0,0,3.344-2.687l-1.191-1.057a11.2,11.2,0,0,0,2.4-4.377l1.524.432,0-.01a12.819,12.819,0,0,0,.487-3.495c0-.255-.007-.509-.022-.761Zm-13.989,10.509h0l.079-.277Zm9.317-7.988a6.782,6.782,0,1,1,.258-1.852A6.793,6.793,0,0,1,333.843,176.419Z"
|
||||
transform="translate(14.219 -31.907)" fill="none" stroke="#99a6d6" stroke-miterlimit="10"
|
||||
stroke-width="0.541"/>
|
||||
<path id="Path_102" data-name="Path 102"
|
||||
d="M120.262,107.332a6.662,6.662,0,0,0-.836-2.855l.829-.462a7.65,7.65,0,0,0-1.6-1.995l-.63.71a6.66,6.66,0,0,0-2.607-1.434l.258-.909-.011,0a7.612,7.612,0,0,0-2.083-.291c-.15,0-.3,0-.448.014l.056.946a6.687,6.687,0,0,0-2.856.834l-.461-.829a7.646,7.646,0,0,0-2,1.6l.709.63a6.673,6.673,0,0,0-1.435,2.606l-.909-.26,0,.019a7.643,7.643,0,0,0-.29,2.082c0,.149,0,.3.012.442l.947-.055a6.672,6.672,0,0,0,.831,2.857l-.83.461a7.662,7.662,0,0,0,1.6,2l.633-.708a6.662,6.662,0,0,0,2.6,1.437l-.261.909.024.006a7.661,7.661,0,0,0,2.083.291c.154,0,.307,0,.461-.014l-.057-.947a6.665,6.665,0,0,0,2.855-.839l.462.829a7.649,7.649,0,0,0,1.993-1.6l-.71-.63a6.667,6.667,0,0,0,1.432-2.609l.909.258v-.006a7.609,7.609,0,0,0,.29-2.082c0-.152,0-.3-.012-.454Zm-8.336,6.262h0l.047-.165Zm5.553-4.759a4.043,4.043,0,1,1,.154-1.1A4.049,4.049,0,0,1,117.479,108.835Z"
|
||||
transform="translate(-37.531 -47.207)" fill="none" stroke="#99a6d6" stroke-miterlimit="10"
|
||||
stroke-width="0.322"/>
|
||||
<path id="Path_103" data-name="Path 103"
|
||||
d="M75.157,180.381a11.214,11.214,0,0,0-1.4-4.792l1.39-.775a12.885,12.885,0,0,0-2.685-3.346L71.4,172.659a11.2,11.2,0,0,0-4.375-2.406l.433-1.524-.02-.005a12.817,12.817,0,0,0-3.495-.487q-.378,0-.751.021l.094,1.589a11.216,11.216,0,0,0-4.793,1.4l-.774-1.39a12.86,12.86,0,0,0-3.349,2.682l1.189,1.058a11.2,11.2,0,0,0-2.409,4.373l-1.524-.434-.007.03a12.818,12.818,0,0,0-.488,3.495c0,.247.007.5.022.741l1.589-.094a11.208,11.208,0,0,0,1.394,4.8l-1.39.771a12.812,12.812,0,0,0,2.679,3.351l1.061-1.189a11.175,11.175,0,0,0,4.371,2.413l-.437,1.524.04.011a12.826,12.826,0,0,0,3.5.487c.257,0,.515-.008.771-.024l-.1-1.588a11.231,11.231,0,0,0,4.79-1.407l.776,1.389a12.836,12.836,0,0,0,3.344-2.687L72.352,188.5a11.2,11.2,0,0,0,2.4-4.377l1.523.432,0-.01a12.816,12.816,0,0,0,.487-3.495c0-.255-.007-.509-.022-.761ZM61.168,190.891h0l.077-.277Zm9.317-7.988a6.782,6.782,0,1,1,.258-1.852A6.793,6.793,0,0,1,70.486,182.9Z"
|
||||
transform="translate(-51.133 -30.298)" fill="none" stroke="#99a6d6" stroke-miterlimit="10"
|
||||
stroke-width="0.541"/>
|
||||
<path id="Path_104" data-name="Path 104"
|
||||
d="M296.644,88.572a5.747,5.747,0,0,0-.721-2.463l.715-.4a6.606,6.606,0,0,0-1.38-1.719l-.544.612a5.732,5.732,0,0,0-2.248-1.237l.222-.783-.01,0a6.618,6.618,0,0,0-1.8-.25c-.13,0-.258,0-.387.011l.049.816a5.755,5.755,0,0,0-2.463.719l-.4-.714a6.582,6.582,0,0,0-1.721,1.378l.612.544a5.75,5.75,0,0,0-1.238,2.248l-.783-.223-.005.015a6.572,6.572,0,0,0-.251,1.8c0,.127,0,.255.011.381l.818-.047a5.752,5.752,0,0,0,.716,2.464l-.715.4a6.59,6.59,0,0,0,1.377,1.722l.545-.61a5.748,5.748,0,0,0,2.247,1.239l-.225.784.021,0a6.571,6.571,0,0,0,1.8.251c.132,0,.265,0,.4-.012l-.05-.816a5.755,5.755,0,0,0,2.463-.723l.4.714a6.6,6.6,0,0,0,1.72-1.382l-.613-.543a5.738,5.738,0,0,0,1.234-2.25l.784.223V90.71a6.52,6.52,0,0,0,.25-1.8c0-.131,0-.261-.011-.391Zm-7.191,5.4h0l.041-.142Zm4.789-4.105a3.491,3.491,0,0,1-3.356,2.541,3.452,3.452,0,0,1-.952-.134,3.5,3.5,0,1,1,4.309-2.408Z"
|
||||
transform="translate(6.726 -51.616)" fill="none" stroke="#99a6d6" stroke-miterlimit="10"
|
||||
stroke-width="0.541"/>
|
||||
<path id="Path_105" data-name="Path 105"
|
||||
d="M171.331,99.773a5.776,5.776,0,0,0-.721-2.463l.714-.4a6.586,6.586,0,0,0-1.379-1.72l-.544.612a5.746,5.746,0,0,0-2.248-1.236l.222-.784-.01,0a6.572,6.572,0,0,0-1.8-.251c-.13,0-.258,0-.387.012l.049.816a5.755,5.755,0,0,0-2.464.719l-.4-.715a6.633,6.633,0,0,0-1.721,1.378l.612.545a5.738,5.738,0,0,0-1.238,2.247l-.784-.223,0,.016a6.571,6.571,0,0,0-.251,1.8c0,.127,0,.255.011.381l.816-.047a5.759,5.759,0,0,0,.718,2.464l-.715.4a6.608,6.608,0,0,0,1.377,1.722l.545-.612a5.766,5.766,0,0,0,2.247,1.241l-.225.783.021.006a6.57,6.57,0,0,0,1.8.25q.2,0,.4-.011l-.05-.816a5.773,5.773,0,0,0,2.463-.724l.4.714a6.585,6.585,0,0,0,1.719-1.38l-.612-.544a5.733,5.733,0,0,0,1.234-2.249l.784.222v0a6.619,6.619,0,0,0,.25-1.8c0-.131,0-.262-.011-.392Zm-7.191,5.4h0l.04-.142Zm4.789-4.105a3.491,3.491,0,0,1-6.85-.949,3.453,3.453,0,0,1,.134-.952,3.49,3.49,0,1,1,6.716,1.9Z"
|
||||
transform="translate(-24.37 -48.836)" fill="none" stroke="#99a6d6" stroke-miterlimit="10"
|
||||
stroke-width="0.541"/>
|
||||
<path id="Path_106" data-name="Path 106"
|
||||
d="M188.716,170.914a5.775,5.775,0,0,0-.721-2.464l.714-.4a6.628,6.628,0,0,0-1.379-1.72l-.544.613a5.747,5.747,0,0,0-2.249-1.237l.223-.784-.01,0a6.618,6.618,0,0,0-1.8-.25c-.13,0-.258,0-.387.011l.049.816a5.756,5.756,0,0,0-2.464.719l-.4-.715a6.593,6.593,0,0,0-1.721,1.379l.612.544a5.735,5.735,0,0,0-1.238,2.248l-.784-.223,0,.015a6.571,6.571,0,0,0-.251,1.8c0,.127,0,.255.011.381l.816-.047a5.754,5.754,0,0,0,.718,2.464l-.715.4a6.589,6.589,0,0,0,1.377,1.722l.545-.612a5.726,5.726,0,0,0,2.247,1.241l-.225.783.02.006a6.588,6.588,0,0,0,1.8.251c.132,0,.265,0,.4-.012l-.05-.816a5.784,5.784,0,0,0,2.461-.723l.4.714a6.636,6.636,0,0,0,1.719-1.382l-.613-.543a5.756,5.756,0,0,0,1.236-2.25l.783.223v-.006a6.571,6.571,0,0,0,.251-1.8c0-.131,0-.261-.011-.392Zm-7.191,5.4h0l.04-.142Zm4.789-4.105a3.488,3.488,0,1,1,.132-.952A3.492,3.492,0,0,1,186.314,172.21Z"
|
||||
transform="translate(-20.056 -31.183)" fill="none" stroke="#99a6d6" stroke-miterlimit="10"
|
||||
stroke-width="0.541"/>
|
||||
<path id="Path_107" data-name="Path 107"
|
||||
d="M399.44,161.581a4.749,4.749,0,0,0-.593-2.026l.587-.327a5.386,5.386,0,0,0-1.135-1.414l-.447.5A4.723,4.723,0,0,0,396,157.3l.183-.644-.009,0a5.445,5.445,0,0,0-1.477-.206c-.106,0-.212,0-.318.01l.04.672a4.752,4.752,0,0,0-2.026.59l-.327-.587a5.424,5.424,0,0,0-1.415,1.133l.5.447a4.725,4.725,0,0,0-1.017,1.849l-.644-.183,0,.012a5.4,5.4,0,0,0-.206,1.477c0,.1,0,.21.009.313l.671-.039a4.745,4.745,0,0,0,.589,2.026l-.588.327a5.435,5.435,0,0,0,1.133,1.417l.448-.5a4.716,4.716,0,0,0,1.847,1.02l-.185.644.017,0a5.445,5.445,0,0,0,1.477.206c.11,0,.218,0,.327-.01l-.041-.671a4.731,4.731,0,0,0,2.025-.6l.328.588a5.405,5.405,0,0,0,1.413-1.136l-.5-.447a4.726,4.726,0,0,0,1.015-1.85l.644.182v0a5.4,5.4,0,0,0,.206-1.478c0-.107,0-.215-.009-.322Zm-5.912,4.441h0l.032-.117Zm3.938-3.376a2.875,2.875,0,0,1-2.761,2.091,2.938,2.938,0,0,1-.783-.11,2.871,2.871,0,0,1,.78-5.633,2.841,2.841,0,0,1,.783.11,2.868,2.868,0,0,1,1.981,3.542Z"
|
||||
transform="translate(32.779 -33.224)" fill="none" stroke="#99a6d6" stroke-miterlimit="10"
|
||||
stroke-width="0.541"/>
|
||||
<path id="Path_108" data-name="Path 108"
|
||||
d="M477.106,196.914a4.737,4.737,0,0,0-.593-2.026l.588-.327a5.429,5.429,0,0,0-1.135-1.414l-.448.5a4.727,4.727,0,0,0-1.848-1.017l.183-.644-.009,0a5.444,5.444,0,0,0-1.477-.206c-.107,0-.212,0-.318.01l.04.672a4.731,4.731,0,0,0-2.026.592l-.327-.588a5.427,5.427,0,0,0-1.415,1.133l.5.448a4.729,4.729,0,0,0-1.018,1.849l-.644-.185,0,.012a5.444,5.444,0,0,0-.206,1.478c0,.1,0,.21.01.313l.671-.04a4.739,4.739,0,0,0,.589,2.027l-.588.326a5.429,5.429,0,0,0,1.132,1.417l.448-.5a4.73,4.73,0,0,0,1.849,1.02l-.185.644.016.005a5.4,5.4,0,0,0,1.478.206c.109,0,.217,0,.326-.01l-.04-.672a4.745,4.745,0,0,0,2.025-.594l.327.587a5.411,5.411,0,0,0,1.414-1.136l-.5-.447a4.7,4.7,0,0,0,1.016-1.85l.644.184v-.005a5.4,5.4,0,0,0,.206-1.477c0-.109,0-.216-.01-.322Zm-5.912,4.442h0l.034-.117Zm3.938-3.376a2.871,2.871,0,0,1-2.76,2.089,2.841,2.841,0,0,1-.783-.11,2.874,2.874,0,1,1,3.542-1.98Z"
|
||||
transform="translate(52.051 -24.456)" fill="none" stroke="#99a6d6" stroke-miterlimit="10"
|
||||
stroke-width="0.541"/>
|
||||
<path id="Path_109" data-name="Path 109"
|
||||
d="M368.188,213.479a7.05,7.05,0,0,0-.879-3l.87-.486a8.068,8.068,0,0,0-1.681-2.1l-.663.745a7.014,7.014,0,0,0-2.741-1.507l.272-.955-.012,0a8,8,0,0,0-2.189-.306c-.157,0-.315.005-.471.014l.059.995a7.047,7.047,0,0,0-3,.876l-.484-.87a8.068,8.068,0,0,0-2.1,1.679l.745.664a7.02,7.02,0,0,0-1.509,2.74l-.954-.273,0,.019a8,8,0,0,0-.306,2.189c0,.156,0,.311.014.464l.995-.059a7.032,7.032,0,0,0,.874,3l-.871.484a8.022,8.022,0,0,0,1.679,2.1l.664-.744a7,7,0,0,0,2.737,1.51l-.273.955.025.008a8.048,8.048,0,0,0,2.189.3c.162,0,.323,0,.484-.015l-.061-.995a7.007,7.007,0,0,0,3-.881l.487.87a8.039,8.039,0,0,0,2.094-1.683l-.746-.663a7.012,7.012,0,0,0,1.505-2.741l.954.271,0-.006a8.048,8.048,0,0,0,.3-2.189c0-.16,0-.318-.014-.477Zm-8.763,6.581h0l.05-.174Zm5.836-5a4.247,4.247,0,1,1,.162-1.161A4.257,4.257,0,0,1,365.261,215.058Z"
|
||||
transform="translate(23.809 -20.959)" fill="none" stroke="#99a6d6" stroke-miterlimit="10"
|
||||
stroke-width="0.262"/>
|
||||
<path id="Path_110" data-name="Path 110"
|
||||
d="M232.641,121.423a5.4,5.4,0,1,1-5.4-5.4A5.4,5.4,0,0,1,232.641,121.423Z"
|
||||
transform="translate(-8.772 -43.255)" fill="none" stroke="#99a6d6" stroke-miterlimit="10"
|
||||
stroke-width="0.541"/>
|
||||
<path id="Path_111" data-name="Path 111"
|
||||
d="M323.119,61.1a3.374,3.374,0,1,1-3.375-3.375A3.375,3.375,0,0,1,323.119,61.1Z"
|
||||
transform="translate(14.685 -57.722)" fill="none" stroke="#99a6d6" stroke-miterlimit="10"
|
||||
stroke-width="0.541"/>
|
||||
<path id="Path_112" data-name="Path 112"
|
||||
d="M415.545,127.468a3.374,3.374,0,1,1-3.374-3.375A3.373,3.373,0,0,1,415.545,127.468Z"
|
||||
transform="translate(37.62 -41.252)" fill="none" stroke="#99a6d6" stroke-miterlimit="10"
|
||||
stroke-width="0.541"/>
|
||||
<path id="Path_113" data-name="Path 113"
|
||||
d="M428.545,189.134a3.374,3.374,0,1,1-3.374-3.374A3.375,3.375,0,0,1,428.545,189.134Z"
|
||||
transform="translate(40.846 -25.95)" fill="none" stroke="#99a6d6" stroke-miterlimit="10"
|
||||
stroke-width="0.541"/>
|
||||
<circle id="Ellipse_11" data-name="Ellipse 11" cx="3.374" cy="3.374" r="3.374"
|
||||
transform="translate(309.897 74.802)" fill="none" stroke="#99a6d6" stroke-miterlimit="10"
|
||||
stroke-width="0.541"/>
|
||||
<path id="Path_114" data-name="Path 114"
|
||||
d="M198.044,71.91a3.374,3.374,0,1,1-3.374-3.374A3.373,3.373,0,0,1,198.044,71.91Z"
|
||||
transform="translate(-16.352 -55.039)" fill="none" stroke="#99a6d6" stroke-miterlimit="10"
|
||||
stroke-width="0.541"/>
|
||||
<path id="Path_115" data-name="Path 115"
|
||||
d="M97,152.4a3.374,3.374,0,1,1-3.375-3.374A3.375,3.375,0,0,1,97,152.4Z"
|
||||
transform="translate(-41.426 -35.064)" fill="none" stroke="#99a6d6" stroke-miterlimit="10"
|
||||
stroke-width="0.541"/>
|
||||
<g id="Group_122" data-name="Group 122" transform="translate(256.261 6.861)">
|
||||
<line id="Line_10" data-name="Line 10" y2="6.523" transform="translate(3.262)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<line id="Line_11" data-name="Line 11" x1="6.523" transform="translate(0 3.262)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<line id="Line_10" data-name="Line 10" y2="6.523" transform="translate(3.262)" fill="none"
|
||||
stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541"/>
|
||||
<line id="Line_11" data-name="Line 11" x1="6.523" transform="translate(0 3.262)" fill="none"
|
||||
stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541"/>
|
||||
</g>
|
||||
<g id="Group_123" data-name="Group 123" transform="translate(61.859 198.114)">
|
||||
<line id="Line_12" data-name="Line 12" y2="6.523" transform="translate(3.262)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<line id="Line_13" data-name="Line 13" x1="6.523" transform="translate(0 3.262)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<line id="Line_12" data-name="Line 12" y2="6.523" transform="translate(3.262)" fill="none"
|
||||
stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541"/>
|
||||
<line id="Line_13" data-name="Line 13" x1="6.523" transform="translate(0 3.262)" fill="none"
|
||||
stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541"/>
|
||||
</g>
|
||||
<g id="Group_124" data-name="Group 124" transform="translate(170.765 67.213)">
|
||||
<line id="Line_14" data-name="Line 14" y2="6.523" transform="translate(3.262)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<line id="Line_15" data-name="Line 15" x1="6.523" transform="translate(0 3.262)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<line id="Line_14" data-name="Line 14" y2="6.523" transform="translate(3.262)" fill="none"
|
||||
stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541"/>
|
||||
<line id="Line_15" data-name="Line 15" x1="6.523" transform="translate(0 3.262)" fill="none"
|
||||
stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541"/>
|
||||
</g>
|
||||
<g id="Group_125" data-name="Group 125" transform="translate(96.5 140.229)">
|
||||
<line id="Line_16" data-name="Line 16" y2="6.523" transform="translate(3.262 0)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<line id="Line_17" data-name="Line 17" x1="6.523" transform="translate(0 3.262)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<line id="Line_16" data-name="Line 16" y2="6.523" transform="translate(3.262 0)" fill="none"
|
||||
stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541"/>
|
||||
<line id="Line_17" data-name="Line 17" x1="6.523" transform="translate(0 3.262)" fill="none"
|
||||
stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541"/>
|
||||
</g>
|
||||
<g id="Group_126" data-name="Group 126" transform="translate(24.654 73.378)">
|
||||
<line id="Line_18" data-name="Line 18" y2="6.523" transform="translate(3.262)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<line id="Line_19" data-name="Line 19" x1="6.523" transform="translate(0 3.262)" fill="none" stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541" />
|
||||
<line id="Line_18" data-name="Line 18" y2="6.523" transform="translate(3.262)" fill="none"
|
||||
stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541"/>
|
||||
<line id="Line_19" data-name="Line 19" x1="6.523" transform="translate(0 3.262)" fill="none"
|
||||
stroke="#99a6d6" stroke-miterlimit="10" stroke-width="0.541"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 28 KiB |
@@ -1,4 +1,4 @@
|
||||
import Vue from 'vue';
|
||||
import Vue from "vue";
|
||||
|
||||
export default class {
|
||||
constructor() {
|
||||
@@ -36,13 +36,13 @@ export default class {
|
||||
}
|
||||
|
||||
normalizeKey(key) {
|
||||
let keyParts = key.replace('[]', '').split('[');
|
||||
let keyParts = key.replace("[]", "").split("[");
|
||||
|
||||
// No need to normalize the key.
|
||||
if (keyParts.length === 1) {
|
||||
return key;
|
||||
}
|
||||
|
||||
return keyParts.join('.').slice(0, -1);
|
||||
return keyParts.join(".").slice(0, -1);
|
||||
}
|
||||
}
|
||||
|
||||
6
Themes/Storefront/resources/assets/public/js/axios.js
Normal file
6
Themes/Storefront/resources/assets/public/js/axios.js
Normal file
@@ -0,0 +1,6 @@
|
||||
import axios from "axios";
|
||||
|
||||
window.axios = axios;
|
||||
|
||||
axios.defaults.headers.common["X-CSRF-TOKEN"] = FleetCart.csrfToken;
|
||||
axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
|
||||
@@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<div class="daily-deals-countdown countdown clearfix">
|
||||
<span class="countdown-row">
|
||||
<span class="countdown-section">
|
||||
<span class="countdown-amount">{{ date.days }}</span>
|
||||
|
||||
<span class="countdown-period">
|
||||
{{ $trans("storefront::product_card.days") }}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span class="countdown-section">
|
||||
<span class="countdown-amount">{{ date.hours }}</span>
|
||||
|
||||
<span class="countdown-period">
|
||||
{{ $trans("storefront::product_card.hours") }}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span class="countdown-section">
|
||||
<span class="countdown-amount">{{ date.minutes }}</span>
|
||||
|
||||
<span class="countdown-period">
|
||||
{{ $trans("storefront::product_card.minutes") }}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span class="countdown-section">
|
||||
<span class="countdown-amount">{{ date.seconds }}</span>
|
||||
|
||||
<span class="countdown-period">
|
||||
{{ $trans("storefront::product_card.seconds") }}
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ["endDate"],
|
||||
|
||||
data() {
|
||||
return {
|
||||
date: {},
|
||||
countdown: null,
|
||||
};
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (new Date() > new Date(this.endDate)) {
|
||||
this.setInitialDate();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.countdown = this.initCountdown();
|
||||
},
|
||||
|
||||
methods: {
|
||||
initCountdown() {
|
||||
return countdown(
|
||||
new Date(this.endDate),
|
||||
({ days, hours, minutes, seconds }) => {
|
||||
if (new Date() > new Date(this.endDate)) {
|
||||
this.setInitialDate();
|
||||
window.clearInterval(this.countdown);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.date = Object.assign({}, this.date, {
|
||||
days: this.leadingZero(days),
|
||||
hours: this.leadingZero(hours),
|
||||
minutes: this.leadingZero(minutes),
|
||||
seconds: this.leadingZero(seconds),
|
||||
});
|
||||
},
|
||||
countdown.DAYS |
|
||||
countdown.HOURS |
|
||||
countdown.MINUTES |
|
||||
countdown.SECONDS
|
||||
);
|
||||
},
|
||||
|
||||
setInitialDate() {
|
||||
this.date = Object.assign({}, this.date, {
|
||||
days: "00",
|
||||
hours: "00",
|
||||
minutes: "00",
|
||||
seconds: "00",
|
||||
});
|
||||
},
|
||||
|
||||
leadingZero(number) {
|
||||
return number < 10 ? "0" + number : number;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -2,13 +2,17 @@
|
||||
<div class="product-card">
|
||||
<div class="product-card-top">
|
||||
<a :href="productUrl" class="product-image">
|
||||
<img :src="baseImage" :class="{ 'image-placeholder': ! hasBaseImage }" alt="product image">
|
||||
<img
|
||||
:src="baseImage"
|
||||
:class="{ 'image-placeholder': !hasBaseImage }"
|
||||
:alt="product.name"
|
||||
/>
|
||||
</a>
|
||||
|
||||
<div class="product-card-actions">
|
||||
<button
|
||||
class="btn btn-wishlist"
|
||||
:class="{ 'added': inWishlist }"
|
||||
:class="{ added: inWishlist }"
|
||||
:title="$trans('storefront::product_card.wishlist')"
|
||||
@click="syncWishlist"
|
||||
>
|
||||
@@ -17,7 +21,7 @@
|
||||
|
||||
<button
|
||||
class="btn btn-compare"
|
||||
:class="{ 'added': inCompareList }"
|
||||
:class="{ added: inCompareList }"
|
||||
:title="$trans('storefront::product_card.compare')"
|
||||
@click="syncCompareList"
|
||||
>
|
||||
@@ -26,42 +30,52 @@
|
||||
</div>
|
||||
|
||||
<ul class="list-inline product-badge">
|
||||
<li class="badge badge-danger" v-if="product.is_out_of_stock">
|
||||
{{ $trans('storefront::product_card.out_of_stock') }}
|
||||
<li class="badge badge-danger" v-if="item.is_out_of_stock">
|
||||
{{ $trans("storefront::product_card.out_of_stock") }}
|
||||
</li>
|
||||
|
||||
<li class="badge badge-primary" v-else-if="product.is_new">
|
||||
{{ $trans('storefront::product_card.new') }}
|
||||
{{ $trans("storefront::product_card.new") }}
|
||||
</li>
|
||||
|
||||
<li class="badge badge-success" v-if="product.has_percentage_special_price">
|
||||
-{{ product.special_price_percent }}%
|
||||
<li
|
||||
class="badge badge-success"
|
||||
v-if="item.has_percentage_special_price"
|
||||
>
|
||||
-{{ item.special_price_percent }}%
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="product-card-middle">
|
||||
<ProductRating :ratingPercent="product.rating_percent" :reviewCount="product.reviews.length"/>
|
||||
<product-rating
|
||||
:ratingPercent="product.rating_percent"
|
||||
:reviewCount="product.reviews.length"
|
||||
>
|
||||
</product-rating>
|
||||
|
||||
<a :href="productUrl" class="product-name">
|
||||
<h6>{{ product.name }}</h6>
|
||||
</a>
|
||||
|
||||
<div class="product-price product-price-clone" v-html="product.formatted_price"></div>
|
||||
<div
|
||||
class="product-price product-price-clone"
|
||||
v-html="item.formatted_price"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<div class="product-card-bottom">
|
||||
<div class="product-price" v-html="product.formatted_price"></div>
|
||||
<div class="product-price" v-html="item.formatted_price"></div>
|
||||
|
||||
<button
|
||||
v-if="hasNoOption || product.is_out_of_stock"
|
||||
v-if="hasNoOption || item.is_out_of_stock"
|
||||
class="btn btn-primary btn-add-to-cart"
|
||||
:class="{ 'btn-loading': addingToCart }"
|
||||
:disabled="product.is_out_of_stock"
|
||||
:disabled="item.is_out_of_stock"
|
||||
@click="addToCart"
|
||||
>
|
||||
<i class="las la-cart-arrow-down"></i>
|
||||
{{ $trans('storefront::product_card.add_to_cart') }}
|
||||
{{ $trans("storefront::product_card.add_to_cart") }}
|
||||
</button>
|
||||
|
||||
<a
|
||||
@@ -70,23 +84,26 @@
|
||||
class="btn btn-primary btn-add-to-cart"
|
||||
>
|
||||
<i class="las la-eye"></i>
|
||||
{{ $trans('storefront::product_card.view_options') }}
|
||||
{{ $trans("storefront::product_card.view_options") }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ProductRating from './ProductRating.vue';
|
||||
import ProductCardMixin from '../mixins/ProductCardMixin';
|
||||
import ProductCardMixin from "../mixins/ProductCardMixin";
|
||||
|
||||
export default {
|
||||
components: { ProductRating },
|
||||
export default {
|
||||
mixins: [ProductCardMixin],
|
||||
|
||||
mixins: [
|
||||
ProductCardMixin,
|
||||
],
|
||||
props: ["product"],
|
||||
|
||||
props: ['product'],
|
||||
};
|
||||
data() {
|
||||
return {
|
||||
item: {
|
||||
...(this.product.variant ? this.product.variant : this.product),
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
<template>
|
||||
<div :href="productUrl" class="vertical-product-card">
|
||||
<a :href="productUrl" class="product-image">
|
||||
<img :src="baseImage" :class="{ 'image-placeholder': ! hasBaseImage }" alt="product-image">
|
||||
<img
|
||||
:src="baseImage"
|
||||
:class="{ 'image-placeholder': !hasBaseImage }"
|
||||
:alt="product.name"
|
||||
/>
|
||||
</a>
|
||||
|
||||
<div class="product-info">
|
||||
@@ -9,24 +13,31 @@
|
||||
<h6>{{ product.name }}</h6>
|
||||
</a>
|
||||
|
||||
<div class="product-price" v-html="product.formatted_price"></div>
|
||||
<div class="product-price" v-html="item.formatted_price"></div>
|
||||
|
||||
<ProductRating :ratingPercent="product.rating_percent" :reviewCount="product.reviews.length"/>
|
||||
<product-rating
|
||||
:ratingPercent="product.rating_percent"
|
||||
:reviewCount="product.reviews.length"
|
||||
>
|
||||
</product-rating>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ProductRating from './ProductRating.vue';
|
||||
import ProductCardMixin from '../mixins/ProductCardMixin';
|
||||
import ProductCardMixin from "../mixins/ProductCardMixin";
|
||||
|
||||
export default {
|
||||
components: { ProductRating },
|
||||
export default {
|
||||
mixins: [ProductCardMixin],
|
||||
|
||||
mixins: [
|
||||
ProductCardMixin,
|
||||
],
|
||||
props: ["product"],
|
||||
|
||||
props: ['product'],
|
||||
};
|
||||
data() {
|
||||
return {
|
||||
item: {
|
||||
...(this.product.variant ? this.product.variant : this.product),
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -7,19 +7,19 @@
|
||||
</li>
|
||||
|
||||
<li v-show="rangeFirstPage !== 1" class="page-item">
|
||||
<button class="page-link" @click="goto(1)">
|
||||
1
|
||||
</button>
|
||||
<button class="page-link" @click="goto(1)">1</button>
|
||||
</li>
|
||||
|
||||
<li v-show="rangeFirstPage === 3" class="page-item">
|
||||
<button class="page-link" @click="goto(2)">
|
||||
2
|
||||
</button>
|
||||
<button class="page-link" @click="goto(2)">2</button>
|
||||
</li>
|
||||
|
||||
<li
|
||||
v-show="rangeFirstPage !== 1 && rangeFirstPage !== 2 && rangeFirstPage !== 3"
|
||||
v-show="
|
||||
rangeFirstPage !== 1 &&
|
||||
rangeFirstPage !== 2 &&
|
||||
rangeFirstPage !== 3
|
||||
"
|
||||
class="page-item disabled"
|
||||
>
|
||||
<span class="page-link">...</span>
|
||||
@@ -37,13 +37,17 @@
|
||||
</li>
|
||||
|
||||
<li
|
||||
v-show="rangeLastPage !== totalPage && rangeLastPage !== (totalPage - 1) && rangeLastPage !== (totalPage - 2)"
|
||||
v-show="
|
||||
rangeLastPage !== totalPage &&
|
||||
rangeLastPage !== totalPage - 1 &&
|
||||
rangeLastPage !== totalPage - 2
|
||||
"
|
||||
class="page-item disabled"
|
||||
>
|
||||
<span class="page-link">...</span>
|
||||
</li>
|
||||
|
||||
<li v-show="rangeLastPage === (totalPage - 2)" class="page-item">
|
||||
<li v-show="rangeLastPage === totalPage - 2" class="page-item">
|
||||
<button class="page-link" @click="goto(totalPage - 1)">
|
||||
{{ totalPage - 1 }}
|
||||
</button>
|
||||
@@ -56,7 +60,11 @@
|
||||
</li>
|
||||
|
||||
<li class="page-item" :class="{ disabled: hasLast }">
|
||||
<button class="page-link" :class="{ disabled: hasLast }" @click="next">
|
||||
<button
|
||||
class="page-link"
|
||||
:class="{ disabled: hasLast }"
|
||||
@click="next"
|
||||
>
|
||||
<i class="las la-angle-right"></i>
|
||||
</button>
|
||||
</li>
|
||||
@@ -64,80 +72,87 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
totalPage: Number,
|
||||
currentPage: Number,
|
||||
rangeMax: {
|
||||
type: Number,
|
||||
default: 3,
|
||||
},
|
||||
export default {
|
||||
props: {
|
||||
totalPage: Number,
|
||||
currentPage: Number,
|
||||
rangeMax: {
|
||||
type: Number,
|
||||
default: 3,
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (this.currentPage > this.totalPage) {
|
||||
this.$emit('page-changed', this.totalPage);
|
||||
mounted() {
|
||||
if (this.currentPage > this.totalPage) {
|
||||
this.$emit("page-changed", this.totalPage);
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
rangeFirstPage() {
|
||||
if (this.currentPage === 1) {
|
||||
return 1;
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
rangeFirstPage() {
|
||||
if (this.currentPage === 1) {
|
||||
if (this.currentPage === this.totalPage) {
|
||||
if (this.totalPage - this.rangeMax < 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (this.currentPage === this.totalPage) {
|
||||
if ((this.totalPage - this.rangeMax) < 0) {
|
||||
return 1;
|
||||
}
|
||||
return this.totalPage - this.rangeMax + 1;
|
||||
}
|
||||
|
||||
return this.totalPage - this.rangeMax + 1;
|
||||
}
|
||||
|
||||
return this.currentPage - 1;
|
||||
},
|
||||
|
||||
rangeLastPage() {
|
||||
return Math.min(this.rangeFirstPage + this.rangeMax - 1, this.totalPage);
|
||||
},
|
||||
|
||||
range() {
|
||||
let rangeList = [];
|
||||
|
||||
for (let page = this.rangeFirstPage; page <= this.rangeLastPage; page += 1) {
|
||||
rangeList.push(page);
|
||||
}
|
||||
|
||||
return rangeList;
|
||||
},
|
||||
|
||||
hasFirst() {
|
||||
return this.currentPage === 1;
|
||||
},
|
||||
|
||||
hasLast() {
|
||||
return this.currentPage === this.totalPage;
|
||||
},
|
||||
return this.currentPage - 1;
|
||||
},
|
||||
|
||||
methods: {
|
||||
prev() {
|
||||
this.$emit('page-changed', this.currentPage - 1);
|
||||
},
|
||||
|
||||
next() {
|
||||
this.$emit('page-changed', this.currentPage + 1);
|
||||
},
|
||||
|
||||
goto(page) {
|
||||
if (this.currentPage !== page) {
|
||||
this.$emit('page-changed', page);
|
||||
}
|
||||
},
|
||||
|
||||
hasActive(page) {
|
||||
return page === this.currentPage;
|
||||
},
|
||||
rangeLastPage() {
|
||||
return Math.min(
|
||||
this.rangeFirstPage + this.rangeMax - 1,
|
||||
this.totalPage
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
range() {
|
||||
let rangeList = [];
|
||||
|
||||
for (
|
||||
let page = this.rangeFirstPage;
|
||||
page <= this.rangeLastPage;
|
||||
page += 1
|
||||
) {
|
||||
rangeList.push(page);
|
||||
}
|
||||
|
||||
return rangeList;
|
||||
},
|
||||
|
||||
hasFirst() {
|
||||
return this.currentPage === 1;
|
||||
},
|
||||
|
||||
hasLast() {
|
||||
return this.currentPage === this.totalPage;
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
prev() {
|
||||
this.$emit("page-changed", this.currentPage - 1);
|
||||
},
|
||||
|
||||
next() {
|
||||
this.$emit("page-changed", this.currentPage + 1);
|
||||
},
|
||||
|
||||
goto(page) {
|
||||
if (this.currentPage !== page) {
|
||||
this.$emit("page-changed", page);
|
||||
}
|
||||
},
|
||||
|
||||
hasActive(page) {
|
||||
return page === this.currentPage;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import Errors from '../../../Errors';
|
||||
import Errors from "../../../Errors";
|
||||
|
||||
export default {
|
||||
props: ['initialAddresses', 'initialDefaultAddress', 'countries'],
|
||||
props: ["initialAddresses", "initialDefaultAddress", "countries"],
|
||||
|
||||
data() {
|
||||
return {
|
||||
addresses: this.initialAddresses,
|
||||
defaultAddress: this.initialDefaultAddress,
|
||||
form: { state: '' },
|
||||
form: { state: "" },
|
||||
states: {},
|
||||
errors: new Errors(),
|
||||
formOpen: false,
|
||||
@@ -36,33 +36,33 @@ export default {
|
||||
|
||||
methods: {
|
||||
changeDefaultAddress(address) {
|
||||
this.$set(this.defaultAddress, 'address_id', address.id);
|
||||
this.$set(this.defaultAddress, "address_id", address.id);
|
||||
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: route('account.change_default_address'),
|
||||
data: { address_id: address.id },
|
||||
}).then((message) => {
|
||||
this.$notify(message);
|
||||
}).catch((xhr) => {
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
});
|
||||
axios
|
||||
.post(route("account.change_default_address"), {
|
||||
address_id: address.id,
|
||||
})
|
||||
.then((response) => {
|
||||
this.$notify(response.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$notify(error.response.data.message);
|
||||
});
|
||||
},
|
||||
|
||||
changeCountry(country) {
|
||||
this.form.country = country;
|
||||
this.form.state = '';
|
||||
this.form.state = "";
|
||||
|
||||
this.fetchStates(country);
|
||||
},
|
||||
|
||||
fetchStates(country) {
|
||||
$.ajax({
|
||||
method: 'GET',
|
||||
url: route('countries.states.index', { code: country }),
|
||||
}).then((states) => {
|
||||
this.$set(this, 'states', states);
|
||||
});
|
||||
async fetchStates(country) {
|
||||
const response = await axios.get(
|
||||
route("countries.states.index", { code: country })
|
||||
);
|
||||
|
||||
this.$set(this, "states", response.data);
|
||||
},
|
||||
|
||||
edit(address) {
|
||||
@@ -74,19 +74,21 @@ export default {
|
||||
},
|
||||
|
||||
remove(address) {
|
||||
if (! confirm(this.$trans('storefront::account.addresses.confirm'))) {
|
||||
if (
|
||||
!confirm(this.$trans("storefront::account.addresses.confirm"))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
method: 'DELETE',
|
||||
url: route('account.addresses.destroy', address.id),
|
||||
}).then((response) => {
|
||||
this.$delete(this.addresses, address.id);
|
||||
this.$notify(response.message);
|
||||
}).catch((xhr) => {
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
});
|
||||
axios
|
||||
.delete(route("account.addresses.destroy", address.id))
|
||||
.then((response) => {
|
||||
this.$delete(this.addresses, address.id);
|
||||
this.$notify(response.data.message);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$notify(error.response.data.message);
|
||||
});
|
||||
},
|
||||
|
||||
cancel() {
|
||||
@@ -108,56 +110,62 @@ export default {
|
||||
},
|
||||
|
||||
update() {
|
||||
$.ajax({
|
||||
method: 'PUT',
|
||||
url: route('account.addresses.update', { id: this.form.id }),
|
||||
data: this.form,
|
||||
}).then((response) => {
|
||||
this.formOpen = false;
|
||||
this.editing = false;
|
||||
axios
|
||||
.put(
|
||||
route("account.addresses.update", { id: this.form.id }),
|
||||
this.form
|
||||
)
|
||||
.then(({ data }) => {
|
||||
this.formOpen = false;
|
||||
this.editing = false;
|
||||
|
||||
this.addresses[this.form.id] = response.address;
|
||||
this.addresses[this.form.id] = data.address;
|
||||
|
||||
this.resetForm();
|
||||
this.$notify(response.message);
|
||||
}).catch((xhr) => {
|
||||
if (xhr.status === 422) {
|
||||
this.errors.record(xhr.responseJSON.errors);
|
||||
}
|
||||
this.resetForm();
|
||||
this.$notify(data.message);
|
||||
})
|
||||
.catch(({ response }) => {
|
||||
if (response.status === 422) {
|
||||
this.errors.record(response.data.errors);
|
||||
}
|
||||
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
}).always(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
this.$notify(response.data.message);
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
|
||||
create() {
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: route('account.addresses.store'),
|
||||
data: this.form,
|
||||
}).then((response) => {
|
||||
this.formOpen = false;
|
||||
axios
|
||||
.post(route("account.addresses.store"), this.form)
|
||||
.then(({ data }) => {
|
||||
this.formOpen = false;
|
||||
|
||||
let address = { [response.address.id]: response.address };
|
||||
let address = { [data.address.id]: data.address };
|
||||
|
||||
this.$set(this, 'addresses', { ...this.addresses, ...address });
|
||||
this.$set(this, "addresses", {
|
||||
...this.addresses,
|
||||
...address,
|
||||
});
|
||||
|
||||
this.resetForm();
|
||||
this.$notify(response.message);
|
||||
}).catch((xhr) => {
|
||||
if (xhr.status === 422) {
|
||||
this.errors.record(xhr.responseJSON.errors);
|
||||
}
|
||||
this.resetForm();
|
||||
this.$notify(data.message);
|
||||
})
|
||||
.catch(({ response }) => {
|
||||
if (response.status === 422) {
|
||||
this.errors.record(response.data.errors);
|
||||
}
|
||||
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
}).always(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
this.$notify(response.data.message);
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
|
||||
resetForm() {
|
||||
this.form = { state: '' };
|
||||
this.form = { state: "" };
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import ProductHelpersMixin from "../../../mixins/ProductHelpersMixin";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
VPagination: () => import("../../VPagination.vue"),
|
||||
},
|
||||
|
||||
mixins: [ProductHelpersMixin],
|
||||
|
||||
data() {
|
||||
return {
|
||||
fetchingReviews: false,
|
||||
reviews: { data: [] },
|
||||
currentPage: 1,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
reviewIsEmpty() {
|
||||
return this.reviews.data.length === 0;
|
||||
},
|
||||
|
||||
totalPage() {
|
||||
return Math.ceil(this.reviews.total / 10);
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
this.fetchReviews();
|
||||
},
|
||||
|
||||
methods: {
|
||||
changePage(page) {
|
||||
this.currentPage = page;
|
||||
|
||||
this.fetchReviews();
|
||||
},
|
||||
|
||||
async fetchReviews() {
|
||||
this.fetchingReviews = true;
|
||||
|
||||
try {
|
||||
const response = await axios.get(
|
||||
route("reviews.products.index", {
|
||||
page: this.currentPage,
|
||||
})
|
||||
);
|
||||
|
||||
this.reviews = response.data;
|
||||
} catch (error) {
|
||||
this.$notify(error.response.data.message);
|
||||
} finally {
|
||||
this.fetchingReviews = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,13 +1,10 @@
|
||||
import store from '../../../store';
|
||||
import VPagination from '../../VPagination.vue';
|
||||
import ProductHelpersMixin from '../../../mixins/ProductHelpersMixin';
|
||||
import store from "../../../store";
|
||||
import ProductHelpersMixin from "../../../mixins/ProductHelpersMixin";
|
||||
|
||||
export default {
|
||||
components: { VPagination },
|
||||
components: { VPagination: () => import("../../VPagination.vue") },
|
||||
|
||||
mixins: [
|
||||
ProductHelpersMixin,
|
||||
],
|
||||
mixins: [ProductHelpersMixin],
|
||||
|
||||
data() {
|
||||
return {
|
||||
@@ -23,7 +20,7 @@ export default {
|
||||
},
|
||||
|
||||
totalPage() {
|
||||
return Math.ceil(this.products.total / 20);
|
||||
return Math.ceil(this.products.total / 10);
|
||||
},
|
||||
},
|
||||
|
||||
@@ -32,21 +29,28 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
fetchWishlist() {
|
||||
changePage(page) {
|
||||
this.currentPage = page;
|
||||
|
||||
this.fetchWishlist();
|
||||
},
|
||||
|
||||
async fetchWishlist() {
|
||||
this.fetchingWishlist = true;
|
||||
|
||||
$.ajax({
|
||||
method: 'GET',
|
||||
url: route('wishlist.products.index', {
|
||||
page: this.currentPage,
|
||||
}),
|
||||
}).then((products) => {
|
||||
this.products = products;
|
||||
}).catch((xhr) => {
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
}).always(() => {
|
||||
try {
|
||||
const response = await axios.get(
|
||||
route("wishlist.products.index", {
|
||||
page: this.currentPage,
|
||||
})
|
||||
);
|
||||
|
||||
this.products = response.data;
|
||||
} catch (error) {
|
||||
this.$notify(error.response.data.message);
|
||||
} finally {
|
||||
this.fetchingWishlist = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
remove(product) {
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import store from '../../store';
|
||||
import CartHelpersMixin from '../../mixins/CartHelpersMixin';
|
||||
import ProductHelpersMixin from '../../mixins/ProductHelpersMixin';
|
||||
import store from "../../store";
|
||||
import CartHelpersMixin from "../../mixins/CartHelpersMixin";
|
||||
import CartItemHelpersMixin from "../../mixins/CartItemHelpersMixin";
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
CartHelpersMixin,
|
||||
ProductHelpersMixin,
|
||||
],
|
||||
mixins: [CartHelpersMixin, CartItemHelpersMixin],
|
||||
|
||||
data() {
|
||||
return {
|
||||
@@ -34,47 +31,25 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
optionValues(option) {
|
||||
let values = [];
|
||||
|
||||
for (let value of option.values) {
|
||||
values.push(value.label);
|
||||
}
|
||||
|
||||
return values.join(', ');
|
||||
},
|
||||
|
||||
updateQuantity(cartItem, qty) {
|
||||
if (qty < 1 || this.exceedsMaxStock(cartItem, qty)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNaN(qty)) {
|
||||
qty = 1;
|
||||
}
|
||||
|
||||
updateCart(cartItem, qty) {
|
||||
this.loadingOrderSummary = true;
|
||||
|
||||
cartItem.qty = qty;
|
||||
|
||||
$.ajax({
|
||||
method: 'PUT',
|
||||
url: route('cart.items.update', { cartItemId: cartItem.id }),
|
||||
data: { qty: qty || 1 },
|
||||
}).then((cart) => {
|
||||
store.updateCart(cart);
|
||||
}).catch((xhr) => {
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
}).always(() => {
|
||||
this.loadingOrderSummary = false;
|
||||
});
|
||||
axios
|
||||
.put(route("cart.items.update", { cartItemId: cartItem.id }), {
|
||||
qty: qty || 1,
|
||||
})
|
||||
.then((response) => {
|
||||
store.updateCart(response.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$notify(error.response.data.message);
|
||||
})
|
||||
.finally(() => {
|
||||
this.loadingOrderSummary = false;
|
||||
});
|
||||
},
|
||||
|
||||
exceedsMaxStock(cartItem, qty) {
|
||||
return cartItem.product.manage_stock && cartItem.product.qty < qty;
|
||||
},
|
||||
|
||||
remove(cartItem) {
|
||||
removeCartItem(cartItem) {
|
||||
this.loadingOrderSummary = true;
|
||||
|
||||
store.removeCartItem(cartItem);
|
||||
@@ -83,16 +58,19 @@ export default {
|
||||
this.crossSellProducts = [];
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
method: 'DELETE',
|
||||
url: route('cart.items.destroy', { cartItemId: cartItem.id }),
|
||||
}).then((cart) => {
|
||||
store.updateCart(cart);
|
||||
}).catch((xhr) => {
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
}).always(() => {
|
||||
this.loadingOrderSummary = false;
|
||||
});
|
||||
axios
|
||||
.delete(
|
||||
route("cart.items.destroy", { cartItemId: cartItem.id })
|
||||
)
|
||||
.then((response) => {
|
||||
store.updateCart(response.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$notify(error.response.data.message);
|
||||
})
|
||||
.finally(() => {
|
||||
this.loadingOrderSummary = false;
|
||||
});
|
||||
},
|
||||
|
||||
clearCart() {
|
||||
@@ -102,29 +80,30 @@ export default {
|
||||
this.crossSellProducts = [];
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: route('cart.clear.store'),
|
||||
}).then((cart) => {
|
||||
store.updateCart(cart);
|
||||
}).catch((xhr) => {
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
});
|
||||
axios
|
||||
.post(route("cart.clear.store"))
|
||||
.then((response) => {
|
||||
store.updateCart(response.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$notify(error.response.data.message);
|
||||
});
|
||||
},
|
||||
|
||||
changeShippingMethod(shippingMethodName) {
|
||||
this.shippingMethodName = shippingMethodName;
|
||||
},
|
||||
|
||||
fetchCrossSellProducts() {
|
||||
$.ajax({
|
||||
method: 'GET',
|
||||
url: route('cart.cross_sell_products.index'),
|
||||
}).then((crossSellProducts) => {
|
||||
this.crossSellProducts = crossSellProducts;
|
||||
}).catch((xhr) => {
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
});
|
||||
async fetchCrossSellProducts() {
|
||||
try {
|
||||
const response = await axios.get(
|
||||
route("cart.cross_sell_products.index")
|
||||
);
|
||||
|
||||
this.crossSellProducts = response.data;
|
||||
} catch (error) {
|
||||
this.$notify(error.response.data.message);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/* eslint-disable */
|
||||
import store from "../../store";
|
||||
import Errors from "../../Errors";
|
||||
import CartHelpersMixin from "../../mixins/CartHelpersMixin";
|
||||
import ProductHelpersMixin from "../../mixins/ProductHelpersMixin";
|
||||
import CartItemHelpersMixin from "../../mixins/CartItemHelpersMixin";
|
||||
|
||||
export default {
|
||||
mixins: [CartHelpersMixin, ProductHelpersMixin],
|
||||
mixins: [CartHelpersMixin, CartItemHelpersMixin],
|
||||
|
||||
props: [
|
||||
"customerEmail",
|
||||
@@ -78,17 +77,13 @@ export default {
|
||||
return this.gateways[this.form.payment_method].instructions;
|
||||
}
|
||||
},
|
||||
|
||||
hasFreeShipping() {
|
||||
return this.cart.coupon?.free_shipping ?? false;
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
"form.billingAddressId": function () {
|
||||
this.mergeSavedBillingAddress();
|
||||
},
|
||||
|
||||
"form.shippingAddressId": function () {
|
||||
this.mergeSavedShippingAddress();
|
||||
},
|
||||
|
||||
"form.billing.city": function (newCity) {
|
||||
if (newCity) {
|
||||
this.addTaxes();
|
||||
@@ -156,6 +151,9 @@ export default {
|
||||
if (this.defaultAddress.address_id) {
|
||||
this.form.billingAddressId = this.defaultAddress.address_id;
|
||||
this.form.shippingAddressId = this.defaultAddress.address_id;
|
||||
|
||||
this.mergeSavedBillingAddress();
|
||||
this.mergeSavedShippingAddress();
|
||||
}
|
||||
|
||||
if (!this.hasAddress) {
|
||||
@@ -181,6 +179,14 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
changeBillingAddress(address) {
|
||||
if (this.form.billingAddressId === address.id) return;
|
||||
|
||||
this.form.billingAddressId = address.id;
|
||||
|
||||
this.mergeSavedBillingAddress();
|
||||
},
|
||||
|
||||
addNewBillingAddress() {
|
||||
this.resetAddressErrors("billing");
|
||||
|
||||
@@ -192,6 +198,14 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
changeShippingAddress(address) {
|
||||
if (this.form.shippingAddressId === address.id) return;
|
||||
|
||||
this.form.shippingAddressId = address.id;
|
||||
|
||||
this.mergeSavedShippingAddress();
|
||||
},
|
||||
|
||||
addNewShippingAddress() {
|
||||
this.resetAddressErrors("shipping");
|
||||
|
||||
@@ -257,8 +271,8 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
this.fetchStates(country, (states) => {
|
||||
this.$set(this.states, "billing", states);
|
||||
this.fetchStates(country, (response) => {
|
||||
this.$set(this.states, "billing", response.data);
|
||||
this.$set(this.form.billing, "state", "");
|
||||
});
|
||||
},
|
||||
@@ -273,17 +287,16 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
this.fetchStates(country, (states) => {
|
||||
this.$set(this.states, "shipping", states);
|
||||
this.fetchStates(country, (response) => {
|
||||
this.$set(this.states, "shipping", response.data);
|
||||
this.$set(this.form.shipping, "state", "");
|
||||
});
|
||||
},
|
||||
|
||||
fetchStates(country, callback) {
|
||||
$.ajax({
|
||||
method: "GET",
|
||||
url: route("countries.states.index", { code: country }),
|
||||
}).then(callback);
|
||||
axios
|
||||
.get(route("countries.states.index", { code: country }))
|
||||
.then(callback);
|
||||
},
|
||||
|
||||
changeBillingState(state) {
|
||||
@@ -302,21 +315,74 @@ export default {
|
||||
this.$set(this.form, "shipping_method", shippingMethodName);
|
||||
},
|
||||
|
||||
addTaxes() {
|
||||
async addTaxes() {
|
||||
this.loadingOrderSummary = true;
|
||||
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: route("cart.taxes.store"),
|
||||
data: this.form,
|
||||
})
|
||||
.then((cart) => {
|
||||
store.updateCart(cart);
|
||||
try {
|
||||
const response = await axios.post(
|
||||
route("cart.taxes.store", {
|
||||
...(store.hasCoupon() && {
|
||||
coupon_code: store.getCoupon(),
|
||||
}),
|
||||
}),
|
||||
this.form
|
||||
);
|
||||
|
||||
store.updateCart(response.data);
|
||||
} catch (error) {
|
||||
this.$notify(error.response.data.message);
|
||||
} finally {
|
||||
this.loadingOrderSummary = false;
|
||||
}
|
||||
},
|
||||
|
||||
updateCart(cartItem, qty) {
|
||||
this.loadingOrderSummary = true;
|
||||
|
||||
axios
|
||||
.put(
|
||||
route("cart.items.update", {
|
||||
cartItemId: cartItem.id,
|
||||
...(store.hasCoupon() && {
|
||||
coupon_code: store.getCoupon(),
|
||||
}),
|
||||
}),
|
||||
{
|
||||
qty: qty || 1,
|
||||
}
|
||||
)
|
||||
.then((response) => {
|
||||
store.updateCart(response.data);
|
||||
})
|
||||
.catch((xhr) => {
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
.catch((error) => {
|
||||
this.$notify(error.response.data.message);
|
||||
})
|
||||
.always(() => {
|
||||
.finally(() => {
|
||||
this.loadingOrderSummary = false;
|
||||
});
|
||||
},
|
||||
|
||||
removeCartItem(cartItem) {
|
||||
this.loadingOrderSummary = true;
|
||||
|
||||
store.removeCartItem(cartItem);
|
||||
|
||||
axios
|
||||
.delete(
|
||||
route("cart.items.destroy", {
|
||||
cartItemId: cartItem.id,
|
||||
...(store.hasCoupon() && {
|
||||
coupon_code: store.getCoupon(),
|
||||
}),
|
||||
})
|
||||
)
|
||||
.then((response) => {
|
||||
store.updateCart(response.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$notify(error.response.data.message);
|
||||
})
|
||||
.finally(() => {
|
||||
this.loadingOrderSummary = false;
|
||||
});
|
||||
},
|
||||
@@ -328,68 +394,72 @@ export default {
|
||||
|
||||
this.placingOrder = true;
|
||||
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: route("checkout.create"),
|
||||
data: {
|
||||
...this.form,
|
||||
ship_to_a_different_address:
|
||||
+this.form.ship_to_a_different_address,
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.redirectUrl) {
|
||||
window.location.href = response.redirectUrl;
|
||||
axios
|
||||
.post(
|
||||
route("checkout.store", {
|
||||
...(store.hasCoupon() && {
|
||||
coupon_code: store.getCoupon(),
|
||||
}),
|
||||
}),
|
||||
{
|
||||
...this.form,
|
||||
ship_to_a_different_address:
|
||||
+this.form.ship_to_a_different_address,
|
||||
}
|
||||
)
|
||||
.then(({ data }) => {
|
||||
if (data.redirectUrl) {
|
||||
window.location.href = data.redirectUrl;
|
||||
} else if (this.form.payment_method === "stripe") {
|
||||
this.confirmStripePayment(response);
|
||||
this.confirmStripePayment(data);
|
||||
} else if (this.form.payment_method === "paytm") {
|
||||
this.confirmPaytmPayment(response);
|
||||
this.confirmPaytmPayment(data);
|
||||
} else if (this.form.payment_method === "razorpay") {
|
||||
this.confirmRazorpayPayment(response);
|
||||
this.confirmRazorpayPayment(data);
|
||||
} else if (this.form.payment_method === "paystack") {
|
||||
this.confirmPaystackPayment(response);
|
||||
this.confirmPaystackPayment(data);
|
||||
} else if (this.form.payment_method === "authorizenet") {
|
||||
this.confirmAuthorizeNetPayment(response);
|
||||
this.confirmAuthorizeNetPayment(data);
|
||||
} else if (this.form.payment_method === "flutterwave") {
|
||||
this.confirmFlutterWavePayment(response);
|
||||
this.confirmFlutterWavePayment(data);
|
||||
} else if (this.form.payment_method === "mercadopago") {
|
||||
this.confirmMercadoPagoPayment(response);
|
||||
this.confirmMercadoPagoPayment(data);
|
||||
} else {
|
||||
this.confirmOrder(
|
||||
response.orderId,
|
||||
data.orderId,
|
||||
this.form.payment_method
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch((xhr) => {
|
||||
if (xhr.status === 422) {
|
||||
this.errors.record(xhr.responseJSON.errors);
|
||||
.catch(({ response }) => {
|
||||
if (response.status === 422) {
|
||||
this.errors.record(response.data.errors);
|
||||
}
|
||||
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
this.$notify(response.data.message);
|
||||
|
||||
this.placingOrder = false;
|
||||
});
|
||||
},
|
||||
|
||||
confirmOrder(orderId, paymentMethod, params = {}) {
|
||||
$.ajax({
|
||||
method: "GET",
|
||||
url: route("checkout.complete.store", {
|
||||
orderId,
|
||||
paymentMethod,
|
||||
...params,
|
||||
}),
|
||||
})
|
||||
axios
|
||||
.get(
|
||||
route("checkout.complete.store", {
|
||||
orderId,
|
||||
paymentMethod,
|
||||
...params,
|
||||
})
|
||||
)
|
||||
.then(() => {
|
||||
window.location.href = route("checkout.complete.show");
|
||||
})
|
||||
.catch((xhr) => {
|
||||
.catch((error) => {
|
||||
this.placingOrder = false;
|
||||
this.loadingOrderSummary = false;
|
||||
|
||||
this.deleteOrder(orderId);
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
this.$notify(error.response.data.message);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -398,12 +468,11 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
method: "GET",
|
||||
url: route("checkout.payment_canceled.store", { orderId }),
|
||||
}).then((xhr) => {
|
||||
this.$notify(xhr.message);
|
||||
});
|
||||
axios
|
||||
.get(route("checkout.payment_canceled.store", { orderId }))
|
||||
.then((response) => {
|
||||
this.$notify(response.data.message);
|
||||
});
|
||||
},
|
||||
|
||||
renderPayPalButton() {
|
||||
@@ -414,31 +483,36 @@ export default {
|
||||
.Buttons({
|
||||
async createOrder() {
|
||||
try {
|
||||
response = await $.ajax({
|
||||
method: "POST",
|
||||
url: route("checkout.create"),
|
||||
data: vm.form,
|
||||
});
|
||||
response = await axios.post(
|
||||
route("checkout.create"),
|
||||
vm.form
|
||||
);
|
||||
|
||||
return response.resourceId;
|
||||
} catch (xhr) {
|
||||
if (xhr.status === 422) {
|
||||
vm.errors.record(xhr.responseJSON.errors);
|
||||
} else {
|
||||
vm.$notify(xhr.responseJSON.message);
|
||||
return response.data.resourceId;
|
||||
} catch ({ response }) {
|
||||
if (response.status === 422) {
|
||||
vm.errors.record(response.data.errors);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
vm.$notify(response.data.message);
|
||||
}
|
||||
},
|
||||
onApprove() {
|
||||
vm.loadingOrderSummary = true;
|
||||
|
||||
vm.confirmOrder(response.orderId, "paypal", response);
|
||||
vm.confirmOrder(
|
||||
response.data.orderId,
|
||||
"paypal",
|
||||
response.data
|
||||
);
|
||||
},
|
||||
onError() {
|
||||
vm.deleteOrder(response.orderId);
|
||||
vm.deleteOrder(response.data.orderId);
|
||||
},
|
||||
onCancel() {
|
||||
vm.deleteOrder(response.orderId);
|
||||
vm.deleteOrder(response.data.orderId);
|
||||
},
|
||||
})
|
||||
.render("#paypal-button-container");
|
||||
@@ -593,8 +667,8 @@ export default {
|
||||
}).openIframe();
|
||||
},
|
||||
|
||||
confirmAuthorizeNetPayment(authorizeNetOrder) {
|
||||
this.authorizeNetToken = authorizeNetOrder.token;
|
||||
confirmAuthorizeNetPayment({ token }) {
|
||||
this.authorizeNetToken = token;
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.$refs.authorizeNetForm.submit();
|
||||
@@ -643,7 +717,7 @@ export default {
|
||||
confirmMercadoPagoPayment(mercadoPagoOrder) {
|
||||
this.placingOrder = false;
|
||||
|
||||
const supportedLocales = {
|
||||
const SUPPORTED_LOCALES = {
|
||||
en_US: "en-US",
|
||||
es_AR: "es-AR",
|
||||
es_CL: "es-CL",
|
||||
@@ -657,7 +731,8 @@ export default {
|
||||
|
||||
const mercadoPago = new MercadoPago(mercadoPagoOrder.publicKey, {
|
||||
locale:
|
||||
supportedLocales[mercadoPagoOrder.currentLocale] || "en-US",
|
||||
SUPPORTED_LOCALES[mercadoPagoOrder.currentLocale] ||
|
||||
"en-US",
|
||||
});
|
||||
|
||||
mercadoPago.checkout({
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
import store from '../../store';
|
||||
import ProductRating from '../ProductRating.vue';
|
||||
import ProductHelpersMixin from '../../mixins/ProductHelpersMixin';
|
||||
import store from "../../store";
|
||||
import ProductHelpersMixin from "../../mixins/ProductHelpersMixin";
|
||||
|
||||
export default {
|
||||
components: { ProductRating },
|
||||
mixins: [ProductHelpersMixin],
|
||||
|
||||
mixins: [
|
||||
ProductHelpersMixin,
|
||||
],
|
||||
|
||||
props: ['compare'],
|
||||
props: ["compare"],
|
||||
|
||||
data() {
|
||||
return {
|
||||
@@ -39,10 +34,10 @@ export default {
|
||||
methods: {
|
||||
badgeClass(product) {
|
||||
if (product.is_in_stock) {
|
||||
return 'badge-success';
|
||||
return "badge-success";
|
||||
}
|
||||
|
||||
return 'badge-danger';
|
||||
return "badge-danger";
|
||||
},
|
||||
|
||||
hasAttribute(product, attribute) {
|
||||
@@ -56,9 +51,11 @@ export default {
|
||||
attributeValues(product, attribute) {
|
||||
for (let productAttribute of product.attributes) {
|
||||
if (productAttribute.name === attribute.name) {
|
||||
return productAttribute.values.map((productAttributeValue) => {
|
||||
return productAttributeValue.value;
|
||||
}).join(', ');
|
||||
return productAttribute.values
|
||||
.map((productAttributeValue) => {
|
||||
return productAttributeValue.value;
|
||||
})
|
||||
.join(", ");
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -66,14 +63,11 @@ export default {
|
||||
remove(product) {
|
||||
this.$delete(this.products, product.id);
|
||||
|
||||
if (! this.hasAnyProduct) {
|
||||
if (!this.hasAnyProduct) {
|
||||
this.relatedProducts = [];
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
method: 'DELETE',
|
||||
url: route('compare.destroy', { id: product.id }),
|
||||
});
|
||||
store.removeFromCompareList(product.id);
|
||||
},
|
||||
|
||||
inWishlist(product) {
|
||||
@@ -86,34 +80,40 @@ export default {
|
||||
|
||||
addToCart(product) {
|
||||
if (product.options_count !== 0) {
|
||||
return window.location.href = this.productUrl(product);
|
||||
return (window.location.href = this.productUrl(product));
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: route('cart.items.store', { product_id: product.id, qty: 1 }),
|
||||
}).then((cart) => {
|
||||
store.updateCart(cart);
|
||||
axios
|
||||
.post(
|
||||
route("cart.items.store", {
|
||||
product_id: product.id,
|
||||
qty: 1,
|
||||
})
|
||||
)
|
||||
.then((response) => {
|
||||
store.updateCart(response.data);
|
||||
|
||||
$('.header-cart').trigger('click');
|
||||
}).catch((xhr) => {
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
});
|
||||
$(".header-cart").trigger("click");
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$notify(error.response.data.message);
|
||||
});
|
||||
},
|
||||
|
||||
fetchRelatedProducts() {
|
||||
async fetchRelatedProducts() {
|
||||
this.fetchingRelatedProducts = true;
|
||||
|
||||
$.ajax({
|
||||
method: 'GET',
|
||||
url: route('compare.related_products.index'),
|
||||
}).then((relatedProducts) => {
|
||||
this.relatedProducts = relatedProducts;
|
||||
}).catch((xhr) => {
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
}).always(() => {
|
||||
try {
|
||||
const response = await axios.get(
|
||||
route("compare.related_products.index")
|
||||
);
|
||||
|
||||
this.relatedProducts = response.data;
|
||||
} catch (error) {
|
||||
this.$notify(error.response.data.message);
|
||||
} finally {
|
||||
this.fetchingRelatedProducts = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
class="banner"
|
||||
:target="banner.open_in_new_window ? '_blank' : '_self'"
|
||||
>
|
||||
<img :src="banner.image.path" alt="banner">
|
||||
<img :src="banner.image.path" alt="Banner" />
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['banner'],
|
||||
};
|
||||
export default {
|
||||
props: ["banner"],
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -6,9 +6,13 @@
|
||||
<a
|
||||
:href="data.banner_1.call_to_action_url"
|
||||
class="banner"
|
||||
:target="data.banner_1.open_in_new_window ? '_blank' : '_self'"
|
||||
:target="
|
||||
data.banner_1.open_in_new_window
|
||||
? '_blank'
|
||||
: '_self'
|
||||
"
|
||||
>
|
||||
<img :src="data.banner_1.image.path" alt="banner">
|
||||
<img :src="data.banner_1.image.path" alt="Banner" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -16,9 +20,13 @@
|
||||
<a
|
||||
:href="data.banner_2.call_to_action_url"
|
||||
class="banner"
|
||||
:target="data.banner_2.open_in_new_window ? '_blank' : '_self'"
|
||||
:target="
|
||||
data.banner_2.open_in_new_window
|
||||
? '_blank'
|
||||
: '_self'
|
||||
"
|
||||
>
|
||||
<img :src="data.banner_2.image.path" alt="banner">
|
||||
<img :src="data.banner_2.image.path" alt="Banner" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -26,9 +34,13 @@
|
||||
<a
|
||||
:href="data.banner_3.call_to_action_url"
|
||||
class="banner"
|
||||
:target="data.banner_3.open_in_new_window ? '_blank' : '_self'"
|
||||
:target="
|
||||
data.banner_3.open_in_new_window
|
||||
? '_blank'
|
||||
: '_self'
|
||||
"
|
||||
>
|
||||
<img :src="data.banner_3.image.path" alt="banner">
|
||||
<img :src="data.banner_3.image.path" alt="Banner" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -37,7 +49,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['data'],
|
||||
};
|
||||
export default {
|
||||
props: ["data"],
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -9,9 +9,13 @@
|
||||
<a
|
||||
:href="data.banner_1.call_to_action_url"
|
||||
class="banner"
|
||||
:target="data.banner_1.open_in_new_window ? '_blank' : '_self'"
|
||||
:target="
|
||||
data.banner_1.open_in_new_window
|
||||
? '_blank'
|
||||
: '_self'
|
||||
"
|
||||
>
|
||||
<img :src="data.banner_1.image.path" alt="banner">
|
||||
<img :src="data.banner_1.image.path" alt="Banner" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -19,9 +23,13 @@
|
||||
<a
|
||||
:href="data.banner_2.call_to_action_url"
|
||||
class="banner"
|
||||
:target="data.banner_2.open_in_new_window ? '_blank' : '_self'"
|
||||
:target="
|
||||
data.banner_2.open_in_new_window
|
||||
? '_blank'
|
||||
: '_self'
|
||||
"
|
||||
>
|
||||
<img :src="data.banner_2.image.path" alt="banner">
|
||||
<img :src="data.banner_2.image.path" alt="Banner" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -29,9 +37,13 @@
|
||||
<a
|
||||
:href="data.banner_3.call_to_action_url"
|
||||
class="banner"
|
||||
:target="data.banner_3.open_in_new_window ? '_blank' : '_self'"
|
||||
:target="
|
||||
data.banner_3.open_in_new_window
|
||||
? '_blank'
|
||||
: '_self'
|
||||
"
|
||||
>
|
||||
<img :src="data.banner_3.image.path" alt="banner">
|
||||
<img :src="data.banner_3.image.path" alt="Banner" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -40,7 +52,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['data'],
|
||||
};
|
||||
export default {
|
||||
props: ["data"],
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -6,9 +6,13 @@
|
||||
<a
|
||||
:href="data.banner_1.call_to_action_url"
|
||||
class="banner"
|
||||
:target="data.banner_1.open_in_new_window ? '_blank' : '_self'"
|
||||
:target="
|
||||
data.banner_1.open_in_new_window
|
||||
? '_blank'
|
||||
: '_self'
|
||||
"
|
||||
>
|
||||
<img :src="data.banner_1.image.path" alt="banner">
|
||||
<img :src="data.banner_1.image.path" alt="Banner" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -16,9 +20,13 @@
|
||||
<a
|
||||
:href="data.banner_2.call_to_action_url"
|
||||
class="banner"
|
||||
:target="data.banner_2.open_in_new_window ? '_blank' : '_self'"
|
||||
:target="
|
||||
data.banner_2.open_in_new_window
|
||||
? '_blank'
|
||||
: '_self'
|
||||
"
|
||||
>
|
||||
<img :src="data.banner_2.image.path" alt="banner">
|
||||
<img :src="data.banner_2.image.path" alt="Banner" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -27,7 +35,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['data'],
|
||||
};
|
||||
export default {
|
||||
props: ["data"],
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -19,7 +19,7 @@ export default {
|
||||
return this.initialLogo.path;
|
||||
}
|
||||
|
||||
return `${window.FleetCart.baseUrl}/themes/storefront/public/images/image-placeholder.png`;
|
||||
return `${window.FleetCart.baseUrl}/build/assets/image-placeholder.png`;
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -15,16 +15,28 @@
|
||||
@click="change(tab)"
|
||||
>
|
||||
<div class="featured-category-image">
|
||||
<img :src="tab.logo" :class="{ 'image-placeholder': ! tab.hasLogo }" alt="category logo">
|
||||
<img
|
||||
:src="tab.logo"
|
||||
:class="{ 'image-placeholder': !tab.hasLogo }"
|
||||
alt="Category logo"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<span class="featured-category-name">{{ tab.label }}</span>
|
||||
<span class="featured-category-name">{{
|
||||
tab.label
|
||||
}}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="tab-content featured-category-products">
|
||||
<ProductCard v-for="product in products" :key="product.id" :product="product"/>
|
||||
<div class="tab-content">
|
||||
<div class="featured-category-products">
|
||||
<ProductCard
|
||||
v-for="product in products"
|
||||
:key="product.id"
|
||||
:product="product"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -33,88 +45,76 @@
|
||||
:key="index"
|
||||
:label="category.name"
|
||||
:initial-logo="category.logo"
|
||||
:url="route('storefront.featured_category_products.index', { categoryNumber: index + 1 })"
|
||||
:url="
|
||||
route('storefront.featured_category_products.index', {
|
||||
categoryNumber: index + 1,
|
||||
})
|
||||
"
|
||||
>
|
||||
</dynamic-tab>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ProductCard from '../ProductCard.vue';
|
||||
import DynamicTabsMixin from '../../mixins/DynamicTabsMixin';
|
||||
import { slickPrevArrow, slickNextArrow } from '../../functions';
|
||||
import { slickPrevArrow, slickNextArrow } from "../../functions";
|
||||
import ProductCard from "../ProductCard.vue";
|
||||
import DynamicTabsMixin from "../../mixins/DynamicTabsMixin";
|
||||
|
||||
export default {
|
||||
components: { ProductCard },
|
||||
export default {
|
||||
components: { ProductCard },
|
||||
|
||||
mixins: [
|
||||
DynamicTabsMixin,
|
||||
],
|
||||
mixins: [DynamicTabsMixin],
|
||||
|
||||
props: ['data'],
|
||||
props: ["data"],
|
||||
|
||||
methods: {
|
||||
selector() {
|
||||
return $('.featured-category-products');
|
||||
},
|
||||
|
||||
slickOptions() {
|
||||
return {
|
||||
rows: 0,
|
||||
dots: true,
|
||||
arrows: false,
|
||||
infinite: true,
|
||||
slidesToShow: 6,
|
||||
slidesToScroll: 6,
|
||||
rtl: window.FleetCart.rtl,
|
||||
prevArrow: slickPrevArrow(),
|
||||
nextArrow: slickNextArrow(),
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1761,
|
||||
settings: {
|
||||
slidesToShow: 5,
|
||||
slidesToScroll: 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 1301,
|
||||
settings: {
|
||||
slidesToShow: 4,
|
||||
slidesToScroll: 4,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 1051,
|
||||
settings: {
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 992,
|
||||
settings: {
|
||||
slidesToShow: 4,
|
||||
slidesToScroll: 4,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 881,
|
||||
settings: {
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 641,
|
||||
settings: {
|
||||
slidesToShow: 2,
|
||||
slidesToScroll: 2,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
selector() {
|
||||
return $(".featured-category-products");
|
||||
},
|
||||
};
|
||||
|
||||
slickOptions() {
|
||||
return {
|
||||
rows: 0,
|
||||
dots: true,
|
||||
arrows: false,
|
||||
infinite: true,
|
||||
slidesToShow: 6,
|
||||
slidesToScroll: 6,
|
||||
rtl: window.FleetCart.rtl,
|
||||
prevArrow: slickPrevArrow(),
|
||||
nextArrow: slickNextArrow(),
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1761,
|
||||
settings: {
|
||||
slidesToShow: 5,
|
||||
slidesToScroll: 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 1301,
|
||||
settings: {
|
||||
slidesToShow: 4,
|
||||
slidesToScroll: 4,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 768,
|
||||
settings: {
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 577,
|
||||
settings: {
|
||||
slidesToShow: 2,
|
||||
slidesToScroll: 2,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,75 +1,89 @@
|
||||
<template>
|
||||
<div class="col-xl-6 col-lg-18">
|
||||
<div class="col-xl-6 col-lg-18" v-if="hasAnyProduct">
|
||||
<div class="daily-deals-wrap">
|
||||
<div class="daily-deals-header clearfix">
|
||||
<h4 class="section-title" v-html="title"></h4>
|
||||
</div>
|
||||
|
||||
<div class="daily-deals" ref="productsPlaceholder">
|
||||
<FlashSaleProductCard v-for="product in products" :key="product.id" :product="product"/>
|
||||
<FlashSaleProductCard
|
||||
v-for="product in products"
|
||||
:key="product.id"
|
||||
:product="product"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FlashSaleProductCard from './FlashSaleProductCard.vue';
|
||||
import { slickPrevArrow, slickNextArrow } from '../../functions';
|
||||
import { slickPrevArrow, slickNextArrow } from "../../functions";
|
||||
import FlashSaleProductCard from "./FlashSaleProductCard.vue";
|
||||
import("countdown").then((module) => (window.countdown = module.default));
|
||||
|
||||
export default {
|
||||
components: { FlashSaleProductCard },
|
||||
export default {
|
||||
components: { FlashSaleProductCard },
|
||||
|
||||
props: ['title', 'url'],
|
||||
props: ["title", "url"],
|
||||
|
||||
data() {
|
||||
return {
|
||||
products: [],
|
||||
};
|
||||
data() {
|
||||
return {
|
||||
products: [],
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
hasAnyProduct() {
|
||||
return this.products.length !== 0;
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
$.ajax({
|
||||
method: 'GET',
|
||||
url: this.url,
|
||||
}).then((products) => {
|
||||
this.products = products;
|
||||
created() {
|
||||
this.fetchProducts();
|
||||
},
|
||||
|
||||
methods: {
|
||||
async fetchProducts() {
|
||||
await axios.get(this.url).then((response) => {
|
||||
this.products = response.data;
|
||||
|
||||
this.$nextTick(() => {
|
||||
$(this.$refs.productsPlaceholder).slick(this.slickOptions());
|
||||
$(this.$refs.productsPlaceholder).slick(
|
||||
this.slickOptions()
|
||||
);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
methods: {
|
||||
slickOptions() {
|
||||
return {
|
||||
rows: 0,
|
||||
dots: false,
|
||||
arrows: true,
|
||||
infinite: true,
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
rtl: window.FleetCart.rtl,
|
||||
prevArrow: slickPrevArrow(),
|
||||
nextArrow: slickNextArrow(),
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1200,
|
||||
settings: {
|
||||
slidesToShow: 2,
|
||||
slidesToScroll: 2,
|
||||
},
|
||||
slickOptions() {
|
||||
return {
|
||||
rows: 0,
|
||||
dots: false,
|
||||
arrows: true,
|
||||
infinite: true,
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
rtl: window.FleetCart.rtl,
|
||||
prevArrow: slickPrevArrow(),
|
||||
nextArrow: slickNextArrow(),
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1200,
|
||||
settings: {
|
||||
slidesToShow: 2,
|
||||
slidesToScroll: 2,
|
||||
},
|
||||
{
|
||||
breakpoint: 768,
|
||||
settings: {
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 768,
|
||||
settings: {
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,28 +1,49 @@
|
||||
<template>
|
||||
<section class="vertical-products-wrap">
|
||||
<section
|
||||
class="vertical-products-wrap"
|
||||
:class="{
|
||||
'flash-sale-enabled': flashSaleEnabled,
|
||||
}"
|
||||
>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<flash-sale
|
||||
v-if="flashSaleEnabled"
|
||||
:title="data.flash_sale_title"
|
||||
:url="route('storefront.flash_sale_products.index')"
|
||||
>
|
||||
</flash-sale>
|
||||
|
||||
<vertical-products
|
||||
:flash-sale-enabled="flashSaleEnabled"
|
||||
:title="data.vertical_products_1_title"
|
||||
:url="route('storefront.vertical_products.index', { columnNumber: 1 })"
|
||||
:url="
|
||||
route('storefront.vertical_products.index', {
|
||||
columnNumber: 1,
|
||||
})
|
||||
"
|
||||
>
|
||||
</vertical-products>
|
||||
|
||||
<vertical-products
|
||||
:flash-sale-enabled="flashSaleEnabled"
|
||||
:title="data.vertical_products_2_title"
|
||||
:url="route('storefront.vertical_products.index', { columnNumber: 2 })"
|
||||
:url="
|
||||
route('storefront.vertical_products.index', {
|
||||
columnNumber: 2,
|
||||
})
|
||||
"
|
||||
>
|
||||
</vertical-products>
|
||||
|
||||
<vertical-products
|
||||
:flash-sale-enabled="flashSaleEnabled"
|
||||
:title="data.vertical_products_3_title"
|
||||
:url="route('storefront.vertical_products.index', { columnNumber: 3 })"
|
||||
:url="
|
||||
route('storefront.vertical_products.index', {
|
||||
columnNumber: 3,
|
||||
})
|
||||
"
|
||||
>
|
||||
</vertical-products>
|
||||
</div>
|
||||
@@ -31,7 +52,12 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['data'],
|
||||
};
|
||||
export default {
|
||||
components: {
|
||||
FlashSale: () => import("./FlashSale.vue"),
|
||||
VerticalProducts: () => import("./VerticalProducts.vue"),
|
||||
},
|
||||
|
||||
props: ["data", "flashSaleEnabled"],
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
<div class="daily-deals-inner">
|
||||
<div class="daily-deals-top">
|
||||
<a :href="productUrl" class="product-image">
|
||||
<img :src="baseImage" :class="{ 'image-placeholder': ! hasBaseImage }" alt="product-image">
|
||||
<img
|
||||
:src="baseImage"
|
||||
:class="{ 'image-placeholder': !hasBaseImage }"
|
||||
:alt="product.name"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -11,22 +15,26 @@
|
||||
</a>
|
||||
|
||||
<div class="product-info">
|
||||
<div class="product-price" v-html="product.formatted_price"></div>
|
||||
<div class="product-price" v-html="item.formatted_price"></div>
|
||||
|
||||
<ProductRating :ratingPercent="product.rating_percent" :reviewCount="product.reviews.length"/>
|
||||
<product-rating
|
||||
:ratingPercent="product.rating_percent"
|
||||
:reviewCount="product.reviews.length"
|
||||
>
|
||||
</product-rating>
|
||||
</div>
|
||||
|
||||
<div class="daily-deals-countdown clearfix"></div>
|
||||
<countdown :end-date="product.pivot.end_date"></countdown>
|
||||
|
||||
<div class="deal-progress">
|
||||
<div class="deal-stock">
|
||||
<div class="stock-available">
|
||||
{{ $trans('storefront::product_card.available') }}
|
||||
{{ $trans("storefront::product_card.available") }}
|
||||
<span>{{ product.pivot.qty }}</span>
|
||||
</div>
|
||||
|
||||
<div class="stock-sold">
|
||||
{{ $trans('storefront::product_card.sold') }}
|
||||
{{ $trans("storefront::product_card.sold") }}
|
||||
<span>{{ product.pivot.sold }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -39,38 +47,30 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ProductRating from '../ProductRating.vue';
|
||||
import ProductCardMixin from '../../mixins/ProductCardMixin';
|
||||
import Countdown from "../Countdown.vue";
|
||||
import ProductCardMixin from "../../mixins/ProductCardMixin";
|
||||
|
||||
export default {
|
||||
components: { ProductRating },
|
||||
export default {
|
||||
components: { Countdown },
|
||||
|
||||
mixins: [
|
||||
ProductCardMixin,
|
||||
],
|
||||
mixins: [ProductCardMixin],
|
||||
|
||||
props: ['product'],
|
||||
props: ["product"],
|
||||
|
||||
computed: {
|
||||
progress() {
|
||||
return (this.product.pivot.sold / this.product.pivot.qty * 100) + '%';
|
||||
data() {
|
||||
return {
|
||||
item: {
|
||||
...(this.product.variant ? this.product.variant : this.product),
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
mounted() {
|
||||
$(this.$el).find('.daily-deals-countdown').countdown({
|
||||
until: new Date(this.product.pivot.end_date),
|
||||
format: 'DHMS',
|
||||
labels: [
|
||||
this.$trans('storefront::product_card.years'),
|
||||
this.$trans('storefront::product_card.months'),
|
||||
this.$trans('storefront::product_card.weeks'),
|
||||
this.$trans('storefront::product_card.days'),
|
||||
this.$trans('storefront::product_card.hours'),
|
||||
this.$trans('storefront::product_card.minutes'),
|
||||
this.$trans('storefront::product_card.seconds'),
|
||||
],
|
||||
});
|
||||
computed: {
|
||||
progress() {
|
||||
return (
|
||||
(this.product.pivot.sold / this.product.pivot.qty) * 100 + "%"
|
||||
);
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<section class="grid-products-wrap clearfix">
|
||||
<div class="container">
|
||||
<div class="tab-products-header clearfix">
|
||||
<ul class="tabs float-left">
|
||||
<ul class="tabs float-left overflow-hidden">
|
||||
<li
|
||||
v-for="(tab, index) in tabs"
|
||||
:key="index"
|
||||
@@ -14,9 +14,21 @@
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="tab-content grid-products">
|
||||
<div v-for="(productChunks, index) in $chunk(products, 12)" :key="index" class="grid-products-inner">
|
||||
<ProductCard v-for="product in productChunks" :key="product.id" :product="product"/>
|
||||
<div class="tab-content">
|
||||
<div class="grid-products">
|
||||
<div
|
||||
v-for="(productChunks, index) in $chunk(products, 12)"
|
||||
:key="index"
|
||||
class="grid-products-slide d-flex flex-wrap flex-grow-1"
|
||||
>
|
||||
<div
|
||||
class="grid-products-item"
|
||||
v-for="product in productChunks"
|
||||
:key="product.id"
|
||||
>
|
||||
<ProductCard :product="product" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -24,7 +36,11 @@
|
||||
v-for="(tabLabel, index) in data"
|
||||
:key="index"
|
||||
:label="tabLabel"
|
||||
:url="route('storefront.product_grid.index', { tabNumber: index + 1 })"
|
||||
:url="
|
||||
route('storefront.product_grid.index', {
|
||||
tabNumber: index + 1,
|
||||
})
|
||||
"
|
||||
>
|
||||
</dynamic-tab>
|
||||
</div>
|
||||
@@ -32,46 +48,44 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ProductCard from '../ProductCard.vue';
|
||||
import DynamicTabsMixin from '../../mixins/DynamicTabsMixin';
|
||||
import { slickPrevArrow, slickNextArrow } from '../../functions';
|
||||
import { slickPrevArrow, slickNextArrow } from "../../functions";
|
||||
import ProductCard from "../ProductCard.vue";
|
||||
import DynamicTabsMixin from "../../mixins/DynamicTabsMixin";
|
||||
|
||||
export default {
|
||||
components: { ProductCard },
|
||||
export default {
|
||||
components: { ProductCard },
|
||||
|
||||
mixins: [
|
||||
DynamicTabsMixin,
|
||||
],
|
||||
mixins: [DynamicTabsMixin],
|
||||
|
||||
props: ['data'],
|
||||
props: ["data"],
|
||||
|
||||
methods: {
|
||||
selector() {
|
||||
return $('.grid-products');
|
||||
},
|
||||
|
||||
slickOptions() {
|
||||
return {
|
||||
rows: 0,
|
||||
dots: false,
|
||||
arrows: true,
|
||||
infinite: true,
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
rtl: window.FleetCart.rtl,
|
||||
prevArrow: slickPrevArrow(),
|
||||
nextArrow: slickNextArrow(),
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 768,
|
||||
settings: {
|
||||
dots: true,
|
||||
arrows: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
selector() {
|
||||
return $(".grid-products");
|
||||
},
|
||||
};
|
||||
|
||||
slickOptions() {
|
||||
return {
|
||||
rows: 0,
|
||||
dots: false,
|
||||
arrows: true,
|
||||
infinite: false,
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
rtl: window.FleetCart.rtl,
|
||||
prevArrow: slickPrevArrow(),
|
||||
nextArrow: slickNextArrow(),
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 768,
|
||||
settings: {
|
||||
dots: true,
|
||||
arrows: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -14,12 +14,14 @@
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="tab-content landscape-left-tab-products">
|
||||
<ProductCard
|
||||
v-for="product in products"
|
||||
:key="product.id"
|
||||
:product="product"
|
||||
/>
|
||||
<div class="tab-content">
|
||||
<div class="landscape-left-tab-products">
|
||||
<ProductCard
|
||||
v-for="product in products"
|
||||
:key="product.id"
|
||||
:product="product"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<dynamic-tab
|
||||
@@ -39,9 +41,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { slickPrevArrow, slickNextArrow } from "../../functions";
|
||||
import ProductCard from "../ProductCard.vue";
|
||||
import DynamicTabsMixin from "../../mixins/DynamicTabsMixin";
|
||||
import { slickPrevArrow, slickNextArrow } from "../../functions";
|
||||
|
||||
export default {
|
||||
components: { ProductCard },
|
||||
@@ -103,7 +105,7 @@ export default {
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 661,
|
||||
breakpoint: 768,
|
||||
settings: {
|
||||
dots: true,
|
||||
arrows: false,
|
||||
|
||||
@@ -16,8 +16,14 @@
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="tab-content landscape-right-tab-products">
|
||||
<ProductCard v-for="product in products" :key="product.id" :product="product"/>
|
||||
<div class="tab-content">
|
||||
<div class="landscape-right-tab-products">
|
||||
<ProductCard
|
||||
v-for="product in products"
|
||||
:key="product.id"
|
||||
:product="product"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -25,83 +31,95 @@
|
||||
v-for="(tabLabel, index) in data.tabs"
|
||||
:key="index"
|
||||
:label="tabLabel"
|
||||
:url="route('storefront.tab_products.index', {sectionNumber: 2, tabNumber: index + 1 })"
|
||||
:url="
|
||||
route('storefront.tab_products.index', {
|
||||
sectionNumber: 2,
|
||||
tabNumber: index + 1,
|
||||
})
|
||||
"
|
||||
>
|
||||
</dynamic-tab>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ProductCard from '../ProductCard.vue';
|
||||
import DynamicTabsMixin from '../../mixins/DynamicTabsMixin';
|
||||
import ProductCard from "../ProductCard.vue";
|
||||
import DynamicTabsMixin from "../../mixins/DynamicTabsMixin";
|
||||
|
||||
export default {
|
||||
components: { ProductCard },
|
||||
export default {
|
||||
components: { ProductCard },
|
||||
|
||||
mixins: [DynamicTabsMixin],
|
||||
mixins: [DynamicTabsMixin],
|
||||
|
||||
props: ['data'],
|
||||
props: ["data"],
|
||||
|
||||
methods: {
|
||||
selector() {
|
||||
return $('.landscape-right-tab-products');
|
||||
},
|
||||
|
||||
slickOptions() {
|
||||
return {
|
||||
rows: 0,
|
||||
dots: true,
|
||||
arrows: false,
|
||||
infinite: true,
|
||||
slidesToShow: 6,
|
||||
slidesToScroll: 6,
|
||||
rtl: window.FleetCart.rtl,
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1761,
|
||||
settings: {
|
||||
slidesToShow: 5,
|
||||
slidesToScroll: 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 1301,
|
||||
settings: {
|
||||
slidesToShow: 4,
|
||||
slidesToScroll: 4,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 1051,
|
||||
settings: {
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 992,
|
||||
settings: {
|
||||
slidesToShow: 4,
|
||||
slidesToScroll: 4,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 881,
|
||||
settings: {
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 641,
|
||||
settings: {
|
||||
slidesToShow: 2,
|
||||
slidesToScroll: 2,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
selector() {
|
||||
return $(".landscape-right-tab-products");
|
||||
},
|
||||
};
|
||||
|
||||
slickOptions() {
|
||||
return {
|
||||
rows: 0,
|
||||
dots: true,
|
||||
arrows: false,
|
||||
infinite: true,
|
||||
slidesToShow: 6,
|
||||
slidesToScroll: 6,
|
||||
rtl: window.FleetCart.rtl,
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1761,
|
||||
settings: {
|
||||
slidesToShow: 5,
|
||||
slidesToScroll: 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 1301,
|
||||
settings: {
|
||||
slidesToShow: 4,
|
||||
slidesToScroll: 4,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 1051,
|
||||
settings: {
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 992,
|
||||
settings: {
|
||||
slidesToShow: 4,
|
||||
slidesToScroll: 4,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 881,
|
||||
settings: {
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 768,
|
||||
settings: {
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 641,
|
||||
settings: {
|
||||
slidesToShow: 2,
|
||||
slidesToScroll: 2,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<section class="top-brands-wrap clearfix">
|
||||
<div class="container">
|
||||
<div class="top-brands clearfix">
|
||||
<div class="top-brands overflow-hidden clearfix">
|
||||
<a
|
||||
v-for="(topBrand, index) in topBrands"
|
||||
:key="index"
|
||||
:href="topBrand.url"
|
||||
class="top-brand-image"
|
||||
class="top-brand-item d-inline-flex align-items-center justify-content-center overflow-hidden"
|
||||
>
|
||||
<img :src="topBrand.logo.path" alt="brand logo">
|
||||
<img :src="topBrand.logo.path" alt="Brand logo" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -16,7 +16,62 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['topBrands'],
|
||||
};
|
||||
export default {
|
||||
props: ["topBrands"],
|
||||
|
||||
mounted() {
|
||||
$(".top-brands").slick(this.slickOptions());
|
||||
},
|
||||
|
||||
methods: {
|
||||
slickOptions() {
|
||||
return {
|
||||
rows: 0,
|
||||
dots: false,
|
||||
arrows: true,
|
||||
infinite: true,
|
||||
slidesToShow: 7,
|
||||
slidesToScroll: 7,
|
||||
rtl: window.FleetCart.rtl,
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1200,
|
||||
settings: {
|
||||
slidesToShow: 6,
|
||||
slidesToScroll: 6,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 1050,
|
||||
settings: {
|
||||
slidesToShow: 5,
|
||||
slidesToScroll: 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 900,
|
||||
settings: {
|
||||
slidesToShow: 4,
|
||||
slidesToScroll: 4,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 750,
|
||||
settings: {
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 450,
|
||||
settings: {
|
||||
slidesToShow: 2,
|
||||
slidesToScroll: 2,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,13 +1,24 @@
|
||||
<template>
|
||||
<div class="col-xl-4 col-lg-6">
|
||||
<div
|
||||
:class="flashSaleEnabled ? 'col-xl-4 col-lg-6' : 'col-xl-6 col-lg-6'"
|
||||
v-if="hasAnyProduct"
|
||||
>
|
||||
<div class="vertical-products">
|
||||
<div class="vertical-products-header">
|
||||
<h4 class="section-title">{{ title }}</h4>
|
||||
</div>
|
||||
|
||||
<div class="vertical-products-slider" ref="productsPlaceholder">
|
||||
<div v-for="(productChunks, index) in $chunk(products, 5)" :key="index" class="vertical-products-slide">
|
||||
<ProductCardVertical v-for="product in productChunks" :key="product.id" :product="product"/>
|
||||
<div
|
||||
v-for="(productChunks, index) in $chunk(products, 5)"
|
||||
:key="index"
|
||||
class="vertical-products-slide"
|
||||
>
|
||||
<ProductCardVertical
|
||||
v-for="product in productChunks"
|
||||
:key="product.id"
|
||||
:product="product"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -15,44 +26,53 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ProductCardVertical from '../ProductCardVertical.vue';
|
||||
import ProductCardVertical from "../ProductCardVertical.vue";
|
||||
|
||||
export default {
|
||||
components: { ProductCardVertical },
|
||||
export default {
|
||||
components: { ProductCardVertical },
|
||||
|
||||
props: ['title', 'url'],
|
||||
props: ["flashSaleEnabled", "title", "url"],
|
||||
|
||||
data() {
|
||||
return {
|
||||
products: [],
|
||||
};
|
||||
data() {
|
||||
return {
|
||||
products: [],
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
hasAnyProduct() {
|
||||
return this.products.length !== 0;
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
$.ajax({
|
||||
method: 'GET',
|
||||
url: this.url,
|
||||
}).then((products) => {
|
||||
this.products = products;
|
||||
created() {
|
||||
this.fetchProducts();
|
||||
},
|
||||
|
||||
methods: {
|
||||
async fetchProducts() {
|
||||
await axios.get(this.url).then((response) => {
|
||||
this.products = response.data;
|
||||
|
||||
this.$nextTick(() => {
|
||||
$(this.$refs.productsPlaceholder).slick(this.slickOptions());
|
||||
$(this.$refs.productsPlaceholder).slick(
|
||||
this.slickOptions()
|
||||
);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
methods: {
|
||||
slickOptions() {
|
||||
return {
|
||||
rows: 0,
|
||||
dots: false,
|
||||
arrows: true,
|
||||
infinite: true,
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
rtl: window.FleetCart.rtl,
|
||||
};
|
||||
},
|
||||
slickOptions() {
|
||||
return {
|
||||
rows: 0,
|
||||
dots: false,
|
||||
arrows: true,
|
||||
infinite: true,
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
rtl: window.FleetCart.rtl,
|
||||
};
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -15,10 +15,7 @@ export default {
|
||||
accept() {
|
||||
this.show = false;
|
||||
|
||||
$.ajax({
|
||||
method: 'DELETE',
|
||||
url: route('storefront.cookie_bar.destroy'),
|
||||
});
|
||||
axios.delete(route("storefront.cookie_bar.destroy"));
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
:placeholder="
|
||||
$trans('storefront::layout.search_for_products')
|
||||
"
|
||||
@focus="showExistingSuggestions"
|
||||
@keydown.esc="hideSuggestions"
|
||||
@keydown.down="nextSuggestion"
|
||||
@keydown.up="prevSuggestion"
|
||||
@@ -92,7 +93,7 @@
|
||||
|
||||
<div class="header-search-sm-form">
|
||||
<form class="search-form" @submit.prevent="search">
|
||||
<div class="btn-close">
|
||||
<div class="btn-close" @click="showSuggestions = false">
|
||||
<i class="las la-arrow-left"></i>
|
||||
</div>
|
||||
|
||||
@@ -107,6 +108,7 @@
|
||||
"
|
||||
:value="form.query"
|
||||
@input="form.query = $event.target.value"
|
||||
@focus="showExistingSuggestions"
|
||||
@keydown.esc="hideSuggestions"
|
||||
@keydown.down="nextSuggestion"
|
||||
@keydown.up="prevSuggestion"
|
||||
@@ -118,7 +120,10 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="search-suggestions" v-if="shouldShowSuggestions">
|
||||
<div
|
||||
class="search-suggestions overflow-hidden"
|
||||
v-if="shouldShowSuggestions"
|
||||
>
|
||||
<div
|
||||
class="search-suggestions-inner custom-scrollbar"
|
||||
ref="searchSuggestionsInner"
|
||||
@@ -179,7 +184,7 @@
|
||||
'image-placeholder':
|
||||
!hasBaseImage(product),
|
||||
}"
|
||||
alt="product image"
|
||||
:alt="product.name"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -212,31 +217,29 @@
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<a
|
||||
v-if="suggestions.remaining !== 0"
|
||||
:href="moreResultsUrl"
|
||||
@click="hideSuggestions"
|
||||
class="more-results"
|
||||
>
|
||||
{{
|
||||
$trans("storefront::layout.more_results", {
|
||||
count: this.suggestions.remaining,
|
||||
})
|
||||
}}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a
|
||||
v-if="suggestions.remaining !== 0"
|
||||
:href="moreResultsUrl"
|
||||
@click="hideSuggestions"
|
||||
class="more-results"
|
||||
>
|
||||
{{
|
||||
$trans("storefront::layout.more_results", {
|
||||
count: this.suggestions.remaining,
|
||||
})
|
||||
}}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ProductHelpersMixin from "../../mixins/ProductHelpersMixin";
|
||||
import { throttle } from "lodash";
|
||||
|
||||
export default {
|
||||
mixins: [ProductHelpersMixin],
|
||||
|
||||
props: [
|
||||
"categories",
|
||||
"mostSearchedKeywords",
|
||||
@@ -303,7 +306,7 @@ export default {
|
||||
},
|
||||
|
||||
watch: {
|
||||
"form.query": function (newQuery) {
|
||||
"form.query": throttle(function (newQuery) {
|
||||
if (newQuery === "") {
|
||||
this.clearSuggestions();
|
||||
} else {
|
||||
@@ -311,7 +314,7 @@ export default {
|
||||
|
||||
this.fetchSuggestions();
|
||||
}
|
||||
},
|
||||
}, 600),
|
||||
},
|
||||
|
||||
methods: {
|
||||
@@ -322,17 +325,16 @@ export default {
|
||||
},
|
||||
|
||||
fetchSuggestions() {
|
||||
$.ajax({
|
||||
method: "GET",
|
||||
url: route("suggestions.index", this.form),
|
||||
}).then((suggestions) => {
|
||||
this.suggestions.categories = suggestions.categories;
|
||||
this.suggestions.products = suggestions.products;
|
||||
this.suggestions.remaining = suggestions.remaining;
|
||||
axios
|
||||
.get(route("suggestions.index", this.form))
|
||||
.then(({ data }) => {
|
||||
this.suggestions.categories = data.categories;
|
||||
this.suggestions.products = data.products;
|
||||
this.suggestions.remaining = data.remaining;
|
||||
|
||||
this.clearActiveSuggestion();
|
||||
this.resetSuggestionScrollBar();
|
||||
});
|
||||
this.clearActiveSuggestion();
|
||||
this.resetSuggestionScrollBar();
|
||||
});
|
||||
},
|
||||
|
||||
search() {
|
||||
@@ -362,12 +364,18 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
showExistingSuggestions() {
|
||||
if (this.form.query !== "") {
|
||||
this.showSuggestions = true;
|
||||
}
|
||||
},
|
||||
|
||||
clearSuggestions() {
|
||||
this.suggestions.categories = [];
|
||||
this.suggestions.products = [];
|
||||
},
|
||||
|
||||
hideSuggestions(e) {
|
||||
hideSuggestions() {
|
||||
this.showSuggestions = false;
|
||||
|
||||
this.clearActiveSuggestion();
|
||||
@@ -447,6 +455,22 @@ export default {
|
||||
this.$refs.searchSuggestionsInner.scrollTop = 0;
|
||||
}
|
||||
},
|
||||
|
||||
productUrl(product) {
|
||||
return route("products.show", product.slug);
|
||||
},
|
||||
|
||||
hasBaseImage(product) {
|
||||
return product.base_image.length !== 0;
|
||||
},
|
||||
|
||||
baseImage(product) {
|
||||
if (this.hasBaseImage(product)) {
|
||||
return product.base_image.path;
|
||||
}
|
||||
|
||||
return `${window.FleetCart.baseUrl}/build/assets/image-placeholder.png`;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
email: '',
|
||||
email: "",
|
||||
subscribed: false,
|
||||
subscribing: false,
|
||||
error: '',
|
||||
error: "",
|
||||
disable_popup: false,
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
email() {
|
||||
this.error = '';
|
||||
this.error = "";
|
||||
},
|
||||
|
||||
disable_popup(bool) {
|
||||
@@ -25,48 +25,46 @@ export default {
|
||||
|
||||
mounted() {
|
||||
setTimeout(() => {
|
||||
$('.newsletter-wrap').modal('show');
|
||||
$(".newsletter-wrap").modal("show");
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
methods: {
|
||||
enableNewsletterPopup() {
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: route('storefront.newsletter_popup.store'),
|
||||
});
|
||||
axios.post(route("storefront.newsletter_popup.store"));
|
||||
},
|
||||
|
||||
disableNewsletterPopup() {
|
||||
$.ajax({
|
||||
method: 'DELETE',
|
||||
url: route('storefront.newsletter_popup.destroy'),
|
||||
});
|
||||
axios.delete(route("storefront.newsletter_popup.destroy"));
|
||||
},
|
||||
|
||||
subscribe() {
|
||||
if (! this.email || this.subscribed) {
|
||||
if (!this.email || this.subscribed) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.subscribing = true;
|
||||
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: route('subscribers.store'),
|
||||
data: { email: this.email },
|
||||
}).then(() => {
|
||||
this.email = '';
|
||||
this.subscribed = true;
|
||||
}).catch((response) => {
|
||||
if (response.status === 422) {
|
||||
this.error = response.responseJSON.errors.email[0];
|
||||
} else {
|
||||
this.error = response.responseJSON.message;
|
||||
}
|
||||
}).always(() => {
|
||||
this.subscribing = false;
|
||||
});
|
||||
axios
|
||||
.post(route("subscribers.store"), {
|
||||
email: this.email,
|
||||
})
|
||||
.then(() => {
|
||||
this.email = "";
|
||||
this.subscribed = true;
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.response.status === 422) {
|
||||
this.error = error.response.data.errors.email[0];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.error = error.response.data.message;
|
||||
})
|
||||
.finally(() => {
|
||||
this.subscribing = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
email: '',
|
||||
email: "",
|
||||
subscribed: false,
|
||||
subscribing: false,
|
||||
};
|
||||
@@ -9,28 +9,32 @@ export default {
|
||||
|
||||
methods: {
|
||||
subscribe() {
|
||||
if (! this.email || this.subscribed) {
|
||||
if (!this.email || this.subscribed) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.subscribing = true;
|
||||
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: route('subscribers.store'),
|
||||
data: { email: this.email },
|
||||
}).then(() => {
|
||||
this.email = '';
|
||||
this.subscribed = true;
|
||||
}).catch((response) => {
|
||||
if (response.status === 422) {
|
||||
this.$notify(response.responseJSON.errors.email[0]);
|
||||
} else {
|
||||
this.$notify(response.responseJSON.message);
|
||||
}
|
||||
}).always(() => {
|
||||
this.subscribing = false;
|
||||
});
|
||||
axios
|
||||
.post(route("subscribers.store"), {
|
||||
email: this.email,
|
||||
})
|
||||
.then(() => {
|
||||
this.email = "";
|
||||
this.subscribed = true;
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.response.status === 422) {
|
||||
this.$notify(error.response.data.errors.email[0]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.$notify(error.response.data.message);
|
||||
})
|
||||
.finally(() => {
|
||||
this.subscribing = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import store from '../../store';
|
||||
import SidebarCartItem from './SidebarCartItem.vue';
|
||||
import store from "../../store";
|
||||
|
||||
export default {
|
||||
components: { SidebarCartItem },
|
||||
components: { SidebarCartItem: () => import("./SidebarCartItem.vue") },
|
||||
|
||||
computed: {
|
||||
cart() {
|
||||
@@ -14,7 +13,30 @@ export default {
|
||||
},
|
||||
|
||||
cartIsNotEmpty() {
|
||||
return ! store.cartIsEmpty();
|
||||
return !store.cartIsEmpty();
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.initEventListeners();
|
||||
},
|
||||
|
||||
methods: {
|
||||
initEventListeners() {
|
||||
const sidebarCartWrap = $(".sidebar-cart-wrap");
|
||||
const overlay = $(".overlay");
|
||||
|
||||
$(".header-cart").on("click", (e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
overlay.addClass("active");
|
||||
sidebarCartWrap.addClass("active");
|
||||
});
|
||||
|
||||
$(".sidebar-cart-close").on("click", () => {
|
||||
overlay.removeClass("active");
|
||||
sidebarCartWrap.removeClass("active");
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,26 +1,98 @@
|
||||
<template>
|
||||
<div class="sidebar-cart-item">
|
||||
<a :href="productUrl(cartItem.product)" class="product-image">
|
||||
<div class="cart-item sidebar-cart-item">
|
||||
<a :href="productUrl(cartItem)" class="product-image">
|
||||
<img
|
||||
:src="baseImage(cartItem.product)"
|
||||
:class="{ 'image-placeholder': ! hasBaseImage(cartItem.product) }"
|
||||
alt="product image"
|
||||
>
|
||||
:src="baseImage(cartItem)"
|
||||
:class="{
|
||||
'image-placeholder': !hasBaseImage(cartItem),
|
||||
}"
|
||||
:alt="cartItem.product.name"
|
||||
/>
|
||||
</a>
|
||||
|
||||
<div class="product-info">
|
||||
<a :href="productUrl(cartItem.product)" class="product-name" :title="cartItem.product.name">
|
||||
<a
|
||||
:href="productUrl(cartItem)"
|
||||
class="product-name"
|
||||
:title="cartItem.product.name"
|
||||
>
|
||||
{{ cartItem.product.name }}
|
||||
</a>
|
||||
|
||||
<ul class="list-inline product-options">
|
||||
<ul
|
||||
v-if="Object.entries(cartItem.variations).length !== 0"
|
||||
class="list-inline product-options"
|
||||
>
|
||||
<li
|
||||
v-for="(variation, key, index) in cartItem.variations"
|
||||
:key="index"
|
||||
>
|
||||
<label>{{ variation.name }}:</label>
|
||||
{{ variation.values[0].label
|
||||
}}{{
|
||||
index === Object.values(cartItem.variations).length - 1
|
||||
? ""
|
||||
: ","
|
||||
}}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul
|
||||
v-if="Object.entries(cartItem.options).length !== 0"
|
||||
class="list-inline product-options"
|
||||
>
|
||||
<li v-for="option in cartItem.options" :key="option.id">
|
||||
<label>{{ option.name }}:</label> {{ optionValues(option) }}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="product-quantity">
|
||||
{{ cartItem.qty }} x <span v-html="cartItem.unitPrice.inCurrentCurrency.formatted"></span>
|
||||
<div class="d-flex align-items-center justify-content-between mt-1">
|
||||
<div class="number-picker">
|
||||
<div class="input-group-quantity">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-number btn-minus"
|
||||
:disabled="cartItem.qty <= 1"
|
||||
@click="updateQuantity(cartItem, cartItem.qty - 1)"
|
||||
>
|
||||
-
|
||||
</button>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
:value="cartItem.qty"
|
||||
min="1"
|
||||
:max="maxQuantity(cartItem)"
|
||||
class="form-control input-number input-quantity"
|
||||
@focus="$event.target.select()"
|
||||
@input="
|
||||
changeQuantity(
|
||||
cartItem,
|
||||
Number($event.target.value)
|
||||
)
|
||||
"
|
||||
@keydown.up="
|
||||
updateQuantity(cartItem, cartItem.qty + 1)
|
||||
"
|
||||
@keydown.down="
|
||||
updateQuantity(cartItem, cartItem.qty - 1)
|
||||
"
|
||||
/>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-number btn-plus"
|
||||
:disabled="isQtyIncreaseDisabled(cartItem)"
|
||||
@click="updateQuantity(cartItem, cartItem.qty + 1)"
|
||||
>
|
||||
+
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="product-price">
|
||||
x {{ cartItem.unitPrice.inCurrentCurrency.formatted }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -33,37 +105,52 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import store from '../../store';
|
||||
import ProductHelpersMixin from '../../mixins/ProductHelpersMixin';
|
||||
import store from "../../store";
|
||||
import CartItemHelpersMixin from "../../mixins/CartItemHelpersMixin";
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
ProductHelpersMixin,
|
||||
],
|
||||
export default {
|
||||
mixins: [CartItemHelpersMixin],
|
||||
|
||||
props: ['cartItem'],
|
||||
props: ["cartItem"],
|
||||
|
||||
methods: {
|
||||
optionValues(option) {
|
||||
let values = [];
|
||||
|
||||
for (let value of option.values) {
|
||||
values.push(value.label);
|
||||
}
|
||||
|
||||
return values.join(', ');
|
||||
},
|
||||
|
||||
remove() {
|
||||
store.removeCartItem(this.cartItem);
|
||||
|
||||
$.ajax({
|
||||
method: 'DELETE',
|
||||
url: route('cart.items.destroy', { cartItemId: this.cartItem.id }),
|
||||
}).then((cart) => {
|
||||
store.updateCart(cart);
|
||||
methods: {
|
||||
updateCart(cartItem, qty) {
|
||||
axios
|
||||
.put(
|
||||
route("cart.items.update", {
|
||||
cartItemId: cartItem.id,
|
||||
...(store.hasCoupon() && {
|
||||
coupon_code: store.getCoupon(),
|
||||
}),
|
||||
}),
|
||||
{
|
||||
qty: qty || 1,
|
||||
}
|
||||
)
|
||||
.then((response) => {
|
||||
store.updateCart(response.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$notify(error.response.data.message);
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
remove() {
|
||||
store.removeCartItem(this.cartItem);
|
||||
|
||||
axios
|
||||
.delete(
|
||||
route("cart.items.destroy", {
|
||||
cartItemId: this.cartItem.id,
|
||||
...(store.hasCoupon() && {
|
||||
coupon_code: store.getCoupon(),
|
||||
}),
|
||||
})
|
||||
)
|
||||
.then((response) => {
|
||||
store.updateCart(response.data);
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import noUiSlider from "nouislider";
|
||||
import { trans } from "../../functions";
|
||||
import { collapseFilters } from "./index/helpers";
|
||||
import noUiSlider from "nouislider";
|
||||
|
||||
export default {
|
||||
components: { VPagination: () => import("../VPagination.vue") },
|
||||
|
||||
props: [
|
||||
"initialQuery",
|
||||
"initialBrandName",
|
||||
@@ -14,11 +15,12 @@ export default {
|
||||
"initialTagName",
|
||||
"initialTagSlug",
|
||||
"initialAttribute",
|
||||
"minPrice",
|
||||
"maxPrice",
|
||||
"initialSort",
|
||||
"initialPerPage",
|
||||
"initialPage",
|
||||
"initialViewMode"
|
||||
"initialViewMode",
|
||||
],
|
||||
|
||||
data() {
|
||||
@@ -40,8 +42,8 @@ export default {
|
||||
toPrice: this.maxPrice,
|
||||
sort: this.initialSort,
|
||||
perPage: this.initialPerPage,
|
||||
page: this.initialPage
|
||||
}
|
||||
page: this.initialPage,
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
@@ -62,26 +64,27 @@ export default {
|
||||
return trans("storefront::products.showing_results", {
|
||||
from: this.products.from,
|
||||
to: this.products.to,
|
||||
total: this.products.total
|
||||
total: this.products.total,
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.addEventListeners();
|
||||
this.initPriceFilter();
|
||||
this.fetchProducts();
|
||||
this.initLatestProductsSlider();
|
||||
},
|
||||
|
||||
methods: {
|
||||
addEventListeners() {
|
||||
$(this.$refs.sortSelect).on("change", e => {
|
||||
$(this.$refs.sortSelect).on("change", (e) => {
|
||||
this.queryParams.sort = e.currentTarget.value;
|
||||
|
||||
this.fetchProducts();
|
||||
});
|
||||
|
||||
$(this.$refs.perPageSelect).on("change", e => {
|
||||
$(this.$refs.perPageSelect).on("change", (e) => {
|
||||
this.queryParams.perPage = e.currentTarget.value;
|
||||
|
||||
this.fetchProducts();
|
||||
@@ -92,11 +95,11 @@ export default {
|
||||
noUiSlider.create(this.$refs.priceRange, {
|
||||
connect: true,
|
||||
direction: window.FleetCart.rtl ? "rtl" : "ltr",
|
||||
start: [0, this.maxPrice],
|
||||
start: [this.minPrice, this.maxPrice],
|
||||
range: {
|
||||
min: [0],
|
||||
max: [this.maxPrice]
|
||||
}
|
||||
min: [this.minPrice],
|
||||
max: [this.maxPrice],
|
||||
},
|
||||
});
|
||||
|
||||
this.$refs.priceRange.noUiSlider.on("update", (values, handle) => {
|
||||
@@ -160,29 +163,36 @@ export default {
|
||||
this.fetchProducts();
|
||||
},
|
||||
|
||||
fetchProducts(options = { updateAttributeFilters: true }) {
|
||||
async fetchProducts(options = { updateAttributeFilters: true }) {
|
||||
this.fetchingProducts = true;
|
||||
|
||||
$.ajax({
|
||||
url: route("products.index", this.queryParams)
|
||||
})
|
||||
.then(response => {
|
||||
this.products = response.products;
|
||||
try {
|
||||
const response = await axios.get(
|
||||
route("products.index", this.queryParams)
|
||||
);
|
||||
|
||||
if (options.updateAttributeFilters) {
|
||||
this.attributeFilters = response.attributes;
|
||||
}
|
||||
this.products = response.data.products;
|
||||
|
||||
this.$nextTick(() => {
|
||||
collapseFilters();
|
||||
});
|
||||
})
|
||||
.catch(xhr => {
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
})
|
||||
.always(() => {
|
||||
this.fetchingProducts = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
if (options.updateAttributeFilters) {
|
||||
this.attributeFilters = response.data.attributes;
|
||||
}
|
||||
} catch (error) {
|
||||
this.$notify(error.response.data.message);
|
||||
} finally {
|
||||
this.fetchingProducts = false;
|
||||
}
|
||||
},
|
||||
|
||||
initLatestProductsSlider() {
|
||||
$(this.$refs.latestProducts).slick({
|
||||
rows: 0,
|
||||
dots: false,
|
||||
arrows: true,
|
||||
infinite: true,
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
rtl: window.FleetCart.rtl,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,22 +1,41 @@
|
||||
import store from '../../store';
|
||||
import Errors from '../../Errors';
|
||||
import ProductRating from '../ProductRating.vue';
|
||||
import ProductCardMixin from '../../mixins/ProductCardMixin';
|
||||
import RelatedProducts from './show/RelatedProducts.vue';
|
||||
import store from "../../store";
|
||||
import Errors from "../../Errors";
|
||||
import GalleryMixin from "./show/mixins/GalleryMixin";
|
||||
import VariationMixin from "./show/mixins/VariationMixin";
|
||||
import VariantMixin from "./show/mixins/VariantMixin";
|
||||
import OptionMixin from "./show/mixins/OptionMixin";
|
||||
import QuantityMixin from "./show/mixins/QuantityMixin";
|
||||
import ReviewMixin from "./show/mixins/ReviewMixin";
|
||||
import ProductCardMixin from "../../mixins/ProductCardMixin";
|
||||
|
||||
export default {
|
||||
components: { ProductRating, RelatedProducts },
|
||||
components: {
|
||||
VPagination: () => import("../VPagination.vue"),
|
||||
RelatedProducts: () => import("./show/RelatedProducts.vue"),
|
||||
},
|
||||
|
||||
mixins: [
|
||||
GalleryMixin,
|
||||
VariationMixin,
|
||||
VariantMixin,
|
||||
OptionMixin,
|
||||
QuantityMixin,
|
||||
ReviewMixin,
|
||||
ProductCardMixin,
|
||||
],
|
||||
|
||||
props: ['product', 'reviewCount', 'avgRating'],
|
||||
props: ["product", "reviewCount", "avgRating"],
|
||||
|
||||
data() {
|
||||
return {
|
||||
item: {
|
||||
...(this.product.variant ? this.product.variant : this.product),
|
||||
},
|
||||
oldMediaLength: 0,
|
||||
activeVariationValues: {},
|
||||
variationImagePath: null,
|
||||
price: this.product.formatted_price,
|
||||
activeTab: 'description',
|
||||
activeTab: "description",
|
||||
currentReviewPage: 1,
|
||||
fetchingReviews: false,
|
||||
reviews: {},
|
||||
@@ -25,6 +44,7 @@ export default {
|
||||
cartItemForm: {
|
||||
product_id: this.product.id,
|
||||
qty: 1,
|
||||
variations: {},
|
||||
options: {},
|
||||
},
|
||||
errors: new Errors(),
|
||||
@@ -32,202 +52,68 @@ export default {
|
||||
},
|
||||
|
||||
computed: {
|
||||
totalReviews() {
|
||||
if (! this.reviews.total) {
|
||||
return this.reviewCount;
|
||||
}
|
||||
|
||||
return this.reviews.total;
|
||||
productUrl() {
|
||||
return route("products.show", {
|
||||
slug: this.product.slug,
|
||||
...(this.hasAnyVariant && {
|
||||
variant: this.item.uid,
|
||||
}),
|
||||
});
|
||||
},
|
||||
|
||||
ratingPercent() {
|
||||
return (this.avgRating / 5) * 100;
|
||||
isActiveItem() {
|
||||
return this.item.is_active === true;
|
||||
},
|
||||
|
||||
emptyReviews() {
|
||||
return this.totalReviews === 0;
|
||||
isAddToCartDisabled() {
|
||||
return this.item.is_out_of_stock ?? true;
|
||||
},
|
||||
|
||||
totalReviewPage() {
|
||||
return Math.ceil(this.reviews.total / 4);
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
this.fetchReviews();
|
||||
},
|
||||
|
||||
mounted() {
|
||||
$(this.$refs.upSellProducts).slick({
|
||||
rows: 0,
|
||||
dots: false,
|
||||
arrows: true,
|
||||
infinite: true,
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
rtl: window.FleetCart.rtl,
|
||||
});
|
||||
},
|
||||
|
||||
methods: {
|
||||
updateQuantity(qty) {
|
||||
if (qty < 1 || this.exceedsMaxStock(qty)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNaN(qty)) {
|
||||
qty = 1;
|
||||
}
|
||||
|
||||
this.cartItemForm.qty = qty;
|
||||
},
|
||||
|
||||
exceedsMaxStock(qty) {
|
||||
return this.product.manage_stock && this.product.qty < qty;
|
||||
},
|
||||
|
||||
changeReviewPage(page) {
|
||||
this.currentReviewPage = page;
|
||||
|
||||
this.fetchReviews();
|
||||
},
|
||||
|
||||
updatePrice() {
|
||||
this.$nextTick(() => {
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: route('products.price.show', { id: this.product.id }),
|
||||
data: { options: this.cartItemForm.options },
|
||||
}).then((price) => {
|
||||
this.price = price;
|
||||
}).catch((xhr) => {
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
updateSelectTypeOptionValue(optionId, e) {
|
||||
this.$set(this.cartItemForm.options, optionId, $(e.target).val());
|
||||
|
||||
this.errors.clear(`options.${optionId}`);
|
||||
},
|
||||
|
||||
updateCheckboxTypeOptionValue(optionId, e) {
|
||||
let values = $(e.target)
|
||||
.parents('.variant-check')
|
||||
.find('input[type="checkbox"]:checked')
|
||||
.map((_, el) => {
|
||||
return el.value;
|
||||
});
|
||||
|
||||
this.$set(this.cartItemForm.options, optionId, values.get());
|
||||
},
|
||||
|
||||
customRadioTypeOptionValueIsActive(optionId, valueId) {
|
||||
if (! this.cartItemForm.options.hasOwnProperty(optionId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.cartItemForm.options[optionId] === valueId;
|
||||
},
|
||||
|
||||
syncCustomRadioTypeOptionValue(optionId, valueId) {
|
||||
if (this.customRadioTypeOptionValueIsActive(optionId, valueId)) {
|
||||
this.$delete(this.cartItemForm.options, optionId);
|
||||
} else {
|
||||
this.$set(this.cartItemForm.options, optionId, valueId);
|
||||
|
||||
this.errors.clear(`options.${optionId}`);
|
||||
}
|
||||
|
||||
this.updatePrice();
|
||||
},
|
||||
|
||||
customCheckboxTypeOptionValueIsActive(optionId, valueId) {
|
||||
if (! this.cartItemForm.options.hasOwnProperty(optionId)) {
|
||||
this.$set(this.cartItemForm.options, optionId, []);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.cartItemForm.options[optionId].includes(valueId);
|
||||
},
|
||||
|
||||
syncCustomCheckboxTypeOptionValue(optionId, valueId) {
|
||||
if (this.customCheckboxTypeOptionValueIsActive(optionId, valueId)) {
|
||||
this.cartItemForm.options[optionId].splice(
|
||||
this.cartItemForm.options[optionId].indexOf(valueId),
|
||||
1
|
||||
);
|
||||
} else {
|
||||
this.cartItemForm.options[optionId].push(valueId);
|
||||
|
||||
this.errors.clear(`options.${optionId}`);
|
||||
}
|
||||
|
||||
this.updatePrice();
|
||||
},
|
||||
|
||||
fetchReviews() {
|
||||
this.fetchingReviews = true;
|
||||
|
||||
$.ajax({
|
||||
method: 'GET',
|
||||
url: route('products.reviews.index', {
|
||||
productId: this.product.id,
|
||||
page: this.currentReviewPage,
|
||||
}),
|
||||
}).then((reviews) => {
|
||||
this.reviews = reviews;
|
||||
}).catch((xhr) => {
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
}).always(() => {
|
||||
this.fetchingReviews = false;
|
||||
});
|
||||
},
|
||||
|
||||
addNewReview() {
|
||||
this.addingNewReview = true;
|
||||
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: route('products.reviews.store', { productId: this.product.id }),
|
||||
data: this.reviewForm,
|
||||
}).then((review) => {
|
||||
this.reviewForm = {};
|
||||
this.reviews.total++;
|
||||
this.reviews.data.unshift(review);
|
||||
|
||||
$('.captcha-input').prev('img').trigger('click');
|
||||
}).catch((xhr) => {
|
||||
if (xhr.status === 422) {
|
||||
this.errors.record(xhr.responseJSON.errors);
|
||||
} else {
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
}
|
||||
}).always(() => {
|
||||
this.addingNewReview = false;
|
||||
});
|
||||
isMobileDevice() {
|
||||
return window.matchMedia("only screen and (max-width: 991px)")
|
||||
.matches;
|
||||
},
|
||||
|
||||
addToCart() {
|
||||
if (this.isAddToCartDisabled) return;
|
||||
|
||||
this.addingToCart = true;
|
||||
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: route('cart.items.store', this.cartItemForm),
|
||||
}).then((cart) => {
|
||||
store.updateCart(cart);
|
||||
axios
|
||||
.post(route("cart.items.store"), {
|
||||
...this.cartItemForm,
|
||||
...(this.hasAnyVariant && { variant_id: this.item.id }),
|
||||
})
|
||||
.then((response) => {
|
||||
store.updateCart(response.data);
|
||||
|
||||
$('.header-cart').trigger('click');
|
||||
}).catch((xhr) => {
|
||||
if (xhr.status === 422) {
|
||||
this.errors.record(xhr.responseJSON.errors);
|
||||
} else {
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
}
|
||||
}).always(() => {
|
||||
this.addingToCart = false;
|
||||
$(".header-cart").trigger("click");
|
||||
})
|
||||
.catch(({ response }) => {
|
||||
if (response.status === 422) {
|
||||
this.errors.record(response.data.errors);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.$notify(response.data.message);
|
||||
})
|
||||
.finally(() => {
|
||||
this.addingToCart = false;
|
||||
});
|
||||
},
|
||||
|
||||
initUpSellProductsSlider() {
|
||||
$(this.$refs.upSellProducts).slick({
|
||||
rows: 0,
|
||||
dots: false,
|
||||
arrows: true,
|
||||
infinite: true,
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
rtl: window.FleetCart.rtl,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<template>
|
||||
<div class="col">
|
||||
<ProductCard :product="product"/>
|
||||
<div class="grid-view-products-item">
|
||||
<ProductCard :product="product" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ProductCard from './../../ProductCard.vue';
|
||||
import ProductCard from "./../../ProductCard.vue";
|
||||
|
||||
export default {
|
||||
components: { ProductCard },
|
||||
export default {
|
||||
components: { ProductCard },
|
||||
|
||||
props: ['product'],
|
||||
};
|
||||
props: ["product"],
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,24 +1,31 @@
|
||||
<template>
|
||||
<div class="list-product-card">
|
||||
<div class="list-product-card-inner">
|
||||
<div class="product-card-left">
|
||||
<div class="product-card-left position-relative">
|
||||
<a :href="productUrl" class="product-image">
|
||||
<img :src="baseImage" :class="{ 'image-placeholder': ! hasBaseImage }" alt="product-image">
|
||||
|
||||
<ul class="list-inline product-badge">
|
||||
<li class="badge badge-danger" v-if="product.is_out_of_stock">
|
||||
{{ $trans('storefront::product_card.out_of_stock') }}
|
||||
</li>
|
||||
|
||||
<li class="badge badge-primary" v-else-if="product.is_new">
|
||||
{{ $trans('storefront::product_card.new') }}
|
||||
</li>
|
||||
|
||||
<li class="badge badge-success" v-if="product.has_percentage_special_price">
|
||||
-{{ product.special_price_percent }}%
|
||||
</li>
|
||||
</ul>
|
||||
<img
|
||||
:src="baseImage"
|
||||
:class="{ 'image-placeholder': !hasBaseImage }"
|
||||
:alt="product.name"
|
||||
/>
|
||||
</a>
|
||||
|
||||
<ul class="list-inline product-badge">
|
||||
<li class="badge badge-danger" v-if="item.is_out_of_stock">
|
||||
{{ $trans("storefront::product_card.out_of_stock") }}
|
||||
</li>
|
||||
|
||||
<li class="badge badge-primary" v-else-if="product.is_new">
|
||||
{{ $trans("storefront::product_card.new") }}
|
||||
</li>
|
||||
|
||||
<li
|
||||
class="badge badge-success"
|
||||
v-if="item.has_percentage_special_price"
|
||||
>
|
||||
-{{ item.special_price_percent }}%
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="product-card-right">
|
||||
@@ -28,19 +35,23 @@
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<ProductRating :ratingPercent="product.rating_percent" :reviewCount="product.reviews.length"/>
|
||||
<product-rating
|
||||
:ratingPercent="product.rating_percent"
|
||||
:reviewCount="product.reviews.length"
|
||||
>
|
||||
</product-rating>
|
||||
|
||||
<div class="product-price" v-html="product.formatted_price"></div>
|
||||
<div class="product-price" v-html="item.formatted_price"></div>
|
||||
|
||||
<button
|
||||
v-if="hasNoOption || product.is_out_of_stock"
|
||||
v-if="hasNoOption || item.is_out_of_stock"
|
||||
class="btn btn-default btn-add-to-cart"
|
||||
:class="{ 'btn-loading': addingToCart }"
|
||||
:disabled="product.is_out_of_stock"
|
||||
:disabled="item.is_out_of_stock"
|
||||
@click="addToCart"
|
||||
>
|
||||
<i class="las la-cart-arrow-down"></i>
|
||||
{{ $trans('storefront::product_card.add_to_cart') }}
|
||||
{{ $trans("storefront::product_card.add_to_cart") }}
|
||||
</button>
|
||||
|
||||
<a
|
||||
@@ -49,26 +60,29 @@
|
||||
class="btn btn-default btn-add-to-cart"
|
||||
>
|
||||
<i class="las la-eye"></i>
|
||||
{{ $trans('storefront::product_card.view_options') }}
|
||||
{{ $trans("storefront::product_card.view_options") }}
|
||||
</a>
|
||||
|
||||
<div class="product-card-actions">
|
||||
<button
|
||||
class="btn btn-wishlist"
|
||||
:class="{ 'added': inWishlist }"
|
||||
:class="{ added: inWishlist }"
|
||||
@click="syncWishlist"
|
||||
>
|
||||
<i class="la-heart" :class="inWishlist ? 'las' : 'lar'"></i>
|
||||
{{ $trans('storefront::product_card.wishlist') }}
|
||||
<i
|
||||
class="la-heart"
|
||||
:class="inWishlist ? 'las' : 'lar'"
|
||||
></i>
|
||||
{{ $trans("storefront::product_card.wishlist") }}
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="btn btn-compare"
|
||||
:class="{ 'added': inCompareList }"
|
||||
:class="{ added: inCompareList }"
|
||||
@click="syncCompareList"
|
||||
>
|
||||
<i class="las la-random"></i>
|
||||
{{ $trans('storefront::product_card.compare') }}
|
||||
{{ $trans("storefront::product_card.compare") }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -77,16 +91,19 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ProductRating from './../../ProductRating.vue';
|
||||
import ProductCardMixin from '../../../mixins/ProductCardMixin';
|
||||
import ProductCardMixin from "../../../mixins/ProductCardMixin";
|
||||
|
||||
export default {
|
||||
components: { ProductRating },
|
||||
export default {
|
||||
mixins: [ProductCardMixin],
|
||||
|
||||
mixins: [
|
||||
ProductCardMixin,
|
||||
],
|
||||
props: ["product"],
|
||||
|
||||
props: ['product'],
|
||||
};
|
||||
data() {
|
||||
return {
|
||||
item: {
|
||||
...(this.product.variant ? this.product.variant : this.product),
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,97 +1,96 @@
|
||||
<template>
|
||||
<section class="landscape-products-wrap" v-if="hasAnyProduct">
|
||||
<div class="products-header">
|
||||
<h5 class="section-title">{{ $trans('storefront::product.related_products') }}</h5>
|
||||
<h5 class="section-title">
|
||||
{{ $trans("storefront::product.related_products") }}
|
||||
</h5>
|
||||
</div>
|
||||
|
||||
<div class="landscape-products" ref="productsPlaceholder">
|
||||
<ProductCard v-for="(product, index) in products" :key="index" :product="product"></ProductCard>
|
||||
<ProductCard
|
||||
v-for="(product, index) in products"
|
||||
:key="index"
|
||||
:product="product"
|
||||
></ProductCard>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ProductCard from './../../ProductCard.vue';
|
||||
import { slickPrevArrow, slickNextArrow } from '../../../functions';
|
||||
import { slickPrevArrow, slickNextArrow } from "../../../functions";
|
||||
import ProductCard from "./../../ProductCard.vue";
|
||||
|
||||
export default {
|
||||
components: { ProductCard },
|
||||
export default {
|
||||
components: { ProductCard },
|
||||
|
||||
props: ['products'],
|
||||
props: ["products"],
|
||||
|
||||
computed: {
|
||||
hasAnyProduct() {
|
||||
return this.products.length !== 0;
|
||||
},
|
||||
computed: {
|
||||
hasAnyProduct() {
|
||||
return this.products.length !== 0;
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
$(this.$refs.productsPlaceholder).slick({
|
||||
rows: 0,
|
||||
dots: false,
|
||||
arrows: true,
|
||||
infinite: true,
|
||||
slidesToShow: 5,
|
||||
slidesToScroll: 5,
|
||||
rtl: window.FleetCart.rtl,
|
||||
prevArrow: slickPrevArrow(),
|
||||
nextArrow: slickNextArrow(),
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1761,
|
||||
settings: {
|
||||
slidesToShow: 4,
|
||||
slidesToScroll: 4,
|
||||
},
|
||||
mounted() {
|
||||
$(this.$refs.productsPlaceholder).slick({
|
||||
rows: 0,
|
||||
dots: false,
|
||||
arrows: true,
|
||||
infinite: true,
|
||||
slidesToShow: 5,
|
||||
slidesToScroll: 5,
|
||||
rtl: window.FleetCart.rtl,
|
||||
prevArrow: slickPrevArrow(),
|
||||
nextArrow: slickNextArrow(),
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1761,
|
||||
settings: {
|
||||
slidesToShow: 4,
|
||||
slidesToScroll: 4,
|
||||
},
|
||||
{
|
||||
breakpoint: 1341,
|
||||
settings: {
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 1341,
|
||||
settings: {
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
},
|
||||
{
|
||||
breakpoint: 1081,
|
||||
settings: {
|
||||
slidesToShow: 2,
|
||||
slidesToScroll: 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 992,
|
||||
settings: {
|
||||
slidesToShow: 4,
|
||||
slidesToScroll: 4,
|
||||
},
|
||||
{
|
||||
breakpoint: 992,
|
||||
settings: {
|
||||
slidesToShow: 4,
|
||||
slidesToScroll: 4,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 881,
|
||||
settings: {
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
},
|
||||
{
|
||||
breakpoint: 881,
|
||||
settings: {
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 661,
|
||||
settings: {
|
||||
dots: true,
|
||||
arrows: false,
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
},
|
||||
{
|
||||
breakpoint: 661,
|
||||
settings: {
|
||||
dots: true,
|
||||
arrows: false,
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 641,
|
||||
settings: {
|
||||
dots: true,
|
||||
arrows: false,
|
||||
slidesToShow: 2,
|
||||
slidesToScroll: 2,
|
||||
},
|
||||
{
|
||||
breakpoint: 641,
|
||||
settings: {
|
||||
dots: true,
|
||||
arrows: false,
|
||||
slidesToShow: 2,
|
||||
slidesToScroll: 2,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,245 @@
|
||||
import Drift from "drift-zoom";
|
||||
import GLightbox from "glightbox";
|
||||
|
||||
let galleryPreviewSlider;
|
||||
let galleryThumbnailSlider;
|
||||
let galleryPreviewLightbox;
|
||||
|
||||
export default {
|
||||
mounted() {
|
||||
galleryPreviewSlider = this.initGalleryPreviewSlider();
|
||||
galleryThumbnailSlider = this.initGalleryThumbnailSlider();
|
||||
galleryPreviewLightbox = this.initGalleryPreviewLightbox();
|
||||
this.initGalleryPreviewZoom();
|
||||
this.initUpSellProductsSlider();
|
||||
},
|
||||
|
||||
methods: {
|
||||
initGalleryPreviewSlider() {
|
||||
return $(".product-gallery-preview").slick({
|
||||
rows: 0,
|
||||
speed: 200,
|
||||
fade: true,
|
||||
dots: false,
|
||||
swipe: false,
|
||||
arrows: false,
|
||||
infinite: false,
|
||||
draggable: false,
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
rtl: window.FleetCart.rtl,
|
||||
});
|
||||
},
|
||||
|
||||
initGalleryThumbnailSlider() {
|
||||
return $(".product-gallery-thumbnail")
|
||||
.on("setPosition", (_, slick) => {
|
||||
if (slick.slideCount <= slick.options.slidesToShow) {
|
||||
slick.$slideTrack.css("transform", "");
|
||||
}
|
||||
})
|
||||
.slick({
|
||||
rows: 0,
|
||||
dots: false,
|
||||
arrows: true,
|
||||
infinite: false,
|
||||
slidesToShow: 6,
|
||||
slideToScroll: 1,
|
||||
focusOnSelect: true,
|
||||
rtl: window.FleetCart.rtl,
|
||||
asNavFor: $(".product-gallery-preview"),
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1601,
|
||||
settings: {
|
||||
slidesToShow: 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 992,
|
||||
settings: {
|
||||
slidesToShow: 6,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 577,
|
||||
settings: {
|
||||
slidesToShow: 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 451,
|
||||
settings: {
|
||||
slidesToShow: 4,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
|
||||
updateGallerySlider() {
|
||||
if (this.hasAnyMedia) {
|
||||
this.addNewGallerySlides();
|
||||
this.removeOldGallerySlides();
|
||||
} else {
|
||||
// Add empty placeholder slide if variant has no media
|
||||
this.addGalleryEmptySlide();
|
||||
this.removeOldGallerySlides();
|
||||
}
|
||||
|
||||
this.addGalleryEventListeners();
|
||||
},
|
||||
|
||||
addNewGallerySlides() {
|
||||
this.item.media.forEach(({ path }, index) => {
|
||||
this.addGalleryPreviewSlide(path, index);
|
||||
this.addGalleryThumbnailSlide(path, index);
|
||||
});
|
||||
},
|
||||
|
||||
addGalleryPreviewSlide(filePath, slideIndex) {
|
||||
galleryPreviewSlider.slick(
|
||||
"slickAdd",
|
||||
this.galleryPreviewSlideTemplate(filePath),
|
||||
slideIndex,
|
||||
true
|
||||
);
|
||||
},
|
||||
|
||||
addGalleryThumbnailSlide(filePath, slideIndex) {
|
||||
galleryThumbnailSlider.slick(
|
||||
"slickAdd",
|
||||
this.galleryThumbnailSlideTemplate(filePath),
|
||||
slideIndex,
|
||||
true
|
||||
);
|
||||
},
|
||||
|
||||
addGalleryEmptySlide() {
|
||||
const filePath = `${FleetCart.baseUrl}/build/assets/image-placeholder.png`;
|
||||
|
||||
galleryPreviewSlider.slick(
|
||||
"slickAdd",
|
||||
this.galleryPreviewEmptySlideTemplate(filePath),
|
||||
null,
|
||||
true
|
||||
);
|
||||
|
||||
galleryThumbnailSlider.slick(
|
||||
"slickAdd",
|
||||
this.galleryThumbnailEmptySlideTemplate(filePath),
|
||||
null,
|
||||
true
|
||||
);
|
||||
},
|
||||
|
||||
removeOldGallerySlides() {
|
||||
const slideCount =
|
||||
galleryPreviewSlider.slick("getSlick").slideCount - 1;
|
||||
|
||||
[...Array(this.oldMediaLength)].forEach((_, index) => {
|
||||
const slideIndex = slideCount - index;
|
||||
|
||||
galleryPreviewSlider.slick("slickRemove", slideIndex);
|
||||
galleryThumbnailSlider.slick("slickRemove", slideIndex);
|
||||
});
|
||||
},
|
||||
|
||||
addGalleryEventListeners() {
|
||||
this.$nextTick(() => {
|
||||
galleryThumbnailSlider.slick("refresh");
|
||||
galleryPreviewLightbox.reload();
|
||||
this.initGalleryPreviewZoom();
|
||||
});
|
||||
},
|
||||
|
||||
initGalleryPreviewZoom() {
|
||||
if (this.isMobileDevice()) {
|
||||
this.initGalleryPreviewMobileZoom();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.initGalleryPreviewDesktopZoom();
|
||||
},
|
||||
|
||||
initGalleryPreviewMobileZoom() {
|
||||
[
|
||||
...document.querySelectorAll(".gallery-preview-item > img"),
|
||||
].forEach((el) => {
|
||||
new Drift(el, {
|
||||
namespace: "mobile-drift",
|
||||
inlinePane: true,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
initGalleryPreviewDesktopZoom() {
|
||||
[
|
||||
...document.querySelectorAll(".gallery-preview-item > img"),
|
||||
].forEach((el) => {
|
||||
new Drift(el, {
|
||||
inlinePane: false,
|
||||
hoverBoundingBox: true,
|
||||
boundingBoxContainer: document.body,
|
||||
paneContainer: document.querySelector(".product-gallery"),
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
initGalleryPreviewLightbox() {
|
||||
return GLightbox({
|
||||
zoomable: true,
|
||||
preload: false,
|
||||
});
|
||||
},
|
||||
|
||||
galleryPreviewSlideTemplate(filePath) {
|
||||
return `
|
||||
<div class="gallery-preview-slide">
|
||||
<div class="gallery-preview-item">
|
||||
<img src="${filePath}" data-zoom="${filePath}" alt="${this.product.name}">
|
||||
|
||||
<a href="${filePath}" data-gallery="product-gallery-preview" class="gallery-view-icon glightbox">
|
||||
<i class="las la-search-plus"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
},
|
||||
|
||||
galleryThumbnailSlideTemplate(filePath) {
|
||||
return `
|
||||
<div class="gallery-thumbnail-slide">
|
||||
<div class="gallery-thumbnail-item">
|
||||
<img src="${filePath}" alt="${this.product.name}">
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
},
|
||||
|
||||
galleryPreviewEmptySlideTemplate(filePath) {
|
||||
return `
|
||||
<div class="gallery-preview-slide">
|
||||
<div class="gallery-preview-item">
|
||||
<img src="${filePath}" data-zoom="${filePath}" alt="${this.product.name}" class="image-placeholder">
|
||||
|
||||
<a href="${filePath}" data-gallery="product-gallery-preview" class="gallery-view-icon glightbox">
|
||||
<i class="las la-search-plus"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
},
|
||||
|
||||
galleryThumbnailEmptySlideTemplate(filePath) {
|
||||
return `
|
||||
<div class="gallery-thumbnail-slide">
|
||||
<div class="gallery-thumbnail-item">
|
||||
<img src="${filePath}" alt="${this.product.name}" class="image-placeholder">
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,61 @@
|
||||
export default {
|
||||
methods: {
|
||||
updateSelectTypeOptionValue(optionId, e) {
|
||||
this.$set(this.cartItemForm.options, optionId, $(e.target).val());
|
||||
|
||||
this.errors.clear(`options.${optionId}`);
|
||||
},
|
||||
|
||||
updateCheckboxTypeOptionValue(optionId, e) {
|
||||
let values = $(e.target)
|
||||
.parents(".variant-check")
|
||||
.find('input[type="checkbox"]:checked')
|
||||
.map((_, el) => {
|
||||
return el.value;
|
||||
});
|
||||
|
||||
this.$set(this.cartItemForm.options, optionId, values.get());
|
||||
},
|
||||
|
||||
customRadioTypeOptionValueIsActive(optionId, valueId) {
|
||||
if (!this.cartItemForm.options.hasOwnProperty(optionId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.cartItemForm.options[optionId] === valueId;
|
||||
},
|
||||
|
||||
syncCustomRadioTypeOptionValue(optionId, valueId) {
|
||||
if (this.customRadioTypeOptionValueIsActive(optionId, valueId)) {
|
||||
this.$delete(this.cartItemForm.options, optionId);
|
||||
} else {
|
||||
this.$set(this.cartItemForm.options, optionId, valueId);
|
||||
|
||||
this.errors.clear(`options.${optionId}`);
|
||||
}
|
||||
},
|
||||
|
||||
customCheckboxTypeOptionValueIsActive(optionId, valueId) {
|
||||
if (!this.cartItemForm.options.hasOwnProperty(optionId)) {
|
||||
this.$set(this.cartItemForm.options, optionId, []);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.cartItemForm.options[optionId].includes(valueId);
|
||||
},
|
||||
|
||||
syncCustomCheckboxTypeOptionValue(optionId, valueId) {
|
||||
if (this.customCheckboxTypeOptionValueIsActive(optionId, valueId)) {
|
||||
this.cartItemForm.options[optionId].splice(
|
||||
this.cartItemForm.options[optionId].indexOf(valueId),
|
||||
1
|
||||
);
|
||||
} else {
|
||||
this.cartItemForm.options[optionId].push(valueId);
|
||||
|
||||
this.errors.clear(`options.${optionId}`);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
export default {
|
||||
computed: {
|
||||
maxQuantity() {
|
||||
return this.item.is_in_stock && this.item.does_manage_stock
|
||||
? this.item.qty
|
||||
: null;
|
||||
},
|
||||
|
||||
isQtyIncreaseDisabled() {
|
||||
return (
|
||||
this.item.is_out_of_stock ||
|
||||
(this.maxQuantity !== null &&
|
||||
this.cartItemForm.qty >= this.item.qty) ||
|
||||
!this.isActiveItem
|
||||
);
|
||||
},
|
||||
|
||||
isQtyDecreaseDisabled() {
|
||||
return (
|
||||
this.item.is_out_of_stock ||
|
||||
this.cartItemForm.qty <= 1 ||
|
||||
!this.isActiveItem
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
updateQuantity(qty) {
|
||||
if (isNaN(qty) || qty < 1) {
|
||||
this.cartItemForm.qty = 1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.cartItemForm.qty = qty;
|
||||
|
||||
if (this.exceedsMaxStock(qty)) {
|
||||
this.cartItemForm.qty = this.item.qty;
|
||||
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
exceedsMaxStock(qty) {
|
||||
return this.item.does_manage_stock && this.item.qty < qty;
|
||||
},
|
||||
|
||||
reduceToMaxQuantity() {
|
||||
if (
|
||||
this.item.does_manage_stock &&
|
||||
this.cartItemForm.qty > this.item.qty
|
||||
) {
|
||||
this.cartItemForm.qty = this.item.qty;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,89 @@
|
||||
export default {
|
||||
computed: {
|
||||
totalReviews() {
|
||||
if (!this.reviews.total) {
|
||||
return this.reviewCount;
|
||||
}
|
||||
|
||||
return this.reviews.total;
|
||||
},
|
||||
|
||||
ratingPercent() {
|
||||
return (this.avgRating / 5) * 100;
|
||||
},
|
||||
|
||||
emptyReviews() {
|
||||
return this.totalReviews === 0;
|
||||
},
|
||||
|
||||
totalReviewPage() {
|
||||
return Math.ceil(this.reviews.total / 5);
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
this.fetchReviews();
|
||||
},
|
||||
|
||||
methods: {
|
||||
async fetchReviews() {
|
||||
this.fetchingReviews = true;
|
||||
|
||||
try {
|
||||
const response = await axios.get(
|
||||
route("products.reviews.index", {
|
||||
productId: this.product.id,
|
||||
page: this.currentReviewPage,
|
||||
})
|
||||
);
|
||||
|
||||
this.reviews = response.data;
|
||||
} catch (error) {
|
||||
this.$notify(error.response.data.message);
|
||||
} finally {
|
||||
this.fetchingReviews = false;
|
||||
}
|
||||
},
|
||||
|
||||
addNewReview() {
|
||||
this.addingNewReview = true;
|
||||
|
||||
axios
|
||||
.post(
|
||||
route("products.reviews.store", {
|
||||
productId: this.product.id,
|
||||
}),
|
||||
this.reviewForm
|
||||
)
|
||||
.then((response) => {
|
||||
this.reviewForm = {};
|
||||
this.reviews.total++;
|
||||
this.reviews.data.unshift(response.data);
|
||||
|
||||
this.$notify(
|
||||
this.$trans("storefront::product.review_submitted")
|
||||
);
|
||||
})
|
||||
.catch(({ response }) => {
|
||||
if (response.status === 422) {
|
||||
this.errors.record(response.data.errors);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.$notify(response.data.message);
|
||||
})
|
||||
.finally(() => {
|
||||
this.addingNewReview = false;
|
||||
|
||||
$(".captcha-field img").trigger("click");
|
||||
});
|
||||
},
|
||||
|
||||
changeReviewPage(page) {
|
||||
this.currentReviewPage = page;
|
||||
|
||||
this.fetchReviews();
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
import md5 from "blueimp-md5";
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
doesVariantExist(uid) {
|
||||
return this.product.variants.some(({ uids }) => uids.includes(uid));
|
||||
},
|
||||
|
||||
setOldMediaLength() {
|
||||
this.oldMediaLength = this.hasAnyMedia ? this.item.media.length : 1;
|
||||
},
|
||||
|
||||
setVariant() {
|
||||
const selectedUids = Object.values(this.cartItemForm.variations)
|
||||
.sort()
|
||||
.join(".");
|
||||
|
||||
const variant = this.product.variants.find(
|
||||
(variant) => variant.uids === selectedUids
|
||||
);
|
||||
|
||||
if (variant !== undefined) {
|
||||
this.item = { ...variant };
|
||||
|
||||
this.reduceToMaxQuantity();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Set empty variant data if variant does not exist
|
||||
const uid = md5(
|
||||
Object.values(this.cartItemForm.variations).sort().join(".")
|
||||
);
|
||||
|
||||
this.item = {
|
||||
uid,
|
||||
media: [],
|
||||
};
|
||||
},
|
||||
|
||||
setVariantSlug() {
|
||||
const url = route("products.show", {
|
||||
slug: this.product.slug,
|
||||
variant: this.item.uid,
|
||||
});
|
||||
|
||||
window.history.replaceState({}, "", url);
|
||||
},
|
||||
|
||||
updateVariantDetails() {
|
||||
this.setOldMediaLength();
|
||||
this.setVariant();
|
||||
this.setVariantSlug();
|
||||
this.updateGallerySlider();
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,106 @@
|
||||
export default {
|
||||
computed: {
|
||||
hasAnyVariationImage() {
|
||||
return this.variationImagePath !== null;
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
this.setActiveVariationsValue();
|
||||
},
|
||||
|
||||
methods: {
|
||||
isVariationValueEnabled(variationUid, variationIndex, valueUid) {
|
||||
// Check if enabled first variation values
|
||||
if (variationIndex === 0) {
|
||||
return this.doesVariantExist(valueUid);
|
||||
}
|
||||
|
||||
// Check if enabled variation values between first and last variation
|
||||
if (
|
||||
variationIndex > 0 &&
|
||||
variationIndex < this.product.variations.length - 1
|
||||
) {
|
||||
return this.doesVariantExist(valueUid);
|
||||
}
|
||||
|
||||
// Check if enabled last variation values
|
||||
if (variationIndex === this.product.variations.length - 1) {
|
||||
const variations = this.cartItemForm.variations;
|
||||
const valueUids = Object.values(variations).filter(
|
||||
(uid) => uid !== variations[variationUid]
|
||||
);
|
||||
|
||||
valueUids.push(valueUid);
|
||||
|
||||
return this.doesVariantExist(valueUids.sort().join("."));
|
||||
}
|
||||
},
|
||||
|
||||
setActiveVariationsValue() {
|
||||
if (!this.hasAnyVariant) return;
|
||||
|
||||
this.item.uids.split(".").forEach((uid) => {
|
||||
this.product.variations.some((variation) => {
|
||||
const value = variation.values.find(
|
||||
(value) => value.uid === uid
|
||||
);
|
||||
|
||||
if (value !== undefined) {
|
||||
this.$set(
|
||||
this.activeVariationValues,
|
||||
variation.uid,
|
||||
value.label
|
||||
);
|
||||
this.$set(
|
||||
this.cartItemForm.variations,
|
||||
variation.uid,
|
||||
uid
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
setActiveVariationValueLabel(variationIndex) {
|
||||
this.variationImagePath = null;
|
||||
|
||||
const variation = this.product.variations[variationIndex];
|
||||
const value = variation.values.find(
|
||||
(value) =>
|
||||
value.uid === this.cartItemForm.variations[variation.uid]
|
||||
);
|
||||
|
||||
this.$set(this.activeVariationValues, variation.uid, value.label);
|
||||
},
|
||||
|
||||
setVariationValueLabel(variationIndex, valueIndex) {
|
||||
const variation = this.product.variations[variationIndex];
|
||||
const value = variation.values[valueIndex];
|
||||
|
||||
if (!this.isMobileDevice() && variation.type === "image") {
|
||||
this.variationImagePath = value.image.path;
|
||||
}
|
||||
|
||||
this.$set(this.activeVariationValues, variation.uid, value.label);
|
||||
},
|
||||
|
||||
isActiveVariationValue(variationUid, valueUid) {
|
||||
if (!this.cartItemForm.variations.hasOwnProperty(variationUid)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.cartItemForm.variations[variationUid] === valueUid;
|
||||
},
|
||||
|
||||
syncVariationValue(variationUid, variationIndex, valueUid, valueIndex) {
|
||||
if (!this.isActiveVariationValue(variationUid, valueUid)) {
|
||||
this.$set(this.cartItemForm.variations, variationUid, valueUid);
|
||||
this.setVariationValueLabel(variationIndex, valueIndex);
|
||||
this.updateVariantDetails();
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,11 +1,11 @@
|
||||
import Vue from 'vue';
|
||||
import Vue from "vue";
|
||||
|
||||
export function notify(message, options = {}) {
|
||||
Vue.$toast.open({
|
||||
message,
|
||||
type: 'default',
|
||||
type: "default",
|
||||
duration: 3000,
|
||||
position: (screen.width < 992) ? 'bottom' : 'bottom-right',
|
||||
position: screen.width < 992 ? "bottom" : "bottom-right",
|
||||
...options,
|
||||
});
|
||||
}
|
||||
@@ -39,23 +39,31 @@ export function chunk(array, size) {
|
||||
export function slickPrevArrow() {
|
||||
if (window.FleetCart.rtl) {
|
||||
return `<div class="arrow-prev">
|
||||
<i class="las la-angle-right"></i> ${trans('storefront::layout.prev')}
|
||||
<i class="las la-angle-right"></i> ${trans(
|
||||
"storefront::layout.prev"
|
||||
)}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
return `<div class="arrow-prev">
|
||||
<i class="las la-angle-left"></i> ${trans('storefront::layout.prev')}
|
||||
<i class="las la-angle-left"></i> ${trans(
|
||||
"storefront::layout.prev"
|
||||
)}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
export function slickNextArrow() {
|
||||
if (window.FleetCart.rtl) {
|
||||
return `<div class="arrow-next">
|
||||
${trans('storefront::layout.next')} <i class="las la-angle-left"></i>
|
||||
${trans(
|
||||
"storefront::layout.next"
|
||||
)} <i class="las la-angle-left"></i>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
return `<div class="arrow-next">
|
||||
${trans('storefront::layout.next')} <i class="las la-angle-right"></i>
|
||||
${trans(
|
||||
"storefront::layout.next"
|
||||
)} <i class="las la-angle-right"></i>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
95
Themes/Storefront/resources/assets/public/js/main.js
Normal file
95
Themes/Storefront/resources/assets/public/js/main.js
Normal file
@@ -0,0 +1,95 @@
|
||||
import "./axios";
|
||||
import "./storefront";
|
||||
|
||||
import Vue from "vue";
|
||||
import store from "./store";
|
||||
import { notify, trans, chunk } from "./functions";
|
||||
import VueToast from "vue-toast-notification";
|
||||
import vClickOutside from "v-click-outside";
|
||||
import HeaderSearch from "./components/layout/HeaderSearch.vue";
|
||||
import ProductRating from "./components/ProductRating.vue";
|
||||
import LandscapeProducts from "./components/LandscapeProducts.vue";
|
||||
import DynamicTab from "./components/home/DynamicTab";
|
||||
import HomeFeatures from "./components/home/HomeFeatures.vue";
|
||||
import FeaturedCategories from "./components/home/FeaturedCategories.vue";
|
||||
import BannerThreeColumnFullWidth from "./components/home/BannerThreeColumnFullWidth.vue";
|
||||
import ProductTabsOne from "./components/home/ProductTabsOne.vue";
|
||||
import TopBrands from "./components/home/TopBrands.vue";
|
||||
import BannerTwoColumn from "./components/home/BannerTwoColumn.vue";
|
||||
import ProductGrid from "./components/home/ProductGrid.vue";
|
||||
import BannerThreeColumn from "./components/home/BannerThreeColumn.vue";
|
||||
import ProductTabsTwo from "./components/home/ProductTabsTwo.vue";
|
||||
import BannerOneColumn from "./components/home/BannerOneColumn.vue";
|
||||
import NewsletterSubscription from "./components/layout/NewsletterSubscription";
|
||||
import ProductIndex from "./components/products/Index";
|
||||
import ProductCardGridView from "./components/products/index/ProductCardGridView.vue";
|
||||
import ProductCardListView from "./components/products/index/ProductCardListView.vue";
|
||||
import ProductCardVertical from "./components/ProductCardVertical.vue";
|
||||
import ProductShow from "./components/products/Show";
|
||||
import CartIndex from "./components/cart/Index";
|
||||
import CheckoutCreate from "./components/checkout/Create";
|
||||
import CompareIndex from "./components/compare/Index";
|
||||
import MyWishlist from "./components/account/wishlist/Index";
|
||||
import MyReviews from "./components/account/reviews/Index";
|
||||
import MyAddresses from "./components/account/addresses/Index";
|
||||
|
||||
Vue.prototype.route = route;
|
||||
Vue.prototype.$notify = notify;
|
||||
Vue.prototype.$trans = trans;
|
||||
Vue.prototype.$chunk = chunk;
|
||||
|
||||
Vue.use(VueToast);
|
||||
Vue.use(vClickOutside);
|
||||
|
||||
Vue.component("header-search", HeaderSearch);
|
||||
Vue.component("product-rating", ProductRating);
|
||||
Vue.component("sidebar-cart", () => import("./components/layout/SidebarCart"));
|
||||
Vue.component("newsletter-popup", () =>
|
||||
import("./components/layout/NewsletterPopup")
|
||||
);
|
||||
Vue.component("newsletter-subscription", NewsletterSubscription);
|
||||
Vue.component("cookie-bar", () => import("./components/layout/CookieBar"));
|
||||
Vue.component("landscape-products", LandscapeProducts);
|
||||
Vue.component("dynamic-tab", DynamicTab);
|
||||
Vue.component("home-features", HomeFeatures);
|
||||
Vue.component("featured-categories", FeaturedCategories);
|
||||
Vue.component("banner-three-column-full-width", BannerThreeColumnFullWidth);
|
||||
Vue.component("product-tabs-one", ProductTabsOne);
|
||||
Vue.component("top-brands", TopBrands);
|
||||
Vue.component("flash-sale-and-vertical-products", () =>
|
||||
import("./components/home/FlashSaleAndVerticalProducts.vue")
|
||||
);
|
||||
Vue.component("banner-two-column", BannerTwoColumn);
|
||||
Vue.component("product-grid", ProductGrid);
|
||||
Vue.component("banner-three-column", BannerThreeColumn);
|
||||
Vue.component("product-tabs-two", ProductTabsTwo);
|
||||
Vue.component("banner-one-column", BannerOneColumn);
|
||||
Vue.component("product-index", ProductIndex);
|
||||
Vue.component("product-card-grid-view", ProductCardGridView);
|
||||
Vue.component("product-card-list-view", ProductCardListView);
|
||||
Vue.component("product-card-vertical", ProductCardVertical);
|
||||
Vue.component("product-show", ProductShow);
|
||||
Vue.component("cart-index", CartIndex);
|
||||
Vue.component("checkout-create", CheckoutCreate);
|
||||
Vue.component("compare-index", CompareIndex);
|
||||
Vue.component("my-wishlist", MyWishlist);
|
||||
Vue.component("my-reviews", MyReviews);
|
||||
Vue.component("my-addresses", MyAddresses);
|
||||
|
||||
new Vue({
|
||||
el: "#app",
|
||||
|
||||
computed: {
|
||||
compareCount() {
|
||||
return store.compareCount();
|
||||
},
|
||||
|
||||
wishlistCount() {
|
||||
return store.wishlistCount();
|
||||
},
|
||||
|
||||
cart() {
|
||||
return store.state.cart;
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
import store from '../store';
|
||||
import store from "../store";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@@ -21,7 +21,7 @@ export default {
|
||||
},
|
||||
|
||||
cartIsNotEmpty() {
|
||||
return ! store.cartIsEmpty();
|
||||
return !store.cartIsEmpty();
|
||||
},
|
||||
|
||||
hasShippingMethod() {
|
||||
@@ -39,45 +39,48 @@ export default {
|
||||
|
||||
methods: {
|
||||
applyCoupon() {
|
||||
if (! this.couponCode) {
|
||||
if (!this.couponCode) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.loadingOrderSummary = true;
|
||||
this.applyingCoupon = true;
|
||||
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: route('cart.coupon.store', { coupon: this.couponCode }),
|
||||
}).then((cart) => {
|
||||
this.couponCode = null;
|
||||
axios
|
||||
.post(route("cart.coupon.store"), { coupon: this.couponCode })
|
||||
.then((response) => {
|
||||
this.couponCode = null;
|
||||
this.couponError = null;
|
||||
|
||||
store.updateCart(cart);
|
||||
}).catch((xhr) => {
|
||||
this.couponError = xhr.responseJSON.message;
|
||||
}).always(() => {
|
||||
this.loadingOrderSummary = false;
|
||||
this.applyingCoupon = false;
|
||||
});
|
||||
store.updateCart(response.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.couponError = error.response.data.message;
|
||||
})
|
||||
.finally(() => {
|
||||
this.loadingOrderSummary = false;
|
||||
this.applyingCoupon = false;
|
||||
});
|
||||
},
|
||||
|
||||
removeCoupon() {
|
||||
this.loadingOrderSummary = true;
|
||||
|
||||
$.ajax({
|
||||
method: 'DELETE',
|
||||
url: route('cart.coupon.destroy'),
|
||||
}).then((cart) => {
|
||||
store.updateCart(cart);
|
||||
}).catch((xhr) => {
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
}).always(() => {
|
||||
this.loadingOrderSummary = false;
|
||||
});
|
||||
axios
|
||||
.delete(route("cart.coupon.destroy"))
|
||||
.then((response) => {
|
||||
store.updateCart(response.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$notify(error.response.data.message);
|
||||
})
|
||||
.finally(() => {
|
||||
this.loadingOrderSummary = false;
|
||||
});
|
||||
},
|
||||
|
||||
updateShippingMethod(shippingMethodName) {
|
||||
if (! shippingMethodName) {
|
||||
async updateShippingMethod(shippingMethodName) {
|
||||
if (!shippingMethodName) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -85,16 +88,24 @@ export default {
|
||||
|
||||
this.changeShippingMethod(shippingMethodName);
|
||||
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: route('cart.shipping_method.store', { shipping_method: shippingMethodName }),
|
||||
}).then((cart) => {
|
||||
store.updateCart(cart);
|
||||
}).catch((xhr) => {
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
}).always(() => {
|
||||
try {
|
||||
const response = await axios.post(
|
||||
route("cart.shipping_method.store", {
|
||||
...(store.hasCoupon() && {
|
||||
coupon_code: store.getCoupon(),
|
||||
}),
|
||||
}),
|
||||
{
|
||||
shipping_method: shippingMethodName,
|
||||
}
|
||||
);
|
||||
|
||||
store.updateCart(response.data);
|
||||
} catch (error) {
|
||||
this.$notify(error.response.data.message);
|
||||
} finally {
|
||||
this.loadingOrderSummary = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
export default {
|
||||
methods: {
|
||||
productUrl({ product, variant }) {
|
||||
return route("products.show", {
|
||||
slug: product.slug,
|
||||
...(variant !== null && {
|
||||
variant: variant.uid,
|
||||
}),
|
||||
});
|
||||
},
|
||||
|
||||
hasBaseImage({ item }) {
|
||||
return item.base_image.length !== 0;
|
||||
},
|
||||
|
||||
baseImage(cartItem) {
|
||||
if (this.hasBaseImage(cartItem)) {
|
||||
return cartItem.item.base_image.path;
|
||||
}
|
||||
|
||||
return `${window.FleetCart.baseUrl}/build/assets/image-placeholder.png`;
|
||||
},
|
||||
|
||||
optionValues(option) {
|
||||
let values = [];
|
||||
|
||||
for (let value of option.values) {
|
||||
values.push(value.label);
|
||||
}
|
||||
|
||||
return values.join(", ");
|
||||
},
|
||||
|
||||
maxQuantity({ item }) {
|
||||
return item.is_in_stock && item.does_manage_stock ? item.qty : null;
|
||||
},
|
||||
|
||||
exceedsMaxStock({ item, qty }) {
|
||||
return item.does_manage_stock && item.qty < qty;
|
||||
},
|
||||
|
||||
isQtyIncreaseDisabled(cartItem) {
|
||||
return (
|
||||
this.maxQuantity(cartItem) !== null &&
|
||||
cartItem.qty >= cartItem.item.qty
|
||||
);
|
||||
},
|
||||
|
||||
changeQuantity(cartItem, qty) {
|
||||
if (isNaN(qty) || qty < 1) {
|
||||
qty = 1;
|
||||
|
||||
this.updateCart(cartItem, qty);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
cartItem.qty = qty;
|
||||
|
||||
if (this.exceedsMaxStock(cartItem)) {
|
||||
qty = cartItem.item.qty;
|
||||
|
||||
this.updateCart(cartItem, qty);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateCart(cartItem, qty);
|
||||
},
|
||||
|
||||
updateQuantity(cartItem, qty) {
|
||||
if (isNaN(qty) || qty < 1) {
|
||||
qty = 1;
|
||||
cartItem.qty = 1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
cartItem.qty = qty;
|
||||
|
||||
if (this.exceedsMaxStock(cartItem)) {
|
||||
cartItem.qty = cartItem.item.qty;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateCart(cartItem, qty);
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -26,7 +26,7 @@ export default {
|
||||
};
|
||||
},
|
||||
|
||||
change(activeTab) {
|
||||
async change(activeTab) {
|
||||
if (this.activeTab === activeTab || activeTab === undefined) {
|
||||
return;
|
||||
}
|
||||
@@ -34,20 +34,17 @@ export default {
|
||||
this.loading = true;
|
||||
this.activeTab = activeTab;
|
||||
|
||||
$.ajax({
|
||||
method: "GET",
|
||||
url: activeTab.url,
|
||||
}).then((products) => {
|
||||
if (this.selector().hasClass("slick-initialized")) {
|
||||
this.selector().slick("unslick");
|
||||
}
|
||||
const response = await axios.get(activeTab.url);
|
||||
|
||||
this.products = products;
|
||||
this.loading = false;
|
||||
if (this.selector().hasClass("slick-initialized")) {
|
||||
this.selector().slick("unslick");
|
||||
}
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.selector().slick(this.slickOptions());
|
||||
});
|
||||
this.products = response.data;
|
||||
this.loading = false;
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.selector().slick(this.slickOptions());
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
@@ -9,7 +9,16 @@ export default {
|
||||
|
||||
computed: {
|
||||
productUrl() {
|
||||
return route("products.show", this.product.slug);
|
||||
return route("products.show", {
|
||||
slug: this.product.slug,
|
||||
...(this.hasAnyVariant && {
|
||||
variant: this.item.uid,
|
||||
}),
|
||||
});
|
||||
},
|
||||
|
||||
hasAnyVariant() {
|
||||
return this.product.variant !== null;
|
||||
},
|
||||
|
||||
hasAnyOption() {
|
||||
@@ -20,16 +29,18 @@ export default {
|
||||
return !this.hasAnyOption;
|
||||
},
|
||||
|
||||
hasAnyMedia() {
|
||||
return this.item.media.length !== 0;
|
||||
},
|
||||
|
||||
hasBaseImage() {
|
||||
return this.product.base_image.length !== 0;
|
||||
return this.item.base_image.length !== 0;
|
||||
},
|
||||
|
||||
baseImage() {
|
||||
if (this.hasBaseImage) {
|
||||
return this.product.base_image.path;
|
||||
}
|
||||
|
||||
return `${window.FleetCart.baseUrl}/themes/storefront/public/images/image-placeholder.png`;
|
||||
return this.hasBaseImage
|
||||
? this.item.base_image.path
|
||||
: `${window.FleetCart.baseUrl}/build/assets/image-placeholder.png`;
|
||||
},
|
||||
|
||||
inWishlist() {
|
||||
@@ -53,24 +64,27 @@ export default {
|
||||
addToCart() {
|
||||
this.addingToCart = true;
|
||||
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: route("cart.items.store", {
|
||||
product_id: this.product.id,
|
||||
qty: 1,
|
||||
}),
|
||||
})
|
||||
.then((cart) => {
|
||||
store.updateCart(cart);
|
||||
axios
|
||||
.post(
|
||||
route("cart.items.store", {
|
||||
product_id: this.product.id,
|
||||
qty: 1,
|
||||
...(this.hasAnyVariant && {
|
||||
variant_id: this.item.id,
|
||||
}),
|
||||
})
|
||||
)
|
||||
.then((response) => {
|
||||
store.updateCart(response.data);
|
||||
|
||||
if (document.location.href !== route("cart.index")) {
|
||||
$(".header-cart").trigger("click");
|
||||
}
|
||||
})
|
||||
.catch((xhr) => {
|
||||
this.$notify(xhr.responseJSON.message);
|
||||
.catch((error) => {
|
||||
this.$notify(error.response.data.message);
|
||||
})
|
||||
.always(() => {
|
||||
.finally(() => {
|
||||
this.addingToCart = false;
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,19 +1,44 @@
|
||||
export default {
|
||||
methods: {
|
||||
productUrl(product) {
|
||||
return route('products.show', product.slug);
|
||||
return route("products.show", {
|
||||
slug: product.slug,
|
||||
...(this.hasAnyVariant(product) && {
|
||||
variant: product.variant.uid,
|
||||
}),
|
||||
});
|
||||
},
|
||||
|
||||
hasAnyVariant(product) {
|
||||
return product.variant !== null;
|
||||
},
|
||||
|
||||
hasBaseImage(product) {
|
||||
return product.base_image.length !== 0;
|
||||
return this.hasAnyVariant(product)
|
||||
? product.variant.base_image.length !== 0
|
||||
: product.base_image.length !== 0;
|
||||
},
|
||||
|
||||
baseImage(product) {
|
||||
if (this.hasBaseImage(product)) {
|
||||
return product.base_image.path;
|
||||
return this.hasAnyVariant(product)
|
||||
? product.variant.base_image.path
|
||||
: product.base_image.path;
|
||||
}
|
||||
|
||||
return `${window.FleetCart.baseUrl}/themes/storefront/public/images/image-placeholder.png`;
|
||||
return `${window.FleetCart.baseUrl}/build/assets/image-placeholder.png`;
|
||||
},
|
||||
|
||||
productPrice(product) {
|
||||
return this.hasAnyVariant(product)
|
||||
? product.variant.formatted_price
|
||||
: product.formatted_price;
|
||||
},
|
||||
|
||||
productIsInStock(product) {
|
||||
return this.hasAnyVariant(product)
|
||||
? product.variant.is_in_stock
|
||||
: product.is_in_stock;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ export default {
|
||||
cart: FleetCart.cart,
|
||||
wishlist: FleetCart.wishlist,
|
||||
compareList: FleetCart.compareList,
|
||||
coupon: {},
|
||||
}),
|
||||
|
||||
cartIsEmpty() {
|
||||
@@ -14,6 +15,8 @@ export default {
|
||||
|
||||
updateCart(cart) {
|
||||
this.state.cart = cart;
|
||||
|
||||
this.setCoupon(cart);
|
||||
},
|
||||
|
||||
removeCartItem(cartItem) {
|
||||
@@ -30,6 +33,24 @@ export default {
|
||||
);
|
||||
},
|
||||
|
||||
hasCoupon() {
|
||||
return this.state.cart.coupon.hasOwnProperty("code");
|
||||
},
|
||||
|
||||
getCoupon() {
|
||||
return this.state.cart.coupon.code;
|
||||
},
|
||||
|
||||
setCoupon(cart) {
|
||||
if (cart.coupon.code) {
|
||||
this.state.cart.coupon = cart.coupon;
|
||||
}
|
||||
},
|
||||
|
||||
compareCount() {
|
||||
return this.state.compareList.length;
|
||||
},
|
||||
|
||||
wishlistCount() {
|
||||
return this.state.wishlist.length;
|
||||
},
|
||||
@@ -46,27 +67,22 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
addToWishlist(productId) {
|
||||
async addToWishlist(productId) {
|
||||
if (FleetCart.loggedIn) {
|
||||
this.state.wishlist.push(productId);
|
||||
} else {
|
||||
return (window.location.href = route("login"));
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: route("wishlist.store"),
|
||||
data: { productId },
|
||||
await axios.post(route("wishlist.store"), {
|
||||
productId,
|
||||
});
|
||||
},
|
||||
|
||||
removeFromWishlist(productId) {
|
||||
this.state.wishlist.splice(this.state.wishlist.indexOf(productId), 1);
|
||||
|
||||
$.ajax({
|
||||
method: "DELETE",
|
||||
url: route("wishlist.destroy", { productId }),
|
||||
});
|
||||
axios.delete(route("wishlist.destroy", { productId }));
|
||||
},
|
||||
|
||||
inCompareList(productId) {
|
||||
@@ -84,22 +100,17 @@ export default {
|
||||
addToCompareList(productId) {
|
||||
this.state.compareList.push(productId);
|
||||
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: route("compare.store"),
|
||||
data: { productId },
|
||||
axios.post(route("compare.store"), {
|
||||
productId,
|
||||
});
|
||||
},
|
||||
|
||||
removeFromCompareList(productId) {
|
||||
async removeFromCompareList(productId) {
|
||||
this.state.compareList.splice(
|
||||
this.state.compareList.indexOf(productId),
|
||||
1
|
||||
);
|
||||
|
||||
$.ajax({
|
||||
method: "DELETE",
|
||||
url: route("compare.destroy", { productId }),
|
||||
});
|
||||
await axios.delete(route("compare.destroy", { productId }));
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,87 +1,65 @@
|
||||
require('./vendors/vendors');
|
||||
import "./vendors/vendors";
|
||||
|
||||
$(() => {
|
||||
|
||||
/* variables
|
||||
/*----------------------------------------*/
|
||||
|
||||
let _window = $(window),
|
||||
body = $('body');
|
||||
body = $("body");
|
||||
|
||||
/* button loading
|
||||
/*----------------------------------------*/
|
||||
|
||||
$('[data-loading]').on('click', (e) => {
|
||||
e.currentTarget.classList.add('btn-loading');
|
||||
$("[data-loading]").on("click", (e) => {
|
||||
e.currentTarget.classList.add("btn-loading");
|
||||
});
|
||||
|
||||
/* select option
|
||||
/*----------------------------------------*/
|
||||
|
||||
let select = $('.custom-select-option');
|
||||
let select = $(".custom-select-option");
|
||||
|
||||
select.niceSelect();
|
||||
|
||||
select.on('change', (e) => {
|
||||
e.target.dispatchEvent(new Event('nice-select-updated', { bubbles: true }));
|
||||
select.on("change", (e) => {
|
||||
e.target.dispatchEvent(
|
||||
new Event("nice-select-updated", { bubbles: true })
|
||||
);
|
||||
});
|
||||
|
||||
/* overlay
|
||||
/*----------------------------------------*/
|
||||
|
||||
let overlay = $('.overlay');
|
||||
|
||||
/* sidebar cart
|
||||
/*----------------------------------------*/
|
||||
|
||||
let headerCart = $('.header-column-right .header-cart'),
|
||||
sidebarCart = $('.sidebar-cart-wrap'),
|
||||
sidebarCartClose = $('.sidebar-cart-close');
|
||||
|
||||
headerCart.on('click', (e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
overlay.addClass('active');
|
||||
sidebarCart.addClass('active');
|
||||
});
|
||||
|
||||
sidebarCartClose.on('click', () => {
|
||||
overlay.removeClass('active');
|
||||
sidebarCart.removeClass('active');
|
||||
});
|
||||
|
||||
sidebarCart.on('click', (e) => {
|
||||
e.stopPropagation();
|
||||
});
|
||||
let overlay = $(".overlay");
|
||||
|
||||
/* header
|
||||
/*----------------------------------------*/
|
||||
|
||||
let headerWrap = $('.header-wrap'),
|
||||
headerWrapInner = $('.header-wrap-inner'),
|
||||
let headerWrap = $(".header-wrap"),
|
||||
headerWrapInner = $(".header-wrap-inner"),
|
||||
headerWrapInnerHeight = headerWrapInner.outerHeight(),
|
||||
headerSearchSm = $('.header-search-sm'),
|
||||
searchInputSm = $('.search-input-sm'),
|
||||
headerSearchSmClose = $('.header-search-sm-form .btn-close');
|
||||
headerSearchSm = $(".header-search-sm"),
|
||||
searchInputSm = $(".search-input-sm"),
|
||||
headerSearchSmClose = $(".header-search-sm-form .btn-close");
|
||||
|
||||
headerSearchSm.on('click', (e) => {
|
||||
headerSearchSm.on("click", (e) => {
|
||||
let target = $(e.currentTarget);
|
||||
|
||||
target.parents('.header-search').next().toggleClass('active');
|
||||
searchInputSm.focus();
|
||||
target.parents(".header-search").next().toggleClass("active");
|
||||
searchInputSm.trigger("focus");
|
||||
});
|
||||
|
||||
headerSearchSmClose.on('click', (e) => {
|
||||
headerSearchSmClose.on("click", (e) => {
|
||||
let target = $(e.currentTarget);
|
||||
|
||||
target.parents('.header-search-sm-form').removeClass('active');
|
||||
target.parents(".header-search-sm-form").removeClass("active");
|
||||
});
|
||||
|
||||
_window.on('resize', () => {
|
||||
_window.on("resize", () => {
|
||||
headerWrapInnerHeight = headerWrapInner.outerHeight();
|
||||
});
|
||||
|
||||
_window.on('load scroll resize', () => {
|
||||
_window.on("load scroll resize", () => {
|
||||
let headerWrapHeight = headerWrap.outerHeight(),
|
||||
headerWrapOffsetTop = headerWrap.offset().top + headerWrapHeight;
|
||||
|
||||
@@ -89,18 +67,18 @@ $(() => {
|
||||
let scrollTop = _window.scrollTop();
|
||||
|
||||
if (scrollTop > headerWrapOffsetTop) {
|
||||
headerWrap.css('padding-top', `${headerWrapInnerHeight}px`);
|
||||
headerWrapInner.addClass('sticky');
|
||||
headerWrap.css("padding-top", `${headerWrapInnerHeight}px`);
|
||||
headerWrapInner.addClass("sticky");
|
||||
|
||||
setTimeout(() => {
|
||||
headerWrapInner.addClass('show');
|
||||
headerWrapInner.addClass("show");
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
headerWrap.css('padding-top', 0);
|
||||
headerWrapInner.removeClass('sticky show');
|
||||
headerWrap.css("padding-top", 0);
|
||||
headerWrapInner.removeClass("sticky show");
|
||||
}
|
||||
|
||||
stickyHeader();
|
||||
@@ -109,9 +87,9 @@ $(() => {
|
||||
/* menu dropdown arrow
|
||||
/*----------------------------------------*/
|
||||
|
||||
let megaMenuItem = $('.mega-menu > li'),
|
||||
subMenuDropdown = $('.sub-menu > .dropdown'),
|
||||
sidebarMenuSubMenu = $('.sidebar-menu .sub-menu');
|
||||
let megaMenuItem = $(".mega-menu > li"),
|
||||
subMenuDropdown = $(".sub-menu > .dropdown"),
|
||||
sidebarMenuSubMenu = $(".sidebar-menu .sub-menu");
|
||||
|
||||
function menuDropdownArrow(parentSelector, childSelector) {
|
||||
parentSelector.each(function () {
|
||||
@@ -119,38 +97,42 @@ $(() => {
|
||||
|
||||
if (self.children().length > 1) {
|
||||
if (window.FleetCart.rtl) {
|
||||
self.children(`${childSelector}`).append('<i class="las la-angle-left"></i>');
|
||||
self.children(`${childSelector}`).append(
|
||||
'<i class="las la-angle-left"></i>'
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
self.children(`${childSelector}`).append('<i class="las la-angle-right"></i>');
|
||||
self.children(`${childSelector}`).append(
|
||||
'<i class="las la-angle-right"></i>'
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
menuDropdownArrow(subMenuDropdown, 'a');
|
||||
menuDropdownArrow(megaMenuItem, '.menu-item');
|
||||
menuDropdownArrow(subMenuDropdown, "a");
|
||||
menuDropdownArrow(megaMenuItem, ".menu-item");
|
||||
|
||||
/* navigation
|
||||
/*----------------------------------------*/
|
||||
|
||||
let moreCategories = $('.more-categories'),
|
||||
categoryDropdown = $('.category-dropdown'),
|
||||
categoryNavInner = $('.category-nav-inner'),
|
||||
categoryDropdownWrap = $('.category-dropdown-wrap'),
|
||||
verticalMegaMenuList = $('.vertical-megamenu > li');
|
||||
let moreCategories = $(".more-categories"),
|
||||
categoryDropdown = $(".category-dropdown"),
|
||||
categoryNavInner = $(".category-nav-inner"),
|
||||
categoryDropdownWrap = $(".category-dropdown-wrap"),
|
||||
verticalMegaMenuList = $(".vertical-megamenu > li");
|
||||
|
||||
categoryNavInner.on('click', () => {
|
||||
categoryDropdownWrap.toggleClass('show');
|
||||
categoryNavInner.on("click", () => {
|
||||
categoryDropdownWrap.toggleClass("show");
|
||||
});
|
||||
|
||||
_window.on('load resize', () => {
|
||||
_window.on("load resize", () => {
|
||||
let verticalMegaMenuListHeight = 0,
|
||||
homeSliderHeight = homeSlider.height(),
|
||||
categoryDropdownHeight = homeSliderHeight;
|
||||
|
||||
categoryDropdown.css('height', `${categoryDropdownHeight}px`);
|
||||
categoryDropdown.css("height", `${categoryDropdownHeight}px`);
|
||||
|
||||
verticalMegaMenuList.each(function () {
|
||||
let self = $(this);
|
||||
@@ -158,52 +140,52 @@ $(() => {
|
||||
verticalMegaMenuListHeight += self.height();
|
||||
|
||||
if (verticalMegaMenuListHeight + 78 > categoryDropdownHeight) {
|
||||
self.addClass('hide');
|
||||
moreCategories.removeClass('hide');
|
||||
self.addClass("hide");
|
||||
moreCategories.removeClass("hide");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
self.removeClass('hide');
|
||||
moreCategories.addClass('hide');
|
||||
self.removeClass("hide");
|
||||
moreCategories.addClass("hide");
|
||||
});
|
||||
});
|
||||
|
||||
/* sidebar menu
|
||||
/*----------------------------------------*/
|
||||
|
||||
let sidebarMenuIcon = $('.sidebar-menu-icon'),
|
||||
sidebarMenuWrap = $('.sidebar-menu-wrap'),
|
||||
sidebarMenuClose = $('.sidebar-menu-close'),
|
||||
sidebarMenuTab = $('.sidebar-menu-tab a'),
|
||||
sidebarMenuList = $('.sidebar-menu li'),
|
||||
sidebarMenuLink = $('.sidebar-menu > li > a'),
|
||||
sidebarMenuListUl = $('.sidebar-menu > li > ul'),
|
||||
sidebarMenuDropdown = $('.sidebar-menu > .dropdown'),
|
||||
sidebarMenuSubMenuUl = $('.sidebar-menu .sub-menu ul'),
|
||||
sidebarMenuSubMenuLink = $('.sidebar-menu .sub-menu > a');
|
||||
let sidebarMenuIcon = $(".sidebar-menu-icon"),
|
||||
sidebarMenuWrap = $(".sidebar-menu-wrap"),
|
||||
sidebarMenuClose = $(".sidebar-menu-close"),
|
||||
sidebarMenuTab = $(".sidebar-menu-tab a"),
|
||||
sidebarMenuList = $(".sidebar-menu li"),
|
||||
sidebarMenuLink = $(".sidebar-menu > li > a"),
|
||||
sidebarMenuListUl = $(".sidebar-menu > li > ul"),
|
||||
sidebarMenuDropdown = $(".sidebar-menu > .dropdown"),
|
||||
sidebarMenuSubMenuUl = $(".sidebar-menu .sub-menu ul"),
|
||||
sidebarMenuSubMenuLink = $(".sidebar-menu .sub-menu > a");
|
||||
|
||||
sidebarMenuIcon.on('click', (e) => {
|
||||
sidebarMenuIcon.on("click", (e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
overlay.addClass('active');
|
||||
sidebarMenuWrap.addClass('active');
|
||||
overlay.addClass("active");
|
||||
sidebarMenuWrap.addClass("active");
|
||||
});
|
||||
|
||||
sidebarMenuClose.on('click', (e) => {
|
||||
overlay.removeClass('active');
|
||||
sidebarMenuWrap.removeClass('active');
|
||||
sidebarMenuClose.on("click", (e) => {
|
||||
overlay.removeClass("active");
|
||||
sidebarMenuWrap.removeClass("active");
|
||||
});
|
||||
|
||||
sidebarMenuWrap.on('click', (e) => {
|
||||
sidebarMenuWrap.on("click", (e) => {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
sidebarMenuTab.on('click', (e) => {
|
||||
sidebarMenuTab.on("click", (e) => {
|
||||
let target = $(e.currentTarget);
|
||||
|
||||
e.preventDefault();
|
||||
target.tab('show');
|
||||
target.tab("show");
|
||||
});
|
||||
|
||||
sidebarMenuList.each(function () {
|
||||
@@ -211,191 +193,131 @@ $(() => {
|
||||
|
||||
if (self.children().length > 1) {
|
||||
if (window.FleetCart.rtl) {
|
||||
self.children('a').after('<i class="las la-angle-left"></i>');
|
||||
self.children("a").after('<i class="las la-angle-left"></i>');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
self.children('a').after('<i class="las la-angle-right"></i>');
|
||||
self.children("a").after('<i class="las la-angle-right"></i>');
|
||||
}
|
||||
});
|
||||
|
||||
sidebarMenuDropdown.on('click', (e) => {
|
||||
sidebarMenuDropdown.on("click", (e) => {
|
||||
let target = $(e.currentTarget);
|
||||
|
||||
if (! target.hasClass('active')) {
|
||||
$('.sidebar-menu > li').removeClass('active');
|
||||
target.addClass('active');
|
||||
if (!target.hasClass("active")) {
|
||||
$(".sidebar-menu > li").removeClass("active");
|
||||
target.addClass("active");
|
||||
} else {
|
||||
$('.sidebar-menu > li').removeClass('active');
|
||||
$(".sidebar-menu > li").removeClass("active");
|
||||
}
|
||||
|
||||
if (! target.children('ul').hasClass('open')) {
|
||||
$('.sidebar-menu .open').removeClass('open').slideUp(300);
|
||||
target.children('ul').addClass('open').slideDown(300);
|
||||
if (!target.children("ul").hasClass("open")) {
|
||||
$(".sidebar-menu .open").removeClass("open").slideUp(300);
|
||||
target.children("ul").addClass("open").slideDown(300);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$('.sidebar-menu .open').removeClass('open').slideUp(300);
|
||||
$(".sidebar-menu .open").removeClass("open").slideUp(300);
|
||||
});
|
||||
|
||||
sidebarMenuLink.on('click', (e) => {
|
||||
sidebarMenuLink.on("click", (e) => {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
sidebarMenuListUl.on('click', (e) => {
|
||||
sidebarMenuListUl.on("click", (e) => {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
sidebarMenuSubMenu.on('click', (e) => {
|
||||
sidebarMenuSubMenu.on("click", (e) => {
|
||||
let target = $(e.currentTarget);
|
||||
|
||||
if (! target.hasClass('active')) {
|
||||
target.addClass('active');
|
||||
if (!target.hasClass("active")) {
|
||||
target.addClass("active");
|
||||
} else {
|
||||
target.removeClass('active');
|
||||
target.removeClass("active");
|
||||
}
|
||||
|
||||
target.children('ul').slideToggle(300);
|
||||
target.children("ul").slideToggle(300);
|
||||
});
|
||||
|
||||
sidebarMenuSubMenuUl.on('click', function (e) {
|
||||
sidebarMenuSubMenuUl.on("click", function (e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
sidebarMenuSubMenuLink.on('click', (e) => {
|
||||
sidebarMenuSubMenuLink.on("click", (e) => {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
/* slider
|
||||
/*----------------------------------------*/
|
||||
|
||||
let homeSlider = $('.home-slider');
|
||||
const homeSlider = $(".home-slider");
|
||||
|
||||
if (homeSlider.length !== 0) {
|
||||
homeSlider.slick({
|
||||
rows: 0,
|
||||
rtl: window.FleetCart.rtl,
|
||||
cssEase: 'ease',
|
||||
speed: Number(homeSlider.data('speed')),
|
||||
fade: !! JSON.parse(homeSlider.data('fade')),
|
||||
dots: !! JSON.parse(homeSlider.data('dots')),
|
||||
arrows: !! JSON.parse(homeSlider.data('arrows')),
|
||||
autoplay: !! JSON.parse(homeSlider.data('autoplay')),
|
||||
autoplaySpeed: Number(homeSlider.data('autoplay-speed')),
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 768,
|
||||
settings: {
|
||||
dots: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
}).slickAnimation();
|
||||
const { speed, autoplay, autoplaySpeed, fade, dots, arrows } =
|
||||
homeSlider.data();
|
||||
|
||||
homeSlider
|
||||
.slick({
|
||||
rows: 0,
|
||||
rtl: window.FleetCart.rtl,
|
||||
cssEase: fade ? "cubic-bezier(0.7, 0, 0.3, 1)" : "ease",
|
||||
speed,
|
||||
autoplay,
|
||||
autoplaySpeed,
|
||||
fade,
|
||||
dots,
|
||||
arrows,
|
||||
})
|
||||
.slickAnimation();
|
||||
}
|
||||
|
||||
/* tooltip
|
||||
/*----------------------------------------*/
|
||||
|
||||
$('[data-toggle="tooltip"]').tooltip({
|
||||
trigger: 'hover',
|
||||
selector: '[data-toggle="tooltip"]',
|
||||
});
|
||||
|
||||
/* top brands
|
||||
/*----------------------------------------*/
|
||||
|
||||
let topBrands = $('.top-brands');
|
||||
|
||||
topBrands.slick({
|
||||
rows: 0,
|
||||
dots: false,
|
||||
arrows: true,
|
||||
infinite: true,
|
||||
slidesToShow: 7,
|
||||
slidesToScroll: 7,
|
||||
rtl: window.FleetCart.rtl,
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1200,
|
||||
settings: {
|
||||
slidesToShow: 6,
|
||||
slidesToScroll: 6,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 1050,
|
||||
settings: {
|
||||
slidesToShow: 5,
|
||||
slidesToScroll: 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 900,
|
||||
settings: {
|
||||
slidesToShow: 4,
|
||||
slidesToScroll: 4,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 750,
|
||||
settings: {
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
breakpoint: 600,
|
||||
settings: {
|
||||
slidesToShow: 2,
|
||||
slidesToScroll: 2,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
/* sidebar filter
|
||||
/*----------------------------------------*/
|
||||
|
||||
let mobileViewFilter = $('.mobile-view-filter');
|
||||
let filterSectionWrap = $('.filter-section-wrap');
|
||||
let sidebarFilterClose = $('.sidebar-filter-close');
|
||||
let mobileViewFilter = $(".mobile-view-filter");
|
||||
let filterSectionWrap = $(".filter-section-wrap");
|
||||
let sidebarFilterClose = $(".sidebar-filter-close");
|
||||
|
||||
mobileViewFilter.on('click', (e) => {
|
||||
mobileViewFilter.on("click", (e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
filterSectionWrap.addClass('active');
|
||||
overlay.addClass('active');
|
||||
filterSectionWrap.addClass("active");
|
||||
overlay.addClass("active");
|
||||
});
|
||||
|
||||
sidebarFilterClose.on('click', () => {
|
||||
filterSectionWrap.removeClass('active');
|
||||
overlay.removeClass('active');
|
||||
sidebarFilterClose.on("click", () => {
|
||||
filterSectionWrap.removeClass("active");
|
||||
overlay.removeClass("active");
|
||||
});
|
||||
|
||||
filterSectionWrap.on('click', (e) => {
|
||||
filterSectionWrap.on("click", (e) => {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
body.on('click', () => {
|
||||
overlay.removeClass('active');
|
||||
sidebarCart.removeClass('active');
|
||||
sidebarMenuWrap.removeClass('active');
|
||||
filterSectionWrap.removeClass('active');
|
||||
body.on("click", () => {
|
||||
overlay.removeClass("active");
|
||||
$(".sidebar-cart-wrap").removeClass("active");
|
||||
sidebarMenuWrap.removeClass("active");
|
||||
filterSectionWrap.removeClass("active");
|
||||
});
|
||||
|
||||
/* browse categories
|
||||
/*----------------------------------------*/
|
||||
|
||||
$('.browse-categories li').each((i, li) => {
|
||||
if ($(li).children('ul').length > 0) {
|
||||
$(li).addClass('parent');
|
||||
$(".browse-categories li").each((_, li) => {
|
||||
if ($(li).children("ul").length > 0) {
|
||||
$(li).addClass("parent");
|
||||
}
|
||||
});
|
||||
|
||||
let filterCategoriesLink = $('.browse-categories li.parent > a');
|
||||
let parentUls = $('.browse-categories li.active').parentsUntil('.browse-categories', 'ul');
|
||||
let filterCategoriesLink = $(".browse-categories li.parent > a");
|
||||
let parentUls = $(".browse-categories li.active").parentsUntil(
|
||||
".browse-categories",
|
||||
"ul"
|
||||
);
|
||||
|
||||
if (window.FleetCart.rtl) {
|
||||
filterCategoriesLink.before('<i class="las la-angle-left"></i>');
|
||||
@@ -403,129 +325,9 @@ $(() => {
|
||||
filterCategoriesLink.before('<i class="las la-angle-right"></i>');
|
||||
}
|
||||
|
||||
parentUls.show().siblings('i').addClass('open');
|
||||
parentUls.show().siblings("i").addClass("open");
|
||||
|
||||
$('.browse-categories li i').on('click', (e) => {
|
||||
$(e.currentTarget).toggleClass('open').siblings('ul').slideToggle(300);
|
||||
});
|
||||
|
||||
/* image gallery
|
||||
/*----------------------------------------*/
|
||||
|
||||
let baseImage = $('.base-image');
|
||||
|
||||
$('.additional-image-wrap').slick({
|
||||
rows: 0,
|
||||
dots: false,
|
||||
arrows: true,
|
||||
vertical: true,
|
||||
infinite: false,
|
||||
slidesToShow: 4,
|
||||
slideToScroll: 1,
|
||||
asNavFor: baseImage,
|
||||
focusOnSelect: true,
|
||||
adaptiveHeight: true,
|
||||
verticalSwiping: true,
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 577,
|
||||
settings: {
|
||||
vertical: false,
|
||||
variableWidth: true,
|
||||
verticalSwiping: false,
|
||||
rtl: window.FleetCart.rtl,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
baseImage.slick({
|
||||
rows: 0,
|
||||
fade: true,
|
||||
dots: false,
|
||||
swipe: false,
|
||||
arrows: false,
|
||||
infinite: false,
|
||||
draggable: false,
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
rtl: window.FleetCart.rtl,
|
||||
});
|
||||
|
||||
baseImage.slickLightbox({
|
||||
src: 'data-image',
|
||||
itemSelector: '.base-image-slide',
|
||||
slick: {
|
||||
fade: true,
|
||||
infinite: false,
|
||||
rtl: window.FleetCart.rtl,
|
||||
},
|
||||
});
|
||||
|
||||
$('.base-image-slide').zoom({
|
||||
magnify: 1.2,
|
||||
touch: false,
|
||||
});
|
||||
|
||||
/* number picker
|
||||
/*----------------------------------------*/
|
||||
|
||||
$('.btn-number').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
let type = $(this).attr('data-type');
|
||||
let input = $(this).closest('.input-group-quantity').find('input.input-quantity');
|
||||
let minValue = input.attr('min');
|
||||
let maxValue = input.attr('max');
|
||||
let currentValue = parseInt(input.val());
|
||||
|
||||
if (! $.isNumeric(currentValue)) {
|
||||
input.val(minValue);
|
||||
input[0].dispatchEvent(new Event('input'), { bubbles: true });
|
||||
}
|
||||
|
||||
if (type === 'minus') {
|
||||
if (currentValue > minValue) {
|
||||
input.val(currentValue - 1);
|
||||
input[0].dispatchEvent(new Event('input'), { bubbles: true });
|
||||
$('.btn-number.btn-plus').removeAttr('disabled');
|
||||
}
|
||||
|
||||
if (input.val() === minValue) {
|
||||
$(this).attr('disabled', true);
|
||||
}
|
||||
} else if (type === 'plus') {
|
||||
if (! maxValue || currentValue < maxValue) {
|
||||
input.val(currentValue + 1);
|
||||
input[0].dispatchEvent(new Event('input'), { bubbles: true });
|
||||
$('.btn-number.btn-minus').removeAttr('disabled');
|
||||
}
|
||||
|
||||
if (input.val() === maxValue) {
|
||||
$(this).attr('disabled', true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('.input-number').on('input', function () {
|
||||
let self = $(this);
|
||||
let minValue = parseInt(self.attr('min'));
|
||||
let maxValue = parseInt(self.attr('max'));
|
||||
let currentValue = parseInt(self.val());
|
||||
|
||||
if (! $.isNumeric(self.val())) {
|
||||
self.val(minValue);
|
||||
$('.btn-number.btn-minus').attr('disabled', true);
|
||||
}
|
||||
|
||||
if (currentValue < minValue) {
|
||||
self.val(minValue);
|
||||
$('.btn-number.btn-minus').attr('disabled', true);
|
||||
}
|
||||
|
||||
if (maxValue && currentValue > maxValue) {
|
||||
self.val(maxValue);
|
||||
$('.btn-number.btn-plus').attr('disabled', true);
|
||||
}
|
||||
$(".browse-categories li i").on("click", (e) => {
|
||||
$(e.currentTarget).toggleClass("open").siblings("ul").slideToggle(300);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
require('flatpickr');
|
||||
import "flatpickr";
|
||||
|
||||
for (let el of $('.datetime-picker')) {
|
||||
for (let el of $(".datetime-picker")) {
|
||||
$(el).flatpickr({
|
||||
mode: el.hasAttribute('data-range') ? 'range' : 'single',
|
||||
enableTime: el.hasAttribute('data-time'),
|
||||
noCalendar: el.hasAttribute('data-no-calender'),
|
||||
mode: el.hasAttribute("data-range") ? "range" : "single",
|
||||
enableTime: el.hasAttribute("data-time"),
|
||||
noCalendar: el.hasAttribute("data-no-calender"),
|
||||
altInput: true,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
window.$ = window.jQuery = require('jquery');
|
||||
|
||||
require('popper.js');
|
||||
require('bootstrap');
|
||||
require('jquery-nice-select');
|
||||
require('jquery-zoom');
|
||||
require('slick-carousel');
|
||||
require('slick-lightbox');
|
||||
require('./slick-animation.js');
|
||||
require('../../../../../node_modules/kbw-countdown/dist/js/jquery.plugin.js');
|
||||
require('../../../../../node_modules/kbw-countdown/src/js/jquery.countdown.js');
|
||||
import "popper.js";
|
||||
import "jquery-nice-select";
|
||||
import "slick-animation";
|
||||
|
||||
@@ -3,7 +3,6 @@ html {
|
||||
}
|
||||
|
||||
body {
|
||||
direction: ltr;
|
||||
font-family: $primary-font;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
@@ -11,20 +10,46 @@ body {
|
||||
min-width: 320px;
|
||||
color: $color-black;
|
||||
overflow-x: hidden;
|
||||
|
||||
&.ltr {
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
&.rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
color: $color-black;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6,
|
||||
ul, ol, li, address, p {
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
ul,
|
||||
ol,
|
||||
li,
|
||||
address,
|
||||
p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div, a, button {
|
||||
&:active, &:focus, &:visited {
|
||||
div,
|
||||
a,
|
||||
button {
|
||||
&:active,
|
||||
&:focus,
|
||||
&:visited {
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
@@ -37,7 +62,8 @@ a {
|
||||
}
|
||||
}
|
||||
|
||||
b, strong {
|
||||
b,
|
||||
strong {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,62 +1,53 @@
|
||||
.alert {
|
||||
font-size: 16px;
|
||||
position: fixed;
|
||||
right: 15px;
|
||||
bottom: 15px;
|
||||
display: flex;
|
||||
margin: 0 0 0 15px;
|
||||
padding: 20px 64px 20px 28px;
|
||||
align-items: center;
|
||||
border: none;
|
||||
border-left: 3px solid;
|
||||
border-radius: $radius-default;
|
||||
font-size: 16px;
|
||||
position: fixed;
|
||||
right: 15px;
|
||||
bottom: 15px;
|
||||
display: flex;
|
||||
margin: 0 0 0 15px;
|
||||
padding: 20px 64px 20px 28px;
|
||||
align-items: center;
|
||||
border: none;
|
||||
border-radius: $radius-default;
|
||||
|
||||
> i {
|
||||
font-size: 20px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
.close {
|
||||
font-size: 16px;
|
||||
top: 50%;
|
||||
right: 17px;
|
||||
padding: 10px;
|
||||
transform: translateY(-50%);
|
||||
transition: $transition-default;
|
||||
|
||||
.close {
|
||||
font-size: 16px;
|
||||
top: 50%;
|
||||
right: 17px;
|
||||
padding: 10px;
|
||||
opacity: 1;
|
||||
transform: translateY(-50%);
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
> i {
|
||||
color: $color-default;
|
||||
color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
> i {
|
||||
color: $color-gray-dark;
|
||||
}
|
||||
}
|
||||
> i {
|
||||
color: $color-gray;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
color: $color-green;
|
||||
background: #e8f7f3;
|
||||
border-color: $color-green;
|
||||
color: $color-green;
|
||||
background: #e8f7f3;
|
||||
border-color: $color-green;
|
||||
}
|
||||
|
||||
.alert-danger {
|
||||
color: $color-red;
|
||||
background: #fbebea;
|
||||
border-color: $color-red;
|
||||
color: $color-red;
|
||||
background: #fbebea;
|
||||
border-color: $color-red;
|
||||
}
|
||||
|
||||
.alert-info {
|
||||
color: $color-info;
|
||||
background: #e2ecf7;
|
||||
border-color: $color-info;
|
||||
color: $color-info;
|
||||
background: #e2ecf7;
|
||||
border-color: $color-info;
|
||||
}
|
||||
|
||||
.alert-warning {
|
||||
color: $color-yellow;
|
||||
background: #fef5ea;
|
||||
border-color: $color-yellow;
|
||||
color: $color-yellow;
|
||||
background: #fef5ea;
|
||||
border-color: $color-yellow;
|
||||
}
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
.badge {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
min-width: 120px;
|
||||
display: inline-block;
|
||||
padding: 10px 15px;
|
||||
text-align: center;
|
||||
border-radius: 20px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
min-width: 120px;
|
||||
display: inline-block;
|
||||
padding: 10px 15px;
|
||||
text-align: center;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.badge-success {
|
||||
color: $color-green;
|
||||
background: #edf9f6;
|
||||
color: $color-green;
|
||||
background: #edf9f6;
|
||||
}
|
||||
|
||||
.badge-danger {
|
||||
color: $color-red;
|
||||
background: #fdf0ed;
|
||||
color: $color-red;
|
||||
background: #fdf0ed;
|
||||
}
|
||||
|
||||
.badge-info {
|
||||
color: $color-info;
|
||||
background: #eef5fb;
|
||||
color: $color-info;
|
||||
background: #eef5fb;
|
||||
}
|
||||
|
||||
.badge-warning {
|
||||
color: $color-yellow;
|
||||
background: #fff9ef;
|
||||
color: $color-yellow;
|
||||
background: #fcf6ec;
|
||||
}
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
font-size: 15px;
|
||||
line-height: 26px;
|
||||
position: relative;
|
||||
border: none;
|
||||
color: $color-black;
|
||||
padding: 7px 24px;
|
||||
border: none;
|
||||
border-radius: $radius-default;
|
||||
transition: $transition-default;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.is-countdown {
|
||||
.countdown {
|
||||
border: none;
|
||||
background: transparent;
|
||||
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
.form-group {
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
label {
|
||||
font-weight: 500;
|
||||
margin-bottom: 9px;
|
||||
label {
|
||||
font-weight: 500;
|
||||
margin-bottom: 9px;
|
||||
|
||||
> span {
|
||||
margin-left: 4px;
|
||||
color: $color-red;
|
||||
}
|
||||
}
|
||||
> span {
|
||||
margin-left: 4px;
|
||||
color: $color-red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-control {
|
||||
font-size: 14px;
|
||||
height: 45px;
|
||||
height: 45px;
|
||||
padding: 10px 15px;
|
||||
border-color: $color-gray-lite;
|
||||
border-color: $color-gray-lite;
|
||||
border-radius: $radius-default;
|
||||
transition: $transition-default;
|
||||
transition: $transition-default;
|
||||
|
||||
&:focus {
|
||||
border-color: $color-default;
|
||||
@@ -42,7 +42,7 @@ textarea {
|
||||
}
|
||||
|
||||
.form-check {
|
||||
padding: 0;
|
||||
padding: 0 !important;
|
||||
|
||||
label {
|
||||
font-weight: 400;
|
||||
@@ -66,44 +66,44 @@ textarea {
|
||||
|
||||
&:checked + label:before,
|
||||
&:not(:checked) + label:before {
|
||||
content: '';
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 1px;
|
||||
width: 18px;
|
||||
top: 2px;
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
border: 1px solid $border-color;
|
||||
border-radius: $radius-default;
|
||||
border-radius: 4px;
|
||||
transition: $transition-default;
|
||||
}
|
||||
|
||||
&:checked + label:after,
|
||||
&:not(:checked) + label:after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
top: 5px;
|
||||
content: "";
|
||||
top: 7px;
|
||||
left: 4px;
|
||||
height: 6px;
|
||||
width: 10px;
|
||||
height: 5px;
|
||||
width: 9px;
|
||||
border: 2px solid;
|
||||
border-color: $color-default;
|
||||
border-color: var(--color-primary);
|
||||
/*rtl:begin:ignore*/
|
||||
border-top: none;
|
||||
border-right: none;
|
||||
transform: rotate(-45deg) scale(0);
|
||||
border-top: none;
|
||||
border-right: none;
|
||||
transform: rotate(-45deg) scale(0);
|
||||
/*rtl:end:ignore*/
|
||||
transition: $transition-default;
|
||||
}
|
||||
|
||||
&:not(:checked) + label:after {
|
||||
opacity: 0;
|
||||
transform: rotate(-45deg) scale(0) #{'/*rtl:ignore*/'};
|
||||
transform: rotate(-45deg) scale(0) #{"/*rtl:ignore*/"};
|
||||
}
|
||||
|
||||
&:checked + label:after {
|
||||
opacity: 1;
|
||||
transform: rotate(-45deg) scale(1) #{'/*rtl:ignore*/'};
|
||||
transform: rotate(-45deg) scale(1) #{"/*rtl:ignore*/"};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -133,28 +133,28 @@ textarea {
|
||||
|
||||
&:checked + label:before,
|
||||
&:not(:checked) + label:before {
|
||||
content: '';
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 2px;
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border: 1px solid $border-color;
|
||||
border-radius: 50%;
|
||||
border-radius: $radius-full;
|
||||
transition: $transition-default;
|
||||
}
|
||||
|
||||
&:checked + label:after,
|
||||
&:not(:checked) + label:after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
top: 7px;
|
||||
left: 5px;
|
||||
height: 7px;
|
||||
width: 7px;
|
||||
content: "";
|
||||
top: 6px;
|
||||
left: 4px;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
background: $color-default;
|
||||
background: var(--color-primary);
|
||||
border-radius: 50%;
|
||||
border-radius: $radius-full;
|
||||
transform: scale(0);
|
||||
transition: $transition-default;
|
||||
}
|
||||
@@ -184,31 +184,31 @@ textarea {
|
||||
}
|
||||
|
||||
.has-error {
|
||||
.form-control {
|
||||
border-color: $color-red;
|
||||
.form-control {
|
||||
border-color: $color-red;
|
||||
|
||||
&:focus {
|
||||
border-color: $color-red;
|
||||
}
|
||||
}
|
||||
&:focus {
|
||||
border-color: $color-red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.error-message {
|
||||
line-height: 20px;
|
||||
display: block;
|
||||
margin: 4px 0 -5px;
|
||||
color: $color-red;
|
||||
display: block;
|
||||
margin: 4px 0 -5px;
|
||||
color: $color-red;
|
||||
}
|
||||
|
||||
::placeholder {
|
||||
color: $color-gray-dark !important;
|
||||
color: darken($color-gray-dark, 5%) !important;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
:-ms-input-placeholder {
|
||||
color: $color-gray-dark !important;
|
||||
color: darken($color-gray-dark, 5%) !important;
|
||||
}
|
||||
|
||||
::-ms-input-placeholder {
|
||||
color: $color-gray-dark !important;
|
||||
color: darken($color-gray-dark, 5%) !important;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
&:before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
content: "";
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
@@ -15,12 +15,12 @@
|
||||
|
||||
&:after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
content: "";
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
border-radius: 50%;
|
||||
border-radius: $radius-full;
|
||||
border: 3px solid $color-default;
|
||||
border: 3px solid var(--color-primary);
|
||||
border-top-color: transparent !important;
|
||||
@@ -32,15 +32,15 @@
|
||||
.btn-loading {
|
||||
color: transparent !important;
|
||||
|
||||
&:after {
|
||||
&:after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
content: "";
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
border: 2px solid $color-white;
|
||||
border-radius: 50%;
|
||||
border-radius: $radius-full;
|
||||
border-top-color: transparent !important;
|
||||
animation: loader-spin 800ms infinite linear;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
.modal {
|
||||
padding-right: 0 !important;
|
||||
|
||||
&.in {
|
||||
opacity: 1;
|
||||
|
||||
.modal-dialog {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-dialog {
|
||||
@@ -15,3 +23,9 @@
|
||||
.modal-body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.modal-backdrop {
|
||||
&.in {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,42 +8,6 @@
|
||||
border-radius: 0;
|
||||
transition: $transition-default;
|
||||
|
||||
&:before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
left: 50%;
|
||||
bottom: 0;
|
||||
height: 1px;
|
||||
width: 0;
|
||||
background: $color-default;
|
||||
background: var(--color-primary);
|
||||
transform: translateX(-50%);
|
||||
transition: 150ms ease-in-out;
|
||||
}
|
||||
|
||||
&:after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
left: 50%;
|
||||
bottom: -7px;
|
||||
height: 8px;
|
||||
width: 15px;
|
||||
background: $color-default;
|
||||
background: var(--color-primary);
|
||||
border-bottom-left-radius: 12px;
|
||||
border-bottom-right-radius: 12px;
|
||||
opacity: 0;
|
||||
transform: translateX(-50%);
|
||||
transition: 150ms ease-in-out;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&:before {
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
font-weight: 500;
|
||||
color: $color-default;
|
||||
@@ -58,18 +22,39 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.loading {
|
||||
pointer-events: none;
|
||||
&:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
left: 50%;
|
||||
bottom: 0;
|
||||
height: 1px;
|
||||
width: 0;
|
||||
background: $color-default;
|
||||
background: var(--color-primary);
|
||||
transform: translateX(-50%);
|
||||
transition: 150ms ease-in-out;
|
||||
}
|
||||
|
||||
&:after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
left: 50%;
|
||||
bottom: -7px;
|
||||
height: 8px;
|
||||
width: 15px;
|
||||
background: $color-default;
|
||||
background: var(--color-primary);
|
||||
border-bottom-left-radius: 12px;
|
||||
border-bottom-right-radius: 12px;
|
||||
opacity: 0;
|
||||
transform: translateX(-50%);
|
||||
transition: 150ms ease-in-out;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&:hover:not(.active) {
|
||||
&:before {
|
||||
left: 0;
|
||||
top: auto;
|
||||
transform: none;
|
||||
animation: tab-loader 1.2s ease infinite;
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: none;
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,6 +62,25 @@
|
||||
.nav-tabs {
|
||||
border: none;
|
||||
|
||||
.nav-item {
|
||||
&.loading {
|
||||
.nav-link {
|
||||
pointer-events: none;
|
||||
|
||||
&:before {
|
||||
left: 0;
|
||||
top: auto;
|
||||
transform: none;
|
||||
animation: tab-loader 1.2s ease infinite;
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
@extend %nav-link;
|
||||
}
|
||||
@@ -90,24 +94,50 @@
|
||||
@extend %nav-link;
|
||||
|
||||
float: left;
|
||||
margin-left: 30px;
|
||||
margin-right: 30px;
|
||||
cursor: pointer;
|
||||
transition: none;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&.active {
|
||||
font-weight: 500;
|
||||
color: $color-default;
|
||||
color: var(--color-primary);
|
||||
cursor: default;
|
||||
|
||||
&:before {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&:after {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.loading {
|
||||
pointer-events: none;
|
||||
|
||||
&:before {
|
||||
left: 0;
|
||||
top: auto;
|
||||
transform: none;
|
||||
animation: tab-loader 1.2s ease infinite;
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
.slick-list {
|
||||
margin: 0 -15px -50px;
|
||||
padding: 30px 0 50px;
|
||||
margin: 0 -10px -50px;
|
||||
padding: 30px 1px 50px 0;
|
||||
|
||||
.slick-track {
|
||||
display: flex;
|
||||
@@ -118,14 +148,14 @@
|
||||
.slick-dots {
|
||||
position: relative;
|
||||
bottom: auto;
|
||||
margin-top: 30px;
|
||||
margin-top: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: $lg) {
|
||||
.tab-content {
|
||||
.slick-list {
|
||||
margin: 0 -8px -50px;
|
||||
margin: 0 -7.5px -50px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import "~vue-toast-notification/dist/theme-default";
|
||||
@import "vue-toast-notification/dist/theme-default";
|
||||
|
||||
.notices {
|
||||
.toast {
|
||||
|
||||
@@ -47,7 +47,8 @@
|
||||
padding: 16px 0 20px;
|
||||
|
||||
.cookie-bar-text {
|
||||
margin: 0 0 14px 0;
|
||||
margin-right: 0;
|
||||
margin-bottom: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@import 'footer/_footer-top',
|
||||
'footer/_footer-bottom';
|
||||
@import "footer/_footer-top";
|
||||
@import "footer/_footer-bottom";
|
||||
|
||||
.footer {
|
||||
padding-top: 70px;
|
||||
padding-top: 60px;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
@import 'header/_header-left',
|
||||
'header/_header-search',
|
||||
'header/_searched-keywords',
|
||||
'header/_search-suggestion',
|
||||
'header/_header-right',
|
||||
'header/_sticky-header';
|
||||
@import "header/_header-left";
|
||||
@import "header/_header-search";
|
||||
@import "header/_searched-keywords";
|
||||
@import "header/_search-suggestion";
|
||||
@import "header/_header-right";
|
||||
@import "header/_sticky-header";
|
||||
|
||||
.header-wrap {
|
||||
position: relative;
|
||||
@@ -11,12 +11,12 @@
|
||||
}
|
||||
|
||||
.header-wrap-inner {
|
||||
padding: 40px 0;
|
||||
padding: 30px 0;
|
||||
}
|
||||
|
||||
@media screen and (max-width: $lg) {
|
||||
.header-wrap-inner {
|
||||
padding: 15px 0;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid $border-color;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
.landscape-products-wrap {
|
||||
margin-top: 45px;
|
||||
margin-top: 45px;
|
||||
|
||||
.products-header {
|
||||
border-bottom: 1px solid $border-color-lite;
|
||||
}
|
||||
.products-header {
|
||||
border-bottom: 1px solid $border-color-lite;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
padding-bottom: 14px;
|
||||
@@ -11,14 +11,14 @@
|
||||
}
|
||||
|
||||
.landscape-products {
|
||||
.arrow-prev.slick-arrow,
|
||||
.arrow-prev.slick-arrow,
|
||||
.arrow-next.slick-arrow {
|
||||
top: -40px;
|
||||
}
|
||||
|
||||
.slick-list {
|
||||
margin: 0 -15px -50px;
|
||||
padding: 30px 0 50px;
|
||||
.slick-list {
|
||||
margin: 0 -10px -50px;
|
||||
padding: 30px 1px 50px 0;
|
||||
|
||||
.slick-track {
|
||||
display: flex;
|
||||
@@ -29,14 +29,14 @@
|
||||
.slick-dots {
|
||||
position: relative;
|
||||
bottom: auto;
|
||||
margin-top: 30px;
|
||||
margin-top: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: $lg) {
|
||||
.landscape-products {
|
||||
.slick-list {
|
||||
margin: 0 -8px -50px;
|
||||
margin: 0 -7.5px -50px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
justify-content: space-between;
|
||||
background: $color-default;
|
||||
background: var(--color-primary);
|
||||
border-radius: $radius-default 0 0 $radius-default;
|
||||
border-radius: $radius-default;
|
||||
cursor: pointer;
|
||||
|
||||
&:after {
|
||||
@@ -71,29 +71,9 @@
|
||||
width: 263px;
|
||||
background: $color-white;
|
||||
border: 1px solid $border-color;
|
||||
border-top: none;
|
||||
border-bottom: none;
|
||||
border-radius: $radius-default;
|
||||
z-index: 4;
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
left: 0;
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
background: $border-color;
|
||||
}
|
||||
|
||||
&:before {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&:after {
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
&.show {
|
||||
display: block;
|
||||
}
|
||||
@@ -102,7 +82,7 @@
|
||||
&:before,
|
||||
&:after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
content: "";
|
||||
left: 50%;
|
||||
border-style: solid;
|
||||
transform: translateX(-50%);
|
||||
@@ -110,14 +90,14 @@
|
||||
}
|
||||
|
||||
&:before {
|
||||
top: -25px;
|
||||
top: -26px;
|
||||
border-width: 13px 15px;
|
||||
border-color: transparent;
|
||||
border-bottom-color: $border-color;
|
||||
}
|
||||
|
||||
&:after {
|
||||
top: -23px;
|
||||
top: -24px;
|
||||
border-width: 12px 14px;
|
||||
border-color: transparent;
|
||||
border-bottom-color: $color-white;
|
||||
@@ -177,7 +157,7 @@
|
||||
|
||||
&:after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
content: "";
|
||||
left: 0;
|
||||
top: 15px;
|
||||
height: 15px;
|
||||
@@ -346,7 +326,7 @@
|
||||
&:hover {
|
||||
> .nav-link {
|
||||
> i {
|
||||
left: 15px #{'/*rtl:ignore*/'};
|
||||
left: 15px #{"/*rtl:ignore*/"};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
|
||||
.newsletter-left {
|
||||
width: 100%;
|
||||
padding: 33px 40px 27px;
|
||||
padding: 33px 30px 27px;
|
||||
text-align: center;
|
||||
|
||||
.title {
|
||||
@@ -133,7 +133,7 @@
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
.newsletter-left {
|
||||
padding: 28px 30px 22px;
|
||||
padding: 28px 25px 22px;
|
||||
|
||||
.sub-title {
|
||||
margin-bottom: 35px;
|
||||
@@ -154,7 +154,8 @@
|
||||
}
|
||||
|
||||
.btn-subscribe {
|
||||
margin: 15px 0 0 0;
|
||||
margin-left: 0;
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@import 'order-summary/_order-summary-top',
|
||||
'order-summary/_order-summary-middle',
|
||||
'order-summary/_order-summary-bottom';
|
||||
@import "order-summary/_order-summary-top";
|
||||
@import "order-summary/_order-summary-middle";
|
||||
@import "order-summary/_order-summary-bottom";
|
||||
|
||||
.order-summary-wrap {
|
||||
width: 380px;
|
||||
@@ -9,12 +9,49 @@
|
||||
}
|
||||
|
||||
.order-summary {
|
||||
padding: 24px 30px 30px;
|
||||
padding: 22px 25px 30px;
|
||||
background: $color-white-dark;
|
||||
border-radius: $radius-default;
|
||||
}
|
||||
|
||||
.price-amount {
|
||||
font-weight: 500;
|
||||
.order-summary-list {
|
||||
li {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 9px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.coupon-code {
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
> span {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
margin-bottom: 0;
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.order-summary-total {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
display: flex;
|
||||
margin-top: 24px;
|
||||
padding-bottom: 0;
|
||||
justify-content: space-between;
|
||||
padding: 14px 0;
|
||||
border-top: 1px solid $color-gray-lite;
|
||||
|
||||
label {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@import 'sidebar-cart/_sidebar-cart-top',
|
||||
'sidebar-cart/_sidebar-cart-middle',
|
||||
'sidebar-cart/_sidebar-cart-bottom';
|
||||
@import "sidebar-cart/_sidebar-cart-top";
|
||||
@import "sidebar-cart/_sidebar-cart-middle";
|
||||
@import "sidebar-cart/_sidebar-cart-bottom";
|
||||
|
||||
.sidebar-cart-wrap {
|
||||
position: fixed;
|
||||
@@ -8,7 +8,7 @@
|
||||
right: -200px;
|
||||
bottom: 0;
|
||||
height: 100%;
|
||||
width: 400px;
|
||||
width: 380px;
|
||||
background: $color-white;
|
||||
box-shadow: 2.5px 4.33px 40px 5px rgba(12, 31, 46, 0.1);
|
||||
opacity: 0;
|
||||
|
||||
@@ -52,10 +52,9 @@
|
||||
|
||||
.nav-item {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
&.nav-tabs {
|
||||
.nav-link {
|
||||
font-weight: 400;
|
||||
padding: 8px;
|
||||
color: $color-gray-dark;
|
||||
text-align: center;
|
||||
@@ -64,7 +63,6 @@
|
||||
border-radius: 0;
|
||||
|
||||
&.active {
|
||||
font-weight: 400;
|
||||
color: $color-black;
|
||||
background: $color-white;
|
||||
cursor: default;
|
||||
@@ -133,7 +131,7 @@
|
||||
> .menu-item {
|
||||
&:after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
content: "";
|
||||
left: 0;
|
||||
top: 16px;
|
||||
height: 15px;
|
||||
|
||||
@@ -44,8 +44,9 @@
|
||||
> input {
|
||||
height: 50px;
|
||||
width: 450px;
|
||||
border: none;
|
||||
padding: 12px 147px 10px 20px;
|
||||
border: none;
|
||||
border-radius: 50px;
|
||||
}
|
||||
|
||||
> .btn-subscribe {
|
||||
@@ -53,7 +54,7 @@
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 5px;
|
||||
border-radius: 0 $radius-default $radius-default 0;
|
||||
border-radius: 50px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
&.top-nav-compare {
|
||||
display: none;
|
||||
}
|
||||
|
||||
> a {
|
||||
display: block;
|
||||
color: $color-black;
|
||||
@@ -82,3 +86,15 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
.top-nav {
|
||||
.top-nav-right-list {
|
||||
> li {
|
||||
&.top-nav-compare {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,8 @@
|
||||
}
|
||||
|
||||
a {
|
||||
line-height: 33px;
|
||||
font-size: 14px;
|
||||
line-height: 30px;
|
||||
display: block;
|
||||
color: $color-gray;
|
||||
border: 1px solid $color-gray-lite;
|
||||
@@ -65,7 +66,6 @@
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: top;
|
||||
|
||||
&:hover {
|
||||
color: $color-default;
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
}
|
||||
|
||||
svg {
|
||||
direction: ltr #{'/*rtl:ignore*/'};
|
||||
direction: ltr #{"/*rtl:ignore*/"};
|
||||
height: 60px;
|
||||
width: 245px;
|
||||
|
||||
|
||||
@@ -2,10 +2,22 @@
|
||||
height: 60px;
|
||||
padding: 0 15px;
|
||||
|
||||
.header-wishlist,
|
||||
.header-cart {
|
||||
.header-column-right-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 20px;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
> span,
|
||||
.icon-wrap > i {
|
||||
color: $color-default;
|
||||
color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
> span {
|
||||
line-height: 28px;
|
||||
@@ -15,27 +27,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
.header-wishlist {
|
||||
&:hover {
|
||||
> span,
|
||||
.icon-wrap > i {
|
||||
color: $color-default;
|
||||
color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.header-cart {
|
||||
margin-left: 35px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
> span,
|
||||
.icon-wrap > i {
|
||||
color: $color-default;
|
||||
color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon-wrap {
|
||||
@@ -43,7 +36,7 @@
|
||||
margin-right: 10px;
|
||||
|
||||
> i {
|
||||
font-size: 34px;
|
||||
font-size: 30px;
|
||||
line-height: 36px;
|
||||
color: $color-black;
|
||||
transition: $transition-default;
|
||||
@@ -58,20 +51,16 @@
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
color: $color-white;
|
||||
background: $color-red;
|
||||
background: $color-default;
|
||||
background: var(--color-primary);
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
border-radius: $radius-full;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: $xl) {
|
||||
.header-column-right {
|
||||
.icon-wrap {
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.header-wishlist,
|
||||
.header-cart {
|
||||
> span {
|
||||
display: none;
|
||||
@@ -82,18 +71,23 @@
|
||||
|
||||
@media screen and (max-width: $lg) {
|
||||
.header-column-right {
|
||||
.header-column-right-item {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.icon-wrap {
|
||||
> i {
|
||||
font-size: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
.header-column-right {
|
||||
.header-compare,
|
||||
.header-wishlist {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.header-cart {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 391px) {
|
||||
.header-column-right {
|
||||
padding-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user