first upload all files
This commit is contained in:
47
Modules/Slider/Admin/SliderTabs.php
Normal file
47
Modules/Slider/Admin/SliderTabs.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Slider\Admin;
|
||||
|
||||
use Modules\Admin\Ui\Tab;
|
||||
use Modules\Admin\Ui\Tabs;
|
||||
|
||||
class SliderTabs extends Tabs
|
||||
{
|
||||
/**
|
||||
* Indicate that submit button should add offset class.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $buttonOffset = false;
|
||||
|
||||
/**
|
||||
* Make new tabs with groups.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function make()
|
||||
{
|
||||
$this->group('slider_information', trans('slider::sliders.tabs.group.slider_information'))
|
||||
->active()
|
||||
->add($this->slides())
|
||||
->add($this->settings());
|
||||
}
|
||||
|
||||
private function slides()
|
||||
{
|
||||
return tap(new Tab('slides', trans('slider::sliders.tabs.slides')), function (Tab $tab) {
|
||||
$tab->active();
|
||||
$tab->weight(5);
|
||||
$tab->view('slider::admin.sliders.tabs.slides');
|
||||
});
|
||||
}
|
||||
|
||||
private function settings()
|
||||
{
|
||||
return tap(new Tab('settings', trans('slider::sliders.tabs.settings')), function (Tab $tab) {
|
||||
$tab->weight(10);
|
||||
$tab->fields(['name']);
|
||||
$tab->view('slider::admin.sliders.tabs.settings');
|
||||
});
|
||||
}
|
||||
}
|
||||
22
Modules/Slider/Config/assets.php
Normal file
22
Modules/Slider/Config/assets.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Define which assets will be available through the asset manager
|
||||
|--------------------------------------------------------------------------
|
||||
| These assets are registered on the asset manager
|
||||
*/
|
||||
'all_assets' => [
|
||||
'admin.slider.css' => ['module' => 'slider:admin/css/slider.css'],
|
||||
'admin.slider.js' => ['module' => 'slider:admin/js/slider.js'],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Define which default assets will always be included in your pages
|
||||
| through the asset pipeline
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
'required_assets' => [],
|
||||
];
|
||||
10
Modules/Slider/Config/permissions.php
Normal file
10
Modules/Slider/Config/permissions.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'admin.sliders' => [
|
||||
'index' => 'slider::permissions.index',
|
||||
'create' => 'slider::permissions.create',
|
||||
'edit' => 'slider::permissions.edit',
|
||||
'destroy' => 'slider::permissions.destroy',
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateSlidersTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('sliders', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->boolean('autoplay')->nullable();
|
||||
$table->integer('autoplay_speed')->nullable();
|
||||
$table->boolean('dots')->nullable();
|
||||
$table->boolean('arrows')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('sliders');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateSliderTranslationsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('slider_translations', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->integer('slider_id')->unsigned();
|
||||
$table->string('locale');
|
||||
$table->string('name');
|
||||
|
||||
$table->unique(['slider_id', 'locale']);
|
||||
$table->foreign('slider_id')->references('id')->on('sliders')->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('slider_translations');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateSliderSlidesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('slider_slides', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->integer('slider_id')->unsigned();
|
||||
$table->integer('file_id')->nullable()->unsigned();
|
||||
$table->text('options')->nullable();
|
||||
$table->string('call_to_action_url')->nullable();
|
||||
$table->boolean('open_in_new_window')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->foreign('slider_id')->references('id')->on('sliders')->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('slider_slides');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateSliderSlideTranslationsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('slider_slide_translations', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->integer('slider_slide_id')->unsigned();
|
||||
$table->string('locale');
|
||||
$table->string('caption_1')->nullable();
|
||||
$table->string('caption_2')->nullable();
|
||||
$table->string('call_to_action_text')->nullable();
|
||||
|
||||
$table->unique(['slider_slide_id', 'locale']);
|
||||
$table->foreign('slider_slide_id')->references('id')->on('slider_slides')->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('slider_slide_translations');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddPositionToSliderSlidesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('slider_slides', function (Blueprint $table) {
|
||||
$table->integer('position')->after('open_in_new_window')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('slider_slides', function (Blueprint $table) {
|
||||
$table->dropColumn('position');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class RemoveFileIdFromSliderSlidesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('slider_slides', function (Blueprint $table) {
|
||||
$table->dropColumn('file_id');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('slider_slides', function (Blueprint $table) {
|
||||
$table->integer('file_id')->nullable()->unsigned();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddFileIdToSliderSlideTranslationsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('slider_slide_translations', function (Blueprint $table) {
|
||||
$table->integer('file_id')->after('locale')->nullable()->unsigned();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('slider_slide_translations', function (Blueprint $table) {
|
||||
$table->dropColumn('file_id');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddDirectionColumnToSliderSlideTranslationsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('slider_slide_translations', function (Blueprint $table) {
|
||||
$table->string('direction')->nullable()->before('call_to_action_text');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('slider_slide_translations', function (Blueprint $table) {
|
||||
$table->dropColumn('direction');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddSpeedColumnToSlidersTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('sliders', function (Blueprint $table) {
|
||||
$table->integer('speed')->nullable()->after('id');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('sliders', function (Blueprint $table) {
|
||||
$table->dropColumn('speed');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddFadeColumnToSlidersTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('sliders', function (Blueprint $table) {
|
||||
$table->boolean('fade')->default(false)->after('autoplay_speed');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('sliders', function (Blueprint $table) {
|
||||
$table->dropColumn('fade');
|
||||
});
|
||||
}
|
||||
}
|
||||
113
Modules/Slider/Entities/Slider.php
Normal file
113
Modules/Slider/Entities/Slider.php
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Slider\Entities;
|
||||
|
||||
use Modules\Admin\Ui\AdminTable;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Modules\Support\Eloquent\Translatable;
|
||||
|
||||
class Slider extends Model
|
||||
{
|
||||
use Translatable;
|
||||
|
||||
/**
|
||||
* The relations to eager load on every query.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $with = ['translations', 'slides'];
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = ['speed', 'autoplay', 'autoplay_speed', 'fade', 'dots', 'arrows'];
|
||||
|
||||
/**
|
||||
* The attributes that are translatable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $translatedAttributes = ['name'];
|
||||
|
||||
/**
|
||||
* Perform any actions required after the model boots.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
{
|
||||
static::saved(function ($slider) {
|
||||
$slider->saveSlides(request('slides', []));
|
||||
$slider->clearCache();
|
||||
});
|
||||
}
|
||||
|
||||
public function shouldAutoPlay()
|
||||
{
|
||||
return $this->autoplay ? 'true' : 'false';
|
||||
}
|
||||
|
||||
public function clearCache()
|
||||
{
|
||||
Cache::tags("sliders.{$this->id}")->flush();
|
||||
}
|
||||
|
||||
public static function findWithSlides($id)
|
||||
{
|
||||
if (is_null($id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return Cache::tags("sliders.{$id}")
|
||||
->rememberForever(md5("sliders.{$id}:" . locale()), function () use ($id) {
|
||||
return static::with('slides')->find($id);
|
||||
});
|
||||
}
|
||||
|
||||
public function slides()
|
||||
{
|
||||
return $this->hasMany(SliderSlide::class)->orderBy('position');
|
||||
}
|
||||
|
||||
public function getAutoplaySpeedAttribute($autoplaySpeed)
|
||||
{
|
||||
return $autoplaySpeed ?: 3000;
|
||||
}
|
||||
|
||||
public function table()
|
||||
{
|
||||
return new AdminTable($this->newQuery());
|
||||
}
|
||||
|
||||
/**
|
||||
* Save slides for the slider.
|
||||
*
|
||||
* @param array $slides
|
||||
* @return void
|
||||
*/
|
||||
public function saveSlides($slides)
|
||||
{
|
||||
$ids = $this->getDeleteCandidates($slides);
|
||||
|
||||
if ($ids->isNotEmpty()) {
|
||||
$this->slides()->whereIn('id', $ids)->delete();
|
||||
}
|
||||
|
||||
foreach (array_reset_index($slides) as $index => $slide) {
|
||||
$this->slides()->updateOrCreate(
|
||||
['id' => $slide['id']],
|
||||
$slide + ['position' => $index]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function getDeleteCandidates($slides = [])
|
||||
{
|
||||
return $this->slides()
|
||||
->pluck('id')
|
||||
->diff(array_pluck($slides, 'id'));
|
||||
}
|
||||
}
|
||||
64
Modules/Slider/Entities/SliderSlide.php
Normal file
64
Modules/Slider/Entities/SliderSlide.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Slider\Entities;
|
||||
|
||||
use Modules\Media\Entities\File;
|
||||
use Modules\Support\Eloquent\Model;
|
||||
use Modules\Support\Eloquent\Translatable;
|
||||
|
||||
class SliderSlide extends Model
|
||||
{
|
||||
use Translatable;
|
||||
|
||||
/**
|
||||
* The relations to eager load on every query.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $with = ['translations', 'file'];
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = ['options', 'call_to_action_url', 'open_in_new_window', 'position'];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'options' => 'array',
|
||||
'open_in_new_window' => 'boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that are translatable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $translatedAttributes = [
|
||||
'file_id',
|
||||
'caption_1',
|
||||
'caption_2',
|
||||
'direction',
|
||||
'call_to_action_text',
|
||||
];
|
||||
|
||||
public function isAlignedLeft()
|
||||
{
|
||||
return $this->direction === 'left';
|
||||
}
|
||||
|
||||
public function isAlignedRight()
|
||||
{
|
||||
return $this->direction === 'right';
|
||||
}
|
||||
|
||||
public function file()
|
||||
{
|
||||
return $this->belongsTo(File::class)->withDefault();
|
||||
}
|
||||
}
|
||||
21
Modules/Slider/Entities/SliderSlideTranslation.php
Normal file
21
Modules/Slider/Entities/SliderSlideTranslation.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Slider\Entities;
|
||||
|
||||
use Modules\Support\Eloquent\TranslationModel;
|
||||
|
||||
class SliderSlideTranslation extends TranslationModel
|
||||
{
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'file_id',
|
||||
'caption_1',
|
||||
'caption_2',
|
||||
'direction',
|
||||
'call_to_action_text',
|
||||
];
|
||||
}
|
||||
15
Modules/Slider/Entities/SliderTranslation.php
Normal file
15
Modules/Slider/Entities/SliderTranslation.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Slider\Entities;
|
||||
|
||||
use Modules\Support\Eloquent\TranslationModel;
|
||||
|
||||
class SliderTranslation extends TranslationModel
|
||||
{
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = ['name'];
|
||||
}
|
||||
40
Modules/Slider/Http/Controllers/Admin/SliderController.php
Normal file
40
Modules/Slider/Http/Controllers/Admin/SliderController.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Slider\Http\Controllers\Admin;
|
||||
|
||||
use Modules\Slider\Entities\Slider;
|
||||
use Modules\Admin\Traits\HasCrudActions;
|
||||
use Modules\Slider\Http\Requests\SaveSliderRequest;
|
||||
|
||||
class SliderController
|
||||
{
|
||||
use HasCrudActions;
|
||||
|
||||
/**
|
||||
* Model for the resource.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = Slider::class;
|
||||
|
||||
/**
|
||||
* Label of the resource.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $label = 'slider::sliders.slider';
|
||||
|
||||
/**
|
||||
* View path of the resource.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $viewPath = 'slider::admin.sliders';
|
||||
|
||||
/**
|
||||
* Form requests for the resource.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $validation = SaveSliderRequest::class;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Slider\Http\Controllers\Admin;
|
||||
|
||||
use Modules\Admin\Traits\HasCrudActions;
|
||||
use Modules\Slider\Entities\SliderOption;
|
||||
use Modules\Slider\Http\Requests\SaveSliderOptionRequest;
|
||||
|
||||
class SliderOptionController
|
||||
{
|
||||
use HasCrudActions;
|
||||
|
||||
/**
|
||||
* Model for the resource.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = SliderOption::class;
|
||||
|
||||
/**
|
||||
* Label of the resource.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $label = 'slider::slider_options.slider_option';
|
||||
|
||||
/**
|
||||
* View path of the resource.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $viewPath = 'slider::admin.slider_options';
|
||||
|
||||
/**
|
||||
* Form requests for the resource.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $validation = SaveSliderOptionRequest::class;
|
||||
}
|
||||
27
Modules/Slider/Http/Requests/SaveSliderOptionRequest.php
Normal file
27
Modules/Slider/Http/Requests/SaveSliderOptionRequest.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Slider\Http\Requests;
|
||||
|
||||
use Modules\Core\Http\Requests\Request;
|
||||
|
||||
class SaveSliderOptionRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Available attributes.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $moduleAttributes = 'slider::attributes';
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'name' => 'required',
|
||||
];
|
||||
}
|
||||
}
|
||||
27
Modules/Slider/Http/Requests/SaveSliderRequest.php
Normal file
27
Modules/Slider/Http/Requests/SaveSliderRequest.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Slider\Http\Requests;
|
||||
|
||||
use Modules\Core\Http\Requests\Request;
|
||||
|
||||
class SaveSliderRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Available attributes.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $availableAttributes = 'slider::attributes';
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'name' => 'required',
|
||||
];
|
||||
}
|
||||
}
|
||||
25
Modules/Slider/Providers/SliderServiceProvider.php
Normal file
25
Modules/Slider/Providers/SliderServiceProvider.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Slider\Providers;
|
||||
|
||||
use Modules\Slider\Admin\SliderTabs;
|
||||
use Modules\Support\Traits\AddsAsset;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Modules\Admin\Ui\Facades\TabManager;
|
||||
|
||||
class SliderServiceProvider extends ServiceProvider
|
||||
{
|
||||
use AddsAsset;
|
||||
|
||||
/**
|
||||
* Bootstrap the application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
TabManager::register('sliders', SliderTabs::class);
|
||||
|
||||
$this->addAdminAssets('admin.sliders.(create|edit)', ['admin.media.js', 'admin.slider.css', 'admin.slider.js']);
|
||||
}
|
||||
}
|
||||
41
Modules/Slider/Resources/assets/admin/js/Slide.js
Normal file
41
Modules/Slider/Resources/assets/admin/js/Slide.js
Normal file
@@ -0,0 +1,41 @@
|
||||
export default class {
|
||||
constructor(data) {
|
||||
this.slidePanelHtml = this.getSlidePanelHtml(data);
|
||||
}
|
||||
|
||||
getSlidePanelHtml(data) {
|
||||
data.slide.options = data.slide.options || this.getDefaultOptions();
|
||||
|
||||
let template = _.template($('#slide-template').html());
|
||||
|
||||
return $(template(data));
|
||||
}
|
||||
|
||||
getDefaultOptions() {
|
||||
return { caption_1: {}, caption_2: {}, direction: 'left', call_to_action: {} };
|
||||
}
|
||||
|
||||
render() {
|
||||
this.attachEventListeners();
|
||||
this.showSelectedOptionBlock();
|
||||
|
||||
return this.slidePanelHtml;
|
||||
}
|
||||
|
||||
attachEventListeners() {
|
||||
this.slidePanelHtml.find('.delete-slide').on('click', () => {
|
||||
this.slidePanelHtml.remove();
|
||||
});
|
||||
|
||||
this.slidePanelHtml.find('.change-option-block').on('change', (e) => {
|
||||
this.slidePanelHtml.find('.slide-options').hide();
|
||||
this.slidePanelHtml.find(`.${e.currentTarget.value}`).show();
|
||||
});
|
||||
}
|
||||
|
||||
showSelectedOptionBlock() {
|
||||
setTimeout(() => {
|
||||
this.slidePanelHtml.find('.change-option-block').trigger('change');
|
||||
});
|
||||
}
|
||||
}
|
||||
58
Modules/Slider/Resources/assets/admin/js/Slider.js
Normal file
58
Modules/Slider/Resources/assets/admin/js/Slider.js
Normal file
@@ -0,0 +1,58 @@
|
||||
import Slide from './Slide';
|
||||
|
||||
export default class {
|
||||
constructor() {
|
||||
this.slideCount = 0;
|
||||
|
||||
this.addSlides(FleetCart.data['slider.slides']);
|
||||
|
||||
if (this.slideCount === 0) {
|
||||
this.addSlide();
|
||||
}
|
||||
|
||||
this.attachEventListeners();
|
||||
this.makeSlidesSortable();
|
||||
}
|
||||
|
||||
addSlides(slides) {
|
||||
for (let attributes of slides) {
|
||||
this.addSlide(attributes);
|
||||
}
|
||||
}
|
||||
|
||||
addSlide(attributes = {}) {
|
||||
let slide = new Slide({ slideNumber: this.slideCount++, slide: attributes });
|
||||
|
||||
$('#slides-wrapper').append(slide.render());
|
||||
}
|
||||
|
||||
attachEventListeners() {
|
||||
$('.add-slide').on('click', () => {
|
||||
this.addSlide();
|
||||
});
|
||||
|
||||
this.attachImagePickerEventListener();
|
||||
}
|
||||
|
||||
attachImagePickerEventListener() {
|
||||
$('#slides-wrapper').on('click', '.slide-image', (e) => {
|
||||
let picker = new MediaPicker({ type: 'image' });
|
||||
|
||||
picker.on('select', (file) => {
|
||||
let html = `
|
||||
<img src="${file.path}">
|
||||
<input type="hidden" name="slides[${e.currentTarget.dataset.slideNumber}][file_id]" value="${file.id}">
|
||||
`;
|
||||
|
||||
$(e.currentTarget).html(html);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
makeSlidesSortable() {
|
||||
Sortable.create(document.getElementById('slides-wrapper'), {
|
||||
handle: '.slide-drag',
|
||||
animation: 150,
|
||||
});
|
||||
}
|
||||
}
|
||||
9
Modules/Slider/Resources/assets/admin/js/main.js
Normal file
9
Modules/Slider/Resources/assets/admin/js/main.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import Slider from './Slider';
|
||||
|
||||
new Slider();
|
||||
|
||||
$('#autoplay').on('change', (e) => {
|
||||
$('.autoplay-speed-field').toggleClass('hide');
|
||||
});
|
||||
|
||||
window.admin.removeSubmitButtonOffsetOn('#slides');
|
||||
147
Modules/Slider/Resources/assets/admin/sass/main.scss
Normal file
147
Modules/Slider/Resources/assets/admin/sass/main.scss
Normal file
@@ -0,0 +1,147 @@
|
||||
.slide {
|
||||
border: 1px solid #e9e9e9;
|
||||
border-radius: 3px;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.slide-header {
|
||||
padding: 15px;
|
||||
background: #f6f6f7;
|
||||
border-bottom: 1px solid #e9e9e9;
|
||||
|
||||
.slide-drag {
|
||||
font-size: 16px;
|
||||
color: #737881;
|
||||
cursor: move;
|
||||
margin: 3px 10px 0 0;
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
|
||||
i {
|
||||
float: left;
|
||||
|
||||
&:nth-child(2) {
|
||||
margin-left: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.slide-body {
|
||||
position: relative;
|
||||
padding: 15px;
|
||||
|
||||
.slide-tabs {
|
||||
margin-left: 170px;
|
||||
|
||||
.nav-tabs {
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
border: none;
|
||||
|
||||
a[data-toggle=tab] {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
border-top: 1px solid #d2d6de;
|
||||
margin-top: -7px;
|
||||
-webkit-margin-before: -6px;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
margin-top: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.slide-image {
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
left: 15px;
|
||||
border: 1px solid #d2d6de;
|
||||
border-radius: 3px;
|
||||
height: 150px;
|
||||
width: 150px;
|
||||
cursor: pointer;
|
||||
z-index: 0;
|
||||
|
||||
> img {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
z-index: 1;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
> i {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
font-size: 70px;
|
||||
color: #d9d9d9;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
|
||||
.slide-options {
|
||||
display: none;
|
||||
|
||||
.form-horizontal {
|
||||
border-top: 1px solid #d2d6de;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin: 6px 0 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 767px) {
|
||||
.slide {
|
||||
.slide-image {
|
||||
position: relative;
|
||||
left: auto;
|
||||
top: auto;
|
||||
margin: 15px auto 30px;
|
||||
display: table;
|
||||
}
|
||||
|
||||
.slide-body .slide-tabs {
|
||||
margin: 0;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.slide-options .form-horizontal {
|
||||
clear: both;
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1199px) {
|
||||
.slide {
|
||||
.slide-body .slide-tabs .checkbox {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
23
Modules/Slider/Resources/lang/en/attributes.php
Normal file
23
Modules/Slider/Resources/lang/en/attributes.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'caption_1' => 'Caption 1',
|
||||
'caption_2' => 'Caption 2',
|
||||
'direction' => 'Direction',
|
||||
'call_to_action_text' => 'Call to Action Text',
|
||||
'call_to_action_url' => 'Call to Action URL',
|
||||
'open_in_new_window' => 'Open in new window',
|
||||
'caption_1_delay' => 'Delay',
|
||||
'caption_1_effect' => 'Effect',
|
||||
'caption_2_delay' => 'Delay',
|
||||
'caption_2_effect' => 'Effect',
|
||||
'call_to_action_delay' => 'Delay',
|
||||
'call_to_action_effect' => 'Effect',
|
||||
'name' => 'Name',
|
||||
'speed' => 'Speed',
|
||||
'autoplay' => 'Autoplay',
|
||||
'autoplay_speed' => 'Autoplay Speed',
|
||||
'fade' => 'Fade',
|
||||
'dots' => 'Dots',
|
||||
'arrows' => 'Arrows',
|
||||
];
|
||||
8
Modules/Slider/Resources/lang/en/permissions.php
Normal file
8
Modules/Slider/Resources/lang/en/permissions.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'index' => 'Index Slider',
|
||||
'create' => 'Create Slider',
|
||||
'edit' => 'Edit Slider',
|
||||
'destroy' => 'Delete Slider',
|
||||
];
|
||||
58
Modules/Slider/Resources/lang/en/sliders.php
Normal file
58
Modules/Slider/Resources/lang/en/sliders.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'slider' => 'Slider',
|
||||
'sliders' => 'Sliders',
|
||||
'table' => [
|
||||
'name' => 'Name',
|
||||
],
|
||||
'tabs' => [
|
||||
'group' => [
|
||||
'slider_information' => 'Slider Information',
|
||||
],
|
||||
'slides' => 'Slides',
|
||||
'settings' => 'Settings',
|
||||
],
|
||||
'slide' => [
|
||||
'add_slide' => 'Add Slide',
|
||||
'image_slide' => 'Image Slide',
|
||||
'form' => [
|
||||
'tabs' => [
|
||||
'general' => 'General',
|
||||
'options' => 'Options',
|
||||
],
|
||||
'directions' => [
|
||||
'left' => 'Left',
|
||||
'right' => 'Right',
|
||||
],
|
||||
'caption_1' => 'Caption 1',
|
||||
'caption_2' => 'Caption 2',
|
||||
'call_to_action' => 'Call to Action',
|
||||
'call_to_action_url' => 'Call to Action URL',
|
||||
'open_in_new_window' => 'Open in new window',
|
||||
'0s' => '0s',
|
||||
'0_3s' => '0.3s',
|
||||
'0_7s' => '0.7s',
|
||||
],
|
||||
],
|
||||
'effects' => [
|
||||
'fadeInUp' => 'fadeInUp',
|
||||
'fadeInDown' => 'fadeInDown',
|
||||
'fadeInLeft' => 'fadeInLeft',
|
||||
'fadeInRight' => 'fadeInRight',
|
||||
'lightSpeedIn' => 'lightSpeedIn',
|
||||
'slideInUp' => 'slideInUp',
|
||||
'slideInDown' => 'slideInDown',
|
||||
'slideInLeft' => 'slideInLeft',
|
||||
'slideInRight' => 'slideInRight',
|
||||
'zoomIn' => 'zoomIn',
|
||||
],
|
||||
'form' => [
|
||||
'enable_autoplay' => 'Enable autoplay',
|
||||
'300ms' => '300ms',
|
||||
'3000ms' => '3000ms',
|
||||
'use_fade_instead_of_slide' => 'Fade slides instead of sliding',
|
||||
'show_dots' => 'Show slider dots',
|
||||
'show_arrows' => 'Show Prev/Next arrows',
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1,18 @@
|
||||
@extends('admin::layout')
|
||||
|
||||
@component('admin::components.page.header')
|
||||
@slot('title', trans('admin::resource.create', ['resource' => trans('slider::sliders.slider')]))
|
||||
|
||||
<li><a href="{{ route('admin.sliders.index') }}">{{ trans('slider::sliders.sliders') }}</a></li>
|
||||
<li class="active">{{ trans('admin::resource.create', ['resource' => trans('slider::sliders.slider')]) }}</li>
|
||||
@endcomponent
|
||||
|
||||
@section('content')
|
||||
<form method="POST" action="{{ route('admin.sliders.store') }}" class="form-horizontal" id="slider-create-form" novalidate>
|
||||
{{ csrf_field() }}
|
||||
|
||||
{!! $tabs->render(compact('slider')) !!}
|
||||
</form>
|
||||
@endsection
|
||||
|
||||
@include('slider::admin.sliders.partials.shortcuts')
|
||||
20
Modules/Slider/Resources/views/admin/sliders/edit.blade.php
Normal file
20
Modules/Slider/Resources/views/admin/sliders/edit.blade.php
Normal file
@@ -0,0 +1,20 @@
|
||||
@extends('admin::layout')
|
||||
|
||||
@component('admin::components.page.header')
|
||||
@slot('title', trans('admin::resource.edit', ['resource' => trans('slider::sliders.slider')]))
|
||||
@slot('subtitle', $slider->name)
|
||||
|
||||
<li><a href="{{ route('admin.sliders.index') }}">{{ trans('slider::sliders.sliders') }}</a></li>
|
||||
<li class="active">{{ trans('admin::resource.edit', ['resource' => trans('slider::sliders.slider')]) }}</li>
|
||||
@endcomponent
|
||||
|
||||
@section('content')
|
||||
<form method="POST" action="{{ route('admin.sliders.update', $slider) }}" class="form-horizontal" id="slider-edit-form" novalidate>
|
||||
{{ csrf_field() }}
|
||||
{{ method_field('put') }}
|
||||
|
||||
{!! $tabs->render(compact('slider')) !!}
|
||||
</form>
|
||||
@endsection
|
||||
|
||||
@include('slider::admin.sliders.partials.shortcuts')
|
||||
36
Modules/Slider/Resources/views/admin/sliders/index.blade.php
Normal file
36
Modules/Slider/Resources/views/admin/sliders/index.blade.php
Normal file
@@ -0,0 +1,36 @@
|
||||
@extends('admin::layout')
|
||||
|
||||
@component('admin::components.page.header')
|
||||
@slot('title', trans('slider::sliders.sliders'))
|
||||
|
||||
<li class="active">{{ trans('slider::sliders.sliders') }}</li>
|
||||
@endcomponent
|
||||
|
||||
@component('admin::components.page.index_table')
|
||||
@slot('buttons', ['create'])
|
||||
@slot('resource', 'sliders')
|
||||
@slot('name', trans('slider::sliders.slider'))
|
||||
|
||||
@component('admin::components.table')
|
||||
@slot('thead')
|
||||
<tr>
|
||||
@include('admin::partials.table.select_all')
|
||||
|
||||
<th>{{ trans('slider::sliders.table.name') }}</th>
|
||||
<th data-sort>{{ trans('admin::admin.table.created') }}</th>
|
||||
</tr>
|
||||
@endslot
|
||||
@endcomponent
|
||||
@endcomponent
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
new DataTable('#sliders-table .table', {
|
||||
columns: [
|
||||
{ data: 'checkbox', orderable: false, searchable: false, width: '3%' },
|
||||
{ data: 'name', name: 'translations.name', orderable: false, defaultContent: '' },
|
||||
{ data: 'created', name: 'created_at' },
|
||||
],
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@@ -0,0 +1,14 @@
|
||||
@push('shortcuts')
|
||||
<dl class="dl-horizontal">
|
||||
<dt><code>b</code></dt>
|
||||
<dd>{{ trans('admin::admin.shortcuts.back_to_index', ['name' => trans('slider::sliders.slider')]) }}</dd>
|
||||
</dl>
|
||||
@endpush
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
keypressAction([
|
||||
{ key: 'b', route: "{{ route('admin.sliders.index') }}" }
|
||||
]);
|
||||
</script>
|
||||
@endpush
|
||||
@@ -0,0 +1,7 @@
|
||||
<div class="form-group">
|
||||
<div class="col-md-10">
|
||||
<button type="submit" class="btn btn-primary" data-loading>
|
||||
{{ trans('admin::admin.buttons.save') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,15 @@
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
{{ Form::text('name', trans('slider::attributes.name'), $errors, $slider, ['required' => true]) }}
|
||||
{{ Form::number('speed', trans('slider::attributes.speed'), $errors, $slider, ['placeholder' => trans('slider::sliders.form.300ms')]) }}
|
||||
{{ Form::checkbox('fade', trans('slider::attributes.fade'), trans('slider::sliders.form.use_fade_instead_of_slide'), $errors, $slider) }}
|
||||
{{ Form::checkbox('autoplay', trans('slider::attributes.autoplay'), trans('slider::sliders.form.enable_autoplay'), $errors, $slider, ['checked' => true]) }}
|
||||
|
||||
<div class="autoplay-speed-field {{ ($slider->autoplay ?? true) ? '' : 'hide' }}">
|
||||
{{ Form::number('autoplay_speed', trans('slider::attributes.autoplay_speed'), $errors, $slider, ['placeholder' => trans('slider::sliders.form.3000ms'), 'checked' => true]) }}
|
||||
</div>
|
||||
|
||||
{{ Form::checkbox('dots', trans('slider::attributes.dots'), trans('slider::sliders.form.show_dots'), $errors, $slider, ['checked' => true]) }}
|
||||
{{ Form::checkbox('arrows', trans('slider::attributes.arrows'), trans('slider::sliders.form.show_arrows'), $errors, $slider, ['checked' => true]) }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,17 @@
|
||||
<div id="slides-wrapper" class="clearfix">
|
||||
{{-- Slides will be added here dynamically using JS --}}
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<button type="button" class="add-slide btn btn-default m-l-15">
|
||||
{{ trans('slider::sliders.slide.add_slide') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@include('slider::admin.sliders.templates.slide')
|
||||
|
||||
@push('globals')
|
||||
<script>
|
||||
FleetCart.data['slider.slides'] = {!! old_json('slides', $slider->slides) !!};
|
||||
</script>
|
||||
@endpush
|
||||
@@ -0,0 +1,43 @@
|
||||
<div class="slide-options call-to-action">
|
||||
<h4>{{ trans("slider::sliders.slide.form.call_to_action") }}</h4>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-12 p-l-0">
|
||||
<label class="control-label col-lg-2 col-md-3 col-sm-3 col-xs-12 text-left p-l-0" for="call-to-action-delay">
|
||||
{{ trans("slider::attributes.call_to_action_delay") }}
|
||||
</label>
|
||||
|
||||
<div class="col-lg-4 col-md-7 col-sm-6 col-xs-7 p-l-0">
|
||||
<input type="number"
|
||||
name="slides[<%- slideNumber %>][options][call_to_action][delay]"
|
||||
class="form-control"
|
||||
id="call-to-action-delay"
|
||||
placeholder="{{ trans('slider::sliders.slide.form.0_7s') }}"
|
||||
value="<%- slide.options.call_to_action.delay %>"
|
||||
step="0.01"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-12 p-l-0">
|
||||
<label class="control-label col-lg-2 col-md-3 col-sm-3 col-xs-12 text-left p-l-0" for="call-to-action-effect">
|
||||
{{ trans("slider::attributes.call_to_action_effect") }}
|
||||
</label>
|
||||
|
||||
<div class="col-lg-4 col-md-7 col-sm-6 col-xs-7 p-l-0">
|
||||
<select name="slides[<%- slideNumber %>][options][call_to_action][effect]"
|
||||
class="form-control custom-select-black"
|
||||
id="call-to-action-effect"
|
||||
>
|
||||
@foreach (trans('slider::sliders.effects') as $effect => $name)
|
||||
<option value="{{ $effect }}" <%= slide.options.call_to_action.effect === '{{ $effect }}' ? 'selected' : '' %>>
|
||||
{{ $name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,43 @@
|
||||
<div class="slide-options caption-{{ $captionNumber }}">
|
||||
<h4>{{ trans("slider::sliders.slide.form.caption_{$captionNumber}") }}</h4>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-12 p-l-0">
|
||||
<label class="control-label col-lg-2 col-md-3 col-sm-3 col-xs-12 text-left p-l-0" for="slides-<%- slideNumber %>-caption-{{ $captionNumber }}-delay">
|
||||
{{ trans("slider::attributes.caption_{$captionNumber}_delay") }}
|
||||
</label>
|
||||
|
||||
<div class="col-lg-4 col-md-7 col-sm-6 col-xs-7 p-l-0">
|
||||
<input type="number"
|
||||
name="slides[<%- slideNumber %>][options][caption_{{ $captionNumber }}][delay]"
|
||||
class="form-control"
|
||||
id="slides-<%- slideNumber %>-caption-{{ $captionNumber }}-delay"
|
||||
placeholder="{{ trans('slider::sliders.slide.form.' . ($captionNumber === 1 ? '0s' : '0_3s')) }}"
|
||||
value="<%- slide.options.caption_{{ $captionNumber }}.delay %>"
|
||||
step="0.01"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-12 p-l-0">
|
||||
<label class="control-label col-lg-2 col-md-3 col-sm-3 col-xs-12 text-left p-l-0" for="slides-<%- slideNumber %>-caption-{{ $captionNumber }}-effect">
|
||||
{{ trans("slider::attributes.caption_{$captionNumber}_effect") }}
|
||||
</label>
|
||||
|
||||
<div class="col-lg-4 col-md-7 col-sm-6 col-xs-7 p-l-0">
|
||||
<select name="slides[<%- slideNumber %>][options][caption_{{ $captionNumber }}][effect]"
|
||||
class="form-control custom-select-black"
|
||||
id="slides-<%- slideNumber %>-caption-{{ $captionNumber }}-effect"
|
||||
>
|
||||
@foreach (trans('slider::sliders.effects') as $effect => $name)
|
||||
<option value="{{ $effect }}" <%= slide.options.caption_{{ $captionNumber }}.effect === '{{ $effect }}' ? 'selected' : '' %>>
|
||||
{{ $name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,166 @@
|
||||
<script type="text/html" id="slide-template">
|
||||
<div class="slide">
|
||||
<div class="slide-header clearfix">
|
||||
<span class="slide-drag pull-left">
|
||||
<i class="fa"></i>
|
||||
<i class="fa"></i>
|
||||
</span>
|
||||
|
||||
<span class="pull-left">
|
||||
{{ trans('slider::sliders.slide.image_slide') }}
|
||||
</span>
|
||||
|
||||
<button type="button" class="delete-slide btn pull-right">
|
||||
<i class="fa fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="slide-body">
|
||||
<input type="hidden" name="slides[<%- slideNumber %>][id]" value="<%- slide.id %>">
|
||||
|
||||
<div class="slide-image" data-slide-number="<%- slideNumber %>">
|
||||
<% if (slide.file && slide.file.path) { %>
|
||||
<img src="<%- slide.file.path %>" alt="slide-image">
|
||||
<input type="hidden" name="slides[<%- slideNumber %>][file_id]" value="<%- slide.file.id %>">
|
||||
<% } else { %>
|
||||
<i class="fa fa-picture-o"></i>
|
||||
<% } %>
|
||||
</div>
|
||||
|
||||
<div class="slide-tabs tab-wrapper">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active">
|
||||
<a href="#slides-<%- slideNumber %>-general" data-toggle="tab">
|
||||
{{ trans('slider::sliders.slide.form.tabs.general') }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#slider-<%- slideNumber %>-options" data-toggle="tab">
|
||||
{{ trans('slider::sliders.slide.form.tabs.options') }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
<div id="slides-<%- slideNumber %>-general" class="general tab-pane fade in active">
|
||||
<div class="row">
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="slides-<%- slideNumber %>-caption-1">
|
||||
{{ trans('slider::attributes.caption_1') }}
|
||||
</label>
|
||||
|
||||
<input type="text"
|
||||
name="slides[<%- slideNumber %>][caption_1]"
|
||||
class="form-control"
|
||||
id="slides-<%- slideNumber %>-caption-1"
|
||||
value="<%- slide.caption_1 %>"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="slides-<%- slideNumber %>-caption-2">
|
||||
{{ trans('slider::attributes.caption_2') }}
|
||||
</label>
|
||||
|
||||
<input type="text"
|
||||
name="slides[<%- slideNumber %>][caption_2]"
|
||||
class="form-control"
|
||||
id="slides-<%- slideNumber %>-caption-2"
|
||||
value="<%- slide.caption_2 %>"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="slides-<%- slideNumber %>-direction">
|
||||
{{ trans('slider::attributes.direction') }}
|
||||
</label>
|
||||
|
||||
<select
|
||||
name="slides[<%- slideNumber %>][direction]"
|
||||
class="form-control"
|
||||
id="slides-<%- slideNumber %>-direction"
|
||||
value="<%- slide.direction %>"
|
||||
>
|
||||
<option value="left" <%= slide.direction === 'left' ? 'selected' : '' %>>
|
||||
{{ trans('slider::sliders.slide.form.directions.left') }}
|
||||
</option>
|
||||
|
||||
<option value="right" <%= slide.direction === 'right' ? 'selected' : '' %>>
|
||||
{{ trans('slider::sliders.slide.form.directions.right') }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="slides[<%- slideNumber %>][call-to-action-text]">
|
||||
{{ trans('slider::attributes.call_to_action_text') }}
|
||||
</label>
|
||||
|
||||
<input type="text"
|
||||
name="slides[<%- slideNumber %>][call_to_action_text]"
|
||||
class="form-control"
|
||||
id="slides[<%- slideNumber %>][call-to-action-text]"
|
||||
value="<%- slide.call_to_action_text %>"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="slides-<%- slideNumber %>-call-to-action-url">
|
||||
{{ trans('slider::attributes.call_to_action_url') }}
|
||||
</label>
|
||||
|
||||
<input type="text"
|
||||
name="slides[<%- slideNumber %>][call_to_action_url]"
|
||||
class="form-control"
|
||||
id="slides-<%- slideNumber %>-call-to-action-url"
|
||||
value="<%- slide.call_to_action_url %>"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 col-md-12">
|
||||
<div class="checkbox">
|
||||
<input type="hidden" name="slides[<%- slideNumber %>][open_in_new_window]" value="0">
|
||||
|
||||
<input type="checkbox"
|
||||
name="slides[<%- slideNumber %>][open_in_new_window]"
|
||||
value="1"
|
||||
id="slides-<%- slideNumber %>-open-in-new-window"
|
||||
<%= slide.open_in_new_window ? 'checked' : '' %>
|
||||
>
|
||||
|
||||
<label for="slides-<%- slideNumber %>-open-in-new-window">
|
||||
{{ trans('slider::attributes.open_in_new_window') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="slider-<%- slideNumber %>-options" class="tab-pane fade in clearfix">
|
||||
<select class="change-option-block custom-select-black pull-right">
|
||||
<option value="caption-1" selected>{{ trans('slider::sliders.slide.form.caption_1') }}</option>
|
||||
<option value="caption-2">{{ trans('slider::sliders.slide.form.caption_2') }}</option>
|
||||
<option value="call-to-action">{{ trans('slider::sliders.slide.form.call_to_action') }}</option>
|
||||
</select>
|
||||
|
||||
@include('slider::admin.sliders.templates.partials.slide_caption', ['captionNumber' => 1])
|
||||
@include('slider::admin.sliders.templates.partials.slide_caption', ['captionNumber' => 2])
|
||||
@include('slider::admin.sliders.templates.partials.slide_call_to_action')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
75
Modules/Slider/Routes/admin.php
Normal file
75
Modules/Slider/Routes/admin.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::get('sliders', [
|
||||
'as' => 'admin.sliders.index',
|
||||
'uses' => 'SliderController@index',
|
||||
'middleware' => 'can:admin.sliders.index',
|
||||
]);
|
||||
|
||||
Route::get('sliders/create', [
|
||||
'as' => 'admin.sliders.create',
|
||||
'uses' => 'SliderController@create',
|
||||
'middleware' => 'can:admin.sliders.create',
|
||||
]);
|
||||
|
||||
Route::post('sliders', [
|
||||
'as' => 'admin.sliders.store',
|
||||
'uses' => 'SliderController@store',
|
||||
'middleware' => 'can:admin.sliders.create',
|
||||
]);
|
||||
|
||||
Route::get('sliders/{id}/edit', [
|
||||
'as' => 'admin.sliders.edit',
|
||||
'uses' => 'SliderController@edit',
|
||||
'middleware' => 'can:admin.sliders.edit',
|
||||
]);
|
||||
|
||||
Route::put('sliders/{id}', [
|
||||
'as' => 'admin.sliders.update',
|
||||
'uses' => 'SliderController@update',
|
||||
'middleware' => 'can:admin.sliders.edit',
|
||||
]);
|
||||
|
||||
Route::delete('sliders/{ids?}', [
|
||||
'as' => 'admin.sliders.destroy',
|
||||
'uses' => 'SliderController@destroy',
|
||||
'middleware' => 'can:admin.sliders.destroy',
|
||||
]);
|
||||
|
||||
Route::get('slider-options', [
|
||||
'as' => 'admin.slider_options.index',
|
||||
'uses' => 'SliderOptionController@index',
|
||||
'middleware' => 'can:admin.slider_options.index',
|
||||
]);
|
||||
|
||||
Route::get('slider-options/create', [
|
||||
'as' => 'admin.slider_options.create',
|
||||
'uses' => 'SliderOptionController@create',
|
||||
'middleware' => 'can:admin.slider_options.create',
|
||||
]);
|
||||
|
||||
Route::post('slider-options', [
|
||||
'as' => 'admin.slider_options.store',
|
||||
'uses' => 'SliderOptionController@store',
|
||||
'middleware' => 'can:admin.slider_options.create',
|
||||
]);
|
||||
|
||||
Route::get('slider-options/{id}/edit', [
|
||||
'as' => 'admin.slider_options.edit',
|
||||
'uses' => 'SliderOptionController@edit',
|
||||
'middleware' => 'can:admin.slider_options.edit',
|
||||
]);
|
||||
|
||||
Route::put('slider-options/{id}', [
|
||||
'as' => 'admin.slider_options.update',
|
||||
'uses' => 'SliderOptionController@update',
|
||||
'middleware' => 'can:admin.slider_options.edit',
|
||||
]);
|
||||
|
||||
Route::delete('slider-options/{ids?}', [
|
||||
'as' => 'admin.slider_options.destroy',
|
||||
'uses' => 'SliderOptionController@destroy',
|
||||
'middleware' => 'can:admin.slider_options.destroy',
|
||||
]);
|
||||
26
Modules/Slider/Sidebar/SidebarExtender.php
Normal file
26
Modules/Slider/Sidebar/SidebarExtender.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Slider\Sidebar;
|
||||
|
||||
use Maatwebsite\Sidebar\Item;
|
||||
use Maatwebsite\Sidebar\Menu;
|
||||
use Maatwebsite\Sidebar\Group;
|
||||
use Modules\Admin\Sidebar\BaseSidebarExtender;
|
||||
|
||||
class SidebarExtender extends BaseSidebarExtender
|
||||
{
|
||||
public function extend(Menu $menu)
|
||||
{
|
||||
$menu->group(trans('admin::sidebar.system'), function (Group $group) {
|
||||
$group->item(trans('admin::sidebar.appearance'), function (Item $item) {
|
||||
$item->item(trans('slider::sliders.sliders'), function (Item $item) {
|
||||
$item->weight(5);
|
||||
$item->route('admin.sliders.index');
|
||||
$item->authorize(
|
||||
$this->auth->hasAccess('admin.sliders.index')
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
27
Modules/Slider/composer.json
Normal file
27
Modules/Slider/composer.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "fleetcart/slider",
|
||||
"description": "The FleetCart Slider Module.",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Envay Soft",
|
||||
"email": "envaysoft@gmail.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.0.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Modules\\Slider\\": ""
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
9
Modules/Slider/module.json
Normal file
9
Modules/Slider/module.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "Slider",
|
||||
"alias": "slider",
|
||||
"description": "The FleetCart Slider Module.",
|
||||
"priority": 100,
|
||||
"providers": [
|
||||
"Modules\\Slider\\Providers\\SliderServiceProvider"
|
||||
]
|
||||
}
|
||||
8
Modules/Slider/webpack.mix.js
Normal file
8
Modules/Slider/webpack.mix.js
Normal file
@@ -0,0 +1,8 @@
|
||||
let mix = require('laravel-mix');
|
||||
let execSync = require('child_process').execSync;
|
||||
|
||||
mix.js(`${__dirname}/Resources/assets/admin/js/main.js`, `${__dirname}/Assets/admin/js/slider.js`)
|
||||
.sass(`${__dirname}/Resources/assets/admin/sass/main.scss`, `${__dirname}/Assets/admin/css/slider.css`)
|
||||
.then(() => {
|
||||
execSync(`npm run rtlcss ${__dirname}/Assets/admin/css/slider.css ${__dirname}/Assets/admin/css/slider.rtl.css`);
|
||||
});
|
||||
Reference in New Issue
Block a user