diff --git a/app/Http/Controllers/BasketController.php b/app/Http/Controllers/BasketController.php index 7cb4f55..261c1e8 100644 --- a/app/Http/Controllers/BasketController.php +++ b/app/Http/Controllers/BasketController.php @@ -39,7 +39,11 @@ class BasketController extends Controller $dbpanier = new Collection(); foreach (Cart::content() as $row) { $product = $row->model; - $product->additionnalProductInfo = $product->additionnalProductInfo($product->product_type); + //$product->additionnalProductInfo = $product->additionnalProductInfo($product->product_type); + $product->calculatedPrices = $product->getCalcPrices(); + + $row->setTaxRate($product->tax->rate); + $row->setDiscountRate($product->discountRate); $cartextendedItem = array( 'cartItem' => $row, diff --git a/app/Http/Controllers/Bo/OrdersController.php b/app/Http/Controllers/Bo/OrdersController.php index 632222c..7824e09 100644 --- a/app/Http/Controllers/Bo/OrdersController.php +++ b/app/Http/Controllers/Bo/OrdersController.php @@ -101,14 +101,23 @@ class OrdersController extends Controller $order_line->order_id = $order->id; $order_line->product_id = $cartItem->model->id; $order_line->quantity = $cartItem->qty; - $order_line->unit_price = $cartItem->price; - $order_line->unit_discount = 0; + //gross unit price + $order_line->unit_price = $cartItem->model->priceHt; + //discount per unit + $order_line->unit_discount = $cartItem->model->discountAmount; + //tax rate for this line $order_line->tax_rate = $cartItem->taxRate; - $order_line->unit_tax = ($order_line->unit_price * ($order_line->tax_rate / 100)); + //tax amount par unit + $order_line->unit_tax = (($order_line->unit_price - $order_line->unit_discount) * ($order_line->tax_rate / 100)); + //discount amount for the line $order_line->total_discount = $order_line->unit_discount * $order_line->quantity; - $order_line->total_ht = $order_line->unit_price * $order_line->quantity; + //gross amount for the line + $order_line->total_ht = ($order_line->unit_price - $order_line->unit_discount) * $order_line->quantity; + //tax amount for the line $order_line->total_tax = $order_line->unit_tax * $order_line->quantity; + //total TTC avec remises de la ligne $order_line->total_ttc = $order_line->total_ht + $order_line->total_tax; + $order_line->save(); } diff --git a/app/Http/Controllers/Bo/ProductsController.php b/app/Http/Controllers/Bo/ProductsController.php index 2282ebc..86d8cb0 100644 --- a/app/Http/Controllers/Bo/ProductsController.php +++ b/app/Http/Controllers/Bo/ProductsController.php @@ -14,7 +14,7 @@ class ProductsController extends Controller { public function index() { - $products = Product::all(); + $products = Product::paginate(10); return view('bo.products.index', compact('products')); } diff --git a/app/Http/Controllers/Bo/PromotionsController.php b/app/Http/Controllers/Bo/PromotionsController.php new file mode 100644 index 0000000..8eeaa73 --- /dev/null +++ b/app/Http/Controllers/Bo/PromotionsController.php @@ -0,0 +1,136 @@ +product_id); + $discType = $request->discount_type_id; + $value = $request->discount_value; + $date_start = $request->date_start_date . " " . $request->date_start_time; + $date_end = $request->date_end_date . " " . $request->date_end_time; + + $request->validate([]); + + $promotion = new Promotion(); + $promotion->discount_type_id = $discType; + $promotion->discount_value = $value; + $promotion->date_start = $date_start; + $promotion->date_end = $date_end; + $promotion->save(); + + //prise en charge de la liaison avec les produits + $promotion->products()->sync($productIds); + + return redirect()->route('bo.promotions.index'); + } + + /** + * Display the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function show($id) + { + // + } + + /** + * Show the form for editing the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function edit($id) + { + $promotion = Promotion::findOrFail($id); + $discTypes = DiscountType::all(); + return view('bo.promotions.edit', compact('promotion', 'discTypes')); + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function update(Request $request, $id) + { + $promotion = Promotion::findOrFail($id); + + $productIds = explode(",", $request->product_id); + $discType = $request->discount_type_id; + $value = $request->discount_value; + $date_start = $request->date_start_date . " " . $request->date_start_time; + $date_end = $request->date_end_date . " " . $request->date_end_time; + + $request->validate([]); + + $promotion->discount_type_id = $discType; + $promotion->discount_value = $value; + $promotion->date_start = $date_start; + $promotion->date_end = $date_end; + $promotion->save(); + + //prise en charge de la liaison avec les produits + $promotion->products()->sync($productIds); + + return redirect()->route('bo.promotions.edit', $promotion->id)->with('success', 'Modifications enregistrés !'); + + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function destroy($id) + { + $p = Promotion::findOrFail($id); + + //prise en charge de la liaison avec les produits + $p->products()->detach(); + + $p->delete(); + + return redirect()->route('bo.promotions.index'); + } +} diff --git a/app/Http/Controllers/ProductsController.php b/app/Http/Controllers/ProductsController.php index fda078d..a2ca406 100644 --- a/app/Http/Controllers/ProductsController.php +++ b/app/Http/Controllers/ProductsController.php @@ -20,7 +20,9 @@ class ProductsController extends Controller { $range = Range::where('slug', $range_slug)->first(); $products = Product::where('range_id', $range->id)->paginate(9); - return view('range', compact('range','products')); + //find promo within range + $offres = Product::where('range_id', $range->id)->has('promotions')->with('promotions')->get(); + return view('range', compact('range','products','offres')); } public function product(Request $request, $product_slug) { diff --git a/app/Lib/LDC/CartCalculator.php b/app/Lib/LDC/CartCalculator.php new file mode 100644 index 0000000..090460f --- /dev/null +++ b/app/Lib/LDC/CartCalculator.php @@ -0,0 +1,42 @@ +price * ($cartItem->getDiscountRate() / 100); + case 'tax': + return round($cartItem->priceTarget * ($cartItem->taxRate / 100), $decimals); + case 'priceTax': + return round($cartItem->priceTarget + $cartItem->tax, $decimals); + case 'discountTotal': + return round($cartItem->discount * $cartItem->qty, $decimals); + case 'priceTotal': + return round($cartItem->price * $cartItem->qty, $decimals); + case 'subtotal': + return max(round($cartItem->priceTotal - $cartItem->discountTotal, $decimals), 0); + case 'priceTarget': + return round(($cartItem->priceTotal - $cartItem->discountTotal) / $cartItem->qty, $decimals); + case 'taxTotal': + //taxe pour un item multiplié par la quantité + $unit_price = max($cartItem->price - $cartItem->discount,0); + $unit_tax = round($unit_price * ($cartItem->taxRate / 100), $decimals); + $taxTotal = round($unit_tax * $cartItem->qty, $decimals); + //return round($cartItem->subtotal * ($cartItem->taxRate / 100), $decimals); + return $taxTotal; + case 'total': + return round($cartItem->subtotal + $cartItem->taxTotal, $decimals); + default: + return; + } + } +} diff --git a/app/Models/DiscountType.php b/app/Models/DiscountType.php new file mode 100644 index 0000000..2d5b245 --- /dev/null +++ b/app/Models/DiscountType.php @@ -0,0 +1,17 @@ +hasMany(Promotion::class, 'discount_type_id'); + } +} diff --git a/app/Models/Order.php b/app/Models/Order.php index bffc981..e4692ff 100644 --- a/app/Models/Order.php +++ b/app/Models/Order.php @@ -16,6 +16,7 @@ class Order extends Model return $this->belongsToMany(Product::class, 'order_lines', 'order_id', 'product_id'); } + //Relations public function lines() { return $this->hasMany(OrderLine::class); @@ -33,4 +34,10 @@ class Order extends Model { return $this->hasOne(Timeslot::class); } + + //Formattages + public function getFormattedTotalTtcAttribute() + { + return $this->attributes['formattedTotalTtc'] = sprintf('%s €', number_format($this->attributes['total'], 2, ',', ' ')); + } } diff --git a/app/Models/OrderLine.php b/app/Models/OrderLine.php index 6be5578..7d8a5fb 100644 --- a/app/Models/OrderLine.php +++ b/app/Models/OrderLine.php @@ -9,6 +9,7 @@ class OrderLine extends Model { use HasFactory; + //Relations public function order() { return $this->belongsTo(Order::class); @@ -18,4 +19,10 @@ class OrderLine extends Model { return $this->belongsTo(Product::class); } + + //Formattages + public function getFormattedTotalTtcAttribute() + { + return $this->attributes['formattedTotalTtc'] = sprintf('%s €', number_format($this->attributes['total_ttc'], 2, ',', ' ')); + } } diff --git a/app/Models/Product.php b/app/Models/Product.php index 48fd245..f026e1f 100644 --- a/app/Models/Product.php +++ b/app/Models/Product.php @@ -2,6 +2,7 @@ namespace App\Models; +use Carbon\Carbon; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; @@ -14,18 +15,200 @@ class Product extends Model implements Buyable use SoftDeletes; use CanBeBought; - //special formatted attribute price - public function getFormattedPriceAttribute() + /** + * Store in protected variables instead of attributes + * Because those are not set in attributes, Laravel will not try to save it to database + */ + protected $priceHt; + + protected $discountedPriceHt; + + protected $priceTtc; + + protected $discountedPriceTtc; + + protected $discountAmount; + + protected $discountRate; + + /** + * init prices on boot + */ + protected static function boot() { - return $this->attributes['formattedPrice'] = sprintf('%s €', number_format($this->attributes['price'], 2, ',', ' ')); + parent::boot(); + + //on data retrived from DB + static::retrieved(function ($model) { + $model->priceHt = $model->getPriceHtAttribute(); + $model->priceTtc = $model->getPriceTtcAttribute(); + $model->discountAmount = $model->getDiscountAmountAttribute(); + $model->discountRate = $model->getDiscountRateAttribute(); + $model->discountedPriceHt = $model->getDiscountedPriceHtAttribute(); + $model->discountedPriceTtc = $model->getDiscountedPriceTtcAttribute(); + }); } - public function getFormattedPriceTTCAttribute() + + /** + * Price calculations + * We need : gross price (prix avant taxe et remises) + * discounted price (prix avant taxe avec remises) + * net price (prix avec taxe) + * net discounted proice (prix avec taxe et remises) + */ + + //Utility to bring prices as a pseudo relation + public function getCalcPrices() { - $ttc = $this->attributes['price'] * 1.2; - return $this->attributes['formattedPriceTTC'] = sprintf('%s €', number_format($ttc, 2, ',', ' ')); + //$prices = new Collection(); + $prices = array( + 'priceHt' => $this->priceHt, + 'discountAmount' => $this->discountAmount, + 'discountRate' => $this->discountRate, + 'discountedPriceHt' => $this->discountedPriceHt, + 'priceTtc' => $this->priceTtc, + 'discountedPriceTtc' => $this->discountedPriceTtc, + ); + //$prices->add($cartextendedItem); + return $prices; } + //gross price + /** + * Mutator method to set priceHt's value + */ + public function setPriceHtAttribute($value) + { + $this->priceHt = $value; + } + + /** + * Get the gross price + * Accessor method for priceHt + * + * @author Olivier Legat + */ + public function getPriceHtAttribute() + { + if(isset($this->priceHt)) { + return $this->priceHt; + } else { + //no calculations, alias of db property + return $this->priceHt = $this->attributes['price']; + } + } + + //discounted price + public function setDiscountedPriceHtAttribute($value) + { + $this->discountedPriceHt = $value; + } + + public function getDiscountedPriceHtAttribute() + { + if (isset($this->discountedPriceHt)) { + return $this->discountedPriceHt; + } else { + return $this->discountedPriceHt = $this->priceHt - $this->discountAmount; + } + } + + //net price + public function setPriceTtcAttribute($value) + { + $this->priceTtc = $value; + } + + public function getPriceTtcAttribute() + { + if (isset($this->priceTtc)) { + return $this->priceTtc; + } else { + return $this->priceTtc = $this->priceHt * ( 1 + ( $this->tax->rate / 100)); + } + } + + //net discounted price + public function setDiscountedPriceTtcAttribute($value) + { + $this->discountedPriceTtc = $value; + } + + public function getDiscountedPriceTtcAttribute() + { + if (isset($this->discountedPriceTtc)) { + return $this->discountedPriceTtc; + } else { + return $this->discountedPriceTtc = $this->discountedPriceHt * ( 1 + ( $this->tax->rate / 100)); + } + } + + /** + * Discount calc + */ + + //montant de remise + public function setDiscountAmountAttribute($value) + { + $this->discountAmount = $value; + } + + public function getDiscountAmountAttribute() + { + if (isset($this->discountAmount)) { + return $this->discountAmount; + } else { + $applicablePromotion = $this->promotions->first(); + if (null !== $applicablePromotion) { + $promo_type = $applicablePromotion->discount_type_id; + if ($promo_type == 1) { + $discountAmount = $applicablePromotion->discount_value; + } else { + $discountAmount = $this->priceHt * ($applicablePromotion->discount_value / 100); + } + } else { + $discountAmount = 0; + } + return $this->discountAmount = $discountAmount; + } + } + + //taux de remise + public function setDiscountRateAttribute($value) + { + $this->discountRate = $value; + } + + public function getDiscountRateAttribute() + { + if (isset($this->discountRate)) { + return $this->discountRate; + } else { + $applicablePromotion = $this->promotions->first(); + if (null !== $applicablePromotion) { + $promo_type = $applicablePromotion->discount_type_id; + if ($promo_type == 1) { + //on veut un pourcentage + $discountRate = ($applicablePromotion->discount_value / $this->priceHt) * 100; + } else { + $discountRate = $applicablePromotion->discount_value; + } + } else { + $discountRate = 0; + } + return $this->discountRate = $discountRate; + } + } + + + // //Buyable interface + // public function getBuyablePrice($options = null) + // { + // return $this->discountedPriceHt; + // } + + //Relations public function range() { return $this->belongsTo('App\Models\Range', 'range_id'); @@ -62,8 +245,23 @@ class Product extends Model implements Buyable //relationship to associated products - public function associated_products() + public function associatedProducts() { return $this->belongsToMany(Product::class, 'products_products', 'product_id', 'associated_id'); } + + //offres speciales + public function promotions() + { + $now = Carbon::now(); + return $this->belongsToMany(Promotion::class) + ->whereDate('date_start', '<=', $now) + ->whereDate('date_end', '>=', $now); + } + + //taxe + public function tax() + { + return $this->belongsTo(TaxRate::class, 'tax_rate_id'); + } } diff --git a/app/Models/Promotion.php b/app/Models/Promotion.php new file mode 100644 index 0000000..de91085 --- /dev/null +++ b/app/Models/Promotion.php @@ -0,0 +1,31 @@ + 'datetime', + 'date_end' => 'datetime', + ]; + + public function products() + { + return $this->belongsToMany(Product::class); + } + + public function discountType() + { + return $this->belongsTo(DiscountType::class, 'discount_type_id'); + } +} diff --git a/app/Models/TaxRate.php b/app/Models/TaxRate.php new file mode 100644 index 0000000..9a61df9 --- /dev/null +++ b/app/Models/TaxRate.php @@ -0,0 +1,17 @@ +hasMany(Product::class, 'tax_rate_id'); + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 463a67c..76c8c58 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -5,6 +5,7 @@ namespace App\Providers; use App\Models\Range; use Illuminate\Support\Facades\View; use Illuminate\Support\ServiceProvider; +use Illuminate\Support\Facades\Blade; class AppServiceProvider extends ServiceProvider { @@ -32,5 +33,10 @@ class AppServiceProvider extends ServiceProvider // on partage les ranges (gammes produit) $ranges = Range::all(); View::share('ranges', $ranges); + + Blade::directive('fmt_currency', function ($expression) { + /* return ""; */ + return ""; + }); } } diff --git a/config/cart.php b/config/cart.php index b5222cc..2050cc5 100644 --- a/config/cart.php +++ b/config/cart.php @@ -12,7 +12,8 @@ return [ | */ - 'calculator' => \Gloudemans\Shoppingcart\Calculation\DefaultCalculator::class, + //'calculator' => \Gloudemans\Shoppingcart\Calculation\DefaultCalculator::class, + 'calculator' => \App\Lib\LDC\CartCalculator::class, /* |-------------------------------------------------------------------------- @@ -70,9 +71,9 @@ return [ 'decimals' => 2, - 'decimal_point' => ',', + 'decimal_point' => '.', - 'thousand_separator' => ' ', + 'thousand_separator' => '', ], diff --git a/database/migrations/2021_04_06_153634_create_discount_types_table.php b/database/migrations/2021_04_06_153634_create_discount_types_table.php new file mode 100644 index 0000000..4563130 --- /dev/null +++ b/database/migrations/2021_04_06_153634_create_discount_types_table.php @@ -0,0 +1,35 @@ +id(); + $table->string('label'); + }); + + $seeder = new DiscountTypesSeeder(); + $seeder->run(); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('discount_types'); + } +} diff --git a/database/migrations/2021_04_06_154003_create_promotions_table.php b/database/migrations/2021_04_06_154003_create_promotions_table.php new file mode 100644 index 0000000..0820922 --- /dev/null +++ b/database/migrations/2021_04_06_154003_create_promotions_table.php @@ -0,0 +1,35 @@ +id(); + $table->foreignId('discount_type_id')->default(1)->constrained('discount_types'); + $table->float('discount_value')->default(0); + $table->timestamp('date_start')->nullable(); + $table->timestamp('date_end')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('promotions'); + } +} diff --git a/database/migrations/2021_04_07_100613_create_product_promotion_table.php b/database/migrations/2021_04_07_100613_create_product_promotion_table.php new file mode 100644 index 0000000..2509b5c --- /dev/null +++ b/database/migrations/2021_04_07_100613_create_product_promotion_table.php @@ -0,0 +1,32 @@ +foreignId('product_id')->constrained('products'); //produit considéré + $table->foreignId('promotion_id')->constrained('promotions'); //promotion associée + $table->collation = 'utf8mb4_unicode_ci'; + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('product_promotion'); + } +} diff --git a/database/migrations/2021_04_07_153852_create_tax_rates_table.php b/database/migrations/2021_04_07_153852_create_tax_rates_table.php new file mode 100644 index 0000000..1d51309 --- /dev/null +++ b/database/migrations/2021_04_07_153852_create_tax_rates_table.php @@ -0,0 +1,36 @@ +id(); + $table->string('label'); + $table->float('rate'); + }); + + $seeder = new TaxRatesSeeder(); + $seeder->run(); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('tax_rates'); + } +} diff --git a/database/migrations/2021_04_07_154718_add_fields_to_products_table.php b/database/migrations/2021_04_07_154718_add_fields_to_products_table.php new file mode 100644 index 0000000..e7d4d08 --- /dev/null +++ b/database/migrations/2021_04_07_154718_add_fields_to_products_table.php @@ -0,0 +1,33 @@ +foreignId('tax_rate_id')->after('price_buy')->default(1)->constrained('tax_rates'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('products', function (Blueprint $table) { + $table->dropForeign(['tax_rate_id']); + $table->dropColumn('tax_rate_id'); + }); + } +} diff --git a/database/seeders/DiscountTypesSeeder.php b/database/seeders/DiscountTypesSeeder.php new file mode 100644 index 0000000..8ed72bc --- /dev/null +++ b/database/seeders/DiscountTypesSeeder.php @@ -0,0 +1,26 @@ +label = "Montant"; + + $pourcentage = new DiscountType(); + $pourcentage->label = "Pourcentage"; + + $montant->save(); + $pourcentage->save(); + } +} diff --git a/database/seeders/TaxRatesSeeder.php b/database/seeders/TaxRatesSeeder.php new file mode 100644 index 0000000..2608482 --- /dev/null +++ b/database/seeders/TaxRatesSeeder.php @@ -0,0 +1,28 @@ +label = "TVA 20%"; + $highTva->rate = 20; + + $lowTva = new TaxRate(); + $lowTva->label = "TVA 5.5%"; + $lowTva->rate = 5.5; + + $highTva->save(); + $lowTva->save(); + } +} diff --git a/package-lock.json b/package-lock.json index a8d0597..e639032 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8271,6 +8271,12 @@ "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", "dev": true }, + "smooth-dnd": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/smooth-dnd/-/smooth-dnd-0.12.1.tgz", + "integrity": "sha512-Dndj/MOG7VP83mvzfGCLGzV2HuK1lWachMtWl/Iuk6zV7noDycIBnflwaPuDzoaapEl3Pc4+ybJArkkx9sxPZg==", + "dev": true + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -9356,6 +9362,15 @@ "vue-style-loader": "^4.1.0" } }, + "vue-smooth-dnd": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/vue-smooth-dnd/-/vue-smooth-dnd-0.8.1.tgz", + "integrity": "sha512-eZVVPTwz4A1cs0+CjXx/ihV+gAl3QBoWQnU6+23Gp59t0WBU99z7ducBQ4FvjBamqOlg8SDOE5eFHQedxwB4Wg==", + "dev": true, + "requires": { + "smooth-dnd": "0.12.1" + } + }, "vue-style-loader": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz", diff --git a/package.json b/package.json index 6c3d440..0fcf9c0 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ }, "devDependencies": { "axios": "^0.21.1", - "bootstrap": "^4.5.0", + "bootstrap": "^4.6.0", "cross-env": "^7.0", "jquery": "^3.6", "laravel-mix": "^5.0.1", @@ -21,6 +21,7 @@ "sass-loader": "^8.0.2", "swiper": "^6.3.4", "toastify-js": "^1.10.0", + "vue-smooth-dnd": "^0.8.1", "vue-template-compiler": "^2.6.12" }, "dependencies": { diff --git a/public/b-o/js/app.js b/public/b-o/js/app.js index 259c352..e8cb0e8 100644 --- a/public/b-o/js/app.js +++ b/public/b-o/js/app.js @@ -2054,6 +2054,200 @@ __webpack_require__.r(__webpack_exports__); /***/ }), +/***/ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/components/ProductsCardsDnd.vue?vue&type=script&lang=js&": +/*!***************************************************************************************************************************************************************************!*\ + !*** ./node_modules/babel-loader/lib??ref--4-0!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/components/ProductsCardsDnd.vue?vue&type=script&lang=js& ***! + \***************************************************************************************************************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var vue_smooth_dnd__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue-smooth-dnd */ "./node_modules/vue-smooth-dnd/dist/vue-smooth-dnd.esm.js"); +/* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../helpers */ "./resources/js/helpers.js"); +/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.common.js"); +/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(vue__WEBPACK_IMPORTED_MODULE_2__); +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// + + + +var i = 0; + +function id() { + return "item-".concat(++i); +} + +function generate(num) { + return Object(_helpers__WEBPACK_IMPORTED_MODULE_1__["generateItems"])(5, function (i) { + return { + id: id(), + data: "Draggable ".concat(num, " - ").concat(i + 1) + }; + }); +} + +/* harmony default export */ __webpack_exports__["default"] = ({ + name: 'Events', + components: { + Container: vue_smooth_dnd__WEBPACK_IMPORTED_MODULE_0__["Container"], + Draggable: vue_smooth_dnd__WEBPACK_IMPORTED_MODULE_0__["Draggable"] + }, + data: function data() { + return { + groups: [], + flags: [], + logs: { + 'get-child-payload': true, + 'should-accept-drop': false, + 'should-animate-drop': false, + 'drag-start': true, + 'drag-end': true, + 'drag-enter': true, + 'drag-leave': true, + 'drop': true + }, + logPayload: true + }; + }, + created: function created() { + this.addColumn(); + }, + methods: { + // ----------------------------------------------------------------------------------------------------------------- + // callbacks + getChildPayload: function getChildPayload(groupIndex, itemIndex) { + this.log('get-child-payload', groupIndex, itemIndex); + return this.groups[groupIndex][itemIndex]; + }, + getShouldAcceptDrop: function getShouldAcceptDrop(index, sourceContainerOptions, payload) { + this.log('should-accept-drop', sourceContainerOptions, payload); + return this.flags[index].drop; + }, + getShouldAnimateDrop: function getShouldAnimateDrop(index, sourceContainerOptions, payload) { + this.log('should-animate-drop', sourceContainerOptions, payload); + return this.flags[index].animate; + }, + // ----------------------------------------------------------------------------------------------------------------- + // events + onDragStart: function onDragStart() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + this.log.apply(this, ['drag-start'].concat(args)); + }, + onDragEnd: function onDragEnd() { + for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + this.log.apply(this, ['drag-end'].concat(args)); + }, + onDragEnter: function onDragEnter() { + for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + args[_key3] = arguments[_key3]; + } + + this.log.apply(this, ['drag-enter'].concat(args)); + }, + onDragLeave: function onDragLeave() { + for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + args[_key4] = arguments[_key4]; + } + + this.log.apply(this, ['drag-leave'].concat(args)); + }, + onDrop: function onDrop(groupIndex, dropResult) { + var result = Object(_helpers__WEBPACK_IMPORTED_MODULE_1__["applyDrag"])(this.groups[groupIndex], dropResult); + vue__WEBPACK_IMPORTED_MODULE_2___default.a.set(this.groups, groupIndex, result); + this.log('drop', dropResult); + }, + // ----------------------------------------------------------------------------------------------------------------- + // app + addColumn: function addColumn() { + this.groups.push(generate(this.groups.length + 1)); + this.flags.push({ + drop: true, + animate: true + }); + }, + removeColumn: function removeColumn() { + this.groups.pop(); + this.flags.pop(); + }, + log: function log(name) { + if (this.logs[name]) { + var _console; + + for (var _len5 = arguments.length, args = new Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) { + args[_key5 - 1] = arguments[_key5]; + } + + this.logPayload ? (_console = console).log.apply(_console, [name].concat(args)) : console.log(name); + } + } + } +}); + +/***/ }), + /***/ "./node_modules/bootstrap/dist/js/bootstrap.js": /*!*****************************************************!*\ !*** ./node_modules/bootstrap/dist/js/bootstrap.js ***! @@ -6513,6 +6707,25 @@ exports.push([module.i, "\n.fade-enter-active[data-v-5546b00a], .fade-leave-acti // exports +/***/ }), + +/***/ "./node_modules/css-loader/index.js?!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/components/ProductsCardsDnd.vue?vue&type=style&index=0&id=4aff55b4&scoped=true&lang=css&": +/*!**********************************************************************************************************************************************************************************************************************************************************************************************************!*\ + !*** ./node_modules/css-loader??ref--7-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src??ref--7-2!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/components/ProductsCardsDnd.vue?vue&type=style&index=0&id=4aff55b4&scoped=true&lang=css& ***! + \**********************************************************************************************************************************************************************************************************************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +exports = module.exports = __webpack_require__(/*! ../../../node_modules/css-loader/lib/css-base.js */ "./node_modules/css-loader/lib/css-base.js")(false); +// imports + + +// module +exports.push([module.i, "\n.controls[data-v-4aff55b4] {\n margin-top: 1em;\n}\n.controls > div[data-v-4aff55b4] {\n padding-top: 1em;\n}\nlabel[data-v-4aff55b4] {\n display: block;\n line-height: 1.6em;\n}\n.columns[data-v-4aff55b4] {\n display: flex;\n justify-content: stretch;\n}\n.column[data-v-4aff55b4] {\n margin-right: 20px;\n flex: 1;\n}\n.column[data-v-4aff55b4] {\n display: flex;\n flex-direction: column;\n flex-grow: 1;\n}\n.column .smooth-dnd-container.vertical[data-v-4aff55b4] {\n display: flex;\n flex-direction: column;\n flex-grow: 1;\n}\n\n", ""]); + +// exports + + /***/ }), /***/ "./node_modules/css-loader/lib/css-base.js": @@ -37729,6 +37942,18 @@ process.umask = function() { return 0; }; /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js"), __webpack_require__(/*! ./../process/browser.js */ "./node_modules/process/browser.js"))) +/***/ }), + +/***/ "./node_modules/smooth-dnd/dist/index.js": +/*!***********************************************!*\ + !*** ./node_modules/smooth-dnd/dist/index.js ***! + \***********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +!function(e,t){ true?t(exports):undefined}(this,function(e){"use strict";var l,t,r="smooth-dnd-container-instance",f="smooth-dnd-draggable-wrapper",o="animated",p="__smooth_dnd_draggable_translation_value",u="__smooth_dnd_draggable_visibility_value",v="smooth-dnd-ghost",g="smooth-dnd-container",d="smooth-dnd-extra-size-for-insertion",h="smooth-dnd-stretcher-element",y="smooth-dnd-stretcher-instance",s="smooth-dnd-disable-touch-action",c="smooth-dnd-no-user-select",i="smooth-dnd-prevent-auto-scroll-class",b="smooth-dnd-drop-preview-default-class",w="smooth-dnd-drop-preview-inner-class",x="smooth-dnd-drop-preview-constant-class",E="smooth-dnd-drop-preview-flex-container-class",n=Object.freeze({containerInstance:r,defaultGroupName:"@@smooth-dnd-default-group@@",wrapperClass:f,defaultGrabHandleClass:"smooth-dnd-default-grap-handle",animationClass:o,translationValue:p,visibilityValue:u,ghostClass:v,containerClass:g,extraSizeForInsertion:d,stretcherElementClass:h,stretcherElementInstance:y,isDraggableDetached:"smoth-dnd-is-draggable-detached",disbaleTouchActions:s,noUserSelectClass:c,preventAutoScrollClass:i,dropPlaceholderDefaultClass:b,dropPlaceholderInnerClass:w,dropPlaceholderWrapperClass:x,dropPlaceholderFlexContainerClass:E}),C={groupName:void 0,behaviour:"move",orientation:"vertical",getChildPayload:void 0,animationDuration:250,autoScrollEnabled:!0,shouldAcceptDrop:void 0,shouldAnimateDrop:void 0};function a(e){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function m(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function D(e){return function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);te.clientWidth:e.scrollHeight>e.clientHeight},T=function(e,t){var n=e,o=t||I(e);for(n=e.parentElement;n;)P(n,"x")&&B(n,"x")&&(o=S(o,n.getBoundingClientRect(),"x")),P(n,"y")&&B(n,"y")&&(o=S(o,n.getBoundingClientRect(),"y")),n=n.parentElement;return o},z=function(e,n){for(var o=e;o;){if(o[r]){var t=function(){var t=o[r];if(n.some(function(e){return e===t}))return{v:t}}();if("object"===a(t))return t.v}o=o.parentElement}return null},N=function(e,t){for(var n=e;n;){if(n.matches(t))return n;n=n.parentElement}return null},L=function(e,t){return-1=e.children.length?e.appendChild(t):e.insertBefore(t,e.children[n])},V=function(){window.getSelection?window.getSelection().empty?window.getSelection().empty():window.getSelection().removeAllRanges&&window.getSelection().removeAllRanges():window.document.selection&&window.document.selection.empty()},X=function(e){if(e){var t=window.getComputedStyle(e);if(t)return t.cursor}return null};function H(e){return!(e.bottom<=e.top||e.right<=e.left)}function Y(e){var s=e.element,c=e.draggables;return function(e,t){var n=e,o=n.removedIndex,r=n.addedIndex,i=n.droppedElement,a=null;if(null!==o&&(a=_(s,o),c.splice(o,1)),null!==r){var l=window.document.createElement("div");l.className="".concat(f),l.appendChild(a&&a.firstElementChild?a.firstElementChild:i),F(s,l,r),r>=c.length?c.push(l):c.splice(r,0,l)}t&&t(e)}}var k=Object.freeze({domDropHandler:Y,reactDropHandler:function(){return{handler:function(){return function(e,t){t&&t(e)}}}}}),G={size:"offsetWidth",distanceToParent:"offsetLeft",translate:"transform",begin:"left",end:"right",dragPosition:"x",scrollSize:"scrollWidth",offsetSize:"offsetWidth",scrollValue:"scrollLeft",scale:"scaleX",setSize:"width",setters:{translate:function(e){return"translate3d(".concat(e,"px, 0, 0)")}}},W={size:"offsetHeight",distanceToParent:"offsetTop",translate:"transform",begin:"top",end:"bottom",dragPosition:"y",scrollSize:"scrollHeight",offsetSize:"offsetHeight",scrollValue:"scrollTop",scale:"scaleY",setSize:"height",setters:{translate:function(e){return"translate3d(0,".concat(e,"px, 0)")}}};function q(n,s,e){n[d]=0;var o=function(o){return{get:function(e,t){return e[o[t]||t]},set:function(e,t,n){e[o[t]]=o.setters[t]?o.setters[t](n):n}}}("horizontal"===s?G:W),c={translation:0};function t(){r(n),function(e){var t=e.getBoundingClientRect();c.scaleX=e.offsetWidth?(t.right-t.left)/e.offsetWidth:1,c.scaleY=e.offsetHeight?(t.bottom-t.top)/e.offsetHeight:1}(n)}function r(e){c.rect=I(e);var t=T(e,c.rect);H(t)&&(c.lastVisibleRect=c.visibleRect),c.visibleRect=t}function i(e){var t=e;if(t.tagName){var n=t.getBoundingClientRect();return"vertical"===s?n.bottom-n.top:n.right-n.left}return o.get(e,"size")*o.get(c,"scale")}function a(e){return o.get(e,"dragPosition")}return window.addEventListener("resize",function(){r(n)}),setTimeout(function(){t()},10),{getSize:i,getContainerRectangles:function(){return{rect:c.rect,visibleRect:c.visibleRect,lastVisibleRect:c.lastVisibleRect}},getBeginEndOfDOMRect:function(e){return{begin:o.get(e,"begin"),end:o.get(e,"end")}},getBeginEndOfContainer:function(){return{begin:o.get(c.rect,"begin")+c.translation,end:o.get(c.rect,"end")+c.translation}},getBeginEndOfContainerVisibleRect:function(){return{begin:o.get(c.visibleRect,"begin")+c.translation,end:o.get(c.visibleRect,"end")+c.translation}},getBeginEnd:function(e){var t=function(e){return(o.get(e,"distanceToParent")+(e[p]||0))*o.get(c,"scale")}(e)+(o.get(c.rect,"begin")+c.translation)-o.get(n,"scrollValue");return{begin:t,end:t+i(e)*o.get(c,"scale")}},getAxisValue:a,setTranslation:function(e,t){t?o.set(e.style,"translate",t):e.style.removeProperty("transform"),e[p]=t},getTranslation:function(e){return e[p]},setVisibility:function(e,t){void 0!==e[u]&&e[u]===t||(t?e.style.removeProperty("visibility"):e.style.visibility="hidden",e[u]=t)},isVisible:function(e){return void 0===e[u]||e[u]},isInVisibleRect:function(e,t){var n=c.visibleRect,o=n.left,r=n.top,i=n.right,a=n.bottom;a-r<2&&(a=r+30);var l=c.rect;return"vertical"===s?e>l.left&&el.top&&t>>0,o=2<=arguments.length?arguments[1]:void 0,r=0;r .").concat(h),{display:"inline-block"}),m($,".".concat(g,".horizontal > .").concat(f),ne),m($,".".concat(g,".vertical > .").concat(f),te),m($,".".concat(f),{"box-sizing":"border-box"}),m($,".".concat(f,".horizontal"),ne),m($,".".concat(f,".vertical"),te),m($,".".concat(f,".animated"),{transition:"transform ease"}),m($,".".concat(v),{"box-sizing":"border-box"}),m($,".".concat(v,".animated"),{transition:"all ease-in-out"}),m($,".".concat(v," *"),{"pointer-events":"none"}),m($,".".concat(s," *"),{"touch-action":"none","-ms-touch-action":"none"}),m($,".".concat(c),{"-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none"}),m($,".".concat(w),{flex:"1"}),m($,".".concat(g,".horizontal > .").concat(x),{height:"100%",overflow:"hidden",display:"table-cell","vertical-align":"top"}),m($,".".concat(g,".vertical > .").concat(x),{overflow:"hidden",display:"block",width:"100%"}),m($,".".concat(E),{width:"100%",height:"100%",display:"flex","justify-content":"stretch","align-items":"stretch"}),m($,".".concat(b),{"background-color":"rgba(150, 150, 150, 0.1)",border:"1px solid #ccc"}),$);function re(o){return Object.keys(o).reduce(function(e,t){var n=o[t];return"object"===a(n)?"".concat(e).concat(t,"{").concat(re(n),"}"):"".concat(e).concat(t,":").concat(n,";")},"")}function ie(e){if(e&&"undefined"!=typeof window){var t=window.document.head||window.document.getElementsByTagName("head")[0],n=window.document.createElement("style"),o=re({"body *":{cursor:"".concat(e," !important")}});return n.type="text/css",n.styleSheet?n.styleSheet.cssText=o:n.appendChild(window.document.createTextNode(o)),t.appendChild(n),n}return null}var ae,le,se=["mousedown","touchstart"],ce=["mousemove","touchmove"],ue=["mouseup","touchend"],de=null,fe=null,ge=null,me=null,pe=[],ve=!1,he=!1,ye=!1,be=!1,we=null,xe=null,Ee=null,Ce=null,De=(ae=null,le=!1,{start:function(){le||(le=!0,function e(){ae=requestAnimationFrame(function(){de.forEach(function(e){return e.layout.invalidateRects()}),setTimeout(function(){null!==ae&&e()},50)})}())},stop:function(){null!==ae&&(cancelAnimationFrame(ae),ae=null),le=!1}}),Se="undefined"!=typeof window&&!!(window.navigator.userAgent.match(/Android/i)||window.navigator.userAgent.match(/webOS/i)||window.navigator.userAgent.match(/iPhone/i)||window.navigator.userAgent.match(/iPad/i)||window.navigator.userAgent.match(/iPod/i)||window.navigator.userAgent.match(/BlackBerry/i)||window.navigator.userAgent.match(/Windows Phone/i));function Oe(){"undefined"!=typeof window&&se.forEach(function(e){window.document.addEventListener(e,Ve,{passive:!1})})}function Re(){return me&&me.ghostParent?me.ghostParent:fe&&fe.parentElement||window.document.body}var Ae,Ie,Be,Pe,Te,ze,Ne=(Pe=null,Te=1,ze=5,function(e,t,n){Ae=Je(e),Be=n,(Ie="number"==typeof t?t:Se?200:0)&&(Pe=setTimeout(Fe,Ie)),ce.forEach(function(e){return window.document.addEventListener(e,Le)},{passive:!1}),ue.forEach(function(e){return window.document.addEventListener(e,Me)},{passive:!1}),window.document.addEventListener("drag",je,{passive:!1})});function Le(e){var t=Je(e),n=t.clientX,o=t.clientY;if(Ie)(Math.abs(Ae.clientX-n)>ze||Math.abs(Ae.clientY-o)>ze)&&_e();else if(Math.abs(Ae.clientX-n)>Te||Math.abs(Ae.clientY-o)>Te)return Fe()}function Me(){_e()}function je(){_e()}function _e(){clearTimeout(Pe),ce.forEach(function(e){return window.document.removeEventListener(e,Le)},{passive:!1}),ue.forEach(function(e){return window.document.removeEventListener(e,Me)},{passive:!1}),window.document.removeEventListener("drag",je,{passive:!1})}function Fe(){clearTimeout(Pe),_e(),Be()}function Ve(e){var t=Je(e);if(!ve&&(void 0===t.button||0===t.button)&&(fe=N(t.target,"."+f))){var n=N(fe,"."+g),o=pe.filter(function(e){return e.element===n})[0],r=o.getOptions().dragHandleSelector,i=o.getOptions().nonDragAreaSelector,a=!0;if(r&&!N(t.target,r)&&(a=!1),i&&N(t.target,i)&&(a=!1),a){o.layout.invalidate(),M(window.document.body,s),M(window.document.body,c);window.document.addEventListener("mouseup",function e(){j(window.document.body,s),j(window.document.body,c),window.document.removeEventListener("mouseup",e)})}a&&Ne(t,o.getOptions().dragBeginDelay,function(){V(),et(t,X(e.target)),ce.forEach(function(e){window.document.addEventListener(e,Xe,{passive:!1})}),ue.forEach(function(e){window.document.addEventListener(e,Ue,{passive:!1})})})}}function Xe(e){e.preventDefault();var t=Je(e);if(me){var n=me.container.getOptions();"contain"===n.behaviour?function(e){var t,n,o,r,i=e.clientX,a=e.clientY,l=1s.end-r/2&&(me.position[n]=s.end-2)}(t,n.orientation):Ee?"y"===Ee?(ge.topLeft.y=t.clientY+ge.positionDelta.top,me.position.y=t.clientY+ge.centerDelta.y,me.mousePosition.y=t.clientY):"x"===Ee&&(ge.topLeft.x=t.clientX+ge.positionDelta.left,me.position.x=t.clientX+ge.centerDelta.x,me.mousePosition.x=t.clientX):(ge.topLeft.x=t.clientX+ge.positionDelta.left,ge.topLeft.y=t.clientY+ge.positionDelta.top,me.position.x=t.clientX+ge.centerDelta.x,me.position.y=t.clientY+ge.centerDelta.y,me.mousePosition.x=t.clientX,me.mousePosition.y=t.clientY),nt(),(be=!we(me))&&We()}else et(t,X(e.target))}var He,Ye,ke,Ge,We=(He=qe,ke=!(Ye=20),Ge=null,function(){for(var e=arguments.length,t=new Array(e),n=0;n=o?null:on.end?a(i,o)+1:i.length;var r=a(i,o,!0);return null!==r?r:i.length}}(e);return function(e){var t=e.dragResult,n=null;return null!==t.pos&&null===(n=o({dragResult:t}))&&(n=t.addedIndex),{addedIndex:n}}}function bt(){var r=null;return function(e){var t=e.dragResult,n=t.addedIndex,o=t.shadowBeginEnd;n!==r&&null!==r&&o&&(o.beginAdjustment=0),r=n}}function wt(e){var u=e.element,d=e.draggables,f=e.layout,g=e.getOptions,m=null;return function(e){var t=e.dragResult,n=t.addedIndex,o=t.removedIndex,r=t.elementSize;if(null===o)if(null!==n){if(!m){var i=f.getBeginEndOfContainer();i.end=i.begin+f.getSize(u);var a=f.getScrollSize(u)>f.getSize(u)?i.begin+f.getScrollSize(u)-f.getScrollValue(u):i.end,l=0 -1 + : _vm.flags[index].drop + }, + on: { + change: function($event) { + var $$a = _vm.flags[index].drop, + $$el = $event.target, + $$c = $$el.checked ? true : false + if (Array.isArray($$a)) { + var $$v = null, + $$i = _vm._i($$a, $$v) + if ($$el.checked) { + $$i < 0 && + _vm.$set( + _vm.flags[index], + "drop", + $$a.concat([$$v]) + ) + } else { + $$i > -1 && + _vm.$set( + _vm.flags[index], + "drop", + $$a.slice(0, $$i).concat($$a.slice($$i + 1)) + ) + } + } else { + _vm.$set(_vm.flags[index], "drop", $$c) + } + } + } + }), + _vm._v(" Accept Drop\n ") + ]), + _vm._v(" "), + _c("label", [ + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.flags[index].animate, + expression: "flags[index].animate" + } + ], + attrs: { type: "checkbox" }, + domProps: { + checked: Array.isArray(_vm.flags[index].animate) + ? _vm._i(_vm.flags[index].animate, null) > -1 + : _vm.flags[index].animate + }, + on: { + change: function($event) { + var $$a = _vm.flags[index].animate, + $$el = $event.target, + $$c = $$el.checked ? true : false + if (Array.isArray($$a)) { + var $$v = null, + $$i = _vm._i($$a, $$v) + if ($$el.checked) { + $$i < 0 && + _vm.$set( + _vm.flags[index], + "animate", + $$a.concat([$$v]) + ) + } else { + $$i > -1 && + _vm.$set( + _vm.flags[index], + "animate", + $$a.slice(0, $$i).concat($$a.slice($$i + 1)) + ) + } + } else { + _vm.$set(_vm.flags[index], "animate", $$c) + } + } + } + }), + _vm._v(" Animate Drop\n ") + ]) + ]), + _vm._v(" "), + _c( + "Container", + { + attrs: { + "data-index": index, + "group-name": "column", + "get-child-payload": function(itemIndex) { + return _vm.getChildPayload(index, itemIndex) + }, + "should-accept-drop": function(src, payload) { + return _vm.getShouldAcceptDrop(index, src, payload) + }, + "should-animate-drop": function(src, payload) { + return _vm.getShouldAnimateDrop(index, src, payload) + } + }, + on: { + "drag-start": _vm.onDragStart, + "drag-enter": function($event) { + return _vm.onDragEnter(index) + }, + "drag-leave": function($event) { + return _vm.onDragLeave(index) + }, + "drag-end": _vm.onDragEnd, + drop: function($event) { + return _vm.onDrop(index, $event) + } + } + }, + _vm._l(items, function(item) { + return _c("Draggable", { key: item.id }, [ + _c("div", { staticClass: "draggable-item" }, [ + _vm._v( + "\n " + _vm._s(item.data) + "\n " + ) + ]) + ]) + }), + 1 + ) + ], + 1 + ) + }), + 0 + ), + _vm._v(" "), + _c("div", { staticClass: "controls" }, [ + _c("div", [ + _c( + "button", + { + attrs: { disabled: _vm.groups.length === 1 }, + on: { + click: function($event) { + return _vm.removeColumn() + } + } + }, + [_vm._v("Remove Column")] + ), + _vm._v(" "), + _c( + "button", + { + on: { + click: function($event) { + return _vm.addColumn() + } + } + }, + [_vm._v("Add Column")] + ) + ]), + _vm._v(" "), + _c( + "div", + [ + _vm._l(_vm.logs, function(key, name) { + return _c("label", { key: name }, [ + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.logs[name], + expression: "logs[name]" + } + ], + attrs: { type: "checkbox" }, + domProps: { + checked: Array.isArray(_vm.logs[name]) + ? _vm._i(_vm.logs[name], null) > -1 + : _vm.logs[name] + }, + on: { + change: function($event) { + var $$a = _vm.logs[name], + $$el = $event.target, + $$c = $$el.checked ? true : false + if (Array.isArray($$a)) { + var $$v = null, + $$i = _vm._i($$a, $$v) + if ($$el.checked) { + $$i < 0 && _vm.$set(_vm.logs, name, $$a.concat([$$v])) + } else { + $$i > -1 && + _vm.$set( + _vm.logs, + name, + $$a.slice(0, $$i).concat($$a.slice($$i + 1)) + ) + } + } else { + _vm.$set(_vm.logs, name, $$c) + } + } + } + }), + _vm._v(" " + _vm._s(name) + "\n ") + ]) + }), + _vm._v(" "), + _c("hr"), + _vm._v(" "), + _c("label", [ + _c("input", { + directives: [ + { + name: "model", + rawName: "v-model", + value: _vm.logPayload, + expression: "logPayload" + } + ], + attrs: { type: "checkbox" }, + domProps: { + checked: Array.isArray(_vm.logPayload) + ? _vm._i(_vm.logPayload, null) > -1 + : _vm.logPayload + }, + on: { + change: function($event) { + var $$a = _vm.logPayload, + $$el = $event.target, + $$c = $$el.checked ? true : false + if (Array.isArray($$a)) { + var $$v = null, + $$i = _vm._i($$a, $$v) + if ($$el.checked) { + $$i < 0 && (_vm.logPayload = $$a.concat([$$v])) + } else { + $$i > -1 && + (_vm.logPayload = $$a + .slice(0, $$i) + .concat($$a.slice($$i + 1))) + } + } else { + _vm.logPayload = $$c + } + } + } + }), + _vm._v(" Log payload\n ") + ]) + ], + 2 + ) + ]) + ]) +} +var staticRenderFns = [] +render._withStripped = true + + + /***/ }), /***/ "./node_modules/vue-loader/lib/runtime/componentNormalizer.js": @@ -38642,6 +39198,221 @@ function normalizeComponent ( } +/***/ }), + +/***/ "./node_modules/vue-smooth-dnd/dist/vue-smooth-dnd.esm.js": +/*!****************************************************************!*\ + !*** ./node_modules/vue-smooth-dnd/dist/vue-smooth-dnd.esm.js ***! + \****************************************************************/ +/*! no static exports found */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Container", function() { return Container; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Draggable", function() { return Draggable; }); +/* harmony import */ var smooth_dnd__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! smooth-dnd */ "./node_modules/smooth-dnd/dist/index.js"); +/* harmony import */ var smooth_dnd__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(smooth_dnd__WEBPACK_IMPORTED_MODULE_0__); +/* harmony reexport (unknown) */ for(var __WEBPACK_IMPORT_KEY__ in smooth_dnd__WEBPACK_IMPORTED_MODULE_0__) if(["default","Container","Draggable"].indexOf(__WEBPACK_IMPORT_KEY__) < 0) (function(key) { __webpack_require__.d(__webpack_exports__, key, function() { return smooth_dnd__WEBPACK_IMPORTED_MODULE_0__[key]; }) }(__WEBPACK_IMPORT_KEY__)); +/** + * Bundle of: vue-smooth-dnd + * Generated: 2019-10-26 + * Version: 0.8.1 + */ + + + + +var isArray = function (obj) { + return Object.prototype.toString.call(obj) === '[object Array]'; +}; + +function getTagProps (ctx, tagClasses) { + var tag = ctx.$props.tag; + if (tag) { + if (typeof tag === 'string') { + var result = { value: tag }; + if (tagClasses) { + result.props = { class: tagClasses }; + } + return result; + } else if (typeof tag === 'object') { + var result$1 = { value: tag.value || 'div', props: tag.props || {} }; + + if (tagClasses) { + if (result$1.props.class) { + if (isArray(result$1.props.class)) { + result$1.props.class.push(tagClasses); + } else { + result$1.props.class = [tagClasses, result$1.props.class]; + } + } else { + result$1.props.class = tagClasses; + } + } + + return result$1; + } + } + return { value: 'div' }; +} + +function validateTagProp (tag) { + if (tag) { + if (typeof tag === 'string') { return true; } + if (typeof tag === 'object') { + if ( + typeof tag.value === 'string' || + typeof tag.value === 'function' || + typeof tag.value === 'object' + ) { + return true; + } + } + return false; + } + return true; +} + +/* eslint-disable curly */ + +smooth_dnd__WEBPACK_IMPORTED_MODULE_0__["smoothDnD"].dropHandler = smooth_dnd__WEBPACK_IMPORTED_MODULE_0__["dropHandlers"].reactDropHandler().handler; +smooth_dnd__WEBPACK_IMPORTED_MODULE_0__["smoothDnD"].wrapChild = false; + +var eventEmitterMap = { + 'drag-start': 'onDragStart', + 'drag-end': 'onDragEnd', + 'drop': 'onDrop', + 'drag-enter': 'onDragEnter', + 'drag-leave': 'onDragLeave', + 'drop-ready': 'onDropReady' +}; + +function getContainerOptions (props, context) { + var options = Object.keys(props).reduce(function (result, key) { + var optionName = key; + var prop = props[optionName]; + + if (prop !== undefined) { + if (typeof prop === 'function') { + if (eventEmitterMap[optionName]) { + result[eventEmitterMap[optionName]] = function (params) { + context.$emit(optionName, params); + }; + } else { + result[optionName] = function () { + var params = [], len = arguments.length; + while ( len-- ) params[ len ] = arguments[ len ]; + + return (prop).apply(void 0, params); + }; + } + } else { + result[optionName] = prop; + } + } + + return result; + }, {}); + + return options; +} + +var mapOptions = function (context) { + var props = Object.assign({}, context.$props, context.$listeners); + return getContainerOptions(props, context); +}; + +var Container = { + name: 'Container', + mounted: function mounted () { + this.containerElement = this.$refs.container || this.$el; + this.container = Object(smooth_dnd__WEBPACK_IMPORTED_MODULE_0__["smoothDnD"])(this.containerElement, mapOptions(this)); + }, + updated: function updated () { + if ( + this.$refs.container !== this.containerElement && + this.$el !== this.containerElement + ) { + if (this.container) { + this.container.dispose(); + } + this.containerElement = this.$refs.container || this.$el; + this.container = Object(smooth_dnd__WEBPACK_IMPORTED_MODULE_0__["smoothDnD"])(this.containerElement, mapOptions(this)); + return; + } + + this.container.setOptions(mapOptions(this)); + }, + destroyed: function destroyed () { + if (this.container) { + this.container.dispose(); + } + }, + props: { + behaviour: String, + groupName: String, + orientation: String, + dragHandleSelector: String, + nonDragAreaSelector: String, + dragBeginDelay: Number, + animationDuration: Number, + autoScrollEnabled: { type: Boolean, default: true }, + lockAxis: String, + dragClass: String, + dropClass: String, + removeOnDropOut: { type: Boolean, default: false }, + 'drag-start': Function, + 'drag-end': Function, + drop: Function, + getChildPayload: Function, + shouldAnimateDrop: Function, + shouldAcceptDrop: Function, + 'drag-enter': Function, + 'drag-leave': Function, + tag: { + validator: validateTagProp, + default: 'div', + }, + getGhostParent: Function, + 'drop-ready': Function, + dropPlaceholder: [Object, Boolean] + }, + render: function (createElement) { + var tagProps = getTagProps(this); + return createElement( + tagProps.value, + Object.assign({}, { ref: 'container' }, tagProps.props), + this.$slots.default + ); + } +}; + +var wrapChild = function (createElement, ctx) { + var tagProps = getTagProps(ctx, smooth_dnd__WEBPACK_IMPORTED_MODULE_0__["constants"].wrapperClass); + return createElement( + tagProps.value, + Object.assign({}, tagProps.props), + ctx.$slots.default + ); +}; + +var Draggable = { + name: 'Draggable', + props: { + tag: { + validator: validateTagProp, + default: 'div' + } + }, + render: function (createElement) { + return wrapChild(createElement, this); + } +}; + + + + /***/ }), /***/ "./node_modules/vue/dist/vue.common.dev.js": @@ -50703,8 +51474,13 @@ module.exports = function(module) { __webpack_require__(/*! ./bootstrap */ "./resources/js/bootstrap.js"); -window.Vue = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.common.js"); +window.Vue = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.common.js"); // Vuex +// import Vuex from 'vuex'; +// import { Container, Draggable } from 'vue-smooth-dnd'; +// import { applyDrag, generateItems } from './helpers'; + Vue.component('faq', __webpack_require__(/*! ./components/Faq.vue */ "./resources/js/components/Faq.vue")["default"]); +Vue.component('products-cards-dnd', __webpack_require__(/*! ./components/ProductsCardsDnd.vue */ "./resources/js/components/ProductsCardsDnd.vue")["default"]); var app = new Vue({ el: '#app' }); @@ -50832,6 +51608,149 @@ __webpack_require__.r(__webpack_exports__); +/***/ }), + +/***/ "./resources/js/components/ProductsCardsDnd.vue": +/*!******************************************************!*\ + !*** ./resources/js/components/ProductsCardsDnd.vue ***! + \******************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _ProductsCardsDnd_vue_vue_type_template_id_4aff55b4_scoped_true___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ProductsCardsDnd.vue?vue&type=template&id=4aff55b4&scoped=true& */ "./resources/js/components/ProductsCardsDnd.vue?vue&type=template&id=4aff55b4&scoped=true&"); +/* harmony import */ var _ProductsCardsDnd_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ProductsCardsDnd.vue?vue&type=script&lang=js& */ "./resources/js/components/ProductsCardsDnd.vue?vue&type=script&lang=js&"); +/* empty/unused harmony star reexport *//* harmony import */ var _ProductsCardsDnd_vue_vue_type_style_index_0_id_4aff55b4_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ProductsCardsDnd.vue?vue&type=style&index=0&id=4aff55b4&scoped=true&lang=css& */ "./resources/js/components/ProductsCardsDnd.vue?vue&type=style&index=0&id=4aff55b4&scoped=true&lang=css&"); +/* harmony import */ var _node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js */ "./node_modules/vue-loader/lib/runtime/componentNormalizer.js"); + + + + + + +/* normalize component */ + +var component = Object(_node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_3__["default"])( + _ProductsCardsDnd_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__["default"], + _ProductsCardsDnd_vue_vue_type_template_id_4aff55b4_scoped_true___WEBPACK_IMPORTED_MODULE_0__["render"], + _ProductsCardsDnd_vue_vue_type_template_id_4aff55b4_scoped_true___WEBPACK_IMPORTED_MODULE_0__["staticRenderFns"], + false, + null, + "4aff55b4", + null + +) + +/* hot reload */ +if (false) { var api; } +component.options.__file = "resources/js/components/ProductsCardsDnd.vue" +/* harmony default export */ __webpack_exports__["default"] = (component.exports); + +/***/ }), + +/***/ "./resources/js/components/ProductsCardsDnd.vue?vue&type=script&lang=js&": +/*!*******************************************************************************!*\ + !*** ./resources/js/components/ProductsCardsDnd.vue?vue&type=script&lang=js& ***! + \*******************************************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _node_modules_babel_loader_lib_index_js_ref_4_0_node_modules_vue_loader_lib_index_js_vue_loader_options_ProductsCardsDnd_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib??ref--4-0!../../../node_modules/vue-loader/lib??vue-loader-options!./ProductsCardsDnd.vue?vue&type=script&lang=js& */ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/components/ProductsCardsDnd.vue?vue&type=script&lang=js&"); +/* empty/unused harmony star reexport */ /* harmony default export */ __webpack_exports__["default"] = (_node_modules_babel_loader_lib_index_js_ref_4_0_node_modules_vue_loader_lib_index_js_vue_loader_options_ProductsCardsDnd_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__["default"]); + +/***/ }), + +/***/ "./resources/js/components/ProductsCardsDnd.vue?vue&type=style&index=0&id=4aff55b4&scoped=true&lang=css&": +/*!***************************************************************************************************************!*\ + !*** ./resources/js/components/ProductsCardsDnd.vue?vue&type=style&index=0&id=4aff55b4&scoped=true&lang=css& ***! + \***************************************************************************************************************/ +/*! no static exports found */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _node_modules_style_loader_index_js_node_modules_css_loader_index_js_ref_7_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_7_2_node_modules_vue_loader_lib_index_js_vue_loader_options_ProductsCardsDnd_vue_vue_type_style_index_0_id_4aff55b4_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/style-loader!../../../node_modules/css-loader??ref--7-1!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/postcss-loader/src??ref--7-2!../../../node_modules/vue-loader/lib??vue-loader-options!./ProductsCardsDnd.vue?vue&type=style&index=0&id=4aff55b4&scoped=true&lang=css& */ "./node_modules/style-loader/index.js!./node_modules/css-loader/index.js?!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/components/ProductsCardsDnd.vue?vue&type=style&index=0&id=4aff55b4&scoped=true&lang=css&"); +/* harmony import */ var _node_modules_style_loader_index_js_node_modules_css_loader_index_js_ref_7_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_7_2_node_modules_vue_loader_lib_index_js_vue_loader_options_ProductsCardsDnd_vue_vue_type_style_index_0_id_4aff55b4_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_index_js_node_modules_css_loader_index_js_ref_7_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_7_2_node_modules_vue_loader_lib_index_js_vue_loader_options_ProductsCardsDnd_vue_vue_type_style_index_0_id_4aff55b4_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__); +/* harmony reexport (unknown) */ for(var __WEBPACK_IMPORT_KEY__ in _node_modules_style_loader_index_js_node_modules_css_loader_index_js_ref_7_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_7_2_node_modules_vue_loader_lib_index_js_vue_loader_options_ProductsCardsDnd_vue_vue_type_style_index_0_id_4aff55b4_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__) if(["default"].indexOf(__WEBPACK_IMPORT_KEY__) < 0) (function(key) { __webpack_require__.d(__webpack_exports__, key, function() { return _node_modules_style_loader_index_js_node_modules_css_loader_index_js_ref_7_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_7_2_node_modules_vue_loader_lib_index_js_vue_loader_options_ProductsCardsDnd_vue_vue_type_style_index_0_id_4aff55b4_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__[key]; }) }(__WEBPACK_IMPORT_KEY__)); + + +/***/ }), + +/***/ "./resources/js/components/ProductsCardsDnd.vue?vue&type=template&id=4aff55b4&scoped=true&": +/*!*************************************************************************************************!*\ + !*** ./resources/js/components/ProductsCardsDnd.vue?vue&type=template&id=4aff55b4&scoped=true& ***! + \*************************************************************************************************/ +/*! exports provided: render, staticRenderFns */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_ProductsCardsDnd_vue_vue_type_template_id_4aff55b4_scoped_true___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!../../../node_modules/vue-loader/lib??vue-loader-options!./ProductsCardsDnd.vue?vue&type=template&id=4aff55b4&scoped=true& */ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/components/ProductsCardsDnd.vue?vue&type=template&id=4aff55b4&scoped=true&"); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "render", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_ProductsCardsDnd_vue_vue_type_template_id_4aff55b4_scoped_true___WEBPACK_IMPORTED_MODULE_0__["render"]; }); + +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "staticRenderFns", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_ProductsCardsDnd_vue_vue_type_template_id_4aff55b4_scoped_true___WEBPACK_IMPORTED_MODULE_0__["staticRenderFns"]; }); + + + +/***/ }), + +/***/ "./resources/js/helpers.js": +/*!*********************************!*\ + !*** ./resources/js/helpers.js ***! + \*********************************/ +/*! exports provided: applyDrag, generateItems */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "applyDrag", function() { return applyDrag; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "generateItems", function() { return generateItems; }); +function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } + +function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } + +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } + +function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); } + +function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } + +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + +//for testing purposes +var applyDrag = function applyDrag(arr, dragResult) { + var removedIndex = dragResult.removedIndex, + addedIndex = dragResult.addedIndex, + payload = dragResult.payload; + if (removedIndex === null && addedIndex === null) return arr; + + var result = _toConsumableArray(arr); + + var itemToAdd = payload; + + if (removedIndex !== null) { + itemToAdd = result.splice(removedIndex, 1)[0]; + } + + if (addedIndex !== null) { + result.splice(addedIndex, 0, itemToAdd); + } + + return result; +}; +var generateItems = function generateItems(count, creator) { + var result = []; + + for (var i = 0; i < count; i++) { + result.push(creator(i)); + } + + return result; +}; + /***/ }), /***/ "./resources/sass/app.scss": diff --git a/public/canard/js/app.js b/public/canard/js/app.js index 9e68814..7cd07a3 100644 --- a/public/canard/js/app.js +++ b/public/canard/js/app.js @@ -2321,6 +2321,10 @@ __webpack_require__.r(__webpack_exports__); // // // +// +// +// +// /* harmony default export */ __webpack_exports__["default"] = ({ props: [], computed: { @@ -2341,7 +2345,8 @@ __webpack_require__.r(__webpack_exports__); success: false, errors: false, showConfirmEmpty: false, - response: '' + response: '', + promotion_slide: -1 }; }, mounted: function mounted() { @@ -2437,6 +2442,28 @@ __webpack_require__.r(__webpack_exports__); type: 'updateCartTotals', cartTotals: result[1] }); + }, + hover: function hover(zone, row_id) { + console.log(this.promotion_slide); + eval("this." + zone + "='" + row_id + "';"); + console.log(this.promotion_slide); + }, + //general purpose TODO : globalize + numFormatter: function numFormatter(num) { + return new Intl.NumberFormat('fr-FR', { + style: 'currency', + currency: 'EUR' + }).format(num); + }, + dateFormatter: function dateFormatter(str) { + var d = new Date(str); + var options = { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric' + }; + return d.toLocaleDateString("fr-FR", options); } } }); @@ -41554,22 +41581,6 @@ var render = function() { [_vm._m(1), _vm._v(" "), _vm._m(2)] ), _vm._v(" "), - _c( - "div", - { - directives: [ - { - name: "show", - rawName: "v-show", - value: !_vm.emptybasket, - expression: "!(emptybasket)" - } - ], - staticClass: "message-box" - }, - [_vm._m(3)] - ), - _vm._v(" "), _c("div", { directives: [ { @@ -41690,10 +41701,7 @@ var render = function() { "article", { staticClass: - "ds-product-card--largehorizontal ds-product-card", - attrs: { - id: "3560070820542" - } + "ds-product-card--largehorizontal ds-product-card" }, [ _c( @@ -41723,7 +41731,7 @@ var render = function() { ] ), _vm._v(" "), - _vm._m(4, true), + _vm._m(3, true), _vm._v(" "), _c( "div", @@ -41824,7 +41832,7 @@ var render = function() { }, [ _vm._v( - "\r\n " + + "\n " + _vm._s( item .cartItem @@ -41836,7 +41844,7 @@ var render = function() { .product .weight_unit ) + - "\r\n " + "\n " ) ] ) @@ -41881,13 +41889,13 @@ var render = function() { }, [ _vm._v( - "\r\n " + + "\n " + _vm._s( item .cartItem .name ) + - "\r\n " + "\n " ) ] ) @@ -41911,13 +41919,13 @@ var render = function() { }, [ _vm._v( - "\r\n " + + "\n " + _vm._s( item .product .sell_unit ) + - "\r\n " + "\n " ) ] ) @@ -41934,6 +41942,318 @@ var render = function() { "ds-product-card--largehorizontal-infos-sec" }, [ + _vm._l( + item.product + .promotions, + function( + promotion + ) { + return _c( + "div", + { + directives: [ + { + name: + "show", + rawName: + "v-show", + value: + item + .product + .calculatedPrices + .discountAmount > + 0, + expression: + "item.product.calculatedPrices.discountAmount>0" + } + ], + staticClass: + "ds-product-card--largehorizontal-promotion" + }, + [ + _c( + "div", + [ + _c( + "div", + { + staticClass: + "promotion-description promotion-description--loyalty" + }, + [ + _c( + "div", + { + staticClass: + "promotion-description__labels", + on: { + mouseover: function( + $event + ) { + return _vm.hover( + "promotion_slide", + item + .cartItem + .rowId + ) + }, + mouseleave: function( + $event + ) { + return _vm.hover( + "promotion_slide", + "-1" + ) + } + } + }, + [ + _c( + "p", + { + staticClass: + "promotion-label", + attrs: { + title: + item + .product + .calculatedPrices + .discountRate + + "% d'économies" + } + }, + [ + _c( + "span", + { + staticClass: + "promotion-label__txt" + }, + [ + _vm._v( + _vm._s( + item + .product + .calculatedPrices + .discountRate + ) + + "% d'économies" + ) + ] + ) + ] + ) + ] + ), + _vm._v( + " " + ), + _c( + "svg", + { + staticClass: + "promotion-description__icon-info", + attrs: { + focusable: + "false" + } + }, + [ + _c( + "use", + { + attrs: { + "xmlns:xlink": + "http://www.w3.org/1999/xlink", + "xlink:href": + "#icon-info" + } + } + ) + ] + ) + ] + ), + _vm._v( + " " + ), + _c( + "section", + { + directives: [ + { + name: + "show", + rawName: + "v-show", + value: + _vm.promotion_slide == + item + .cartItem + .rowId, + expression: + "promotion_slide == item.cartItem.rowId" + } + ], + staticClass: + "promotion-slide" + }, + [ + _c( + "header", + { + staticClass: + "promotion-slide__header promotion-slide__header--loyalty" + }, + [ + _c( + "p", + { + staticClass: + "promotion-slide__header-txt" + }, + [ + _c( + "svg", + { + staticClass: + "promotion-slide__icon-promo", + attrs: { + focusable: + "false" + } + }, + [ + _c( + "use", + { + attrs: { + "xmlns:xlink": + "http://www.w3.org/1999/xlink", + "xlink:href": + "#icon-carrefour-loyalty-card-hightlighted" + } + } + ) + ] + ), + _vm._v( + " " + ), + _c( + "span", + { + staticClass: + "promotion-slide__header-label" + }, + [ + _vm._v( + "\n Economisé\n " + ) + ] + ), + _vm._v( + " " + ), + _c( + "span", + { + staticClass: + "promotion-slide__header-discount" + }, + [ + _vm._v( + "\n " + + _vm._s( + _vm.numFormatter( + (Math.round( + (item + .product + .calculatedPrices + .priceTtc - + item + .product + .calculatedPrices + .discountedPriceTtc) * + 100 + ) / + 100) * + item + .cartItem + .qty + ) + ) + + "\n " + ) + ] + ) + ] + ) + ] + ), + _vm._v( + " " + ), + _c( + "p", + { + staticClass: + "promotion-slide__txt" + }, + [ + _c( + "span", + [ + _c( + "b", + [ + _vm._v( + _vm._s( + item + .product + .calculatedPrices + .discountRate + ) + + "% d'économies" + ) + ] + ), + _c( + "br" + ) + ] + ), + _vm._v( + " " + ), + _c( + "span", + { + staticClass: + "promotion-slide__end-date" + }, + [ + _vm._v( + "Offre valable jusqu'au " + + _vm._s( + _vm.dateFormatter( + promotion.date_end + ) + ) + ) + ] + ) + ] + ) + ] + ) + ] + ) + ] + ) + } + ), + _vm._v(" "), _c( "div", { @@ -41963,18 +42283,16 @@ var render = function() { }, [ _vm._v( - "\r\n " + + "\n " + _vm._s( - item - .cartItem - .price * - (1 + - item - .cartItem - .taxRate / - 100) + _vm.numFormatter( + item + .product + .calculatedPrices + .discountedPriceTtc + ) ) + - "€ TTC\r\n " + "\n " ) ] ) @@ -42073,13 +42391,13 @@ var render = function() { }, [ _vm._v( - "\r\n " + + "\n " + _vm._s( item .cartItem .qty ) + - "\r\n " + "\n " ) ] ), @@ -42143,14 +42461,15 @@ var render = function() { " " ), _vm._m( - 5, + 4, true ) ] ) ] ) - ] + ], + 2 ) ] ) @@ -42187,7 +42506,7 @@ var render = function() { "products-brief-data products-brief--items" }, [ - _vm._m(6), + _vm._m(5), _vm._v(" "), _c("dd", [ _c( @@ -42198,9 +42517,13 @@ var render = function() { }, [ _vm._v( - "\r\n " + - _vm._s(_vm.cartTotals.totalTTC) + - " €\r\n " + "\n " + + _vm._s( + _vm.numFormatter( + _vm.cartTotals.totalTTC + ) + ) + + "\n " ) ] ) @@ -42256,7 +42579,7 @@ var render = function() { ] ), _vm._v( - "\r\n Vider le panier\r\n " + "\n Vider le panier\n " ) ] ) @@ -42290,7 +42613,7 @@ var render = function() { "div", { staticClass: "modal__container" }, [ - _vm._m(7), + _vm._m(6), _vm._v(" "), _c( "div", @@ -42322,14 +42645,14 @@ var render = function() { }, [ _vm._v( - "\r\n Oui, vider mon panier\r\n " + "\n Oui, vider mon panier\n " ) ] ) ] ), _vm._v(" "), - _vm._m(8) + _vm._m(7) ]) ] ) @@ -42343,7 +42666,7 @@ var render = function() { ) ]), _vm._v(" "), - _vm._m(9) + _vm._m(8) ]) ]) ]) @@ -42364,7 +42687,7 @@ var render = function() { }, [ _vm._v( - "\r\n Total\r\n " + "\n Total\n " ) ] ), @@ -42377,15 +42700,17 @@ var render = function() { }, [ _vm._v( - "\r\n " + - _vm._s(_vm.cartTotals.totalTTC) + - " €\r\n " + "\n " + + _vm._s( + _vm.numFormatter(_vm.cartTotals.totalTTC) + ) + + "\n " ) ] ) ]), _vm._v(" "), - _vm._m(10) + _vm._m(9) ] ) ] @@ -42470,9 +42795,7 @@ var staticRenderFns = [ var _c = _vm._self._c || _h return _c("div", { staticClass: "basket-panel__title-wrapper" }, [ _c("span", { staticClass: "title title_medium" }, [ - _vm._v( - "\r\n Aperçu panier\r\n " - ) + _vm._v("\n Aperçu panier\n ") ]) ]) }, @@ -42486,52 +42809,6 @@ var staticRenderFns = [ [_c("span", [_vm._v("Fermer")])] ) }, - function() { - var _vm = this - var _h = _vm.$createElement - var _c = _vm._self._c || _h - return _c("div", { staticClass: "message-box__inner" }, [ - _c( - "div", - { - staticClass: - "message-box__heading message-box__icon message-box__icon--low" - }, - [ - _vm._v( - "\r\n Vous n’êtes pas connecté\r\n " - ) - ] - ), - _vm._v(" "), - _c("div", { staticClass: "message-box__body" }, [ - _vm._v( - "\r\n Connectez-vous ou créez votre compte pour passer votre commande\r\n " - ) - ]), - _vm._v(" "), - _c("a", { - staticClass: "message-box__alert-title", - attrs: { href: "#", target: "" } - }), - _vm._v(" "), - _c("div", { staticClass: "message-box__actions" }, [ - _c("div", [ - _c("a", { attrs: { href: "/connexion" } }, [ - _vm._v( - "\r\n Me connecter\r\n " - ) - ]), - _vm._v(" "), - _c("a", { attrs: { href: "/inscription" } }, [ - _vm._v( - "\r\n Créer mon compte\r\n " - ) - ]) - ]) - ]) - ]) - }, function() { var _vm = this var _h = _vm.$createElement @@ -42586,7 +42863,7 @@ var staticRenderFns = [ return _c("div", { staticClass: "modal__body" }, [ _c("div", { staticClass: "checkout-clear-basket__modal__title" }, [ _vm._v( - "\r\n Voulez-vous réellement vider votre panier ?\r\n " + "\n Voulez-vous réellement vider votre panier ?\n " ) ]) ]) @@ -42620,7 +42897,7 @@ var staticRenderFns = [ _c("section", { staticClass: "checkout-loyalty-info__top-section" }, [ _c("h3", { staticClass: "ds-title ds-title--bold ds-title--xs" }, [ _vm._v( - "\r\n Avantages fidélité\r\n " + "\n Avantages fidélité\n " ) ]) ]) @@ -42639,7 +42916,7 @@ var staticRenderFns = [ _c("a", { attrs: { href: "/commande/recap" } }, [ _c("span", { staticClass: "pl-button__label" }, [ _vm._v( - "\r\n Commander\r\n " + "\n Commander\n " ) ]) ]) @@ -56304,11 +56581,14 @@ module.exports = function(module) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */ var swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! swiper/swiper-bundle */ "./node_modules/swiper/swiper-bundle.js"); -/* harmony import */ var swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js"); -/* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var vuex__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vuex */ "./node_modules/vuex/dist/vuex.esm.js"); +/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"); +/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! swiper/swiper-bundle */ "./node_modules/swiper/swiper-bundle.js"); +/* harmony import */ var swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js"); +/* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var vuex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! vuex */ "./node_modules/vuex/dist/vuex.esm.js"); + @@ -56316,7 +56596,7 @@ __webpack_require__(/*! ./bootstrap */ "./resources/views/front/canard/js/bootst __webpack_require__(/*! ./cart.js */ "./resources/views/front/canard/js/cart.js"); -window.Toastify = toastify_js__WEBPACK_IMPORTED_MODULE_1___default.a; +window.Toastify = toastify_js__WEBPACK_IMPORTED_MODULE_2___default.a; window.Vue = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.common.js"); // Vuex @@ -56338,7 +56618,7 @@ Vue.component('basket-counter', { }, template: '{{ count }}' }); -var store = new vuex__WEBPACK_IMPORTED_MODULE_2__["default"].Store({ +var store = new vuex__WEBPACK_IMPORTED_MODULE_3__["default"].Store({ state: { panier: {}, cartTotals: {} @@ -56372,7 +56652,7 @@ var app = new Vue({ $(document).ready(function () { //document is ready we can free css transitions $('.preload').removeClass("preload"); - var mainslider = new swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_0___default.a('.mainslider .swiper-container', { + var mainslider = new swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_1___default.a('.mainslider .swiper-container', { pagination: { el: '.mainslider__pagination', bulletClass: 'slider-bullet', @@ -56380,7 +56660,7 @@ $(document).ready(function () { clickable: true } }); - var rp_slider = new swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_0___default.a('.rp-slider .swiper-container', { + var rp_slider = new swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_1___default.a('.rp-slider .swiper-container', { slidesPerView: 4, spaceBetween: 40, navigation: { @@ -56412,7 +56692,7 @@ $(document).ready(function () { } } }); - var rp_slider_mobile = new swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_0___default.a('.related-products-mobile .swiper-container', { + var rp_slider_mobile = new swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_1___default.a('.related-products-mobile .swiper-container', { slidesPerView: 4, spaceBetween: 20, navigation: { diff --git a/resources/js/app.js b/resources/js/app.js index b6fd958..d201a82 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -1,7 +1,13 @@ require('./bootstrap'); window.Vue = require('vue'); +// Vuex +// import Vuex from 'vuex'; +// import { Container, Draggable } from 'vue-smooth-dnd'; +// import { applyDrag, generateItems } from './helpers'; + Vue.component('faq', require('./components/Faq.vue').default); +Vue.component('products-cards-dnd', require('./components/ProductsCardsDnd.vue').default); const app = new Vue({ el: '#app', diff --git a/resources/js/components/ProductsCardsDnd.vue b/resources/js/components/ProductsCardsDnd.vue new file mode 100644 index 0000000..9cd56ef --- /dev/null +++ b/resources/js/components/ProductsCardsDnd.vue @@ -0,0 +1,214 @@ + + + + + diff --git a/resources/js/helpers.js b/resources/js/helpers.js new file mode 100644 index 0000000..e1b3762 --- /dev/null +++ b/resources/js/helpers.js @@ -0,0 +1,26 @@ +//for testing purposes +export const applyDrag = (arr, dragResult) => { + const { removedIndex, addedIndex, payload } = dragResult + if (removedIndex === null && addedIndex === null) return arr + + const result = [...arr] + let itemToAdd = payload + + if (removedIndex !== null) { + itemToAdd = result.splice(removedIndex, 1)[0] + } + + if (addedIndex !== null) { + result.splice(addedIndex, 0, itemToAdd) + } + + return result + } + +export const generateItems = (count, creator) => { + const result = [] + for (let i = 0; i < count; i++) { + result.push(creator(i)) + } + return result +} diff --git a/resources/views/bo/products/index.blade.php b/resources/views/bo/products/index.blade.php index 2aec890..4f94a40 100644 --- a/resources/views/bo/products/index.blade.php +++ b/resources/views/bo/products/index.blade.php @@ -51,5 +51,7 @@ @endforeach + {{ $products->links() }} + @endsection diff --git a/resources/views/bo/promotions/create.blade.php b/resources/views/bo/promotions/create.blade.php new file mode 100644 index 0000000..29f1f2c --- /dev/null +++ b/resources/views/bo/promotions/create.blade.php @@ -0,0 +1,54 @@ +@extends('layouts.bo-layout') + +@section('content') +
+ @csrf +
+

< Promotions Création

+
+
+
+ @if ($errors->any()) +
+
    + @foreach ($errors->all() as $error) +
  • {{ $error }}
  • + @endforeach +
+
+ @endif + + {{-- //TODO implementer plus tard --}} + +
+ + +
+
+
+ + +
+
+ + + montant ou pourcentage de remise selon le type choisi +
+
+ + + +
+
+ + + +
+
+
+@endsection diff --git a/resources/views/bo/promotions/edit.blade.php b/resources/views/bo/promotions/edit.blade.php new file mode 100644 index 0000000..ff1b6c0 --- /dev/null +++ b/resources/views/bo/promotions/edit.blade.php @@ -0,0 +1,56 @@ +@extends('layouts.bo-layout') + +@section('content') +
+ @method('PUT') + @csrf +
+

< Promotion Modification

+ @if (session('success')) + {{ session('success') }} + @endif +
+
+
+ @if ($errors->any()) +
+
    + @foreach ($errors->all() as $error) +
  • {{ $error }}
  • + @endforeach +
+
+ @endif + +
+ + products->pluck('id')->all())) }}" required> +
+
+
+ + +
+
+ + + montant ou pourcentage de remise selon le type choisi +
+
+ + + +
+
+ + + +
+
+
+@endsection diff --git a/resources/views/bo/promotions/index.blade.php b/resources/views/bo/promotions/index.blade.php new file mode 100644 index 0000000..ea20917 --- /dev/null +++ b/resources/views/bo/promotions/index.blade.php @@ -0,0 +1,61 @@ +@extends('layouts.bo-layout') + +@section('content') +
+

Promotions Liste

+ + @if ($errors->any()) + @foreach($errors->all() as $error) + {{ $error }} + @endforeach + @endif + Créer une promotion +
+ + + + + + + + + + + @foreach ($promotions as $promotion) + + + + + + + @endforeach + +
TypeValeurDébutFinProduits Concernés
{{$promotion->discountType->label}} + {{$promotion->discount_value}} + {{$promotion->date_start}}{{$promotion->date_end}} + @foreach ($promotion->products as $product) +
+ {{$product->name}} +
+
{{$product->name}}
+ Prix HT avant promo : {{$product->price}} +

Prix HT après promo : + @if ($promotion->discountType->id == 1) + {{$product->price-$promotion->discount_value}} + @else + {{$product->price-($product->price*$promotion->discount_value/100)}} + @endif +

+
+
+ @endforeach +
+ Éditer +
+ @method('DELETE') + @csrf + +
+
+@endsection diff --git a/resources/views/front/canard/js/app.js b/resources/views/front/canard/js/app.js index ff9224e..3091688 100644 --- a/resources/views/front/canard/js/app.js +++ b/resources/views/front/canard/js/app.js @@ -1,3 +1,4 @@ +import { isWindow } from 'jquery'; import Swiper from 'swiper/swiper-bundle'; import Toastify from "toastify-js"; require('./bootstrap'); diff --git a/resources/views/front/canard/js/components/BasketPanel.vue b/resources/views/front/canard/js/components/BasketPanel.vue index 37e025e..adfc3cc 100644 --- a/resources/views/front/canard/js/components/BasketPanel.vue +++ b/resources/views/front/canard/js/components/BasketPanel.vue @@ -60,7 +60,7 @@ Fermer -
+
- +
@@ -132,7 +132,7 @@
  1. -
    +
    @@ -193,38 +193,43 @@
- +
-
-

20% d'économies

-
+
+

+ {{ item.product.calculatedPrices.discountRate }}% d'économies +

+
+
-
- -->
- {{ (item.cartItem.price * (1+item.cartItem.taxRate/100)) }}€ TTC + {{ numFormatter(item.product.calculatedPrices.discountedPriceTtc) }}
@@ -275,7 +280,7 @@
- {{cartTotals.totalTTC}} € + {{numFormatter(cartTotals.totalTTC)}}
@@ -335,7 +340,7 @@ Total

- {{cartTotals.totalTTC}} € + {{numFormatter(cartTotals.totalTTC)}}

+
- +
-
+
Offre spéciale
- Bloc de foie gras avec 30% de morceaux 450 g en terrine - + {{ $product->name }} +
- 3,80€/pièce -
10,00€/pièce
+ @fmt_currency($product->discountedPriceTtc) / {{ $product->sell_unit }} +
@fmt_currency($product->priceTtc)/{{ $product->sell_unit }}
- +
- +
- + @endforeach + {{-- Fin Section offre spéciale --}} @foreach ($products as $product)
{{ $product->name }}
-
{{ $product->formattedPriceTTC }}/{{ $product->sell_unit }}
+
@fmt_currency($product->discountedPriceTtc)/{{ $product->sell_unit }}
diff --git a/resources/views/front/canard/product.blade.php b/resources/views/front/canard/product.blade.php index 4c4268d..43be1d2 100644 --- a/resources/views/front/canard/product.blade.php +++ b/resources/views/front/canard/product.blade.php @@ -25,7 +25,7 @@
-
{{ $product->formattedPriceTTC }}/pièce
+
@fmt_currency($product->discountedPriceTtc)/{{$product->sell_unit}}
- diff --git a/resources/views/front/canard/sales/confirm.blade.php b/resources/views/front/canard/sales/confirm.blade.php index 1ad9e94..3cc8fc0 100644 --- a/resources/views/front/canard/sales/confirm.blade.php +++ b/resources/views/front/canard/sales/confirm.blade.php @@ -26,12 +26,12 @@ Une confirmation vient de vous être envoyée sur l’adresse mail {{ $order->cu
{{ $line->quantity }} x
{{ $line->product->name }}
-
{{ $line->total_ttc }} €
+
{{ $line->formattedTotalTtc }}
@endforeach
Total
-
{{ $order->total }} €
+
{{ $order->formattedTotalTtc }}
A retirer le {{$order->timeslot->day}} à {{$order->timeslot->time}}, à l’adresse suivante :
diff --git a/resources/views/front/canard/sales/recap.blade.php b/resources/views/front/canard/sales/recap.blade.php index 4eb7655..708c6da 100644 --- a/resources/views/front/canard/sales/recap.blade.php +++ b/resources/views/front/canard/sales/recap.blade.php @@ -53,7 +53,7 @@
- {{ $cartItem->price }} € / {{ $cartItem->model->sell_unit }} + @fmt_currency($cartItem->model->discountedPriceTtc) / {{ $cartItem->model->sell_unit }}
@@ -95,8 +95,8 @@
-
{{ $cartItem->price }} €
-
{{ $cartItem->price * $cartItem->qty }} €
+
@fmt_currency($cartItem->model->discountedPriceTtc)
+
{{ sprintf('%s €', number_format($cartItem->model->discountedPriceTtc * $cartItem->qty, 2, ',', ' ')) }}
@endforeach diff --git a/resources/views/layouts/bo-layout.blade.php b/resources/views/layouts/bo-layout.blade.php index c02a8bb..1be2557 100644 --- a/resources/views/layouts/bo-layout.blade.php +++ b/resources/views/layouts/bo-layout.blade.php @@ -60,6 +60,49 @@ Gammes de produits +
+ {{--
+
+

+ +

+
+ +
+ +
+
--}} +
+
+

+ +

+
+ + +
+