From 86f6ee9a13abe0a5241a48e03280fd583702113e Mon Sep 17 00:00:00 2001 From: Ludovic CANDELLIER Date: Tue, 26 Oct 2021 21:41:46 +0200 Subject: [PATCH] Synchro back-office, fix on tariffs --- Gruntfile.js | 33 +- app/Contracts/Commentator.php | 15 + .../Admin/Core/CommentsDataTable.php | 2 +- app/Datatables/Shop/ArticlesDataTable.php | 17 +- app/Http/Controllers/Controller.php | 8 + .../Controllers/Shop/CategoryController.php | 10 +- app/Http/Controllers/Shop/HomeController.php | 17 +- app/Models/Core/Comment.php | 66 ++- app/Models/Shop/Article.php | 16 +- app/Models/Shop/Category.php | 5 + app/Models/Shop/Offer.php | 30 +- app/Models/Shop/PriceList.php | 3 +- app/Models/Shop/Tariff.php | 3 +- app/Models/Shop/Variation.php | 2 +- app/Repositories/Botanic/Species.php | 2 +- app/Repositories/Botanic/Varieties.php | 2 +- .../Core/Auth/UserStatusTeams.php | 26 - app/Repositories/Core/Auth/UserStatuses.php | 100 ---- app/Repositories/Core/DateTime.php | 59 +- app/Repositories/Core/Media.php | 55 -- app/Repositories/Core/Medias.php | 99 ++++ app/Repositories/Shop/Articles.php | 19 +- app/Repositories/Shop/Categories.php | 5 + app/Repositories/Shop/Offers.php | 11 +- app/Repositories/Shop/Tags.php | 6 + app/Traits/CanComment.php | 11 + app/Traits/HasComments.php | 36 ++ build/css/site.css | 27 + build/js/site.js | 18 + build/js/taxonomy-browser.js | 520 ++++++++++++++++++ composer.json | 10 +- .../partials/characteristics.blade.php | 4 +- .../partials/product/description.blade.php | 2 +- .../views/Admin/Shop/Offers/form.blade.php | 20 +- .../Admin/Shop/PriceLists/modal.blade.php | 101 ++-- .../views/Admin/Shop/Tariffs/form.blade.php | 9 +- resources/views/Shop/home.blade.php | 5 +- resources/views/Shop/home2.twig | 57 -- resources/views/Shop/layout/layout.blade.php | 6 +- .../Shop/layout/partials/article.blade.php | 6 +- .../partials/category_articles.blade.php | 4 +- .../Shop/layout/partials/sections.blade.php | 10 +- .../Shop/layout/partials/submenu.blade.php | 19 + resources/views/Shop/shelve.blade.php | 21 + routes/Shop/route.php | 4 +- 45 files changed, 1095 insertions(+), 406 deletions(-) create mode 100644 app/Contracts/Commentator.php delete mode 100644 app/Repositories/Core/Auth/UserStatusTeams.php delete mode 100644 app/Repositories/Core/Auth/UserStatuses.php delete mode 100644 app/Repositories/Core/Media.php create mode 100644 app/Repositories/Core/Medias.php create mode 100644 app/Traits/CanComment.php create mode 100644 app/Traits/HasComments.php create mode 100644 build/js/site.js create mode 100644 build/js/taxonomy-browser.js delete mode 100644 resources/views/Shop/home2.twig create mode 100644 resources/views/Shop/layout/partials/submenu.blade.php create mode 100644 resources/views/Shop/shelve.blade.php diff --git a/Gruntfile.js b/Gruntfile.js index 34a3bf61..e020f183 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -14,6 +14,19 @@ var jsCompat = [ 'node_modules/es6-promise/dist/es6-promise.min.js', ] +var jsSite = [ + jsBase, + jsBootstrap, + 'build/js/site.js', +] + +var cssSite = [ + 'node_modules/bootstrap/dist/css/bootstrap.min.css', + 'node_modules/@fortawesome/fontawesome-free/css/all.min.css', + 'node_modules/animate.css/animate.min.css', + 'build/css/site.css', +] + var jsAdminLTE = [ jsBase, jsBootstrap, @@ -88,7 +101,7 @@ var jsMain = [ var cssPrint = [ // 'node_modules/bootstrap/dist/css/bootstrap.min.css', - 'node_modules/@fortawesome/fontawesome-free/css/fontawesome.min.css', + 'cssIcons', 'build/print.css' ] @@ -179,7 +192,8 @@ module.exports = function(grunt) { 'public/assets/js/main.min.js': jsMain, 'public/assets/css/main.min.css': cssMain, 'public/assets/plugins/datatables.min.js': jsDataTables, - 'public/assets/plugins/adminlte/adminlte.min.js': jsAdminLTE + 'public/assets/plugins/adminlte/adminlte.min.js': jsAdminLTE, + 'public/js/site.min.js': jsSite, }, ] }, @@ -194,6 +208,14 @@ module.exports = function(grunt) { options: { separator: '\n' }, + sitecss: { + src: cssSite, + dest: 'public/css/site.min.css' + }, + siteJs: { + src: jsSite, + dest: 'public/js/site.min.js' + }, mainjs: { src: jsMain, dest: 'public/assets/js/main.min.js' @@ -232,6 +254,9 @@ module.exports = function(grunt) { { 'public/assets/css/print.min.css': cssPrint }, + { + 'public/css/site.min.css': cssSite + }, ] } }, @@ -242,13 +267,13 @@ module.exports = function(grunt) { expand: true, cwd: 'node_modules/@fortawesome/fontawesome-free/webfonts/', src: ['**'], - dest: 'public/assets/fonts/' + dest: 'public/webfonts/' }, { expand: true, cwd: 'build/fonts', src: ['**'], - dest: 'public/assets/fonts/' + dest: 'public/webfonts/' }, { expand: true, diff --git a/app/Contracts/Commentator.php b/app/Contracts/Commentator.php new file mode 100644 index 00000000..40e963a4 --- /dev/null +++ b/app/Contracts/Commentator.php @@ -0,0 +1,15 @@ +withCount(['categories', 'tags'])->joinRelationship('article_nature'); + $model = $model::with(['article_nature','image'])->withCount(['categories', 'tags'])->joinRelationship('article_nature'); $model = self::filterByArticleNature($model); return self::buildQuery($model); } @@ -25,10 +26,22 @@ class ArticlesDataTable extends DataTable return $article_nature_id ? $model->byArticleNature($article_nature_id) : $model; } + public function modifier($datatables) + { + $datatables + ->editColumn('thumb', function (Article $article) { + return Articles::getThumbsSrc($article->image); + }) + ->rawColumns(['thumb','action']); + return parent::modifier($datatables); + } + + protected function getColumns() { return [ Column::make('article_nature.name')->title('Nature'), + Column::make('thumb')->searchable(false), Column::make('name')->title('Nom'), Column::make('tags_count')->title('Tags')->class('text-right')->searchable(false), Column::make('categories_count')->title('Rayons')->class('text-right')->searchable(false), diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index a0a2a8a3..7a1b8d4c 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -7,7 +7,15 @@ use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Routing\Controller as BaseController; +use App\Repositories\Shop\Categories; + class Controller extends BaseController { use AuthorizesRequests, DispatchesJobs, ValidatesRequests; + + public static function init() + { + $data['categories'] = Categories::getTree(); + return $data; + } } diff --git a/app/Http/Controllers/Shop/CategoryController.php b/app/Http/Controllers/Shop/CategoryController.php index b05c35f8..65b488ab 100644 --- a/app/Http/Controllers/Shop/CategoryController.php +++ b/app/Http/Controllers/Shop/CategoryController.php @@ -6,11 +6,11 @@ use Illuminate\Http\Request; use App\Http\Controllers\Controller; use App\Repositories\Shop\Categories; -use App\Datatables\Shop\CategoriesDataTable; +use App\Repositories\Shop\Offers; class CategoryController extends Controller { - public function index(CategoriesDataTable $dataTable) + public function index() { return $dataTable->render('Shop.Categories.list'); } @@ -22,8 +22,10 @@ class CategoryController extends Controller public function show($id) { - $data = Categories::get($id); - return view('Shop.Categories.view', $data); + $data = self::init(); + $data['category'] = Categories::getByCategory($id)->toArray(); + $data['offers'] = Offers::getByCategory($id)->toArray(); + return view('Shop.shelve', $data); } public function getTree() diff --git a/app/Http/Controllers/Shop/HomeController.php b/app/Http/Controllers/Shop/HomeController.php index 8836a637..d5afb2b3 100644 --- a/app/Http/Controllers/Shop/HomeController.php +++ b/app/Http/Controllers/Shop/HomeController.php @@ -7,30 +7,19 @@ use App\Http\Controllers\Controller; use App\Repositories\Shop\Articles; use App\Repositories\Shop\Categories; +use App\Repositories\Shop\Offers; class HomeController extends Controller { - /** - * Create a new controller instance. - * - * @return void - */ public function __construct() { // $this->middleware('auth'); } - /** - * Show the application dashboard. - * - * @return \Illuminate\Contracts\Support\Renderable - */ public function index() { - $data['categories'] = Categories::getTree(); - $data['category'] = Categories::get(15)->toArray(); - $data['articles'] = Articles::getByCategory(0)->toArray(); - // dump($data); + $data = self::init(); + $data['offers'] = Offers::getLast()->toArray(); return view('Shop.home', $data); } } diff --git a/app/Models/Core/Comment.php b/app/Models/Core/Comment.php index 3d72debc..7e1f8bb5 100644 --- a/app/Models/Core/Comment.php +++ b/app/Models/Core/Comment.php @@ -2,22 +2,68 @@ namespace App\Models\Core; +use Exception; use Illuminate\Database\Eloquent\Model; -use Illuminate\Database\Eloquent\SoftDeletes; - -use App\Repositories\Core\DateTime; +use App\Traits\HasComments; class Comment extends Model { - protected $guarded = []; + use HasComments; - public function user() + protected $fillable = [ + 'comment', + 'user_id', + 'is_approved' + ]; + + protected $casts = [ + 'is_approved' => 'boolean' + ]; + + public function scopeApproved($query) { - return $this->belongsTo(\App\Models\Core\Auth\User::class); + return $query->where('is_approved', true); } - public function getUpdatedAtAttribute($value) + public function commentable() { - return DateTime::DateToLocale($value); - } -} \ No newline at end of file + return $this->morphTo(); + } + + public function commentator() + { + return $this->belongsTo($this->getAuthModelName(), 'user_id'); + } + + public function approve() + { + $this->update([ + 'is_approved' => true, + ]); + + return $this; + } + + public function disapprove() + { + $this->update([ + 'is_approved' => false, + ]); + + return $this; + } + + protected function getAuthModelName() + { + if (config('comments.user_model')) { + return config('comments.user_model'); + } + + if (!is_null(config('auth.providers.users.model'))) { + return config('auth.providers.users.model'); + } + + throw new Exception('Could not determine the commentator model name.'); + } + +} diff --git a/app/Models/Shop/Article.php b/app/Models/Shop/Article.php index 0fdabaa3..8475ba50 100644 --- a/app/Models/Shop/Article.php +++ b/app/Models/Shop/Article.php @@ -10,13 +10,14 @@ use Spatie\MediaLibrary\HasMedia; use Spatie\MediaLibrary\InteractsWithMedia; use Spatie\MediaLibrary\MediaCollections\Models\Media; -use BeyondCode\Comments\Traits\HasComments; use Rinvex\Categories\Traits\Categorizable; use Rinvex\Tags\Traits\Taggable; use Kirschbaum\PowerJoins\PowerJoins; use Fico7489\Laravel\EloquentJoin\Traits\EloquentJoin; use Wildside\Userstamps\Userstamps; +use App\Traits\HasComments; + class Article extends Model implements HasMedia { use Categorizable, EloquentJoin, HasComments, InteractsWithMedia, Powerjoins, Taggable, SoftDeletes, UserStamps; @@ -44,6 +45,11 @@ class Article extends Model implements HasMedia return $this->hasMany(InvoiceItem::class); } + public function offers() + { + return $this->hasMany(Offer::class); + } + public function prices() { return $this->hasMany(Price::class); @@ -66,6 +72,9 @@ class Article extends Model implements HasMedia public function scopeByCategory($query, $category_id) { + return $query->whereHas('categories', function ($query) use ($category_id) { + $query->where('id', $category_id); + }); } public function scopeByArticleNature($query, $id) @@ -83,6 +92,11 @@ class Article extends Model implements HasMedia return $query->where($this->table . '.product_id', $model_id); } + public function scopeWithOffers($query) + { + return $query->has('Offers'); + } + public function registerMediaConversions(Media $media = null) : void { $this->addMediaConversion('thumb')->fit(Manipulations::FIT_CROP, 32, 32); diff --git a/app/Models/Shop/Category.php b/app/Models/Shop/Category.php index 5ce69da8..09c3c8a3 100644 --- a/app/Models/Shop/Category.php +++ b/app/Models/Shop/Category.php @@ -35,4 +35,9 @@ class Category extends Model return $this->belongsTo(app('rinvex.categories.category'),'category_id'); } + public function scopeByCategory($query, $category_id) + { + return $query->where('category_id', $category_id); + } + } diff --git a/app/Models/Shop/Offer.php b/app/Models/Shop/Offer.php index cc8c584a..fd7ddc70 100644 --- a/app/Models/Shop/Offer.php +++ b/app/Models/Shop/Offer.php @@ -4,7 +4,8 @@ namespace App\Models\Shop; use Illuminate\Database\Eloquent\Model; -use BeyondCode\Comments\Traits\HasComments; +use App\Traits\HasComments; + class Offer extends Model { use HasComments; @@ -17,6 +18,11 @@ class Offer extends Model return $this->belongsTo(Article::class); } + public function categories() + { + return $this->article->categories(); + } + public function variation() { return $this->belongsTo(Variation::class); @@ -26,4 +32,26 @@ class Offer extends Model { return $this->belongsTo(Tariff::class); } + + public function scopeByArticle($query, $id) + { + return $query->where('article_id', $id); + } + + public function scopeByCategory($query, $category_id) + { + return $query->whereHas('article.categories', function ($query) use ($category_id) { + $query->where('category_id', $category_id); + }); + } + + public function scopeByStatus($query, $id) + { + return $query->where('status_id', $id); + } + + public function scopeByVariation($query, $id) + { + return $query->where('variation_id', $id); + } } diff --git a/app/Models/Shop/PriceList.php b/app/Models/Shop/PriceList.php index 83619f0c..4c4de2ac 100644 --- a/app/Models/Shop/PriceList.php +++ b/app/Models/Shop/PriceList.php @@ -4,9 +4,10 @@ namespace App\Models\Shop; use Illuminate\Database\Eloquent\Model; -use BeyondCode\Comments\Traits\HasComments; use Znck\Eloquent\Traits\BelongsToThrough; +use App\Traits\HasComments; + class PriceList extends Model { use BelongsToThrough, HasComments; diff --git a/app/Models/Shop/Tariff.php b/app/Models/Shop/Tariff.php index d0705130..9c8e1419 100644 --- a/app/Models/Shop/Tariff.php +++ b/app/Models/Shop/Tariff.php @@ -5,9 +5,10 @@ namespace App\Models\Shop; use Illuminate\Database\Eloquent\Model; use Staudenmeir\EloquentHasManyDeep\HasRelationships; -use BeyondCode\Comments\Traits\HasComments; use Kirschbaum\PowerJoins\PowerJoins; +use App\Traits\HasComments; + class Tariff extends Model { use HasComments, HasRelationships, PowerJoins; diff --git a/app/Models/Shop/Variation.php b/app/Models/Shop/Variation.php index 645c3016..b44698e8 100644 --- a/app/Models/Shop/Variation.php +++ b/app/Models/Shop/Variation.php @@ -4,7 +4,7 @@ namespace App\Models\Shop; use Illuminate\Database\Eloquent\Model; -use BeyondCode\Comments\Traits\HasComments; +use App\Traits\HasComments; class Variation extends Model { use HasComments; diff --git a/app/Repositories/Botanic/Species.php b/app/Repositories/Botanic/Species.php index d9526132..2c541265 100644 --- a/app/Repositories/Botanic/Species.php +++ b/app/Repositories/Botanic/Species.php @@ -52,7 +52,7 @@ class Species public static function get($id) { - return Specie::findOrFail($id); + return Specie::with('tags.group')->findOrFail($id); } public static function storeFull($data) diff --git a/app/Repositories/Botanic/Varieties.php b/app/Repositories/Botanic/Varieties.php index 82705353..91cbb367 100644 --- a/app/Repositories/Botanic/Varieties.php +++ b/app/Repositories/Botanic/Varieties.php @@ -46,7 +46,7 @@ class Varieties public static function get($id) { - return Variety::findOrFail($id); + return Variety::with('tags.group')->findOrFail($id); } public static function getFull($id) diff --git a/app/Repositories/Core/Auth/UserStatusTeams.php b/app/Repositories/Core/Auth/UserStatusTeams.php deleted file mode 100644 index 895eaa22..00000000 --- a/app/Repositories/Core/Auth/UserStatusTeams.php +++ /dev/null @@ -1,26 +0,0 @@ -delete(); - } - - // associe une équipe avec un statut utilisateur - public function insert_team($user_status_id, $team_id) - { - return UserStatusTeam::create(['team_id' => $team_id, 'user_status_id' => $user_status_id]); - } - - // récupère les équipes d'un statut utilisateur donné - public function select_teams_by_id($id) - { - return UserStatusTeam::select('team_id')->byUserStatus($id)->get(); - } -} diff --git a/app/Repositories/Core/Auth/UserStatuses.php b/app/Repositories/Core/Auth/UserStatuses.php deleted file mode 100644 index 775c06c0..00000000 --- a/app/Repositories/Core/Auth/UserStatuses.php +++ /dev/null @@ -1,100 +0,0 @@ - $name, 'translated' => $translated, 'negociator' => $negociator]); - } - - // reset le négociateur parmi les statuts - public static function reset_negociator_status() - { - return UserStatus::update(['negociator' => null]); - } - - // récupère toutes les infos sur les statuts utilisateur - public static function select_all() - { - return UserStatus::all()->toArray(); - } - - // récupère les infos pour un statut utilisateur donné - public static function select_by_id($id) - { - return UserStatus::find($id)->toArray(); - } - - // récupère les infos pour un statut utilisateur donné - public static function select_by_name($name) - { - return UserStatus::byName($name)->first()->toArray(); - } - - // récupère les infos du statut considéré comme négociant d'un contrat - public static function select_by_negociator() - { - $status = UserStatus::byNegociator()->first(); - return $status ? $status->toArray() : null; - } - - // met à jour le statut actif/inactif d'un statut utilisateur - public static function toggle_active($id, $active) - { - return UserStatus::find($id)->update(['active' => $active]); - } - - // met à jour les informations d'un statut utilisateur - public static function update($id, $name, $translated, $negociator) - { - return UserStatus::find($id)->update(['id' => $id, 'name' => $name, 'translated' => $translated, 'negociator' => $negociator]); - } - - // met à jour les informations d'un statut utilisateur - public static function update_negociator($id, $negociator) - { - return UserStatus::find($id)->update(['negociator' => $negociator]); - } - - public static function getAllUserStatuses($input) - { - $data = []; - $statuses = self::select_all(); - foreach ($statuses as $status) { - if ($status['active'] <= 0) { - continue; - } - $item = array(); - $item['id'] = $status['id']; - $item['name'] = \App\Repositories\Translate::translateClient($status['translated']); - array_push($data, $item); - } - $data = \App\Repositories\Functions::array_orderby($data, 'name', SORT_ASC); - return $data; - } - - public static function getOptions() - { - return UserStatus::orderBy('name', 'asc')->get()->pluck('name', 'id')->toArray(); - } - - public static function getNegociatorsOptions() - { - } -} diff --git a/app/Repositories/Core/DateTime.php b/app/Repositories/Core/DateTime.php index 5580341b..a396eab2 100644 --- a/app/Repositories/Core/DateTime.php +++ b/app/Repositories/Core/DateTime.php @@ -36,7 +36,7 @@ class DateTime if (!is_null($date) && !empty($date)) { $date = Carbon::parse($date)->format($format); } elseif ($date == 'now') { - $date = Carbon::now()->format($format); + $date = today()->format($format); } return $date; } @@ -47,7 +47,7 @@ class DateTime if (!is_null($date) && !empty($date)) { $date = Carbon::parse($date)->format($format); } elseif ($date == 'now') { - $date = Carbon::now()->format($format); + $date = now()->format($format); } return $date; } @@ -76,6 +76,9 @@ class DateTime public static function convertTime($date) { $format = self::getLocaleFormatDatetime(); + if (strlen($date) == 16) { + $date .= ':00'; + } return !empty($date) ? Carbon::createFromFormat($format, $date)->isoFormat('Y-MM-DD HH:mm:ss') : null; } @@ -102,12 +105,12 @@ class DateTime { $locale = self::getLang(); switch ($locale) { - case 'fr': - case 'en': - $format = 'd/m/Y'; - break; - default: - $format = 'Y-m-d'; + case 'fr': + case 'en': + $format = 'd/m/Y'; + break; + default: + $format = 'Y-m-d'; } return $format; } @@ -116,29 +119,45 @@ class DateTime { $locale = self::getLang(); switch ($locale) { - case 'fr': - case 'en': - $format = 'd/m/Y H:i:s'; - break; - default: - $format = 'Y-m-d H:i:s'; + case 'fr': + case 'en': + $format = 'd/m/Y H:i:s'; + break; + default: + $format = 'Y-m-d H:i:s'; } return $format; } - public static function getLocaleDateFull($date) + public static function getLocaleDateFull($date = false) { - return Carbon::parse($date)->isoFormat('LLLL'); + return self::getISOFormat('LL', $date); } - public static function getLocaleDateFullShort($date) + public static function getLocaleDateTimeFull($date = false) { - return Carbon::parse($date)->isoFormat('lll'); + return self::getISOFormat('LLL', $date); } - public static function getLocaleHour($date) + public static function getLocaleDateFullShort($date = false) { - return Carbon::parse($date)->isoFormat(''); + return self::getISOFormat('ll', $date); + } + + public static function getLocaleDateTimeFullShort($date = false) + { + return self::getISOFormat('lll', $date); + } + + public static function getLocaleTime($date = false) + { + return self::getISOFormat('LT', $date); + } + + public static function getISOFormat($format, $date = false) + { + $date = $date ? $date : now(); + return Carbon::parse($date)->isoFormat($format); } public static function relativeTime() diff --git a/app/Repositories/Core/Media.php b/app/Repositories/Core/Media.php deleted file mode 100644 index 222a22d1..00000000 --- a/app/Repositories/Core/Media.php +++ /dev/null @@ -1,55 +0,0 @@ -getMedia(); - foreach ($model->media as $key => $media) { - $model->media[$key]['url'] = $media->getUrl(); - } - return $model->media; - } - - public static function storeImages($model, $files) - { - if ($files) { - foreach ($files as $file) { - self::storeImage($model, $file); - } - } - } - - public static function storeImage($model, $file) - { - return $model->addMedia($file)->toMediaCollection('images'); - } - - public static function deleteImage($model, $index) - { - $model->getMedia(); - $ret = $model->media[$index]->delete(); - return "1"; - } - - public static function getThumbSrc($image) - { - if (!$image) { - return null; - } - $id = $image['id']; - $images = json_decode($image['responsive_images'], true); - /* - $urls = $images['medialibrary_original']['urls']; - - $img = $urls[count($urls)-1]; - $src = "storage/$id/responsive-images/$img"; - */ - return $src ?? null; - } -} diff --git a/app/Repositories/Core/Medias.php b/app/Repositories/Core/Medias.php new file mode 100644 index 00000000..f1257138 --- /dev/null +++ b/app/Repositories/Core/Medias.php @@ -0,0 +1,99 @@ +getMedia($collection)->first(); + return $img ? $img->getUrl($conversion) : false; + } + + public static function getImages($model) + { + if (!$model) { + return false; + } + $model->getMedia(); + foreach ($model->media as $key => $media) { + $model->media[$key]['url'] = $media->getUrl(); + } + return $model->media; + } + + public static function storeImages($model, $files) + { + if ($files) { + foreach ($files as $file) { + self::storeImage($model, $file); + } + } + } + + public static function storeImage($model, $file, $collection = 'images') + { + return $model->addMedia($file)->sanitizingFileName(function ($fileName) { + return str_replace(['#', '/', '\\', ' '], '-', $fileName); + })->toMediaCollection($collection); + } + + public static function deleteImages($model, $collection = 'images') + { + $ret = $model->clearMediaCollection($collection); + return true; + } + + public static function deleteImage($model, $index) + { + $model->getMedia(); + $ret = $model->media[$index]->delete(); + return true; + } + + public static function buildURL($image, $conversion = '') + { + return self::getPath($image) . self::getConversion($image, $conversion); + } + + public static function getPath($image) + { + $model = basename(str_replace('\\', '/', $image->model_type)); + return '/storage/' . $model . '/' . $image->collection_name . '/' . $image->id; + } + + public static function getConversion($image, $conversion = '') + { + // return $conversion ? '/conversions/' . $image->name . '-' . $conversion . self::getExtension($image->file_name) : $image->file_name; + return $conversion ? '/conversions/' . $image->name . '-' . $conversion . '.jpg' : $image->file_name; + } + + public static function getExtension($filename) + { + return '.' . pathinfo($filename, PATHINFO_EXTENSION); + } + + public static function getThumbSrc($image) + { + if (!$image) { + return null; + } + $id = $image['id']; + $filename = $image['name'] . '-thumb' . self::getExtension($image['file_name']); + + return "/storage/$id/conversions/$filename"; + } + + public static function getPreviewSrc($image) + { + if (!$image) { + return null; + } + $id = $image['id']; + $filename = $image['name'] . '-preview' . self::getExtension($image['file_name']); + + return "/storage/$id/conversions/$filename"; + } + +} diff --git a/app/Repositories/Shop/Articles.php b/app/Repositories/Shop/Articles.php index 0343e140..1a11b408 100644 --- a/app/Repositories/Shop/Articles.php +++ b/app/Repositories/Shop/Articles.php @@ -5,7 +5,7 @@ namespace App\Repositories\Shop; use Illuminate\Support\Str; use App\Repositories\Core\Tag; -use App\Repositories\Core\Media; +use App\Repositories\Core\Medias; use App\Repositories\Core\Comments; use App\Repositories\Botanic\Species; use App\Repositories\Botanic\Varieties; @@ -74,7 +74,7 @@ class Articles public static function getInherited($id) { - $article = Article::with('product.tags')->findOrFail($id); + $article = Article::with('product.tags.group')->findOrFail($id); $product_type = $article->product_type; switch ($product_type) { case 'App\Models\Botanic\Variety': @@ -245,26 +245,31 @@ class Articles public static function storeImages($article, $files) { - return Media::storeImages($article, $files); + return Medias::storeImages($article, $files); } public static function storeImage($article, $file) { - return Media::storeImage($article, $file); + return Medias::storeImage($article, $file); } public static function getImages($id) { - return Media::getImages(self::get($id)); + return Medias::getImages(self::get($id)); } public static function getThumbSrc($image) { - return Media::getThumbSrc($image); + return Medias::getThumbSrc($image); + } + + public static function getPreviewSrc($image) + { + return Medias::getPreviewSrc($image); } public static function deleteImage($id, $index) { - return Media::deleteImage(self::get($id), $index); + return Medias::deleteImage(self::get($id), $index); } } diff --git a/app/Repositories/Shop/Categories.php b/app/Repositories/Shop/Categories.php index ef5484f9..2010cfa9 100644 --- a/app/Repositories/Shop/Categories.php +++ b/app/Repositories/Shop/Categories.php @@ -16,6 +16,11 @@ class Categories return Category::with('CategoryTree')->find($id); } + public static function getByCategory($category_id) + { + return Category::byCategory($category_id)->first(); + } + public static function getTree() { return CategoryTrees::getTree(); diff --git a/app/Repositories/Shop/Offers.php b/app/Repositories/Shop/Offers.php index 7f190e60..4e797989 100644 --- a/app/Repositories/Shop/Offers.php +++ b/app/Repositories/Shop/Offers.php @@ -6,14 +6,15 @@ use App\Models\Shop\Offer; class Offers { - public static function getOptions() + + public static function getLast() { - return Offer::orderBy('value', 'asc')->get()->pluck('value', 'id')->toArray(); + return Offer::with(['article.image'])->orderByDesc('updated_at')->get(); } - - public static function getOptionsByPackage($package_id) + + public static function getByCategory($category_id) { - return Offer::byPackage($package_id)->orderBy('value', 'asc')->get()->pluck('value', 'id')->toArray(); + return Offer::with(['article.image'])->byCategory($category_id)->get(); } public static function getAll() diff --git a/app/Repositories/Shop/Tags.php b/app/Repositories/Shop/Tags.php index f360b0fd..75849f81 100644 --- a/app/Repositories/Shop/Tags.php +++ b/app/Repositories/Shop/Tags.php @@ -29,6 +29,12 @@ class Tags return Tag::orderBy('order', 'asc')->get(); } + public static function getFullname($id) + { + $tag = Tag::with('group')->find($id); + return $tag->group->name . '-' . $tag->name; + } + public static function get($id) { return Tag::find($id); diff --git a/app/Traits/CanComment.php b/app/Traits/CanComment.php new file mode 100644 index 00000000..382dc0dd --- /dev/null +++ b/app/Traits/CanComment.php @@ -0,0 +1,11 @@ +morphMany(Comment::class, 'commentable'); + } + + public function comment(string $comment) + { + return $this->commentAsUser(auth()->user(), $comment); + } + + public function commentAsUser(?Model $user, string $comment) + { + + $comment = new Comment([ + 'comment' => $comment, + 'is_approved' => ($user instanceof Commentator) ? ! $user->needsCommentApproval($this) : false, + 'user_id' => is_null($user) ? null : $user->getKey(), + 'commentable_id' => $this->getKey(), + 'commentable_type' => get_class(), + ]); + + return $this->comments()->save($comment); + } + +} \ No newline at end of file diff --git a/build/css/site.css b/build/css/site.css index e883f029..71c0a46c 100644 --- a/build/css/site.css +++ b/build/css/site.css @@ -1,4 +1,31 @@ .bg-green { background-color: #517B39; +} + +@media (min-width: 992px){ + .dropdown-menu .dropdown-toggle:after{ + border-top: .3em solid transparent; + border-right: 0; + border-bottom: .3em solid transparent; + border-left: .3em solid; + } + .dropdown-menu .dropdown-menu{ + margin-left:0; margin-right: 0; + } + .dropdown-menu li{ + position: relative; + } + .nav-item .submenu{ + display: none; + position: absolute; + left:100%; top:-7px; + } + .nav-item .submenu-left{ + right:100%; left:auto; + } + .dropdown-menu > li:hover{ background-color: #f1f1f1 } + .dropdown-menu > li:hover > .submenu{ + display: block; + } } \ No newline at end of file diff --git a/build/js/site.js b/build/js/site.js new file mode 100644 index 00000000..04302416 --- /dev/null +++ b/build/js/site.js @@ -0,0 +1,18 @@ +// Prevent closing from click inside dropdown +$(document).on('click', '.dropdown-menu', function (e) { + e.stopPropagation(); + }); + + // make it as accordion for smaller screens + if ($(window).width() < 992) { + $('.dropdown-menu a').click(function(e){ + e.preventDefault(); + if($(this).next('.submenu').length){ + $(this).next('.submenu').toggle(); + } + $('.dropdown').on('hide.bs.dropdown', function () { + $(this).find('.submenu').hide(); + }) + }); + } + \ No newline at end of file diff --git a/build/js/taxonomy-browser.js b/build/js/taxonomy-browser.js new file mode 100644 index 00000000..2ed3d325 --- /dev/null +++ b/build/js/taxonomy-browser.js @@ -0,0 +1,520 @@ +/*! + * Fancytree Taxonomy Browser + * + * Copyright (c) 2015, Martin Wendt (https://wwWendt.de) + * + * Released under the MIT license + * https://github.com/mar10/fancytree/wiki/LicenseInfo + * + * @version @VERSION + * @date @DATE + */ + +/* global Handlebars */ +/* eslint-disable no-console */ + +(function($, window, document) { + "use strict"; + + /******************************************************************************* + * Private functions and variables + */ + + var taxonTree, + searchResultTree, + tmplDetails, + tmplInfoPane, + tmplMedia, + timerMap = {}, + USER_AGENT = "Fancytree Taxonomy Browser/1.0", + GBIF_URL = "//api.gbif.org/v1/", + TAXONOMY_KEY = "d7dddbf4-2cf0-4f39-9b2a-bb099caae36c", // GBIF backbone taxonomy + SEARCH_PAGE_SIZE = 5, + CHILD_NODE_PAGE_SIZE = 200, + glyphOpts = { + preset: "bootstrap3", + map: { + expanderClosed: "glyphicon glyphicon-menu-right", // glyphicon-plus-sign + expanderLazy: "glyphicon glyphicon-menu-right", // glyphicon-plus-sign + expanderOpen: "glyphicon glyphicon-menu-down", // glyphicon-collapse-down + }, + }; + + // Load and compile handlebar templates + + $.get("details.tmpl.html", function(data) { + tmplDetails = Handlebars.compile(data); + Handlebars.registerPartial("tmplDetails", tmplDetails); + }); + $.get("media.tmpl.html", function(data) { + tmplMedia = Handlebars.compile(data); + Handlebars.registerPartial("tmplMedia", tmplMedia); + }); + $.get("info-pane.tmpl.html", function(data) { + tmplInfoPane = Handlebars.compile(data); + }); + + /** Update UI elements according to current status + */ + function updateControls() { + var query = $.trim($("input[name=query]").val()); + + $("#btnPin").attr("disabled", !taxonTree.getActiveNode()); + $("#btnUnpin") + .attr("disabled", !taxonTree.isFilterActive()) + .toggleClass("btn-success", taxonTree.isFilterActive()); + $("#btnResetSearch").attr("disabled", query.length === 0); + $("#btnSearch").attr("disabled", query.length < 2); + } + + /** + * Invoke callback after `ms` milliseconds. + * Any pending action of this type is cancelled before. + */ + function _delay(tag, ms, callback) { + /*jshint -W040:true */ + var self = this; + + tag = "" + (tag || "default"); + if (timerMap[tag] != null) { + clearTimeout(timerMap[tag]); + delete timerMap[tag]; + // console.log("Cancel timer '" + tag + "'"); + } + if (ms == null || callback == null) { + return; + } + // console.log("Start timer '" + tag + "'"); + timerMap[tag] = setTimeout(function() { + // console.log("Execute timer '" + tag + "'"); + callback.call(self); + }, +ms); + } + + /** + */ + function _callWebservice(cmd, data) { + return $.ajax({ + url: GBIF_URL + cmd, + data: $.extend({}, data), + cache: true, + headers: { "Api-User-Agent": USER_AGENT }, + dataType: "jsonp", + }); + } + + /** + */ + function updateItemDetails(key) { + $("#tmplDetails").addClass("busy"); + $.bbq.pushState({ key: key }); + + $.when( + _callWebservice("species/" + key), + _callWebservice("species/" + key + "/speciesProfiles"), + _callWebservice("species/" + key + "/synonyms"), + _callWebservice("species/" + key + "/descriptions"), + _callWebservice("species/" + key + "/media") + ).done(function(species, profiles, synonyms, descriptions, media) { + // Requests are resolved as: [ data, statusText, jqXHR ] + species = species[0]; + profiles = profiles[0]; + synonyms = synonyms[0]; + descriptions = descriptions[0]; + media = media[0]; + + var info = $.extend(species, { + profileList: profiles.results, // marine, extinct + profile: + profiles.results.length === 1 ? profiles.results[0] : null, // marine, extinct + synonyms: synonyms.results, + descriptions: descriptions.results, + descriptionsByLang: {}, + media: media.results, + now: new Date().toString(), + }); + + $.each(info.descriptions, function(i, o) { + if (!info.descriptionsByLang[o.language]) { + info.descriptionsByLang[o.language] = []; + } + info.descriptionsByLang[o.language].push(o); + }); + + console.log("updateItemDetails", info); + $("#tmplDetails") + // .html(tmplDetails(info)) + .removeClass("busy"); + $("#tmplMedia") + // .html(tmplMedia(info)) + .removeClass("busy"); + $("#tmplInfoPane") + .html(tmplInfoPane(info)) + .removeClass("busy"); + + $("[data-toggle='popover']").popover(); + $(".carousel").carousel(); + $("#mediaCounter").text("" + (media.results.length || "")); + // $("[data-toggle='collapse']").collapse(); + updateControls(); + }); + } + + /** + */ + function updateBreadcrumb(key, loadTreeNodes) { + var $ol = $("ol.breadcrumb").addClass("busy"), + activeNode = taxonTree.getActiveNode(); + + if (activeNode && activeNode.key !== key) { + activeNode.setActive(false); // deactivate, in case the new key is not found + } + $.when( + _callWebservice("species/" + key + "/parents"), + _callWebservice("species/" + key) + ).done(function(parents, node) { + // Both requests resolved (result format: [ data, statusText, jqXHR ]) + var nodeList = parents[0], + keyList = []; + + nodeList.push(node[0]); + + // Display as
    list (for Bootstrap breadcrumbs) + $ol.empty().removeClass("busy"); + $.each(nodeList, function(i, o) { + var name = o.vernacularName || o.canonicalName; + keyList.push(o.key); + if ("" + o.key === "" + key) { + $ol.append( + $("
  1. ").append( + $("", { + text: name, + title: o.rank, + }) + ) + ); + } else { + $ol.append( + $("
  2. ").append( + $("", { + href: "#key=" + o.key, + text: name, + title: o.rank, + }) + ) + ); + } + }); + if (loadTreeNodes) { + // console.log("updateBreadcrumb - loadKeyPath", keyList); + taxonTree.loadKeyPath("/" + keyList.join("/"), function( + n, + status + ) { + // console.log("... updateBreadcrumb - loadKeyPath " + n.title + ": " + status); + switch (status) { + case "loaded": + n.makeVisible(); + break; + case "ok": + n.setActive(); + // n.makeVisible(); + break; + } + }); + } + }); + } + + /** + */ + function search(query) { + query = $.trim(query); + console.log("searching for '" + query + "'..."); + // Store the source options for optional paging + searchResultTree.lastSourceOpts = { + // url: GBIF_URL + "species/match", // Fuzzy matches scientific names against the GBIF Backbone Taxonomy + url: GBIF_URL + "species/search", // Full text search of name usages covering the scientific and vernacular name, the species description, distribution and the entire classification across all name usages of all or some checklists + data: { + q: query, + datasetKey: TAXONOMY_KEY, + // name: query, + // strict: "true", + // hl: true, + limit: SEARCH_PAGE_SIZE, + offset: 0, + }, + cache: true, + // headers: { "Api-User-Agent": USER_AGENT } + // dataType: "jsonp" + }; + $("#searchResultTree").addClass("busy"); + searchResultTree + .reload(searchResultTree.lastSourceOpts) + .done(function(result) { + // console.log("search returned", result); + if (result.length < 1) { + searchResultTree.getRootNode().setStatus("nodata"); + } + $("#searchResultTree").removeClass("busy"); + + // https://github.com/tbasse/jquery-truncate + // SLOW! + // $("div.truncate").truncate({ + // multiline: true + // }); + + updateControls(); + }); + } + + /******************************************************************************* + * Pageload Handler + */ + + $(function() { + $("#taxonTree").fancytree({ + extensions: ["filter", "glyph", "wide"], + filter: { + mode: "hide", + }, + glyph: glyphOpts, + autoCollapse: true, + activeVisible: true, + autoScroll: true, + source: { + url: GBIF_URL + "species/root/" + TAXONOMY_KEY, + data: {}, + cache: true, + // dataType: "jsonp" + }, + init: function(event, data) { + updateControls(); + $(window).trigger("hashchange"); // trigger on initial page load + }, + lazyLoad: function(event, data) { + data.result = { + url: GBIF_URL + "species/" + data.node.key + "/children", + data: { + limit: CHILD_NODE_PAGE_SIZE, + }, + cache: true, + // dataType: "jsonp" + }; + // store this request options for later paging + data.node.lastSourceOpts = data.result; + }, + postProcess: function(event, data) { + var response = data.response; + + data.node.info("taxonTree postProcess", response); + data.result = $.map(response.results, function(o) { + return ( + o && { + title: o.vernacularName || o.canonicalName, + key: o.key, + nubKey: o.nubKey, + folder: true, + lazy: true, + } + ); + }); + if (response.endOfRecords === false) { + // Allow paging + data.result.push({ + title: "(more)", + statusNodeType: "paging", + }); + } else { + // No need to store the extra data + delete data.node.lastSourceOpts; + } + }, + activate: function(event, data) { + $("#tmplDetails").addClass("busy"); + $("ol.breadcrumb").addClass("busy"); + updateControls(); + _delay("showDetails", 500, function() { + updateItemDetails(data.node.key); + updateBreadcrumb(data.node.key); + }); + }, + clickPaging: function(event, data) { + // Load the next page of results + var source = $.extend( + true, + {}, + data.node.parent.lastSourceOpts + ); + source.data.offset = data.node.parent.countChildren() - 1; + data.node.replaceWith(source); + }, + }); + + $("#searchResultTree").fancytree({ + extensions: ["table", "wide"], + source: [{ title: "No Results." }], + minExpandLevel: 2, + icon: false, + table: { + nodeColumnIdx: 2, + }, + postProcess: function(event, data) { + var response = data.response; + + data.node.info("search postProcess", response); + data.result = $.map(response.results, function(o) { + var res = $.extend( + { + title: o.scientificName, + key: o.key, + }, + o + ); + return res; + }); + // Append paging link + if ( + response.count != null && + response.offset + response.limit < response.count + ) { + data.result.push({ + title: + "(" + + (response.count - + response.offset - + response.limit) + + " more)", + statusNodeType: "paging", + }); + } + data.node.info("search postProcess 2", data.result); + }, + // loadChildren: function(event, data) { + // $("#searchResultTree td div.cell").truncate({ + // multiline: true + // }); + // }, + renderColumns: function(event, data) { + var i, + node = data.node, + $tdList = $(node.tr).find(">td"), + cnList = node.data.vernacularNames + ? $.map(node.data.vernacularNames, function(o) { + return o.vernacularName; + }) + : []; + + i = 0; + function _setCell($cell, text) { + $("
    ") + .attr("title", text) + .text(text) + .appendTo($cell); + } + $tdList.eq(i++).text(node.key); + $tdList.eq(i++).text(node.data.rank); + i++; // #1: node.title = scientificName + // $tdList.eq(i++).text(cnList.join(", ")); + _setCell($tdList.eq(i++), cnList.join(", ")); + $tdList.eq(i++).text(node.data.canonicalName); + // $tdList.eq(i++).text(node.data.accordingTo); + _setCell($tdList.eq(i++), node.data.accordingTo); + $tdList.eq(i++).text(node.data.taxonomicStatus); + $tdList.eq(i++).text(node.data.nameType); + $tdList.eq(i++).text(node.data.numOccurrences); + $tdList.eq(i++).text(node.data.numDescendants); + // $tdList.eq(i++).text(node.data.authorship); + _setCell($tdList.eq(i++), node.data.authorship); + // $tdList.eq(i++).text(node.data.publishedIn); + _setCell($tdList.eq(i++), node.data.publishedIn); + }, + activate: function(event, data) { + if (data.node.isStatusNode()) { + return; + } + _delay("activateNode", 500, function() { + updateItemDetails(data.node.key); + updateBreadcrumb(data.node.key); + }); + }, + clickPaging: function(event, data) { + // Load the next page of results + var source = $.extend( + true, + {}, + searchResultTree.lastSourceOpts + ); + source.data.offset = data.node.parent.countChildren() - 1; + data.node.replaceWith(source); + }, + }); + + taxonTree = $.ui.fancytree.getTree("#taxonTree"); + searchResultTree = $.ui.fancytree.getTree("#searchResultTree"); + + // Bind a callback that executes when document.location.hash changes. + // (This code uses bbq: https://github.com/cowboy/jquery-bbq) + $(window).on("hashchange", function(e) { + var key = $.bbq.getState("key"); + console.log("bbq key", key); + if (key) { + updateBreadcrumb(key, true); + } + }); // don't trigger now, since we need the the taxonTree root nodes to be loaded first + + $("input[name=query]") + .on("keyup", function(e) { + var query = $.trim($(this).val()), + lastQuery = $(this).data("lastQuery"); + + if ((e && e.which === $.ui.keyCode.ESCAPE) || query === "") { + $("#btnResetSearch").click(); + return; + } + if (e && e.which === $.ui.keyCode.ENTER && query.length >= 2) { + $("#btnSearch").click(); + return; + } + if (query === lastQuery || query.length < 2) { + console.log("Ignored query '" + query + "'"); + return; + } + $(this).data("lastQuery", query); + _delay("search", 1, function() { + $("#btnSearch").click(); + }); + $("#btnResetSearch").attr("disabled", query.length === 0); + $("#btnSearch").attr("disabled", query.length < 2); + }) + .focus(); + + $("#btnResetSearch").click(function(e) { + $("#searchResultPane").collapse("hide"); + $("input[name=query]").val(""); + searchResultTree.clear(); + updateControls(); + }); + + $("#btnSearch") + .click(function(event) { + $("#searchResultPane").collapse("show"); + search($("input[name=query]").val()); + }) + .attr("disabled", true); + + $("#btnPin").click(function(event) { + taxonTree.filterBranches(function(n) { + return n.isActive(); + }); + updateControls(); + }); + + $("#btnUnpin").click(function(event) { + taxonTree.clearFilter(); + updateControls(); + }); + + // ----------------------------------------------------------------------------- + }); // end of pageload handler +})(jQuery, window, document); diff --git a/composer.json b/composer.json index 94162a78..3db0f222 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,6 @@ "arrilot/laravel-widgets": "^3.13", "barryvdh/laravel-dompdf": "^0.9", "barryvdh/laravel-snappy": "^0.4.7", - "beyondcode/laravel-comments": "^1.2", "box/spout": "^3.3", "browner12/helpers": "^3.0", "cesargb/laravel-cascade-delete": "^1.2", @@ -25,7 +24,6 @@ "darryldecode/cart": "^4.1", "datatables/datatables": "^1.10", "ddzobov/laravel-pivot-softdeletes": "^2.1", - "deployer/deployer": "^6.8", "dompdf/dompdf": "^1.0.2", "dyrynda/laravel-cascade-soft-deletes": "^4.1", "eduardokum/laravel-mail-auto-embed": "^1.0", @@ -54,9 +52,9 @@ "league/climate": "^3.5", "league/period": "^4.9", "livewire/livewire": "^2.4", - "lorisleiva/laravel-deployer": "^0.3.2", "maatwebsite/excel": "^3.1", "mad-web/laravel-initializer": "^3.3", + "maximeb/laravel-8-paybox-gateway": "^1.1", "moneyphp/money": "^3.3", "mpdf/mpdf": "^8.0", "mpociot/teamwork": "^6.1", @@ -72,7 +70,6 @@ "santigarcor/laratrust": "^6.0", "sebastienheyd/boilerplate": "^7.5", "sensiolabs/security-checker": "^6.0", - "sheub/ban-france-provider": "^1.0@dev", "smajohusic/laravel-mail-logger": "^1.0", "spatie/eloquent-sortable": "^3.11", "spatie/image-optimizer": "^1.4", @@ -95,16 +92,12 @@ "barryvdh/laravel-debugbar": "^3.5", "bestmomo/laravel5-artisan-language": "^0.3", "beyondcode/laravel-dump-server": "^1.0", - "beyondcode/laravel-er-diagram-generator": "^1.2", - "cybercog/laravel-whoops-editor": "^3.0", - "daniel-werner/php-quality-tools": "^1.1", "enlightn/enlightn": "^1.16", "facade/ignition": "^2.9", "fakerphp/faker": "^1.13", "geekality/timer": "^1.2", "imanghafoori/laravel-microscope": "^1.0", "mockery/mockery": "^1.4.2", - "mtolhuys/laravel-schematics": "^0.10.3", "nunomaduro/collision": "^5.4", "nunomaduro/larastan": "^0.7", "nunomaduro/laravel-mojito": "^0.2.6", @@ -113,6 +106,7 @@ "phpmetrics/phpmetrics": "^2.7", "phpunit/phpunit": "^9.3.3", "spatie/laravel-web-tinker": "^1.4", + "squizlabs/php_codesniffer": "3.*", "staudenmeir/dusk-updater": "^1.2", "wnx/laravel-stats": "^2.4", "wulfheart/pretty_routes": "^0.3.0" diff --git a/resources/views/Admin/Shop/Articles/partials/characteristics.blade.php b/resources/views/Admin/Shop/Articles/partials/characteristics.blade.php index a9409d3b..87abf743 100644 --- a/resources/views/Admin/Shop/Articles/partials/characteristics.blade.php +++ b/resources/views/Admin/Shop/Articles/partials/characteristics.blade.php @@ -1,5 +1,5 @@
    -
    +
    @@ -55,7 +55,7 @@
    -
    +
    @include('Admin.Shop.Articles.partials.product.images')
    diff --git a/resources/views/Admin/Shop/Articles/partials/product/description.blade.php b/resources/views/Admin/Shop/Articles/partials/product/description.blade.php index 3ffdf525..c1f15be9 100644 --- a/resources/views/Admin/Shop/Articles/partials/product/description.blade.php +++ b/resources/views/Admin/Shop/Articles/partials/product/description.blade.php @@ -7,7 +7,7 @@ @if ($inherited['tags'])
    Tags
    @foreach ($inherited['tags'] as $tag) - {{ $tag['name'] }} + @endforeach @endif @endcomponent diff --git a/resources/views/Admin/Shop/Offers/form.blade.php b/resources/views/Admin/Shop/Offers/form.blade.php index 0cf72450..eabb2dc6 100644 --- a/resources/views/Admin/Shop/Offers/form.blade.php +++ b/resources/views/Admin/Shop/Offers/form.blade.php @@ -1,5 +1,5 @@
    -
    +
    {{ Form::label('article_id', 'Article') }} @@ -20,15 +20,7 @@ @include('components.select', ['name' => 'tariff_id', 'id_name' => 'tariff_id', 'list' => $tariffs ?? null, 'value' => $offer['tariff_id'] ?? null, 'with_empty' => '', 'class' => 'select2 select_tariffs'])
    -
    -
    - @component('components.card', ['title' => 'Previsualisation']) -
    -
    -
    - @endcomponent -
    -
    + @component('components.card', ['title' => 'Disponibilité'])
    @@ -58,6 +50,14 @@
    @endcomponent
    +
    + @component('components.card', ['title' => 'Previsualisation']) +
    +
    +
    + @endcomponent +
    +
    @include('components.save') diff --git a/resources/views/Admin/Shop/PriceLists/modal.blade.php b/resources/views/Admin/Shop/PriceLists/modal.blade.php index 1814e45e..6ec5bf45 100644 --- a/resources/views/Admin/Shop/PriceLists/modal.blade.php +++ b/resources/views/Admin/Shop/PriceLists/modal.blade.php @@ -53,56 +53,57 @@ - + function handle_prices() { + $('.price').change(function() { + $col_tax = $(this).parent().parent().find('.tax'); + tax_selected = $col_tax.find('option:selected').text(); + price_taxed = $(this).val() * (1 + (tax_selected / 100)); + price_taxed = price_taxed.toFixed(2); + console.log(price_taxed); + $(this).parent().parent().find('.price_taxed').val(price_taxed); + }) + } + + function handle_taxes() { + $('.tax').change(function() { + tax_selected = $(this).find('option:selected').text(); + price = $(this).parent().parent().find('.price').val(); + price_taxed = price * (1 + (tax_selected / 100)); + price_taxed = price_taxed.toFixed(2); + $(this).parent().parent().find('.price_taxed').val(price_taxed); + }) + } + + function handle_prices_taxed() { + $('.price_taxed').change(function() { + $col_tax = $(this).parent().parent().find('.tax'); + tax_selected = $col_tax.find('option:selected').text(); + price = $(this).val() / (1 + (tax_selected / 100)); + price = price.toFixed(2); + $(this).parent().parent().find('.price').val(price); + }) + } + + function handlePrices() { + handle_prices(); + handle_taxes(); + handle_prices_taxed(); + } + + $(function() { + handleAddPrice(); + handlePrices(); + }); + + diff --git a/resources/views/Admin/Shop/Tariffs/form.blade.php b/resources/views/Admin/Shop/Tariffs/form.blade.php index 687e69eb..adb239c6 100644 --- a/resources/views/Admin/Shop/Tariffs/form.blade.php +++ b/resources/views/Admin/Shop/Tariffs/form.blade.php @@ -50,7 +50,7 @@
    -
    +
    @if ($tariff['id'] ?? false) @@ -70,6 +70,7 @@ @include('components.save') @include('load.form.editor') +@include('load.form.save') @include('load.form.select2') @include('load.layout.modal') @@ -77,19 +78,21 @@ - - - - \ No newline at end of file diff --git a/resources/views/Shop/layout/layout.blade.php b/resources/views/Shop/layout/layout.blade.php index 21fde05f..ebc5f0c1 100644 --- a/resources/views/Shop/layout/layout.blade.php +++ b/resources/views/Shop/layout/layout.blade.php @@ -9,13 +9,13 @@ - OpenSemis + Jardin'enVie - + @stack('css') @@ -42,7 +42,7 @@
    - + @stack('scripts') diff --git a/resources/views/Shop/layout/partials/article.blade.php b/resources/views/Shop/layout/partials/article.blade.php index 5a7bb6ba..a720d904 100644 --- a/resources/views/Shop/layout/partials/article.blade.php +++ b/resources/views/Shop/layout/partials/article.blade.php @@ -1,7 +1,7 @@ -
  3. @else @endif @endforeach diff --git a/resources/views/Shop/layout/partials/submenu.blade.php b/resources/views/Shop/layout/partials/submenu.blade.php new file mode 100644 index 00000000..891015bd --- /dev/null +++ b/resources/views/Shop/layout/partials/submenu.blade.php @@ -0,0 +1,19 @@ +@foreach ($categories as $category) +
  4. + @if ($category['children'] ?? false) + +
    + {{ $category['name'] }} + + + +
    +
    + + @else + {{ $category['name'] }} + @endif +
  5. +@endforeach diff --git a/resources/views/Shop/shelve.blade.php b/resources/views/Shop/shelve.blade.php new file mode 100644 index 00000000..05e7a2a7 --- /dev/null +++ b/resources/views/Shop/shelve.blade.php @@ -0,0 +1,21 @@ +@extends('Shop.layout.layout', [ + 'title' => __('home.title'), +]) + +@section('content') +
    +
    +

    {{ $category['name'] }}

    +

    {!! $category['description'] !!}

    +
    +
    + @include('Shop.layout.partials.category_add') +
    +
    + +
    +
    + @include('Shop.layout.partials.category_articles') +
    +
    +@endsection \ No newline at end of file diff --git a/routes/Shop/route.php b/routes/Shop/route.php index 75e546b0..7f5b0146 100644 --- a/routes/Shop/route.php +++ b/routes/Shop/route.php @@ -1,9 +1,9 @@ namespace('Shop')->name('Shop.')->group(function () { + include( __DIR__ . '/Articles.php'); + include( __DIR__ . '/Categories.php'); include( __DIR__ . '/Customers.php'); include( __DIR__ . '/Invoices.php'); include( __DIR__ . '/Orders.php'); - include( __DIR__ . '/Articles.php'); - include( __DIR__ . '/Categories.php'); });