add CRUD concept
This commit is contained in:
parent
ec5f2f8bd1
commit
9fdc2260f0
62 changed files with 1539 additions and 129 deletions
|
|
@ -9,25 +9,39 @@ enum ColorsEnum : int {
|
|||
case lightgreen = 4;
|
||||
case brown = 5;
|
||||
|
||||
public function label(): string {
|
||||
return static::getLabel($this);
|
||||
}
|
||||
|
||||
public function color(): string {
|
||||
return static::getColor($this);
|
||||
}
|
||||
|
||||
public static function getLabel(self $value): string {
|
||||
return match ($value) {
|
||||
self::redwine => __('Redwine'),
|
||||
self::orange => __('Orange'),
|
||||
self::blue => __('Blue'),
|
||||
self::lightgreen => __('Lightgreen'),
|
||||
self::brown => __('Brown'),
|
||||
};
|
||||
}
|
||||
public static function getColor(self $value): string {
|
||||
return match ($value) {
|
||||
self::redwine => rgb(165 25 60),
|
||||
self::orange => rgb(240 165 0),
|
||||
self::blue => rgb(95 155 210),
|
||||
self::lightgreen => rgb(180 190 0),
|
||||
self::brown => rgb(95 40 45),
|
||||
self::redwine => "rgb(165 25 60)",
|
||||
self::orange => "rgb(240 165 0)",
|
||||
self::blue => "rgb(95 155 210)",
|
||||
self::lightgreen => "rgb(180 190 0)",
|
||||
self::brown => "rgb(95 40 45)",
|
||||
};
|
||||
}
|
||||
|
||||
public static function getColors(): array {
|
||||
public static function getData(): array {
|
||||
$arrayEnum = [];
|
||||
foreach (self::cases() as $key => $value) {
|
||||
$arrayEnum = array_merge($arrayEnum, [[
|
||||
"value" => $value->value,
|
||||
"label" => $value->label(),
|
||||
"color" => $value->color()
|
||||
]]);
|
||||
}
|
||||
|
|
|
|||
18
app/Enums/InputType.php
Normal file
18
app/Enums/InputType.php
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum InputType : int {
|
||||
case boolean = 1;
|
||||
case number = 2;
|
||||
case string = 3;
|
||||
case text = 4;
|
||||
case url = 5;
|
||||
case videoVimeo = 6;
|
||||
case image = 7;
|
||||
case imageArray = 8;
|
||||
case labelArray = 9;
|
||||
case dropdownArray = 10;
|
||||
case miniblocArray = 11;
|
||||
case selectEnum = 12;
|
||||
}
|
||||
164
app/Http/Controllers/Bo/ConceptController.php
Normal file
164
app/Http/Controllers/Bo/ConceptController.php
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\Concepts\StoreConceptRequest;
|
||||
use App\Http\Requests\Bo\Concepts\UpdateConceptRequest;
|
||||
use App\Models\Concept;
|
||||
use App\Traits\Controllers\UpdateModelStatus;
|
||||
use App\Traits\Models\ChangesModelOrder;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ConceptController extends Controller
|
||||
{
|
||||
use ChangesModelOrder;
|
||||
use UpdateModelStatus;
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $concepts */
|
||||
$concepts = Concept::query();
|
||||
|
||||
if ($request->search) {
|
||||
$this->searchQuery(
|
||||
$concepts,
|
||||
$request->search,
|
||||
null,
|
||||
'seo_title',
|
||||
'name',
|
||||
'title',
|
||||
'subtitle',
|
||||
);
|
||||
}
|
||||
|
||||
$this->sortQuery($concepts);
|
||||
$searchFields = trans('Name');
|
||||
|
||||
$conceptModels = $concepts->paginate(10);
|
||||
|
||||
return view('bo.pages.concepts.index', compact('conceptModels', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$conceptData = Concept::getEmptyData();
|
||||
|
||||
return view('bo.pages.concepts.create', compact('conceptData'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Concepts\StoreConceptRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(StoreConceptRequest $request)
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$concept = new Concept();
|
||||
$concept->data = $concept->getEmptyData();
|
||||
$concept->fill(array_replace_recursive(
|
||||
\json_decode(\json_encode($concept->toArray()), true),
|
||||
$request->validated()
|
||||
));
|
||||
|
||||
if ($concept->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.concepts.edit', $concept)
|
||||
->with('success', trans(
|
||||
':model has been created',
|
||||
['model' => Str::singular(trans('models.classes.concepts'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model cannot be created',
|
||||
['model' => Str::singular(trans('models.classes.concepts'))]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Concept $concept
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit(Concept $concept)
|
||||
{
|
||||
return view('bo.pages.concepts.edit', [
|
||||
'conceptModel' => $concept
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Concepts\UpdateConceptRequest $request
|
||||
* @param \App\Models\Concept $concept
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(UpdateConceptRequest $request, Concept $concept)
|
||||
{
|
||||
return DB::transaction(function () use ($request, $concept) {
|
||||
$concept->fill(array_replace_recursive(
|
||||
\json_decode(\json_encode($concept->toArray()), true),
|
||||
$request->validated()
|
||||
));
|
||||
|
||||
if ($concept->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.concepts.edit', $concept)
|
||||
->with('success', trans(
|
||||
'Modification(s) from :model saved',
|
||||
['model' => Str::singular(trans('models.classes.concepts'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'Modification(s) from :model cannot be saved',
|
||||
['model' => Str::singular(trans('models.classes.concepts'))]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Concept $concept
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Concept $concept)
|
||||
{
|
||||
if ($concept->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.concepts.index')
|
||||
->with('success', trans(
|
||||
':model has been deleted',
|
||||
['model' => Str::singular(trans('models.classes.concepts'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model cannot be deleted',
|
||||
['model' => Str::singular(trans('models.classes.concepts'))]
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -44,11 +44,14 @@ class HomeController extends Controller
|
|||
return redirect()
|
||||
->route('bo.homes.edit', $home)
|
||||
->with('success', trans(
|
||||
':model a été mis à jour',
|
||||
'Modification(s) from :model saved',
|
||||
['model' => Str::singular(trans('models.classes.homes'))]
|
||||
));
|
||||
} //end if
|
||||
return back();
|
||||
return back()->with('success', trans(
|
||||
'Modification(s) from :model cannot be saved',
|
||||
['model' => Str::singular(trans('models.classes.homes'))]
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
87
app/Http/Requests/Bo/Concepts/StoreConceptRequest.php
Normal file
87
app/Http/Requests/Bo/Concepts/StoreConceptRequest.php
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo\Concepts;
|
||||
|
||||
use App\Http\Requests\Bo\UpdateMiniCrudRequest;
|
||||
use App\Traits\Requests\HasPicture;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class StoreConceptRequest extends UpdateMiniCrudRequest
|
||||
{
|
||||
use HasPicture;
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the data for validation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$this->merge([
|
||||
'slug' => Str::slug(strip_tags($this->name))
|
||||
]);
|
||||
$this->mergePicture('picture');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
$rules = [
|
||||
'seo_title' => 'required|min:3|max:70',
|
||||
'seo_description' => 'required|min:50|max:160',
|
||||
|
||||
'name' => 'required|min:3|max:70',
|
||||
'title' => 'required|min:3|max:70',
|
||||
'subtitle' => 'required|min:3|max:70',
|
||||
'description' => 'required|string|min:15',
|
||||
'data' => 'present|array',
|
||||
'data.*' => 'required|array',
|
||||
|
||||
'picture_alt' => 'required|min:3|max:255',
|
||||
'picture_title' => 'required|min:3|max:255',
|
||||
];
|
||||
return \array_merge(
|
||||
$rules,
|
||||
$this->pictureRules('picture', true, 1512, 354, 1512, 354),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes()
|
||||
{
|
||||
return [
|
||||
'seo_title' => trans('titre') . ' seo',
|
||||
'seo_description' => trans('description') . ' seo',
|
||||
|
||||
'name' => trans('name of the concept'),
|
||||
'slug' => trans('slug of the concept'),
|
||||
'title' => trans('title of the concept'),
|
||||
'subtitle' => trans('subtitle of the concept'),
|
||||
'description' => trans('description of the concept'),
|
||||
'data' => trans('values of the data'),
|
||||
'data.*.value' => trans('value of the data'),
|
||||
|
||||
'picture' => trans('illustration'),
|
||||
'picture_alt' => trans('alt attribute of the image'),
|
||||
'picture_title' => trans('title attribute of the image'),
|
||||
];
|
||||
}
|
||||
}
|
||||
9
app/Http/Requests/Bo/Concepts/UpdateConceptRequest.php
Normal file
9
app/Http/Requests/Bo/Concepts/UpdateConceptRequest.php
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo\Concepts;
|
||||
|
||||
use App\Http\Requests\Bo\Concepts\StoreConceptRequest;
|
||||
|
||||
class UpdateConceptRequest extends StoreConceptRequest
|
||||
{
|
||||
}
|
||||
|
|
@ -41,13 +41,13 @@ class UpdateHomeRequest extends FormRequest
|
|||
'seo_description' => 'required|min:50|max:160',
|
||||
|
||||
'part1_title' => 'required|min:3|max:70',
|
||||
'part1_title_span' => 'required|min:3|max:70',
|
||||
'part1_subtitle' => 'required|min:3|max:70',
|
||||
'part1_text_1' => 'required|string|min:15',
|
||||
'part1_text_2' => 'required|string|min:15',
|
||||
'part1_text_3' => 'required|string|min:15',
|
||||
|
||||
'part2_title' => 'required|min:3|max:70',
|
||||
'part2_title_span' => 'required|min:3|max:70',
|
||||
'part2_subtitle' => 'required|min:3|max:70',
|
||||
'part2_text' => 'required|string|min:15',
|
||||
'part2_list' => 'present|array',
|
||||
'part2_list.*' => 'required|array',
|
||||
|
|
@ -76,13 +76,13 @@ class UpdateHomeRequest extends FormRequest
|
|||
'seo_description' => trans('description') . ' seo',
|
||||
|
||||
'part1_title' => trans('title part.1'),
|
||||
'part1_title_span' => trans('subtitle part.1'),
|
||||
'part1_subtitle' => trans('subtitle part.1'),
|
||||
'part1_text_1' => trans('text 1 part.1'),
|
||||
'part1_text_2' => trans('text 2 part.1'),
|
||||
'part1_text_3' => trans('text 3 part.1'),
|
||||
|
||||
'part2_title' => trans('title part.2'),
|
||||
'part2_title_span' => trans('subtitle part.2'),
|
||||
'part2_subtitle' => trans('subtitle part.2'),
|
||||
'part2_text' => trans('text part.2'),
|
||||
'part2_list' => trans('values of the list part.2'),
|
||||
'part2_list.*.value' => trans('value of the list part.2'),
|
||||
|
|
|
|||
156
app/Http/Requests/Bo/UpdateMiniCrudRequest.php
Normal file
156
app/Http/Requests/Bo/UpdateMiniCrudRequest.php
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo;
|
||||
|
||||
use App\Enums\InputType;
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
abstract class UpdateMiniCrudRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* The model parameter name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $modelName = null;
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
|
||||
* @phpcs:disable Generic.Metrics.NestingLevel.TooHigh
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
// phpcs:enable
|
||||
$rules = [];
|
||||
foreach ($this->{$this->modelName}->data as $iptName => $input) {
|
||||
$input = \json_decode(\json_encode($input), true);
|
||||
switch ($input['inputType']['value']) {
|
||||
case InputType::number()->value:
|
||||
$rules = array_merge($rules, [
|
||||
"data.$iptName.value" => $this->compileValidate('required|numeric', $input)
|
||||
]);
|
||||
break;
|
||||
case InputType::string()->value:
|
||||
$rules = array_merge($rules, [
|
||||
"data.$iptName.value" => $this->compileValidate('required|string|min:3', $input)
|
||||
]);
|
||||
break;
|
||||
case InputType::text()->value:
|
||||
$mergeRules = $this->compileValidate('required|string|min:15', $input);
|
||||
$mergeRules = collect(\explode('|', $mergeRules))
|
||||
->map(function ($rule) {
|
||||
if (\strpos($rule, 'max:') !== false) {
|
||||
$max = \intval(str_replace('max:', '', $rule));
|
||||
return function ($attribute, $value, $fail) use ($max) {
|
||||
if (\strlen(\strip_tags($value)) > $max) {
|
||||
$fail("$attribute ne doit pas excéder $max caractères");
|
||||
}
|
||||
};
|
||||
}
|
||||
return $rule;
|
||||
});
|
||||
$rules = array_merge($rules, [
|
||||
"data.$iptName.text" => $mergeRules
|
||||
]);
|
||||
break;
|
||||
case InputType::image()->value:
|
||||
$ipt = $this->data[$iptName];
|
||||
$max = isset($ipt['dimensionsMax']);
|
||||
$dim = collect(explode(
|
||||
',',
|
||||
$ipt['dimensionsMax'] ?? $input['dimensions']
|
||||
))->mapWithKeys(function ($v) {
|
||||
$v = explode(' ', $v);
|
||||
return [$v[0] => $v[1]];
|
||||
});
|
||||
$rules = array_merge($rules, [
|
||||
"data.$iptName.value" => $this->compileValidate(
|
||||
implode('|', [
|
||||
'required',
|
||||
'image',
|
||||
'mimes:png,jpg,jpeg',
|
||||
sprintf(
|
||||
'dimensions:%s=%d,%s=%d',
|
||||
$max ? 'max_height' : 'height',
|
||||
$dim['hauteur'],
|
||||
$max ? 'max_width' : 'width',
|
||||
$dim['largeur']
|
||||
)
|
||||
]),
|
||||
$input
|
||||
),
|
||||
"data.$iptName.alt" => $this->compileValidate('required|string|min:5', $input),
|
||||
"data.$iptName.title" => $this->compileValidate('required|string|min:5', $input)
|
||||
]);
|
||||
break;
|
||||
case InputType::url()->value:
|
||||
$rules = array_merge($rules, [
|
||||
"data.$iptName.value" => [
|
||||
'required', 'url',
|
||||
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
try {
|
||||
ToolboxHelper::assertNoInternalUrls($attribute, $value);
|
||||
ToolboxHelper::assertNoInternalBoUrls($attribute, $value);
|
||||
} catch (ValidationException $e) {
|
||||
$fail(collect($e->errors())->first()[0]);
|
||||
}
|
||||
}
|
||||
]
|
||||
]);
|
||||
break;
|
||||
case InputType::boolean()->value:
|
||||
$all = $this->all();
|
||||
$nested = ToolboxHelper::dotStringToNestedArray(
|
||||
"data.$iptName.value",
|
||||
$this->input("data.$iptName.value") ? true : false
|
||||
);
|
||||
$all = array_merge_recursive_distinct($all, $nested);
|
||||
$this->merge($all);
|
||||
$rules = array_merge($rules, [
|
||||
"data.$iptName.value" => 'boolean'
|
||||
]);
|
||||
break;
|
||||
} //end switch
|
||||
} //end foreach
|
||||
return $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string $inputTypeValidate
|
||||
* @param array $input
|
||||
* @return string
|
||||
*/
|
||||
public function compileValidate(string $inputTypeValidate, array $input): string
|
||||
{
|
||||
if (!isset($input['validate']) or !\is_string($input['validate'])) {
|
||||
return $inputTypeValidate;
|
||||
}
|
||||
/** @var array */
|
||||
$inputValidate = explode('|', $input['validate']);
|
||||
$out = explode('|', $inputTypeValidate);
|
||||
foreach ($inputValidate as $validate) {
|
||||
if (!\in_array($validate, $out)) {
|
||||
$out[] = $validate;
|
||||
}
|
||||
}
|
||||
return \implode('|', $out);
|
||||
}
|
||||
}
|
||||
|
|
@ -234,4 +234,24 @@ class ToolboxHelper
|
|||
throw new \RuntimeException('cannot handle $input of type ' . \gettype($input));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates an array from a dot separated string
|
||||
*
|
||||
* @param string $path
|
||||
* @param mixed $value
|
||||
* @param string $separator
|
||||
* @return array
|
||||
*/
|
||||
public static function dotStringToNestedArray(string $path, $value, string $separator = '.'): array
|
||||
{
|
||||
$arr = $value;
|
||||
$keys = array_reverse(explode($separator, $path));
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$arr = [$key => $arr];
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,15 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\Concepts\ColorsEnum;
|
||||
use App\Enums\InputType;
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use App\Traits\Models\MiniCrudModel;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
|
||||
/**
|
||||
* @property integer $id
|
||||
|
|
@ -14,16 +19,19 @@ use Illuminate\Database\Eloquent\Model;
|
|||
* @property string $name
|
||||
* @property string $slug
|
||||
* @property string $title
|
||||
* @property string $title_span
|
||||
* @property string $subtitle
|
||||
* @property string $description
|
||||
* @property string $content
|
||||
* @property string $picture
|
||||
* @property string $picture_alt
|
||||
* @property string $picture_title
|
||||
* @property string $created_at
|
||||
* @property string $updated_at
|
||||
*/
|
||||
class Concept extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use MiniCrudModel;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
|
|
@ -34,14 +42,26 @@ class Concept extends Model
|
|||
'name',
|
||||
'slug',
|
||||
'title',
|
||||
'title_span',
|
||||
'subtitle',
|
||||
'description',
|
||||
'content',
|
||||
'data',
|
||||
'picture',
|
||||
'picture_alt',
|
||||
'picture_title',
|
||||
'order',
|
||||
'created_at',
|
||||
'updated_at'
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'data' => 'array',
|
||||
];
|
||||
|
||||
// * EVENTS
|
||||
|
||||
/**
|
||||
|
|
@ -52,9 +72,13 @@ class Concept extends Model
|
|||
protected static function booted()
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
self::setSlug($model);
|
||||
self::assertFieldIsUnique('name', $model->name);
|
||||
self::manageFields($model);
|
||||
self::setOrder($model);
|
||||
});
|
||||
static::updating(function (self $model) {
|
||||
self::setSlug($model);
|
||||
self::manageFields($model);
|
||||
});
|
||||
static::updated(function (self $model) {
|
||||
|
|
@ -68,17 +92,41 @@ class Concept extends Model
|
|||
// * METHODS
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
* Set the slug.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function setSlug(Model $model)
|
||||
{
|
||||
$model->slug = Str::slug($model->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Common methods function.
|
||||
*
|
||||
* @param Model $model
|
||||
* @return void
|
||||
*/
|
||||
private static function manageFields(Model $model)
|
||||
{
|
||||
self::assertFieldIsUnique('name', $model->name);
|
||||
ToolboxHelper::assertNoInternalBoUrls('description', $model->description);
|
||||
$model->description = clean($model->description);
|
||||
$model->picture = FileStorageHelper::storeFile($model, $model->picture, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set order after the last element of the list.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
*/
|
||||
private static function setOrder(Model $model): void
|
||||
{
|
||||
$model->order = \intval(self::query()->max('order')) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts using validation that the field is unique.
|
||||
*
|
||||
|
|
@ -92,4 +140,130 @@ class Concept extends Model
|
|||
$table = (new self())->getTable();
|
||||
ToolboxHelper::assertFieldIsUnique($table, $nameField, $valueField, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the structure necessary of data.
|
||||
*
|
||||
* @param Model $model
|
||||
* @return void
|
||||
*/
|
||||
public static function getEmptyData(
|
||||
string $title = null,
|
||||
int $color = null,
|
||||
string $text = null,
|
||||
string $img = null,
|
||||
string $imgAlt = null,
|
||||
string $imgTitle = null
|
||||
) {
|
||||
return [
|
||||
// * BLOC 1
|
||||
"bloc_1_title" => [
|
||||
"label" => "Bloc 1 - Title",
|
||||
"inputType" => InputType::string,
|
||||
"value" => $title ?? "",
|
||||
"validate" => "required|min:4|max:100"
|
||||
],
|
||||
"bloc_1_color" => [
|
||||
"label" => "Bloc 1 - Color",
|
||||
"inputType" => InputType::selectEnum,
|
||||
"value" => $color ?? "",
|
||||
"validate" => ["required", "integer", new Enum(ColorsEnum::class)]
|
||||
],
|
||||
"bloc_1_text" => [
|
||||
"label" => "Bloc 1 - Text",
|
||||
"inputType" => InputType::text,
|
||||
"value" => $text ?? "",
|
||||
"validate" => "string|min:10"
|
||||
],
|
||||
"bloc_1_image" => [
|
||||
"label" => "Bloc 1 - Image",
|
||||
"dimensions" => ["width" => 1140, "height" => 795],
|
||||
"inputType" => InputType::image,
|
||||
"alt" => $imgAlt ?? "",
|
||||
"title" => $imgTitle ?? "",
|
||||
"value" => $img ?? "",
|
||||
],
|
||||
// * BLOC 2
|
||||
"bloc_2_title" => [
|
||||
"label" => "Bloc 2 - Title",
|
||||
"inputType" => InputType::string,
|
||||
"value" => $title ?? "",
|
||||
"validate" => "required|min:4|max:100"
|
||||
],
|
||||
"bloc_2_color" => [
|
||||
"label" => "Bloc 2 - Color",
|
||||
"inputType" => InputType::selectEnum,
|
||||
"value" => $color ?? "",
|
||||
"validate" => ["required", "integer", new Enum(ColorsEnum::class)]
|
||||
],
|
||||
"bloc_2_text" => [
|
||||
"label" => "Bloc 2 - Text",
|
||||
"inputType" => InputType::text,
|
||||
"value" => $text ?? "",
|
||||
"validate" => "string|min:10"
|
||||
],
|
||||
"bloc_2_image" => [
|
||||
"label" => "Bloc 2 - Image",
|
||||
"dimensions" => ["width" => 1140, "height" => 795],
|
||||
"inputType" => InputType::image,
|
||||
"alt" => $imgAlt ?? "",
|
||||
"title" => $imgTitle ?? "",
|
||||
"value" => $img ?? "",
|
||||
],
|
||||
// * BLOC 3
|
||||
"bloc_3_title" => [
|
||||
"label" => "Bloc 3 - Title",
|
||||
"inputType" => InputType::string,
|
||||
"value" => $title ?? "",
|
||||
"validate" => "required|min:4|max:100"
|
||||
],
|
||||
"bloc_3_color" => [
|
||||
"label" => "Bloc 3 - Color",
|
||||
"inputType" => InputType::selectEnum,
|
||||
"value" => $color ?? "",
|
||||
"validate" => ["required", "integer", new Enum(ColorsEnum::class)]
|
||||
],
|
||||
"bloc_3_text" => [
|
||||
"label" => "Bloc 3 - Text",
|
||||
"inputType" => InputType::text,
|
||||
"value" => $text ?? "",
|
||||
"validate" => "string|min:10"
|
||||
],
|
||||
"bloc_3_image" => [
|
||||
"label" => "Bloc 3 - Image",
|
||||
"dimensions" => ["width" => 1140, "height" => 795],
|
||||
"inputType" => InputType::image,
|
||||
"alt" => $imgAlt ?? "",
|
||||
"title" => $imgTitle ?? "",
|
||||
"value" => $img ?? "",
|
||||
],
|
||||
// * BLOC 4
|
||||
"bloc_4_title" => [
|
||||
"label" => "Bloc 4 - Title",
|
||||
"inputType" => InputType::string,
|
||||
"value" => $title ?? "",
|
||||
"validate" => "required|min:4|max:100"
|
||||
],
|
||||
"bloc_4_color" => [
|
||||
"label" => "Bloc 4 - Color",
|
||||
"inputType" => InputType::selectEnum,
|
||||
"value" => $color ?? "",
|
||||
"validate" => ["required", "integer", new Enum(ColorsEnum::class)]
|
||||
],
|
||||
"bloc_4_text" => [
|
||||
"label" => "Bloc 4 - Text",
|
||||
"inputType" => InputType::text,
|
||||
"value" => $text ?? "",
|
||||
"validate" => "string|min:10"
|
||||
],
|
||||
"bloc_4_image" => [
|
||||
"label" => "Bloc 4 - Image",
|
||||
"dimensions" => ["width" => 1140, "height" => 795],
|
||||
"inputType" => InputType::image,
|
||||
"alt" => $imgAlt ?? "",
|
||||
"title" => $imgTitle ?? "",
|
||||
"value" => $img ?? "",
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ use Illuminate\Database\Eloquent\Model;
|
|||
* @property string $seo_title
|
||||
* @property string $seo_description
|
||||
* @property string $part1_title
|
||||
* @property string $part1_title_span
|
||||
* @property string $part1_subtitle
|
||||
* @property string $part1_text_1
|
||||
* @property string $part1_text_2
|
||||
* @property string $part1_text_3
|
||||
* @property string $part2_title
|
||||
* @property string $part2_title_span
|
||||
* @property string $part2_subtitle
|
||||
* @property string $part2_text
|
||||
* @property string $part2_list
|
||||
* @property string $part3_picture
|
||||
|
|
@ -41,12 +41,12 @@ class Home extends Model
|
|||
'seo_title',
|
||||
'seo_description',
|
||||
'part1_title',
|
||||
'part1_title_span',
|
||||
'part1_subtitle',
|
||||
'part1_text_1',
|
||||
'part1_text_2',
|
||||
'part1_text_3',
|
||||
'part2_title',
|
||||
'part2_title_span',
|
||||
'part2_subtitle',
|
||||
'part2_text',
|
||||
'part2_list',
|
||||
'part3_picture',
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\Concept;
|
||||
use Illuminate\Cache\RateLimiting\Limit;
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
|
|
@ -39,6 +40,8 @@ class RouteServiceProvider extends ServiceProvider
|
|||
->namespace($this->namespace)
|
||||
->group(base_path('routes/web-fo.php'));
|
||||
});
|
||||
|
||||
Route::model('concept', Concept::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use App\Models\Home;
|
|||
use Illuminate\Pagination\Paginator;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
|
|
@ -22,9 +23,9 @@ class ViewServiceProvider extends ServiceProvider
|
|||
// * FORCE BOOTSTRAP PAGINATOR (or custom if in front)
|
||||
// Early boot, request wont be filled as expected.
|
||||
if (collect(explode('/', \request()->getPathInfo()))->get(1) === 'bo') {
|
||||
Paginator::useBootstrap();
|
||||
Paginator::defaultview('bo.modules.pagination');
|
||||
} else {
|
||||
Paginator::defaultview('fo.partials.pagination');
|
||||
Paginator::defaultview('fo.modules.pagination');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -32,10 +33,14 @@ class ViewServiceProvider extends ServiceProvider
|
|||
return json_decode(File::get(\app_path('../composer.json')));
|
||||
});
|
||||
// Share composer.json infos.
|
||||
View::share('cpsr_name', $appInfos->name);
|
||||
View::share('cpsr_version', $appInfos->version);
|
||||
View::share('cpsr_license', $appInfos->license);
|
||||
View::share('cpsr_time', now()->parse($appInfos->time)->isoFormat('Y'));
|
||||
View::share('globalHome', Home::firstOrFail());
|
||||
if (isset($appInfos->name) and isset($appInfos->version) and isset($appInfos->license) and isset($appInfos->time)) {
|
||||
View::share('cpsr_name', $appInfos->name);
|
||||
View::share('cpsr_version', $appInfos->version);
|
||||
View::share('cpsr_license', $appInfos->license);
|
||||
View::share('cpsr_time', now()->parse($appInfos->time)->isoFormat('Y'));
|
||||
}
|
||||
if (Schema::hasTable('homes')) {
|
||||
View::share('globalHome', Home::first());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
94
app/Traits/Models/MiniCrudModel.php
Normal file
94
app/Traits/Models/MiniCrudModel.php
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
|
||||
namespace App\Traits\Models;
|
||||
|
||||
use App\Enums\InputType;
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
|
||||
trait MiniCrudModel
|
||||
{
|
||||
/**
|
||||
* Fill the model with an array of attributes.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return void
|
||||
* @throws \Illuminate\Database\Eloquent\MassAssignmentException If fill prop is not allowed.
|
||||
*/
|
||||
public function fill(array $attributes)
|
||||
{
|
||||
parent::fill($attributes);
|
||||
if (isset($attributes['data'])) {
|
||||
$this->setData($attributes['data']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a specific prop
|
||||
*
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
private function setData(array $data): void
|
||||
{
|
||||
$attrs = $this->attributes;
|
||||
if (isset($attrs['data'])) {
|
||||
unset($attrs['data']);
|
||||
}
|
||||
$data = $this->serializeData($data);
|
||||
$this->setRawAttributes(\array_merge_recursive(
|
||||
$attrs,
|
||||
['data' => $data]
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data attribute
|
||||
* Cast json_decode to object.
|
||||
*
|
||||
* @return object|null
|
||||
*/
|
||||
protected function getDataAttribute(): ?object
|
||||
{
|
||||
return \json_decode($this->getAttributes()['data'] ?? json_encode($this->getEmptyData())) ?? '[]';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data attribute
|
||||
* Cast json_decode to object.
|
||||
*
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
protected function setDataAttribute(array $data): void
|
||||
{
|
||||
$this->setData($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize properties
|
||||
*
|
||||
* @param array $data
|
||||
* @return string
|
||||
* @throws \ErrorException If input type is no handled.
|
||||
* @throws \Illuminate\Validation\ValidationException If url is a bo url.
|
||||
* @phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
|
||||
*/
|
||||
private function serializeData(array $data): string
|
||||
{
|
||||
foreach ($data as $o => $input) {
|
||||
switch ($input['inputType'] ?? $input['inputType']) {
|
||||
case InputType::image->value:
|
||||
$data[$o]['value'] = FileStorageHelper::storeFile($this, $input['value'], true);
|
||||
break;
|
||||
case InputType::boolean->value:
|
||||
case InputType::text->value:
|
||||
case InputType::number->value:
|
||||
case InputType::string->value:
|
||||
case InputType::videoVimeo->value:
|
||||
case InputType::url->value:
|
||||
}
|
||||
} //end foreach
|
||||
return json_encode($data);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "Wenn dann mit respekt",
|
||||
"name": "ldcweb/wenn-dann-mit-respekt",
|
||||
"version": "1.0.0",
|
||||
"type": "project",
|
||||
"time": "2023-03-16",
|
||||
|
|
@ -52,6 +52,14 @@
|
|||
}
|
||||
},
|
||||
"scripts": {
|
||||
"refresh": [
|
||||
"@php artisan optimize:clear",
|
||||
"@php artisan clear-compiled",
|
||||
"@php artisan view:clear",
|
||||
"@php artisan route:clear",
|
||||
"@php artisan config:clear",
|
||||
"@php artisan cache:clear"
|
||||
],
|
||||
"post-autoload-dump": [
|
||||
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
||||
"@php artisan package:discover --ansi"
|
||||
|
|
|
|||
2
composer.lock
generated
2
composer.lock
generated
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "eee884d4ea0363ba9b1f0f62410bb38f",
|
||||
"content-hash": "0bc4ba3bc4ba2da26748340ed29c18bc",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brick/math",
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ return [
|
|||
|
|
||||
*/
|
||||
|
||||
'view' => 'breadcrumbs/breadrcumb-layout',
|
||||
'view' => 'modules/breadcrumbs/breadcrumb-layout',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -26,15 +26,17 @@ final class ConceptFactory extends Factory
|
|||
public function definition(): array
|
||||
{
|
||||
$name = fake()->unique()->firstname;
|
||||
|
||||
return [
|
||||
'seo_title' => fake()->word,
|
||||
'seo_description' => fake()->text,
|
||||
'name' => $name,
|
||||
'slug' => Str::slug($name),
|
||||
'title' => fake()->word,
|
||||
'title_span' => fake()->word,
|
||||
'subtitle' => fake()->word,
|
||||
'description' => fake()->text,
|
||||
'content' => fake()->text,
|
||||
'picture_alt' => fake()->word,
|
||||
'picture_title' => fake()->word,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,12 +36,12 @@ final class HomeFactory extends Factory
|
|||
'seo_title' => fake()->word,
|
||||
'seo_description' => fake()->text,
|
||||
'part1_title' => fake()->word,
|
||||
'part1_title_span' => fake()->word,
|
||||
'part1_subtitle' => fake()->word,
|
||||
'part1_text_1' => fake()->text,
|
||||
'part1_text_2' => fake()->text,
|
||||
'part1_text_3' => fake()->text,
|
||||
'part2_title' => fake()->word,
|
||||
'part2_title_span' => fake()->word,
|
||||
'part2_subtitle' => fake()->word,
|
||||
'part2_text' => fake()->text,
|
||||
'part2_list' => $part2_list,
|
||||
'part2_product1_id' => fake()->randomElement(Product::pluck('id')),
|
||||
|
|
|
|||
BIN
database/factories/assets/concepts/default-picture-1140x795.png
Normal file
BIN
database/factories/assets/concepts/default-picture-1140x795.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.7 KiB |
BIN
database/factories/assets/concepts/default-picture-1512x354.png
Normal file
BIN
database/factories/assets/concepts/default-picture-1512x354.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 508 KiB |
|
|
@ -20,10 +20,13 @@ return new class extends Migration
|
|||
$table->string('name')->comment('Nom du concept');
|
||||
$table->string('slug')->unique()->comment('Slug du nom de la page');
|
||||
$table->string('title')->comment('Titre de la page');
|
||||
$table->string('title_span')->comment('Seconde partie du titre de la page');
|
||||
$table->string('description')->comment('Description du concept');
|
||||
$table->mediumText('content')->comment('Tableau d\'objets');
|
||||
$table->string('subtitle')->comment('Seconde partie du titre de la page');
|
||||
$table->text('description')->comment('Description du concept');
|
||||
$table->json('data')->comment('Tableau d\'objets');
|
||||
$table->string('picture')->comment('Path de l\'image, 1512px x 354px');
|
||||
$table->string('picture_alt')->comment('Attribut alt de l\'image');
|
||||
$table->string('picture_title')->comment('Titre de l\'image');
|
||||
$table->integer('order')->comment('Pour ordonner les concepts');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@ return new class extends Migration
|
|||
$table->string('seo_title')->comment('Utilisé pour la balise title de la page');
|
||||
$table->string('seo_description')->comment('Utilisé pour la balise méta description de la page');
|
||||
$table->string('part1_title')->comment('Titre de la partie 1');
|
||||
$table->string('part1_title_span')->comment('Seconde partie du titre de la partie 1');
|
||||
$table->string('part1_subtitle')->comment('Seconde partie du titre de la partie 1');
|
||||
$table->string('part1_text_1')->comment('Premier paragraphe de la partie 1');
|
||||
$table->string('part1_text_2')->comment('Second paragraphe de la partie 1');
|
||||
$table->string('part1_text_3')->comment('Troisième paragraphe de la partie 1');
|
||||
$table->string('part2_title')->comment('Titre de la partie 2');
|
||||
$table->string('part2_title_span')->comment('Seconde partie du titre de la partie 2');
|
||||
$table->string('part2_subtitle')->comment('Seconde partie du titre de la partie 2');
|
||||
$table->string('part2_text')->comment('Paragraphe de la partie 2');
|
||||
$table->json('part2_list')->comment('Tableau JSON de string');
|
||||
$table->unsignedBigInteger('part2_product1_id')->comment('Produit lié 1, FK');
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Enums\Concepts\ColorsEnum;
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Models\Concept;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
|
@ -18,8 +19,20 @@ class ConceptSeeder extends Seeder
|
|||
$jj = 1;
|
||||
Concept::factory(20)->make()->each(function (Concept $concept) use (&$jj) {
|
||||
$concept->picture = FileStorageHelper::storeFile($concept, new \SplFileInfo(\resource_path(
|
||||
'../database/factories/assets/concepts/default-picture-1512x3540.png'
|
||||
'../database/factories/assets/concepts/default-picture-1512x354.png'
|
||||
)));
|
||||
$dataImg = FileStorageHelper::storeFile($concept, new \SplFileInfo(\resource_path(
|
||||
'../database/factories/assets/concepts/default-picture-1140x795.png'
|
||||
)));
|
||||
$concept->data = $concept->getEmptyData(
|
||||
fake()->words(2, true),
|
||||
\collect(ColorsEnum::cases())->random()->value,
|
||||
fake()->text(),
|
||||
$dataImg,
|
||||
fake()->words(4, true),
|
||||
fake()->words(4, true)
|
||||
);
|
||||
$concept->order = $jj;
|
||||
$concept->saveOrFail();
|
||||
$jj = $jj + 1;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4,5 +4,6 @@ return [
|
|||
'classes' => [
|
||||
'homes' => 'Homepage',
|
||||
'products' => 'Products',
|
||||
'concepts' => 'Concepts',
|
||||
]
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
.need-word-counter {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
border-radius: 0 0 0.375rem 0.375rem !important;
|
||||
}
|
||||
|
||||
|
|
|
|||
2
resources/sass/bo/vendor/_bootstrap.scss
vendored
2
resources/sass/bo/vendor/_bootstrap.scss
vendored
|
|
@ -37,6 +37,8 @@
|
|||
@import "~/bootstrap/scss/close";
|
||||
@import "~/bootstrap/scss/card";
|
||||
@import "~/bootstrap/scss/offcanvas";
|
||||
@import "~/bootstrap/scss/badge";
|
||||
@import "~/bootstrap/scss/breadcrumb";
|
||||
|
||||
// 6. Optionally include utilities API last to generate classes based on the Sass map in `_utilities.scss`
|
||||
@import "~/bootstrap/scss/utilities/api";
|
||||
|
|
|
|||
|
|
@ -482,7 +482,7 @@ export default defineComponent({
|
|||
return {
|
||||
intId: "",
|
||||
intValue: "",
|
||||
intValueFileName: this.__("Sélectionnez une image"),
|
||||
intValueFileName: this.__("Choose a file"),
|
||||
intHelper: "",
|
||||
intName: "",
|
||||
intRequired: true,
|
||||
|
|
@ -703,7 +703,7 @@ export default defineComponent({
|
|||
removeFile() {
|
||||
const actualImage = this.$refs.actualImage as HTMLInputElement;
|
||||
actualImage.value = "";
|
||||
this.intValueFileName = this.__("Sélectionnez une image");
|
||||
this.intValueFileName = this.__("Choose a file");
|
||||
this.intValue = "";
|
||||
},
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,13 +3,11 @@
|
|||
class="word-counter-varchar position-relative d-flex flex-row justify-content-around align-items-center w-100"
|
||||
>
|
||||
<span class="words">
|
||||
{{ __("Words") }}
|
||||
:
|
||||
{{ __("Words") }}:
|
||||
{{ intWords }}
|
||||
</span>
|
||||
<span class="chars">
|
||||
{{ __("Characters") }}
|
||||
:
|
||||
{{ __("Characters") }}:
|
||||
{{ intChars }}
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||
);
|
||||
}
|
||||
confirm.methods.confirm(
|
||||
"Confirmez",
|
||||
"Voulez-vous vraiment supprimer cet élément ?",
|
||||
"Confirm",
|
||||
"Do you really want to remove this element ?",
|
||||
el as HTMLFormElement,
|
||||
function () {
|
||||
(el as HTMLFormElement).submit();
|
||||
|
|
@ -35,8 +35,8 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||
);
|
||||
}
|
||||
confirm.methods.confirm(
|
||||
"Confirmez",
|
||||
"Voulez-vous vraiment marquer cet élément comme traité ?",
|
||||
"Confirm",
|
||||
"Do you really want to mark this item as treated ?",
|
||||
el as HTMLFormElement,
|
||||
function () {
|
||||
(el as HTMLFormElement).submit();
|
||||
|
|
@ -57,8 +57,8 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||
);
|
||||
}
|
||||
confirm.methods.confirm(
|
||||
"Confirmez",
|
||||
"Voulez-vous enregistrer cet élément tel-quel ?",
|
||||
"Confirm",
|
||||
"Do you want to save this element as it is ?",
|
||||
el as HTMLFormElement,
|
||||
function () {
|
||||
(el as HTMLFormElement).submit();
|
||||
|
|
@ -85,8 +85,8 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||
const promise = new Promise(
|
||||
(resolve: (value: boolean) => void) => {
|
||||
confirm.methods.confirm(
|
||||
"Confirmez",
|
||||
"Êtes vous sure ?",
|
||||
"Confirm",
|
||||
"Are you sure ?",
|
||||
el,
|
||||
function (response: SweetAlertResult<any>) {
|
||||
resolve(response.isConfirmed);
|
||||
|
|
|
|||
|
|
@ -27,10 +27,10 @@ export default {
|
|||
showCancelButton: true,
|
||||
confirmButtonText:
|
||||
options.confirmButtonText ??
|
||||
trans.default.methods.__("Oui"),
|
||||
trans.default.methods.__("Yes"),
|
||||
cancelButtonText:
|
||||
options.cancelButtonText ??
|
||||
trans.default.methods.__("Annuler"),
|
||||
trans.default.methods.__("Cancel"),
|
||||
reverseButtons: true,
|
||||
// * Bootstrap Styling
|
||||
customClass: {
|
||||
|
|
@ -49,7 +49,7 @@ export default {
|
|||
) {
|
||||
Swal.fire({
|
||||
title: trans.default.methods.__(
|
||||
"L'opération n'as pas été effectuée"
|
||||
"The operation has not been performed"
|
||||
),
|
||||
confirmButtonText: trans.default.methods.__("Ok"),
|
||||
// * Bootstrap Styling
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
@extends('bo.layout')
|
||||
@section('title', __('Authentification'))
|
||||
@section('description', __('Formulaire d\'authentification au back-office.'))
|
||||
@section('breadcrumb', 'no')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
|
|
|
|||
|
|
@ -12,15 +12,8 @@
|
|||
@else
|
||||
@php $authLayout = 'col px-md-4'; @endphp
|
||||
@endauth
|
||||
@auth('backend')
|
||||
<div class="row">
|
||||
<div class="{{ $authLayout }}">
|
||||
@include('modules.breadcrumb.breadcrumb-layout')
|
||||
</div>
|
||||
</div>
|
||||
@endauth
|
||||
<div class="row justify-content-center">
|
||||
<div class="{{ $authLayout }} mt-3">
|
||||
<div class="{{ $authLayout }}">
|
||||
<div class="container mx-auto m-0 p-0">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col col-xl-7">
|
||||
|
|
@ -32,6 +25,9 @@
|
|||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="{{ $authLayout }}">
|
||||
@auth('backend')
|
||||
@include('modules.breadcrumbs.breadcrumb-body')
|
||||
@endauth
|
||||
@yield('content')
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
<meta name="msapplication-TileColor" content="#da532c">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
@include('modules.breadcrumb.breadcrumb-head')
|
||||
@include('modules.breadcrumbs.breadcrumb-head')
|
||||
|
||||
<!-- STYLES -->
|
||||
@vite(['resources/sass/bo/bo.scss'])
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<h5 class="offcanvas-title">{{ __('Users menu') }}</h5>
|
||||
<button type="button" class="btn-close btn-close-dark" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body pt-2">
|
||||
<div class="offcanvas-body">
|
||||
<ul class="navbar-nav w-100">
|
||||
<!-- Model Links -->
|
||||
@include('bo.layouts.nav-menu')
|
||||
|
|
|
|||
|
|
@ -11,4 +11,10 @@
|
|||
{{ __('models.classes.homes') }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link @if (Route::is('bo.concepts.*'))active @endif" href="{{ route('bo.concepts.index') }}"
|
||||
role="button" data-bs-toggle="tooltip" title="{{ __('List all :model', ['model' => __('models.classes.concepts')]) }}">
|
||||
{{ __('models.classes.concepts') }}
|
||||
</a>
|
||||
</li>
|
||||
@endauth
|
||||
|
|
|
|||
140
resources/views/bo/modules/minicrud-form-inputs.blade.php
Normal file
140
resources/views/bo/modules/minicrud-form-inputs.blade.php
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
{{-- MINI CRUD EDIT --}}
|
||||
@php
|
||||
$data = (isset($model->data)) ? $model->getEmptyData() : $conceptData;
|
||||
@endphp
|
||||
@foreach ($data as $k => $input)
|
||||
@php
|
||||
$input = json_decode(json_encode($input), true);
|
||||
@endphp
|
||||
@switch(intval($input['inputType']))
|
||||
@case(intval(App\Enums\InputType::url->value))
|
||||
@case(intval(App\Enums\InputType::string->value))
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
<fieldset class="border h-100 bg-white p-3">
|
||||
<legend>{{ $input['label'] }} *</legend>
|
||||
<div class="row">
|
||||
<div class="col-12 mb-3">
|
||||
@include('bo.partials.inputs.varchar', [
|
||||
'id' => Str::slug($input["label"]),
|
||||
'label' => $input['label'] . ' of the ' . __('models.classes.concepts'),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'data['.$k.'][value]',
|
||||
'value' => $model->data->{$k}->value ?? null,
|
||||
'required' => true,
|
||||
'model' => $model ?? null,
|
||||
'helper' => __('Must be in 3 characters minimum, 255 maximum.')
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
@break
|
||||
|
||||
@case(intval(App\Enums\InputType::number->value))
|
||||
<div class="form-group">
|
||||
<label for="{{ $k }}"><small>{{ $input['label'] }}*</small></label>
|
||||
<input id="{{ $k }}" type="number" step="0.01" class="form-control"
|
||||
name="data[{{ $k }}][value]" placeholder="{{ $input['label'] }}"
|
||||
value="{{ old("data.$k.value") ?? ($input['value'] ?? '') }}" required>
|
||||
</div>
|
||||
@break
|
||||
|
||||
@case(intval(App\Enums\InputType::text->value))
|
||||
<div class="col-12 mb-3">
|
||||
<fieldset class="border bg-white p-3">
|
||||
<legend>{{ $input['label'] }} *</legend>
|
||||
<div class="row mb-3">
|
||||
<div class="col-12">
|
||||
@include('bo.partials.inputs.text-html', [
|
||||
'id' => Str::slug($input["label"]),
|
||||
'name' => 'data['.$k.'][value]',
|
||||
'value' => $model->data->{$k}->value ?? null,
|
||||
'model' => $model ?? null,
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
@include('modules.input-error', ['inputName' => 'data['.$k.'][value]'])
|
||||
@break
|
||||
|
||||
@case(intval(App\Enums\InputType::boolean->value))
|
||||
@case(intval(App\Enums\InputType::image->value))
|
||||
<div class="col-12 mb-3">
|
||||
<fieldset class="border h-100 bg-white p-3">
|
||||
<legend>{{ $input['label'] }} *</legend>
|
||||
<div class="row">
|
||||
{{-- PICTURE_ALT --}}
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
@include('bo.partials.inputs.varchar', [
|
||||
'id' => Str::slug($input["label"]) . '-alt',
|
||||
'label' => __('Alt attribute of the image'),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'data['.$k.'][alt]',
|
||||
'value' => $model->data->{$k}->alt ?? null,
|
||||
'required' => true,
|
||||
'model' => $model ?? null,
|
||||
'helper' => __('Must describe your image for search engines and blind people (5 to 6 words, minimum 3 characters).'),
|
||||
])
|
||||
</div>
|
||||
{{-- PICTURE_TITLE --}}
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
@include('bo.partials.inputs.varchar', [
|
||||
'id' => Str::slug($input["label"]) . '-title',
|
||||
'label' => __('Title attribute of the image'),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'data['.$k.'][title]',
|
||||
'value' => $model->data->{$k}->title ?? null,
|
||||
'required' => true,
|
||||
'model' => $model ?? null,
|
||||
'helper' => __('Useful for users, displayed by moving the mouse over the image (minimum 3 characters).'),
|
||||
])
|
||||
</div>
|
||||
{{-- PICTURE --}}
|
||||
<div class="col-12 mb-3">
|
||||
@include('bo.partials.inputs.varchar-picture', [
|
||||
'id' => Str::slug($input["label"]),
|
||||
'name' => 'data['.$k.'][value]',
|
||||
'width' => $input['dimensions']['width'],
|
||||
'height' => $input['dimensions']['height'],
|
||||
'model' => $model ?? null,
|
||||
'value' => $model->data->{$k}->value ?? null,
|
||||
'helper' => __('Must be :widthpx (width) by :heightpx (height).', [
|
||||
'width' => $input['dimensions']['width'],
|
||||
'height' => $input['dimensions']['height'],
|
||||
]),
|
||||
'required' => true,
|
||||
'preview' => true,
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
@break
|
||||
@case(intval(App\Enums\InputType::imageArray->value))
|
||||
@case(intval(App\Enums\InputType::labelArray->value))
|
||||
@case(intval(App\Enums\InputType::selectEnum->value))
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
<fieldset class="border h-100 bg-white p-3">
|
||||
<legend>{{ $input['label'] }} *</legend>
|
||||
<div class="row">
|
||||
<div class="col-12 mb-3">
|
||||
@include('bo.partials.inputs.select-enum', [
|
||||
'id' => Str::slug($input["label"]),
|
||||
'label' => $input['label'] . ' associated',
|
||||
'name' => 'data['.$k.'][value]',
|
||||
'model' => $model ?? null,
|
||||
'require' => true,
|
||||
'associatedModels' => $selectedEnum ?? [],
|
||||
'helper' => trans('Selectionnez un :enum parmis la liste.', ['enum' => $input['label']]),
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
@break
|
||||
|
||||
@default
|
||||
@php throw new Exception('Input type not handled'); @endphp
|
||||
@endswitch
|
||||
@endforeach
|
||||
60
resources/views/bo/modules/pagination.blade.php
Normal file
60
resources/views/bo/modules/pagination.blade.php
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
@if ($paginator->hasPages())
|
||||
<nav>
|
||||
<ul class="pagination d-flex justify-content-center align-items-center my-3">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<li class="page-item disabled" data-bs-toggle="tooltip" data-bs-placement="top"
|
||||
title="{{ __('Previous page') }}" aria-disabled="true" aria-label="@lang('Previous page')">
|
||||
<span class="page-link" aria-hidden="true">‹</span>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item">
|
||||
<a class="page-link" data-bs-toggle="tooltip" data-bs-placement="top"
|
||||
title="{{ __('Previous page') }}" href="{{ $paginator->previousPageUrl() }}"
|
||||
rel="prev" aria-label="@lang('Previous page')">‹</a>
|
||||
</li>
|
||||
@endif
|
||||
|
||||
{{-- Pagination Elements --}}
|
||||
@foreach ($elements as $element)
|
||||
{{-- "Three Dots" Separator --}}
|
||||
@if (is_string($element))
|
||||
<li class="page-item disabled" aria-disabled="true"><span
|
||||
class="page-link">{{ $element }}</span></li>
|
||||
@endif
|
||||
|
||||
{{-- Array Of Links --}}
|
||||
@if (is_array($element))
|
||||
@foreach ($element as $page => $url)
|
||||
@if ($page == $paginator->currentPage())
|
||||
<li class="page-item active" data-bs-toggle="tooltip" data-bs-placement="top"
|
||||
title="{{ __('Actual page') }}" aria-current="page">
|
||||
<span class="page-link">{{ $page }}</span>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item">
|
||||
<a class="page-link" data-bs-toggle="tooltip" data-bs-placement="top"
|
||||
title="{{ __('Page n°:id', ['id' => $page]) }}"
|
||||
href="{{ $url }}">{{ $page }}</a>
|
||||
</li>
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<li class="page-item">
|
||||
<a class="page-link" data-bs-toggle="tooltip" data-bs-placement="top" title="{{ __('Next page') }}"
|
||||
href="{{ $paginator->nextPageUrl() }}" rel="next"
|
||||
aria-label="@lang('Next page')">›</a>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item disabled" data-bs-toggle="tooltip" data-bs-placement="top"
|
||||
title="{{ __('Next page') }}" aria-disabled="true" aria-label="@lang('Next page')">
|
||||
<span class="page-link" aria-hidden="true">›</span>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
</nav>
|
||||
@endif
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
$iArgs['search'] = request()->sort_way;
|
||||
}
|
||||
@endphp
|
||||
<div class="row mb-3">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<form id="searchForm" action="{{ request()->url() }}">
|
||||
<div class="input-group">
|
||||
|
|
@ -25,11 +25,13 @@
|
|||
@if(request()->group)
|
||||
<input class="d-none" type="text" name="group" value="{{ request()->group }}">
|
||||
@endif
|
||||
<input type="search" id="searchField" name="search" class="form-control" value="{{ request()->search }}" placeholder="{{ __('Vos mots clés ici...') }}"/>
|
||||
<button type="submit" class="btn btn-primary" data-bs-toggle="tooltip" title="{{ __('Lancer la recherche') }}">
|
||||
<input type="search" id="searchField" name="search" class="form-control"
|
||||
value="{{ request()->search }}" placeholder="{{ __('Your keywords here...') }}"/>
|
||||
<button type="submit" class="btn btn-primary" data-bs-toggle="tooltip" title="{{ __('Start search') }}">
|
||||
<i class="fas fa-search"></i>
|
||||
</button>
|
||||
<button id="searchDelete" type="button" class="btn btn-danger" data-bs-toggle="tooltip" title="{{ __('Effacer la recherche') }}">
|
||||
<button id="searchDelete" type="button" class="btn btn-danger" data-bs-toggle="tooltip"
|
||||
title="{{ __('Delete search') }}">
|
||||
<i class="fas fa-backspace"></i>
|
||||
</button>
|
||||
@push('scripts')
|
||||
|
|
@ -30,7 +30,7 @@ $ignore = (isset($ignore) and is_array($ignore)) ? $ignore : [];
|
|||
@if(!session("$routeName.sort_way") or session("$routeName.sort_col") !== $col or (session("$routeName.sort_way") === 'desc' and session("$routeName.sort_col") === $col))
|
||||
<a class="col_sort text-info lead asc"
|
||||
href="{{ request()->fullUrlWithQuery(array_merge($iArgs, ['sort_way' => 'asc', 'rst' => null])) }}"
|
||||
title="{{ __('Trier :name en ordre ascendant', ['name' => Str::lower($colname)]) }}"
|
||||
title="{{ __('Sort :name in ascending order', ['name' => Str::lower($colname)]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
↓
|
||||
</a>
|
||||
|
|
@ -38,7 +38,7 @@ $ignore = (isset($ignore) and is_array($ignore)) ? $ignore : [];
|
|||
@if(!session("$routeName.sort_way") or session("$routeName.sort_col") !== $col or (session("$routeName.sort_way") === 'asc' and session("$routeName.sort_col") === $col))
|
||||
<a class="col_sort text-info lead desc"
|
||||
href="{{ request()->fullUrlWithQuery(array_merge($iArgs, ['sort_way' => 'desc', 'rst' => null])) }}"
|
||||
title="{{ __('Trier :name en ordre descendant', ['name' => Str::lower($colname)]) }}"
|
||||
title="{{ __('Sort :name in descending order', ['name' => Str::lower($colname)]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
↑
|
||||
</a>
|
||||
|
|
@ -52,11 +52,11 @@ $ignore = (isset($ignore) and is_array($ignore)) ? $ignore : [];
|
|||
<a class="btn btn-small btn-danger"
|
||||
href="{{ request()->fullUrlWithQuery(['sort_col' => null, 'sort_way' => null, 'rst' => true, 'search' => null]) }}"
|
||||
data-bs-toggle="tooltip"
|
||||
title="{{ __('Effacer le tri') }}">
|
||||
title="{{ __('Delete the sorting') }}">
|
||||
<i class="fa fa-eraser"></i>
|
||||
</a>
|
||||
@else
|
||||
<span data-bs-toggle="tooltip" data-bs-placement="top" title="{{ __('Ici, les flèches servent à trier et non pas à filtrer') }}">
|
||||
<span data-bs-toggle="tooltip" data-bs-placement="top" title="{{ __('Here, the arrows are used to sort and not to filter') }}">
|
||||
<i class="fas fa-question-circle"></i>
|
||||
</span>
|
||||
@endif
|
||||
43
resources/views/bo/pages/concepts/create.blade.php
Normal file
43
resources/views/bo/pages/concepts/create.blade.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
@extends('bo.layout')
|
||||
|
||||
@section('title', sprintf('%s - %s', Str::singular(__('models.classes.concepts')), Str::ucfirst(__('create'))))
|
||||
@section('description', __('Creation of a new concept.'))
|
||||
|
||||
@section('breadcrumb', request()->route()->getName())
|
||||
|
||||
@section('content')
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 class="col h2">
|
||||
<a href="{{ route('bo.concepts.index') }}"
|
||||
class="btn btn-primary text-decoration-none m-0"
|
||||
data-bs="tooltip"
|
||||
data-bs-placement="top"
|
||||
title="{{ __('form.return_list') }}">
|
||||
<i class="fa-solid fa-arrow-left"></i>
|
||||
</a>
|
||||
<span class="fw-bold">{{ Str::singular(__('models.classes.concepts')) }}</span> <small class="text-muted">{{ __('create') }}</small>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body bg-light">
|
||||
<form id="formSubmit" action="{{ route('bo.concepts.store') }}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
@include('bo.pages.concepts.form-inputs')
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<button type="submit" class="btn btn-primary"
|
||||
title="{{ __('Save :model', ['model' => Str::singular(__('models.classes.concepts'))]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
{{ __('Save') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
43
resources/views/bo/pages/concepts/edit.blade.php
Normal file
43
resources/views/bo/pages/concepts/edit.blade.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
@extends('bo.layout', ['brParam' => $conceptModel])
|
||||
|
||||
@section('title', sprintf('%s - %s %s', Str::singular(__('models.classes.concepts')), Str::ucfirst(__('edit')), $conceptModel->seo_title))
|
||||
@section('description', $conceptModel->seo_description)
|
||||
|
||||
@section('breadcrumb', request()->route()->getName())
|
||||
|
||||
@section('content')
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 class="col h2">
|
||||
<a href="{{ route('bo.concepts.index') }}"
|
||||
class="btn btn-primary text-decoration-none m-0"
|
||||
data-bs="tooltip"
|
||||
data-bs-placement="top"
|
||||
title="{{ __('form.return_list') }}">
|
||||
<i class="fa-solid fa-arrow-left"></i>
|
||||
</a>
|
||||
<span class="fw-bold">{{ Str::singular(__('models.classes.concepts')) }}</span> <small class="text-muted">{{ __('edit') }}</small>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body bg-light">
|
||||
<form id="formSubmit" action="{{ route('bo.concepts.update', $conceptModel->id) }}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
@include('bo.pages.concepts.form-inputs', ['model' => $conceptModel])
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<button type="submit" class="btn btn-primary"
|
||||
title="{{ __('Save :model', ['model' => Str::singular(__('models.classes.concepts'))]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
{{ __('Save') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
178
resources/views/bo/pages/concepts/form-inputs.blade.php
Normal file
178
resources/views/bo/pages/concepts/form-inputs.blade.php
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
<div class="row">
|
||||
{{-- SEO_TITLE --}}
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
<fieldset class="border h-100 bg-white p-3">
|
||||
<legend>{{ __('SEO Title') }} *</legend>
|
||||
<div class="row">
|
||||
<div class="col-12 mb-3">
|
||||
@include('bo.partials.inputs.varchar', [
|
||||
'id' => 'conceptSeoTitle',
|
||||
'label' => __('SEO title of the :model', ['model' => Str::singular(__('models.classes.concepts'))]),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'seo_title',
|
||||
'required' => true,
|
||||
'model' => $conceptModel ?? null,
|
||||
'helper' => __('Must be in 3 characters minimum, 255 maximum.'),
|
||||
'placeholder' => __('A beautiful title'),
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{-- SEO_DESCRIPTION --}}
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
<fieldset class="border h-100 bg-white p-3">
|
||||
<legend>{{ __('SEO Description') }} *</legend>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
@include('bo.partials.inputs.varchar-multiline', [
|
||||
'id' => 'conceptSeoDescription',
|
||||
'label' => __('SEO description of the :model', ['model' => Str::singular(__('models.classes.concepts'))]),
|
||||
'name' => 'seo_description',
|
||||
'model' => $conceptModel ?? null,
|
||||
'required' => true,
|
||||
'helper' => __('Must be in 50 characters minimum, 160 maximum.'),
|
||||
'placeholder' => __('A description of the content for search engines.'),
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{-- TITLE --}}
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
<fieldset class="border h-100 bg-white p-3">
|
||||
<legend>{{ __('Title') }} *</legend>
|
||||
<div class="row">
|
||||
<div class="col-12 mb-3">
|
||||
@include('bo.partials.inputs.varchar', [
|
||||
'id' => 'conceptTitle',
|
||||
'label' => __('Title of the :model', ['model' => Str::singular(__('models.classes.concepts'))]),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'title',
|
||||
'required' => true,
|
||||
'model' => $conceptModel ?? null,
|
||||
'helper' => __('Must be in 3 characters minimum, 255 maximum.'),
|
||||
'placeholder' => __('A beautiful title'),
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{-- SUBTITLE --}}
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
<fieldset class="border h-100 bg-white p-3">
|
||||
<legend>{{ __('Subtitle') }} *</legend>
|
||||
<div class="row">
|
||||
<div class="col-12 mb-3">
|
||||
@include('bo.partials.inputs.varchar', [
|
||||
'id' => 'conceptSubtitle',
|
||||
'label' => __('Subtitle of the :model', ['model' => Str::singular(__('models.classes.concepts'))]),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'subtitle',
|
||||
'required' => true,
|
||||
'model' => $conceptModel ?? null,
|
||||
'helper' => __('Must be in 3 characters minimum, 255 maximum.'),
|
||||
'placeholder' => __('A beautiful subtitle'),
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{-- NAME --}}
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
<fieldset class="border h-100 bg-white p-3">
|
||||
<legend>{{ __('Name') }} *</legend>
|
||||
<div class="row">
|
||||
<div class="col-12 mb-3">
|
||||
@include('bo.partials.inputs.varchar', [
|
||||
'id' => 'conceptName',
|
||||
'label' => __('Name of the :model', ['model' => Str::singular(__('models.classes.concepts'))]),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'name',
|
||||
'required' => true,
|
||||
'model' => $conceptModel ?? null,
|
||||
'helper' => __('Must be in 3 characters minimum, 255 maximum.'),
|
||||
'placeholder' => __('A beautiful name'),
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{-- DESCRIPTION --}}
|
||||
<div class="col-12 mb-3">
|
||||
<fieldset class="border bg-white p-3">
|
||||
<legend>{{ __('Description') }} *</legend>
|
||||
<div class="row mb-3">
|
||||
<div class="col-12">
|
||||
@include('bo.partials.inputs.text-html', [
|
||||
'id' => 'conceptDescription',
|
||||
'name' => 'description',
|
||||
'model' => $conceptModel ?? null,
|
||||
'helper' => __('Proofread your content before publishing it (minimum 15 characters).'),
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{-- MINICRUD --}}
|
||||
<div class="col-12 mb-3">
|
||||
<button class="btn btn-primary col-form-label rounded-0 dropdown-toggle w-100" type="button" data-bs-toggle="collapse" data-bs-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample">
|
||||
<b>{{ __('ALL BLOCS') }}</b>
|
||||
</button>
|
||||
<div class="collapse" id="collapseExample">
|
||||
<div class="card card-body bg-light rounded-0">
|
||||
<div class="row">
|
||||
@include('bo.modules.minicrud-form-inputs', [
|
||||
'model' => $conceptModel ?? $conceptData,
|
||||
'selectedEnum' => \App\Enums\Concepts\ColorsEnum::getData()
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{-- PICTURE --}}
|
||||
<div class="col-12 mb-3">
|
||||
<fieldset class="border h-100 bg-white p-3">
|
||||
<legend>{{ __('Illustration') }} *</legend>
|
||||
<div class="row">
|
||||
{{-- PICTURE_ALT --}}
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
@include('bo.partials.inputs.varchar', [
|
||||
'id' => 'homePart3PictureAlt',
|
||||
'label' => __('Alt attribute of the :model', ['model' => Str::singular(__('models.classes.concepts'))]),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'picture_alt',
|
||||
'required' => true,
|
||||
'model' => $conceptModel ?? null,
|
||||
'helper' => __('Must describe your image for search engines and blind people (5 to 6 words, minimum 3 characters).'),
|
||||
])
|
||||
</div>
|
||||
{{-- PICTURE_TITLE --}}
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
@include('bo.partials.inputs.varchar', [
|
||||
'id' => 'homePart3PictureTitle',
|
||||
'label' => __('Title attribute of the :model', ['model' => Str::singular(__('models.classes.concepts'))]),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'picture_title',
|
||||
'required' => true,
|
||||
'model' => $conceptModel ?? null,
|
||||
'helper' => __('Useful for users, displayed by moving the mouse over the image (minimum 3 characters).'),
|
||||
])
|
||||
</div>
|
||||
{{-- PICTURE --}}
|
||||
<div class="col-12 mb-3">
|
||||
@include('bo.partials.inputs.varchar-picture', [
|
||||
'id' => 'homePart3Picture',
|
||||
'name' => 'picture',
|
||||
'width' => 1512,
|
||||
'height' => 354,
|
||||
'model' => $conceptModel ?? null,
|
||||
'helper' => __('Must be 1512px (width) by 354px (height).'),
|
||||
'required' => true,
|
||||
'preview' => true,
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
122
resources/views/bo/pages/concepts/index.blade.php
Normal file
122
resources/views/bo/pages/concepts/index.blade.php
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
@extends('bo.layout')
|
||||
|
||||
@section('title', sprintf('%s - %s', __('models.classes.concepts'), Str::ucfirst(__('liste'))))
|
||||
|
||||
@section('content')
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 class="col h2">
|
||||
<span class="fw-bold">{{ __('models.classes.concepts') }}</span> <small class="text-muted">{{ Str::ucfirst(__('list')) }}</small>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="col-md-3 d-flex align-items-center">
|
||||
<div class="input-group justify-content-end">
|
||||
<a href="{{ route('bo.concepts.create') }}"
|
||||
class="btn btn-primary"
|
||||
title="{{ __('Create a :model', ['model' => Str::singular(__('models.classes.concepts'))]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@include('bo.modules.search-bar')
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-md-6 p-0">
|
||||
{{ $conceptModels->withQueryString()->onEachSide(1)->links() }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="table-responsive">
|
||||
<table class="table fix-action m-0">
|
||||
<thead>
|
||||
@php
|
||||
$rst = !is_null(request()->rst);
|
||||
$routeName = request()->route()->getName();
|
||||
$noOrder = Session::get("$routeName.sort_col") !== 'order' and (Session::has("$routeName.sort_col") or Session::has("$routeName.sort_way"));
|
||||
$cols = ['name' => __('Name'), 'title' => __('Title'), 'subtitle' => __('Subtitle'), 'order' => __('Order'), 'updated_at' => __('Updated at')];
|
||||
@endphp
|
||||
@include('bo.modules.table-col-sorter', [ 'cols' => $cols, 'mobileHide' => ['status']])
|
||||
</thead>
|
||||
<tbody>
|
||||
@if($conceptModels->count())
|
||||
@foreach ($conceptModels as $conceptModel)
|
||||
<tr>
|
||||
<td class="align-middle">{{ $conceptModel->name }}</td>
|
||||
<td class="align-middle">{{ $conceptModel->title }}</td>
|
||||
<td class="align-middle">{{ $conceptModel->subtitle }}</td>
|
||||
@if(!$noOrder or $rst)
|
||||
<td class="d-flex">
|
||||
<form action="{{ route('bo.concepts.change-order', ['concept' => $conceptModel, 'action' => 'up']) }}"
|
||||
method="POST"
|
||||
class="text-center @if($loop->first and $conceptModels->onFirstPage()) invisible @endif">
|
||||
@csrf
|
||||
<button type="submit"
|
||||
class="btn btn-sm @if(($loop->first and $conceptModels->onFirstPage())) disabled @endif"
|
||||
title="{{ __('Change the order of appearance upwards') }}"
|
||||
data-bs-toggle="tooltip">
|
||||
<i class="fas fa-arrow-alt-circle-up"></i>
|
||||
</button>
|
||||
</form>
|
||||
<form action="{{ route('bo.concepts.change-order', ['concept' => $conceptModel, 'action' => 'down']) }}"
|
||||
method="POST"
|
||||
class="text-center @if($loop->last and $conceptModels->currentPage() === $conceptModels->lastPage()) invisible @endif">
|
||||
@csrf
|
||||
<button type="submit"
|
||||
class="btn btn-sm @if($loop->last and $conceptModels->currentPage() === $conceptModels->lastPage()) disabled @endif"
|
||||
title="{{ __('Change the order of appearance downwards') }}"
|
||||
data-bs-toggle="tooltip">
|
||||
<i class="fas fa-arrow-alt-circle-down"></i>
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
@endif
|
||||
<td class="align-middle">
|
||||
<span class="badge bg-warning text-dark text-wrap">{{ $conceptModel->updated_at->formatLocalized('%d/%m/%Y à %H:%M') }}</span>
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
<form action="{{ route('bo.concepts.destroy', $conceptModel->id) }}" method="POST" class="btn-group confirmDeleteJS" novalidate>
|
||||
<a class="btn btn-sm btn-primary"
|
||||
href="{{ route('bo.concepts.edit', $conceptModel->id) }}"
|
||||
title="{{ __('Edit this :model', ['model' => Str::singular(__('models.classes.concepts'))]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
<i class="fa-solid fa-pencil"></i>
|
||||
</a>
|
||||
@method('DELETE')
|
||||
@csrf
|
||||
<div class="btn-group" role="group">
|
||||
<button class="btn btn-sm btn-danger"
|
||||
title="{{ __('Delete this :model', ['model' => Str::singular(__('models.classes.concepts'))]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@else
|
||||
<tr>
|
||||
<td colspan="5" class="text-center">
|
||||
<span class="h3">{{ __('No results for :models', ['models' => __('models.classes.concepts') ])}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-md-6 p-0">
|
||||
{{ $conceptModels->withQueryString()->onEachSide(1)->links() }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
<div class="col">
|
||||
<div class="card text-center">
|
||||
<div class="card-header fw-bold">
|
||||
<h1 class="h4 fw-bold">{{ __('Dashboard') }}</h1>
|
||||
<h1 class="h2 fw-bold">{{ __('Dashboard') }}</h1>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1 class="col h4">
|
||||
<span class="fw-bold">{{ __('models.classes.homes') }}</span> <small class="text-muted">{{ __('edit') }}</small>
|
||||
<h1 class="col h2">
|
||||
<span class="fw-bold">{{ __('models.classes.homes') }}</span> <small class="text-muted">{{ Str::ucfirst(__('edit')) }}</small>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
@method('PUT')
|
||||
@include('bo.pages.homes.form-inputs', compact('homeModel'))
|
||||
<div class="row">
|
||||
<div class="col text-center text-md-end">
|
||||
<div class="col text-center">
|
||||
<button type="submit" class="btn btn-primary"
|
||||
title="{{ __('Save :model', ['model' => Str::singular(__('models.classes.homes'))]) }}"
|
||||
data-bs-toggle="tooltip">
|
||||
|
|
|
|||
|
|
@ -61,17 +61,17 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{-- PART.1 TITLE SPAN --}}
|
||||
{{-- PART.1 SUBTITLE --}}
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
<fieldset class="border h-100 bg-white p-3">
|
||||
<legend>{{ __('Subtitle') }} *</legend>
|
||||
<div class="row">
|
||||
<div class="col-12 mb-3">
|
||||
@include('bo.partials.inputs.varchar', [
|
||||
'id' => 'homePart1TitleSpan',
|
||||
'id' => 'homePart1Subtitle',
|
||||
'label' => __('Subtitle of the part.1'),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'part1_title_span',
|
||||
'name' => 'part1_subtitle',
|
||||
'required' => true,
|
||||
'model' => $homeModel,
|
||||
'helper' => __('Must be in 3 characters minimum, 255 maximum.'),
|
||||
|
|
@ -154,17 +154,17 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{-- PART.2 TITLE SPAN --}}
|
||||
{{-- PART.2 SUBTITLE --}}
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
<fieldset class="border h-100 bg-white p-3">
|
||||
<legend>{{ __('Subtitle') }} *</legend>
|
||||
<div class="row">
|
||||
<div class="col-12 mb-3">
|
||||
@include('bo.partials.inputs.varchar', [
|
||||
'id' => 'homePart2TitleSpan',
|
||||
'id' => 'homePart2Subtitle',
|
||||
'label' => __('Subtitle of the part.2'),
|
||||
'hasWordCounter' => true,
|
||||
'name' => 'part2_title_span',
|
||||
'name' => 'part2_subtitle',
|
||||
'required' => true,
|
||||
'model' => $homeModel,
|
||||
'helper' => __('Must be in 3 characters minimum, 255 maximum.'),
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
@endif
|
||||
<select id="{{ $name }}" class="form-select" name="{{ $name }}" aria-describedby="{{ $id }}Help" @if(!empty($require))required @endif>
|
||||
@foreach ($associatedModels as $associatedModel)
|
||||
<option value="{{ $associatedModel['value'] }}" @if (old($name, $model->{$name}->value ?? 1) == $associatedModel['value']) selected @endif>
|
||||
<option value="{{ $associatedModel['value'] }}" @if (old($name, $model->{$name}->value ?? (isset($model->data)) ? intval($model->data->{$k}->value) : '' ?? 1) == $associatedModel['value']) selected @endif>
|
||||
{{ $associatedModel['label'] }}
|
||||
</option>
|
||||
@endforeach
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
@php
|
||||
$data = [
|
||||
'name' => $name,
|
||||
'text' => old($name, $model->{$name} ?? '')
|
||||
'text' => old($name, $model->{$name} ?? $value ?? '')
|
||||
];
|
||||
@endphp
|
||||
<div class="ck-editor" data-json='@json($data)'></div>
|
||||
@include('modules.input-error', [
|
||||
'inputName' => $name,
|
||||
'helperId' => "{$id}Help",
|
||||
'helper' => $helper ?? __('Relisez bien votre contenu avant de le publier (minimum 15 caractères).'),
|
||||
'helper' => $helper ?? __('Proofread your content before publishing it (minimum 15 characters).'),
|
||||
])
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ $data = [
|
|||
'helper' => $helper,
|
||||
'width' => $width,
|
||||
'height' => $height,
|
||||
'value' => $model->{$name} ?? '',
|
||||
'value' => $model->{$name} ?? $value ?? '',
|
||||
'preview' => $preview ?? false,
|
||||
'browseEvent' => $browseEvent ?? false,
|
||||
'required' => $required ?? false,
|
||||
];
|
||||
@endphp
|
||||
@include('modules.input-error', ['inputName' => $name, 'helper' => null])
|
||||
<div class="image-input" data-json='@json($data)'></div>
|
||||
@include('modules.input-error', ['inputName' => $name, 'helper' => null])
|
||||
|
|
|
|||
|
|
@ -8,19 +8,19 @@
|
|||
@endif
|
||||
<input name="{{ $name }}"
|
||||
type="text"
|
||||
value="{{ old($name, $model->{$name} ?? '') }}"
|
||||
value="{{ old($name, $model->{$name} ?? $value ?? '') }}"
|
||||
class="form-control
|
||||
@if(!empty($hasWordCounter ?? false))
|
||||
need-word-counter
|
||||
@endif"
|
||||
id="{{ $id }}"
|
||||
aria-describedby="{{ $id }}Help"
|
||||
placeholder="{{ $placeholder ?? __('Un nom beau et explicite') }}"
|
||||
placeholder="{{ $placeholder ?? __('A beautiful title') }}"
|
||||
@if(!empty($required))
|
||||
required
|
||||
@endif>
|
||||
@include('modules.input-error', [
|
||||
'inputName' => $name,
|
||||
'helperId' => '{{ $id }}Help',
|
||||
'helperId' => $id.'Help',
|
||||
'helper' => $helper
|
||||
])
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-md-10 col-lg-8 mt-3">
|
||||
@include('modules.breadcrumb.breadcrumb-body')
|
||||
@include('modules.breadcrumbs.breadcrumb-body')
|
||||
</div>
|
||||
</div>
|
||||
<div class="row p-md-3 justify-content-center">
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
@hasSection('breadcrumb')
|
||||
@if(Breadcrumbs::exists(app()->view->getSections()['breadcrumb']))
|
||||
{{ call_user_func_array('Breadcrumbs::view', array_merge(
|
||||
['breadcrumbs::json-ld', app()->view->getSections()['breadcrumb']],
|
||||
!empty($brParam) ? (is_array($brParam) ? $brParam : [$brParam]) : []
|
||||
)) }}
|
||||
@endif
|
||||
@elseif(Breadcrumbs::exists(request()->route()->getName()))
|
||||
{{ Breadcrumbs::view('breadcrumbs::json-ld', request()->route()->getName()) }}
|
||||
@endif
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
@if (isset($breadcrumbs))
|
||||
@unless ($breadcrumbs->isEmpty())
|
||||
<nav aria-label="breadcrumb" class="d-inline">
|
||||
<ol class="breadcrumb d-inline-flex">
|
||||
@foreach ($breadcrumbs as $breadcrumb)
|
||||
@if (!is_null($breadcrumb->url) && !$loop->last)
|
||||
<li class="breadcrumb-item"><a href="{{ $breadcrumb->url }}" rel="nofollow">{{ $breadcrumb->title }}</a></li>
|
||||
@else
|
||||
<li class="breadcrumb-item active" aria-current="page">{{ $breadcrumb->title }}</li>
|
||||
@endif
|
||||
@endforeach
|
||||
</ol>
|
||||
</nav>
|
||||
@endunless
|
||||
@endif
|
||||
|
|
@ -5,6 +5,8 @@
|
|||
!empty($brParam) ? (is_array($brParam) ? $brParam : [$brParam]) : []
|
||||
)) }}
|
||||
@endif
|
||||
@elseif(Breadcrumbs::exists(request()->route()->getName()))
|
||||
@elseif(request()->route() != null)
|
||||
@if(Breadcrumbs::exists(request()->route()->getName()))
|
||||
{{ Breadcrumbs::render(request()->route()->getName()) }}
|
||||
@endif
|
||||
@endif
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
@hasSection('breadcrumb')
|
||||
@if(Breadcrumbs::exists(app()->view->getSections()['breadcrumb']))
|
||||
{{ Breadcrumbs::view('breadcrumbs::json-ld', app()->view->getSections()['breadcrumb'], $brParam ?? null) }}
|
||||
@endif
|
||||
@elseif(request()->route() != null)
|
||||
@if (Breadcrumbs::exists(request()->route()->getName()))
|
||||
{{ Breadcrumbs::view('breadcrumbs::json-ld', request()->route()->getName()) }}
|
||||
@endif
|
||||
@endif
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
@if (count($breadcrumbs))
|
||||
<ol class="breadcrumb flex-nowrap @if(!Request::is('bo/*')) w-100 m-0 @else mb-3 @endif">
|
||||
@foreach ($breadcrumbs as $breadcrumb)
|
||||
@if ($breadcrumb->url && !$loop->last)
|
||||
<li class="breadcrumb-item d-flex">
|
||||
<a class="text-decoration-none @if(!Request::is('bo/*')) text-white py-3 @endif" href="{{ $breadcrumb->url }}">
|
||||
{{ $breadcrumb->title }}
|
||||
</a>
|
||||
</li>
|
||||
@else
|
||||
<li class="breadcrumb-item btn-games d-flex align-items-center flex-grow-1 active">
|
||||
{{ $breadcrumb->title }}
|
||||
</li>
|
||||
@endif
|
||||
@endforeach
|
||||
</ol>
|
||||
@endif
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Concept;
|
||||
use App\Models\Home;
|
||||
use Diglactic\Breadcrumbs\Breadcrumbs;
|
||||
use Diglactic\Breadcrumbs\Generator;
|
||||
|
||||
// * DASHBOARD
|
||||
Breadcrumbs::for('bo.dashboard', function (Generator $trail) {
|
||||
$trail->push(trans('Dashboard'), route('bo.dashboard'));
|
||||
});
|
||||
|
||||
// * HOMEPAGE
|
||||
Breadcrumbs::for('bo.homes.edit', function (Generator $trail, Home $homeModel) {
|
||||
$trail->push(trans('Homepage'), route('bo.homes.edit', $homeModel));
|
||||
$trail->push(trans('Edit'));
|
||||
});
|
||||
|
||||
// * CONCEPTS
|
||||
Breadcrumbs::for('bo.concepts.index', function (Generator $trail) {
|
||||
$trail->push(trans('Concepts'), route('bo.concepts.index'));
|
||||
});
|
||||
Breadcrumbs::for('bo.concepts.create', function (Generator $trail) {
|
||||
$trail->parent('bo.concepts.index');
|
||||
$trail->push(trans('Create'), route('bo.concepts.create'));
|
||||
});
|
||||
Breadcrumbs::for('bo.concepts.edit', function (Generator $trail, Concept $concept) {
|
||||
$trail->parent('bo.concepts.index');
|
||||
$trail->push(trans('Edit'), route('bo.concepts.edit', $concept->slug));
|
||||
});
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
|
||||
use App\Http\Controllers\Bo\ConceptController;
|
||||
use App\Http\Controllers\Bo\DashboardController;
|
||||
use App\Http\Controllers\Bo\HomeController;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
|
@ -26,12 +27,21 @@ Route::prefix('bo')
|
|||
}
|
||||
);
|
||||
|
||||
Route::middleware('auth:backend')->group(function () {
|
||||
Route::get('/', [DashboardController::class, 'index'])->name('dashboard');
|
||||
Route::middleware('auth:backend')->group(function () {
|
||||
Route::get('/', [DashboardController::class, 'index'])->name('dashboard');
|
||||
|
||||
// * HOMEPAGE
|
||||
Route::resource('homes', HomeController::class)->except(['show'])
|
||||
->withoutMiddleware('htmlsanitize')
|
||||
->middleware(['htmlsanitize:part1_text_1,part1_text_2,part1_text_3,part2_text']);
|
||||
});
|
||||
});
|
||||
// * HOMEPAGE
|
||||
Route::resource('homes', HomeController::class)->except(['show'])
|
||||
->withoutMiddleware('htmlsanitize')
|
||||
->middleware(['htmlsanitize:part1_text_1,part1_text_2,part1_text_3,part2_text']);
|
||||
|
||||
// * CONCEPTS
|
||||
Route::resource('concepts', ConceptController::class)->except(['show'])
|
||||
->withoutMiddleware('htmlsanitize')
|
||||
->middleware(['htmlsanitize:description,data']);
|
||||
Route::put('/concepts/create/new', [ConceptController::class, 'store'])->name('concepts.store');
|
||||
Route::post('/concepts/{concept}/change-order', [ConceptController::class, 'changeOrder'])
|
||||
->name('concepts.change-order');
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue