Synchro back-office, fix on tariffs
This commit is contained in:
33
Gruntfile.js
33
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,
|
||||
|
||||
15
app/Contracts/Commentator.php
Normal file
15
app/Contracts/Commentator.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace BeyondCode\Comments\Contracts;
|
||||
|
||||
|
||||
interface Commentator
|
||||
{
|
||||
/**
|
||||
* Check if a comment for a specific model needs to be approved.
|
||||
* @param mixed $model
|
||||
* @return bool
|
||||
*/
|
||||
public function needsCommentApproval($model): bool;
|
||||
|
||||
}
|
||||
@@ -5,7 +5,7 @@ namespace App\Datatables\Admin\Core;
|
||||
use Yajra\DataTables\Html\Column;
|
||||
use App\Datatables\ParentDataTable as DataTable;
|
||||
|
||||
use App\Models\Admin\Core\Comment;
|
||||
use App\Models\Core\Comment;
|
||||
use App\Repositories\Core\Comments;
|
||||
|
||||
class CommentsDataTable extends DataTable
|
||||
|
||||
@@ -6,15 +6,16 @@ use Yajra\DataTables\Html\Column;
|
||||
|
||||
use App\Datatables\ParentDataTable as DataTable;
|
||||
use App\Models\Shop\Article;
|
||||
use App\Repositories\Shop\Articles;
|
||||
|
||||
class ArticlesDataTable extends DataTable
|
||||
{
|
||||
public $model_name = 'articles';
|
||||
public $sortedColumn = 1;
|
||||
public $sortedColumn = 2;
|
||||
|
||||
public function query(Article $model)
|
||||
{
|
||||
$model = $model::with('article_nature')->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),
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
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.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
<?php
|
||||
namespace App\Repositories\Core\Auth;
|
||||
|
||||
use App\Models\Core\Auth\UserStatusTeam;
|
||||
|
||||
class UserStatusTeams
|
||||
{
|
||||
|
||||
// supprime l'association entre les équipes et le statut utilisateur donné
|
||||
public function delete_teams($id)
|
||||
{
|
||||
return UserStatusTeam::byUserStatus($id)->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();
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
<?php
|
||||
namespace App\Repositories\Core\Auth;
|
||||
|
||||
use App\Models\Core\Auth\UserStatus;
|
||||
|
||||
class UserStatuses
|
||||
{
|
||||
// compte le nombre de statut utilisateur
|
||||
public static function count()
|
||||
{
|
||||
return UserStatus::count();
|
||||
}
|
||||
|
||||
// supprime un statut utilisateur
|
||||
public static function delete($id)
|
||||
{
|
||||
return UserStatus::destroy($id);
|
||||
}
|
||||
|
||||
// ajoute un statut utilisateur
|
||||
public static function insert($name, $translated, $negociator)
|
||||
{
|
||||
return UserStatus::create(['name' => $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()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -126,19 +129,35 @@ class DateTime
|
||||
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()
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repositories\Core;
|
||||
|
||||
class Media
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
99
app/Repositories/Core/Medias.php
Normal file
99
app/Repositories/Core/Medias.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repositories\Core;
|
||||
|
||||
class Medias
|
||||
{
|
||||
|
||||
public static function getImage($model, $conversion = 'normal', $collection = 'images')
|
||||
{
|
||||
$img = $model->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";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
|
||||
11
app/Traits/CanComment.php
Normal file
11
app/Traits/CanComment.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
trait CanComment
|
||||
{
|
||||
public function needsCommentApproval($model): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
36
app/Traits/HasComments.php
Normal file
36
app/Traits/HasComments.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use App\Contracts\Commentator;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||
use App\Models\Core\Comment;
|
||||
|
||||
trait HasComments
|
||||
{
|
||||
public function comments()
|
||||
{
|
||||
return $this->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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,3 +2,30 @@
|
||||
.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;
|
||||
}
|
||||
}
|
||||
18
build/js/site.js
Normal file
18
build/js/site.js
Normal file
@@ -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();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
520
build/js/taxonomy-browser.js
Normal file
520
build/js/taxonomy-browser.js
Normal file
@@ -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 <OL> 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(
|
||||
$("<li class='active'>").append(
|
||||
$("<span>", {
|
||||
text: name,
|
||||
title: o.rank,
|
||||
})
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$ol.append(
|
||||
$("<li>").append(
|
||||
$("<a>", {
|
||||
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) {
|
||||
$("<div class='truncate'>")
|
||||
.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);
|
||||
@@ -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"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="col-lg-8">
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-3">
|
||||
@@ -55,7 +55,7 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="col-lg-4">
|
||||
<div id="product_images_inherited">
|
||||
@include('Admin.Shop.Articles.partials.product.images')
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
@if ($inherited['tags'])
|
||||
<h6> Tags</h6>
|
||||
@foreach ($inherited['tags'] as $tag)
|
||||
<span class="btn btn-xs">{{ $tag['name'] }}</span>
|
||||
<button type="button" class="btn btn-secondary btn-xs">{{ $tag['group']['name'] }}-{{ $tag['name'] }}</button>
|
||||
@endforeach
|
||||
@endif
|
||||
@endcomponent
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div class="row mb-3">
|
||||
<div class="col-3">
|
||||
<div class="col-6">
|
||||
<div class="row mb-3">
|
||||
<div class="col-12">
|
||||
{{ 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'])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
@component('components.card', ['title' => 'Previsualisation'])
|
||||
<div id="preview-article"></div>
|
||||
<div id="preview-variation"></div>
|
||||
<div id="preview-tariff"></div>
|
||||
@endcomponent
|
||||
</div>
|
||||
<div class="col-3">
|
||||
|
||||
@component('components.card', ['title' => 'Disponibilité'])
|
||||
<div class="row mb-3">
|
||||
<div class="col-12 col-xl-6">
|
||||
@@ -58,6 +50,14 @@
|
||||
</div>
|
||||
@endcomponent
|
||||
</div>
|
||||
<div class="col-6">
|
||||
@component('components.card', ['title' => 'Previsualisation'])
|
||||
<div id="preview-article"></div>
|
||||
<div id="preview-variation"></div>
|
||||
<div id="preview-tariff"></div>
|
||||
@endcomponent
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@include('components.save')
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
</form>
|
||||
|
||||
|
||||
<script>
|
||||
<script>
|
||||
function handleAddPrice() {
|
||||
$('#add_price').click( function () {
|
||||
var index = $('#prices-table tbody tr').length;
|
||||
@@ -66,17 +66,18 @@
|
||||
|
||||
function handle_prices() {
|
||||
$('.price').change(function() {
|
||||
$col_tax = $(this).parent().parent().find('.tax')();
|
||||
tax_selected = $col_tax.find('select option:selected').text();
|
||||
$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).text();
|
||||
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);
|
||||
@@ -86,8 +87,8 @@
|
||||
|
||||
function handle_prices_taxed() {
|
||||
$('.price_taxed').change(function() {
|
||||
$col_tax = $(this).parent().parent().find('.tax')();
|
||||
tax_selected = $col_tax.find('select option:selected').text();
|
||||
$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);
|
||||
@@ -105,4 +106,4 @@
|
||||
handlePrices();
|
||||
});
|
||||
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="row mb-3">
|
||||
<div class="col-12">
|
||||
|
||||
@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 @@
|
||||
<script>
|
||||
$(function() {
|
||||
initEditor();
|
||||
initSelect2();
|
||||
initSaveForm('#tariffs-form');
|
||||
});
|
||||
|
||||
function PriceListCreate() {
|
||||
var tariff_id = $('#id').val();
|
||||
var url_open = "{{ route('Admin.Shop.PriceLists.modalCreate') }}/" + tariff_id;
|
||||
var url_save = "{{ route('Admin.Shop.PriceLists.storeAjax') }}";
|
||||
openModal("{{ __('price_list') }}", '#price_list-form', url_open, url_save, "PriceListRefresh();");
|
||||
openModal("{{ __('price_list') }}", '#price_list-form', url_open, url_save, "PriceListRefresh();","extra-large");
|
||||
}
|
||||
|
||||
function PriceListEdit(id) {
|
||||
var url_open = "{{ route('Admin.Shop.PriceLists.modalEdit') }}/" + id;
|
||||
var url_save = "{{ route('Admin.Shop.PriceLists.storeAjax') }}";
|
||||
openModal("{{ __('price_list') }}", '#price_list-form', url_open, url_save, "PriceListRefresh();");
|
||||
openModal("{{ __('price_list') }}", '#price_list-form', url_open, url_save, "PriceListRefresh();","extra-large");
|
||||
}
|
||||
|
||||
function PriceListRefresh()
|
||||
|
||||
@@ -3,8 +3,5 @@
|
||||
])
|
||||
|
||||
@section('content')
|
||||
|
||||
@include("Shop.layout.partials.block-breadcrumb")
|
||||
@include("Shop.layout.partials.category")
|
||||
|
||||
@include('Shop.layout.partials.category_articles')
|
||||
@endsection
|
||||
@@ -1,57 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="fr">
|
||||
|
||||
<head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
|
||||
<title>OpenSemis</title>
|
||||
<meta name="description" content="Boutique propulsée par HumaN.E.T">
|
||||
<meta name="keywords" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link rel="icon" type="image/vnd.microsoft.icon" href="img/favicon.ico?1528709483">
|
||||
<link rel="shortcut icon" type="image/x-icon" href="img/favicon.ico?1528709483">
|
||||
<link rel="stylesheet" href="/css/theme.css" type="text/css" media="all">
|
||||
|
||||
{{ include("Shop._partials.presta_js")}}
|
||||
|
||||
</head>
|
||||
|
||||
<body id="index" class="lang-fr country-us currency-usd layout-full-width page-index tax-display-disabled">
|
||||
|
||||
<main>
|
||||
|
||||
{{ include("Shop._partials.header") }}
|
||||
{{ include("Shop._partials.notifications") }}
|
||||
|
||||
<div id="top_home">
|
||||
|
||||
<div id="spin-wrapper"></div>
|
||||
<div id="siteloader">
|
||||
<div class="loader"></div>
|
||||
</div>
|
||||
|
||||
{{ include("Shop._partials.slider") }}
|
||||
{{ include("Shop._partials.block-banner") }}
|
||||
{{ include("Shop._partials.block-products") }}
|
||||
|
||||
|
||||
{{ include("Shop._partials.block-breadcrumb") }}
|
||||
{{ include("Shop._partials.wrapper") }}
|
||||
|
||||
{{ include("Shop._partials.block-bottom")}}
|
||||
|
||||
{{ include("Shop._partials.footer")}}
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<a id="slidetop" href="#" > </a>
|
||||
|
||||
<script type="text/javascript" src="/js/theme.js" ></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -9,13 +9,13 @@
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
|
||||
<title>OpenSemis</title>
|
||||
<title>Jardin'enVie</title>
|
||||
<meta name="description" content="Vente de semences, variété anciennes">
|
||||
<meta name="keywords" content="">
|
||||
|
||||
<link rel="icon" type="image/vnd.microsoft.icon" href="img/favicon.ico">
|
||||
<link rel="shortcut icon" type="image/x-icon" href="img/favicon.ico">
|
||||
<link rel="stylesheet" href="css/site.min.css" type="text/css" media="all">
|
||||
<link rel="stylesheet" href="/css/site.min.css" type="text/css" media="all">
|
||||
|
||||
@stack('css')
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript" src="js/site.min.js" ></script>
|
||||
<script type="text/javascript" src="/js/site.min.js" ></script>
|
||||
|
||||
@stack('scripts')
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="card" style="width: 18rem;">
|
||||
<img src="{{ App\Repositories\Shop\Articles::getThumbSrc($article['image']) }}" class="card-img-top" alt="...">
|
||||
<div class="card">
|
||||
<img src="{{ App\Repositories\Shop\Articles::getPreviewSrc($offer['article']['image']) }}" class="card-img-top" alt="...">
|
||||
<div class="card-body">
|
||||
<span class="card-title">{{ $article['name'] }}</span>
|
||||
<span class="card-title">{{ $offer['article']['name'] }}</span>
|
||||
<span class="pull-right">
|
||||
<i class="fa fa-heart"></i>
|
||||
</span>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<div class="row">
|
||||
@foreach ($articles as $article)
|
||||
<div class="col-3">
|
||||
@foreach ($offers as $offer)
|
||||
<div class="col-sm-6 col-md-3 col-lg-2">
|
||||
@include('Shop.layout.partials.article')
|
||||
</div>
|
||||
@endforeach
|
||||
|
||||
@@ -7,15 +7,13 @@
|
||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
{{ $category['name'] }}
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||
@foreach ($category['children'] as $children)
|
||||
<a class="dropdown-item" href="{{ $children['id'] }}">{{ $children['name'] }}</a>
|
||||
@endforeach
|
||||
</div>
|
||||
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||
@include('Shop.layout.partials.submenu', ['categories' => $category['children']])
|
||||
</ul>
|
||||
</li>
|
||||
@else
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ $category['id'] }}">{{ $category['name'] }}</a>
|
||||
<a class="nav-link" href="{{ route('Shop.Categories.show', ['id' => $category['id']]) }}">{{ $category['name'] }}</a>
|
||||
</li>
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
19
resources/views/Shop/layout/partials/submenu.blade.php
Normal file
19
resources/views/Shop/layout/partials/submenu.blade.php
Normal file
@@ -0,0 +1,19 @@
|
||||
@foreach ($categories as $category)
|
||||
<li>
|
||||
@if ($category['children'] ?? false)
|
||||
<a class="dropdown-item" href="#">
|
||||
<div class="w-100">
|
||||
{{ $category['name'] }}
|
||||
<span style="float: right;">
|
||||
<i class="fa fa-caret-right"></i>
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
<ul class="submenu dropdown-menu">
|
||||
@include('Shop.layout.partials.submenu', ['categories' => $category['children']])
|
||||
</ul>
|
||||
@else
|
||||
<a class="dropdown-item" href="{{ route('Shop.Categories.show', ['id' => $category['id']]) }}">{{ $category['name'] }}</a>
|
||||
@endif
|
||||
</li>
|
||||
@endforeach
|
||||
21
resources/views/Shop/shelve.blade.php
Normal file
21
resources/views/Shop/shelve.blade.php
Normal file
@@ -0,0 +1,21 @@
|
||||
@extends('Shop.layout.layout', [
|
||||
'title' => __('home.title'),
|
||||
])
|
||||
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
<h1 style="font-size: 2em;">{{ $category['name'] }}</h1>
|
||||
<h3 style="font-size: 1.2em;">{!! $category['description'] !!}</h3>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
@include('Shop.layout.partials.category_add')
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
@include('Shop.layout.partials.category_articles')
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -1,9 +1,9 @@
|
||||
<?php
|
||||
|
||||
Route::prefix('Shop')->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');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user