Merge branch 'issue-63' into 'develop'

clean blades - #63

See merge request ldc-web/projets/agis!32
This commit is contained in:
Vincent BRIDIER 2024-02-08 15:00:43 +00:00
commit 95d552c429
60 changed files with 250 additions and 1016 deletions

View file

@ -1,229 +0,0 @@
<?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']) {
case InputType::number->value:
$rules = array_merge($rules, [
"data.$iptName.value" => $this->compileValidate('required|numeric', $input)
]);
break;
case InputType::videoYoutube->value:
$rules = array_merge($rules, [
"data.$iptName.value" => $this->compileValidate('regex:%([^"&?\/\s]{11})%i', $input)
]);
break;
case InputType::videoVimeo->value:
$rules = array_merge($rules, [
"data.$iptName.value" => $this->compileValidate('regex:%([0-9]{8,10})%i', $input)
]);
break;
case InputType::video->value:
$rules = array_merge($rules, [
"data.$iptName.value" => $this->compileValidate([
'regex:%([0-9]{8,10}|[^"&?\/\s]{11})%i'
], $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($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.value" => $mergeRules
]);
break;
case InputType::image->value:
$required = $this->isUpdate() ? 'sometimes' : 'required';
$ipt = $this->data[$iptName];
$max = isset($ipt['dimensionsMax']);
$dim = \is_string($input['dimensions']) ? collect(explode(
',',
(isset($ipt['dimensionsMax']) and is_string($ipt['dimensionsMax'])) ?
$ipt['dimensionsMax'] : $input['dimensions']
))->mapWithKeys(function ($v) {
$v = explode(' ', $v);
return [$v[0] => $v[1]];
}) : $input['dimensions'];
// * Adapt dimensions
$sizes = (object)[
'minHeight' => $dim['height'],
'maxHeight' => $dim['height'],
'minWith' => $dim['width'],
'maxWith' => $dim['width'],
];
$rules = array_merge($rules, [
"data.$iptName.value" => [
function (string $attribute, $value, callable $fail) use ($sizes) {
ToolboxHelper::validatePicture($attribute, $value, $fail, $sizes);
}
],
$this->compileValidate(
implode('|', [
$required,
'image',
'mimes:png,jpg,jpeg',
sprintf(
'dimensions:%s=%d,%s=%d',
$max ? 'max_height' : 'height',
$dim['height'],
$max ? 'max_width' : 'width',
$dim['width']
)
]),
$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 = ToolboxHelper::arrayMergeRecursiveDistinct($all, $nested);
$this->merge($all);
$rules = array_merge($rules, [
"data.$iptName.value" => 'boolean'
]);
break;
} //end switch
} //end foreach
return $rules;
}
/**
* Undocumented function
*
* @param string|array $inputTypeValidate
* @param array $input
* @return array
*/
public function compileValidate(string|array $inputTypeValidate, array $input): array
{
if (\is_string($inputTypeValidate)) {
$inputTypeValidate = explode('|', $inputTypeValidate);
}
/** @var array|string */
$inputValidate = \collect($input)->get('validate', $input);
$inputValidate = \is_string($inputValidate) ? explode('|', $inputValidate) : $inputValidate;
foreach ($inputValidate as $validate) {
if (!\in_array($validate, $inputTypeValidate)) {
$inputTypeValidate[] = $validate;
}
}
$test = \collect($inputTypeValidate)->all();
$test = \collect($inputTypeValidate)->sort(function ($valueA, $valueB) {
$valueA = $this->ruleHasToComeFirst($valueA) ? 0 : 2;
$valueB = $this->ruleHasToComeFirst($valueB) ? 1 : 2;
return $valueA - $valueB;
})->unique()->all();
return \collect($inputTypeValidate)->unique()->sort(function ($valueA, $valueB) {
$valueA = $this->ruleHasToComeFirst($valueA) ? 0 : 2;
$valueB = $this->ruleHasToComeFirst($valueB) ? 1 : 2;
return $valueA - $valueB;
})->all();
}
/**
* Does the rulle need to come first ?
*
* @param string $rule
* @return boolean
*/
private function ruleHasToComeFirst(string $rule): bool
{
$rule = \collect(\explode(':', $rule, 1))->filter()->first(null, '');
return \collect([
'nullable', 'present', 'required', 'required_if',
'required_unless', 'required_with', 'required_with_all',
'required_without', 'required_without_all', 'required_with_all',
'missing', 'missing_if', 'missing_unless',
'missing_with', 'missing_with_all',
])->first(fn (string $firstRule) => \strpos($rule, $firstRule) === 0) ? true : false;
}
/**
* Is this request an update request ?
*
* @return boolean
*/
private function isUpdate(): bool
{
return $this->isMethod('PUT');
}
}

View file

@ -1,180 +0,0 @@
<?php
namespace App\Traits\Models;
use App\Enums\InputType;
use App\Lib\Helpers\FileStorageHelper;
use App\Lib\Helpers\ToolboxHelper;
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.
* @phpcs:disable Squiz.Commenting.FunctionComment.EmptyThrows
*/
public function fill(array $attributes)
{
// phpcs:enable
parent::fill($attributes);
if (isset($attributes['data'])) {
$this->setData($attributes['data']);
}
}
/**
* Apply function on data typed text while on save event
*
* @return void
*/
public function minicrudCreating()
{
/** @var array<string,array> */
$data = $this->data;
foreach ($data as &$input) {
switch ($input['inputType']) {
case InputType::text->value:
$input['text'] = clean($input['text']);
$input['text'] = FileStorageHelper::storeModelFilesFromHtml($this, $input['text']);
break;
} //end switch
} //end foreach
$this->data = $data;
}
/**
* Apply function on data typed text while on update event
*
* @return void
*/
public function minicrudUpdating()
{
$this->minicrudCreating();
}
/**
* Apply function on data typed text while on updated event
*
* @return void
*/
public function minicrudUpdated()
{
/** @var array */
foreach ($this->data as $index => $input) {
switch ($input['inputType']) {
case InputType::text->value:
$original = ToolboxHelper::getOriginal($this, 'data');
FileStorageHelper::removeOldModelFilesFromHtml(
$input['text'],
$original[$index]['text'] ?? ''
);
break;
} //end switch
} //end foreach
}
/**
* Apply function on data typed text while on deleted event
*
* @return void
*/
public function minicrudDeleted()
{
/** @var array */
foreach ($this->data as $input) {
switch ($input['inputType']) {
case InputType::text->value:
FileStorageHelper::removeModelFilesOfHtml($input['text']);
break;
} //end switch
} //end foreach
}
/**
* 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']);
}
$this->setAttribute('data', $data);
}
/**
* Set a specific prop
*
* @param array $value
* @return void
*/
protected function setDataAttribute(array $value): void
{
$this->attributes['data'] = $this->castAttributeAsJson(
'data',
$this->serializeData($value)
);
}
/**
* Set a specific prop
*
* @param string|null $data
* @return array
*/
protected function getDataAttribute(string|null $data): array
{
return $this->fromJson($data ?? $this->attributes['data'] ?? '[]');
}
/**
* Serialize properties
*
* @param array $data
* @return array
* @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): array
{
foreach ($data as $o => $input) {
switch ($input['inputType']) {
case InputType::image->value:
$data[$o]['value'] = \preg_replace(
'/^\/|^/',
'',
FileStorageHelper::storeFile($this, $input['value'], true)
);
break;
case InputType::selectEnum->value:
case InputType::boolean->value:
case InputType::password->value:
case InputType::email->value:
case InputType::number->value:
case InputType::videoVimeo->value:
case InputType::videoYoutube->value:
case InputType::video->value:
break;
case InputType::string->value:
case InputType::text->value:
case InputType::url->value:
ToolboxHelper::assertNoInternalBoUrls('content', $input['value']);
break;
default:
throw new \ErrorException(sprintf(
'Unknown input Type %s',
$input['inputType']
));
} //end switch
} //end foreach
return $data;
}
}

View file

@ -3,65 +3,66 @@
@section('description', __('Formulaire d\'authentification au back-office.'))
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8 p-0">
<div class="card">
<div class="card-header">{{ __('Connexion') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('bo.login') }}">
@csrf
<div class="row mb-3">
<label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Adresse Email') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email"
value="{{ old('email') }}" autocomplete="email" autofocus required>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Mot de passe') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror"
name="password" autocomplete="current-password" required>
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<div class="col-md-6 offset-md-4">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
<label class="form-check-label user-select-none" for="remember">
{{ __('Se souvenir de moi') }}
</label>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8 p-0">
<div class="card">
<div class="card-header">{{ __('Connexion') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('bo.login') }}">
@csrf
<div class="row mb-3">
<label class="col-md-4 col-form-label text-md-end" for="email">{{ __('Adresse Email') }}</label>
<div class="col-md-6">
<input class="form-control @error('email') is-invalid @enderror" id="email" name="email"
type="email" value="{{ old('email') }}" autocomplete="email" autofocus required>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
</div>
<div class="row mb-0">
<div class="col-md-8 offset-md-4">
<button type="submit" class="btn btn-primary">
<span>{{ __('Connexion') }}</span>
<i class="fa-solid fa-arrow-right-from-bracket"></i>
</button>
@if (Route::has('bo.password.request'))
<a class="btn btn-link" href="{{ route('bo.password.request') }}">
{{ __('Mot de passe oublié ?') }}
</a>
@endif
<div class="row mb-3">
<label class="col-md-4 col-form-label text-md-end" for="password">{{ __('Mot de passe') }}</label>
<div class="col-md-6">
<input class="form-control @error('password') is-invalid @enderror" id="password" name="password"
type="password" autocomplete="current-password" required>
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
</div>
</form>
<div class="row mb-3">
<div class="col-md-6 offset-md-4">
<div class="form-check">
<input class="form-check-input" id="remember" name="remember" type="checkbox"
{{ old('remember') ? 'checked' : '' }}>
<label class="form-check-label user-select-none" for="remember">
{{ __('Se souvenir de moi') }}
</label>
</div>
</div>
</div>
<div class="row mb-0">
<div class="col-md-8 offset-md-4">
<button class="btn btn-primary" type="submit">
<span>{{ __('Connexion') }}</span>
<i class="fa-solid fa-arrow-right-from-bracket"></i>
</button>
@if (Route::has('bo.password.request'))
<a class="btn btn-link" href="{{ route('bo.password.request') }}">
{{ __('Mot de passe oublié ?') }}
</a>
@endif
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection

View file

@ -62,7 +62,7 @@
</button>
<div class="dropdown-menu dropdown-menu-end m-0 text-center" aria-labelledby="navbarDropdown">
<a class="dropdown-item w-100 text-decoration-none p-2" data-bs-toggle="tooltip" data-bs-placement="left"
href="{{ route('bo.users.edit',auth('backend')->user()->getKey()) }}"
href="{{ route('bo.users.edit', auth('backend')->user()->getKey()) }}"
title="{{ __('Accéder à son profile') }}">
{{ __('Profile') }}
</a>

View file

@ -3,8 +3,7 @@
<div class="d-flex justify-content-center align-items-center">
<form class="@if ($loop->first and $models->onFirstPage()) invisible @endif"
action="{{ route('bo.' . $routeName . '.change-order', [Str::singular($routeName) => $model, 'direction' => 'up']) }}"
method="POST"
>
method="POST">
@csrf
@method('PATCH')
<button class="btn btn-sm btn-outline-secondary @if ($loop->first and $models->onFirstPage()) disabled @endif" data-bs-toggle="tooltip"
@ -14,8 +13,7 @@
</form>
<form class="@if ($loop->last and $models->currentPage() === $models->lastPage()) invisible @endif"
action="{{ route('bo.' . $routeName . '.change-order', [Str::singular($routeName) => $model, 'direction' => 'down']) }}"
method="POST"
>
method="POST">
@csrf
@method('PATCH')
<button class="btn btn-sm btn-outline-secondary @if ($loop->last and $models->currentPage() === $models->lastPage()) disabled @endif ms-1" data-bs-toggle="tooltip"

View file

@ -1,15 +1,6 @@
{{-- GET ACTUAL PAGINATION --}}
@php
$pagination = intval(
Cache::get(
'pagination.' .
\Illuminate\Support\Str::slug(
request()
->route()
->getName(),
),
),
);
$pagination = intval(Cache::get('pagination.' . \Illuminate\Support\Str::slug(request()->route()->getName())));
@endphp
@if ($paginator->items())
<nav class="pagination-custom d-flex justify-content-between align-items-center">

View file

@ -2,8 +2,7 @@
@section('title', __('Édition d\'un :model', ['model' => __('models.classes.activity_log')]))
@section('description', __('Édition d\'un :model déjà existant', ['model' => __('models.classes.activity_log')]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.create', 0, ['model' => __('models.classes.commitment')]))
@section('description', trans_choice('crud.meta.description.create', 2, ['model' => __('models.classes.commitment')]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.edit', 0, ['model' => __('models.classes.commitment')]))
@section('description', trans_choice('crud.meta.description.edit', 0, ['model' => __('models.classes.commitment')]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -20,9 +20,7 @@
alt="{{ $commitmentModel->picture_alt }}" height="50px">
</td>
@php
$routeName = request()
->route()
->getName();
$routeName = request()->route()->getName();
@endphp
@if (empty(request()->search) && Session::get("$routeName.sort_col") === 'order')
@include('bo.modules.change-model-order', [

View file

@ -1,7 +1,6 @@
@extends('bo.layout')
@section('title',
Str::of(__('models.classes.commitment'))->plural()->ucfirst())
@section('title', Str::of(__('models.classes.commitment'))->plural()->ucfirst())
@section('description', trans_choice('crud.meta.description.index', 0, ['model' => Str::plural(__('models.classes.commitment'))]))
@section('content')

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.edit', 0, ['model' => __('models.classes.convictionpage')]))
@section('description', trans_choice('crud.meta.description.edit', 0, ['model' => __('models.classes.convictionpage')]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.edit', 1, ['model' => __('models.classes.explorerpage')]))
@section('description', trans_choice('crud.meta.description.edit', 1, ['model' => __('models.classes.explorerpage')]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.edit', 0, ['model' => __('models.classes.homepage')]))
@section('description', trans_choice('crud.meta.description.edit', 0, ['model' => __('models.classes.homepage')]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.edit', 0, ['model' => __('models.classes.joinuspage')]))
@section('description', trans_choice('crud.meta.description.edit', 0, ['model' => __('models.classes.joinuspage')]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.create', 1, ['model' => __('models.classes.news')]))
@section('description', trans_choice('crud.meta.description.create', 1, ['model' => __('models.classes.news')]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.edit', 1, ['model' => __('models.classes.news')]))
@section('description', trans_choice('crud.meta.description.edit', 1, ['model' => __('models.classes.news')]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -18,12 +18,10 @@
<td class="text-center align-middle">{{ $newsModel->title }}</td>
<td class="text-center align-middle">{{ $newsModel->category->label() }}</td>
<td class="text-center align-middle">
<img height="50px" src="/{{ $newsModel->picture }}">
<img src="/{{ $newsModel->picture }}" height="50px">
</td>
@php
$routeName = request()
->route()
->getName();
$routeName = request()->route()->getName();
@endphp
@if (empty(request()->search) && Session::get("$routeName.sort_col") === 'order')
@include('bo.modules.change-model-order', [

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.create', 0, ['model' => __('models.classes.product')]))
@section('description', trans_choice('crud.meta.description.create', 0, ['model' => __('models.classes.product')]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.edit', 0, ['model' => __('models.classes.product')]))
@section('description', trans_choice('crud.meta.description.edit', 0, ['model' => __('models.classes.product')]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -18,12 +18,10 @@
<td class="text-center align-middle">{{ $productModel->title }}</td>
<td class="text-center align-middle">{{ $productModel->subtitle }}</td>
<td class="text-center align-middle">
<img height="50px" src="/{{ $productModel->picture_packshot }}">
<img src="/{{ $productModel->picture_packshot }}" height="50px">
</td>
@php
$routeName = request()
->route()
->getName();
$routeName = request()->route()->getName();
@endphp
@if (empty(request()->search) && Session::get("$routeName.sort_col") === 'order')
@include('bo.modules.change-model-order', [

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.create', 1, ['model' => __('models.classes.range')]))
@section('description', trans_choice('crud.meta.description.create', 1, ['model' => __('models.classes.range')]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.edit', 1, ['model' => __('models.classes.range')]))
@section('description', trans_choice('crud.meta.description.edit', 1, ['model' => __('models.classes.range')]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -16,12 +16,10 @@
<tr class="border-bottom list-item">
<td class="text-center align-middle">{{ $rangeModel->title }}</td>
<td class="text-center align-middle">
<img height="50px" src="/{{ $rangeModel->picture }}">
<img src="/{{ $rangeModel->picture }}" height="50px">
</td>
@php
$routeName = request()
->route()
->getName();
$routeName = request()->route()->getName();
@endphp
@if (empty(request()->search) && Session::get("$routeName.sort_col") === 'order')
@include('bo.modules.change-model-order', [

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.create', 1, ['model' => trans_choice('models.classes.seasonal_section', 1)]))
@section('description', trans_choice('crud.meta.description.create', 1, ['model' => trans_choice('models.classes.seasonal_section', 1)]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.edit', 0, ['model' => __('models.classes.seasonal_section')]))
@section('description', trans_choice('crud.meta.description.edit', 1, ['model' => __('models.classes.seasonal_section')]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -17,7 +17,7 @@
<td class="text-center align-middle">{{ $seasonalSectionModel->title }}</td>
<td class="text-center align-middle">{{ $seasonalSectionModel->background->label() }}</td>
<td class="text-center align-middle">
<img height="50px" src="/{{ $seasonalSectionModel->picture }}">
<img src="/{{ $seasonalSectionModel->picture }}" height="50px">
</td>
@include('bo.modules.change-published-status', [
'routeName' => 'seasonalsections',
@ -28,8 +28,8 @@
</td>
<td class="text-end align-middle">
@canAny(['delete', 'duplicate', 'update'], $seasonalSectionModel)
<form class="btn-group confirmDeleteTS" action="{{ route('bo.seasonalsections.destroy', $seasonalSectionModel) }}" method="POST"
novalidate>
<form class="btn-group confirmDeleteTS" action="{{ route('bo.seasonalsections.destroy', $seasonalSectionModel) }}"
method="POST" novalidate>
@can('duplicate', $seasonalSectionModel)
<a class="btn btn-sm btn-secondary" data-bs-toggle="tooltip"
href="{{ route('bo.seasonalsections.duplicate', ['seasonal_section' => $seasonalSectionModel]) }}"

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.create', 0, ['model' => __('models.classes.stamp')]))
@section('description', trans_choice('crud.meta.description.create', 0, ['model' => __('models.classes.stamp')]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.edit', 0, ['model' => __('models.classes.stamp')]))
@section('description', trans_choice('crud.meta.description.edit', 0, ['model' => __('models.classes.stamp')]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -15,14 +15,12 @@
@foreach ($stampModels as $stampModel)
<tr class="border-bottom list-item">
<td class="text-center align-middle">
<img height="50px" src="/{{ $stampModel->picture }}">
<img src="/{{ $stampModel->picture }}" height="50px">
</td>
<td class="text-center align-middle">{{ $stampModel->picture_alt }}</td>
<td class="text-center align-middle">{{ $stampModel->picture_title }}</td>
@php
$routeName = request()
->route()
->getName();
$routeName = request()->route()->getName();
@endphp
@if (empty(request()->search) && Session::get("$routeName.sort_col") === 'order')
@include('bo.modules.change-model-order', [

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.edit', 1, ['model' => trans_choice('models.classes.static_page', 1)]))
@section('description', trans_choice('crud.meta.description.edit', 1, ['model' => trans_choice('models.classes.static_page', 1)]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -126,30 +126,30 @@
</div>
@if (\in_array($staticPageModel->type, [\App\Enums\StaticPageType::confidentiality, \App\Enums\StaticPageType::legals]))
<div class="row">
{{-- CONTENT --}}
<div class="col-12 mb-3">
<fieldset class="border p-3">
<legend>{{ Str::ucfirst(__('validation.attributes.content')) }}</legend>
<div class="row mb-3">
<div class="col-12">
@include('bo.partials.inputs.text-html', [
'id' => 'staticPageContent',
'label' => __(':field :inter:model', [
'field' => Str::ucfirst(__('validation.attributes.content')),
'inter' => __('validation.custom.of_the.female'),
'model' => trans_choice('models.classes.static_page', 1),
]),
'name' => 'content',
'model' => $staticPageModel ?? null,
'required' => true,
'helper' => __('crud.minicrud.text_warning'),
])
<div class="row">
{{-- CONTENT --}}
<div class="col-12 mb-3">
<fieldset class="border p-3">
<legend>{{ Str::ucfirst(__('validation.attributes.content')) }}</legend>
<div class="row mb-3">
<div class="col-12">
@include('bo.partials.inputs.text-html', [
'id' => 'staticPageContent',
'label' => __(':field :inter:model', [
'field' => Str::ucfirst(__('validation.attributes.content')),
'inter' => __('validation.custom.of_the.female'),
'model' => trans_choice('models.classes.static_page', 1),
]),
'name' => 'content',
'model' => $staticPageModel ?? null,
'required' => true,
'helper' => __('crud.minicrud.text_warning'),
])
</div>
</div>
</div>
</fieldset>
</fieldset>
</div>
</div>
</div>
@endif
<div class="row">

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.create', 0, ['model' => __('models.classes.testimonial')]))
@section('description', trans_choice('crud.meta.description.create', 0, ['model' => __('models.classes.testimonial')]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.edit', 0, ['model' => __('models.classes.testimonial')]))
@section('description', trans_choice('crud.meta.description.edit', 0, ['model' => __('models.classes.testimonial')]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -23,9 +23,7 @@
<td class="text-center align-middle">{{ $testimonialModel->job }}</td>
<td class="text-center align-middle">{{ $testimonialModel->statut }}</td>
@php
$routeName = request()
->route()
->getName();
$routeName = request()->route()->getName();
@endphp
@if (empty(request()->search) && Session::get("$routeName.sort_col") === 'order')
@include('bo.modules.change-model-order', [

View file

@ -1,7 +1,6 @@
@extends('bo.layout')
@section('title',
Str::of(__('models.classes.testimonial'))->plural()->ucfirst())
@section('title', Str::of(__('models.classes.testimonial'))->plural()->ucfirst())
@section('description', trans_choice('crud.meta.description.index', 0, ['model' => __('models.classes.testimonial')]))
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap">

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.create', 0, ['model' => __('models.classes.user')]))
@section('description', trans_choice('crud.meta.description.create', 0, ['model' => __('models.classes.user')]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -2,8 +2,7 @@
@section('title', trans_choice('crud.meta.title.edit', 0, ['model' => __('models.classes.user')]))
@section('description', trans_choice('crud.meta.description.edit', 0, ['model' => __('models.classes.user')]))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="d-flex justify-content-between flex-md-nowrap align-items-center flex-wrap pb-3">

View file

@ -82,8 +82,7 @@
'required' => true,
'associatedModels' => Arr::where(
\App\Enums\Users\RoleEnum::toArray(),
fn(object $role) => $role->value >=
auth('backend')->user()->role->value()),
fn(object $role) => $role->value >= auth('backend')->user()->role->value()),
'helper' => __('Sélectionnez un rôle dans la liste déroulante.'),
])
</div>

View file

@ -1,3 +1,4 @@
{{-- blade-formatter-disable --}}
@component('mail::message')
# Bonjour,

View file

@ -1,3 +1,4 @@
{{-- blade-formatter-disable --}}
@component('mail::message')
# Bonjour,

View file

@ -9,14 +9,18 @@
<button id="backtotop"><i class="arrow up"></i></button>
@include('fo.layouts.header')
<main>
<div class="row container mx-auto">
<div class="col-12 p-0">
@include('modules.flash-messages')
<div class="container">
<div class="row mx-auto">
<div class="col-12 p-0">
@include('modules.flash-messages')
</div>
</div>
</div>
<div class="row container-fluid justify-content-center">
<div class="col-12 col-md-10 col-lg-8 mt-3">
@include('modules.breadcrumbs.breadcrumb-body')
<div class="container-fluid">
<div class="row justify-content-center">
<div class="col-12 col-md-10 col-lg-8 mt-3">
@include('modules.breadcrumbs.breadcrumb-body')
</div>
</div>
</div>
@yield('content')

View file

@ -37,10 +37,10 @@
<div class="row">
<div class="col-12 col-lg-3 p-lg-3">
<address class="d-flex flex-column m-0">
<span class="text-uppercase fw-bold">Siège Social Agis</span>
<span class="text-uppercase">802 Rue Sainte-Geneviève</span>
<span class="text-uppercase">84000 Avignon</span>
<a class="link-dark text-uppercase" href="tel:+33490809999">T. +33 (0)4 90 80 99 99</a>
<span class="text-uppercase fw-bold">{{ __('Siège Social Agis') }}</span>
<span class="text-uppercase">{{ __('802 Rue Sainte-Geneviève') }}</span>
<span class="text-uppercase">{{ __('84000 Avignon') }}</span>
<a class="link-dark text-uppercase" href="tel:+33490809999">{{ __('T. +33 (0)4 90 80 99 99') }}</a>
</address>
</div>
<div class="col-12 col-lg-6 d-flex flex-column flex-lg-row justify-content-around p-lg-3">

View file

@ -2,8 +2,7 @@
@section('title', __($staticPageModel->seo_title))
@section('description', __($staticPageModel->seo_description))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="about-us">

View file

@ -2,8 +2,7 @@
@section('title', __('Accueil'))
@section('description', __('Description site'))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="container">

View file

@ -2,8 +2,7 @@
@section('title', $contactModel->seo_title ?? __('Contact'))
@section('description', $contactModel->seo_description ?? __('Contactez-nous !'))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<section class="contact">

View file

@ -2,8 +2,7 @@
@section('title', $staticPageModel->seo_title ?? __('Nos convictions'))
@section('description', $staticPageModel->seo_description ?? __('Les convictions de la marque Agis'))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<section class="convictions col-12 overflow-hidden">
@ -270,8 +269,6 @@
<h2 class="black-title f-readex-pro w-100 my-5 px-4 text-center text-white">
{{ __('04 Intégrer son territoire') }}
</h2>
{{-- </div> --}}
{{-- <div class="ms-0 ms-lg-5 ps-0 ps-lg-5 me-0 pe-0"> --}}
<div class="row">
<div class="col-12 col-lg-6">
<div class="container">
@ -287,8 +284,6 @@
alt="{{ __('Dessin d\'une main tenant des tomates et des champignons') }}">
</div>
</div>
{{-- </div> --}}
{{-- <div class="container"> --}}
<div class="row mt-4">
<div class="col-12 col-lg-6">
<p class="fw-bold">{{ __('L\'entreprise, acteur local, participe à la vie de sa collectivité') }}&nbsp;:</p>

View file

@ -6,7 +6,7 @@
request()->route()->getName())
@section('content')
<section class="explorerpage col-12 container-fluid overflow-hidden">
<section class="explorerpage container-fluid overflow-hidden">
<!-- TITLE CARD -->
<section class="bg-agis-yellow title-card">
<div class="lh-sm px-md-5 my-2 px-4 py-2 text-center">

View file

@ -2,8 +2,7 @@
@section('title', __($staticPageModel->seo_title))
@section('description', __($staticPageModel->seo_description))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<div class="container">

View file

@ -2,8 +2,7 @@
@section('title', $staticPageModel->seo_title ?? __('Accueil'))
@section('description', $staticPageModel->seo_description ?? __('Description site'))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<section class="news position-relative bg-agis-grey pb-5">

View file

@ -2,26 +2,27 @@
@section('title', $newsModel->seo_title ?? __('Actualités'))
@section('description', $newsModel->seo_description ?? __('Les actualités de la marque'))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<section class="news-single mx-auto mb-5">
<div class="row container mx-auto">
<div class="col-12">
<a class="btn btn-secondary" href="{{ route('fo.news.index') }}">{{ __('< Retour aux actualités') }}</a>
</div>
<div class="col-12">
<h1 class="news-single-title f-sheldon text-uppercase lh-sm my-3 text-center">
<span class="divide d-block w-100 mt-xl-3 my-2"></span>
{{ $newsModel->title }}
<span class="divide d-block w-100 mt-xl-3 my-2"></span>
</h1>
</div>
<div class="col-12">
<p class="f-readex-pro mb-0">
{{ \Carbon\Carbon::parse($newsModel->publish_at)->locale('fr_FR')->isoFormat('D MMM Y') }}</p>
<p class="fs-3 mb-3">{{ __($newsModel->category->label()) }}</p>
<div class="container">
<div class="row mx-auto">
<div class="col-12">
<a class="btn btn-secondary" href="{{ route('fo.news.index') }}">{{ __('< Retour aux actualités') }}</a>
</div>
<div class="col-12">
<h1 class="news-single-title f-sheldon text-uppercase lh-sm my-3 text-center">
<span class="divide d-block w-100 mt-xl-3 my-2"></span>
{{ $newsModel->title }}
<span class="divide d-block w-100 mt-xl-3 my-2"></span>
</h1>
</div>
<div class="col-12">
<p class="f-readex-pro mb-0">
{{ \Carbon\Carbon::parse($newsModel->publish_at)->locale('fr_FR')->isoFormat('D MMM Y') }}</p>
<p class="fs-3 mb-3">{{ __($newsModel->category->label()) }}</p>
</div>
</div>
</div>
<article class="bg-agis-grey pt-5">
@ -45,14 +46,14 @@
<div class="row pb-5">
<div class="col text-center">
<p class="fs-3 mt-5">{{ __('Partager sur') }}</p>
<a class="text-decoration-none" href="https://www.facebook.com/sharer/sharer.php?u={{ urlencode(str_replace('http://', 'https://', request()->fullurl())) }}&t={{ urlencode($newsModel->title) }}"
title="{{ __('Partager sur Facebook') }}"
target="_blank">
<a class="text-decoration-none"
href="https://www.facebook.com/sharer/sharer.php?u={{ urlencode(str_replace('http://', 'https://', request()->fullurl())) }}&t={{ urlencode($newsModel->title) }}"
title="{{ __('Partager sur Facebook') }}" target="_blank">
@include('fo.partials.social-svg-facebook')
</a>
<a class="text-decoration-none" href="https://www.linkedin.com/sharing/share-offsite/?url={{ urlencode(str_replace('http://', 'https://', request()->fullurl())) }}"
title="{{ __('Partager sur Linkedin') }}"
target="_blank">
<a class="text-decoration-none"
href="https://www.linkedin.com/sharing/share-offsite/?url={{ urlencode(str_replace('http://', 'https://', request()->fullurl())) }}"
title="{{ __('Partager sur Linkedin') }}" target="_blank">
@include('fo.partials.social-svg-linkedin')
</a>
</div>

View file

@ -2,8 +2,7 @@
@section('title', $productModel->seo_title ?? __('Fiche produit'))
@section('description', $productModel->seo_description ?? __('Fiche descriptive d\'un produit'))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<section class="product col-12 overflow-hidden">

View file

@ -2,8 +2,7 @@
@section('title', $staticPageModel->seo_title ?? __('Gammes'))
@section('description', $staticPageModel->seo_description ?? __('Nos gammes à savourer !'))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<section class="ranges position-relative">

View file

@ -2,8 +2,7 @@
@section('title', $rangeModel->seo_title ?? __('Gamme'))
@section('description', $rangeModel->seo_description ?? __('La gamme à savourer !'))
@section('breadcrumb',
request()->route()->getName())
@section('breadcrumb', request()->route()->getName())
@section('content')
<section class="ranges range position-relative">

View file

@ -6,5 +6,5 @@
) }}
@endif
@elseif(Breadcrumbs::exists(request()->route()->getName()))
{{ Breadcrumbs::view('breadcrumbs::json-ld',request()->route()->getName()) }}
{{ Breadcrumbs::view('breadcrumbs::json-ld', request()->route()->getName()) }}
@endif

View file

@ -1,47 +1,47 @@
@if(!request()->routeIs('login'))
@if ($message = Session::get('success', Session::get('bo.success')))
<div class="alert alert-success alert-dismissible fade show m-0 mb-3" role="alert">
<i class="fa-solid fa-circle-check"></i>
<strong>{!! nl2br(e($message)) !!}</strong>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="{{ __('Fermer') }}"></button>
</div>
@endif
@if ($message = Session::get('error', Session::get('bo.error')))
<div class="alert alert-danger alert-dismissible fade show m-0 mb-3" role="alert">
<i class="fa-solid fa-circle-xmark"></i>
<strong>{!! nl2br(e($message)) !!}</strong>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="{{ __('Fermer') }}"></button>
</div>
@endif
@if ($message = Session::get('warning', Session::get('bo.warning')))
<div class="alert alert-warning alert-dismissible fade show m-0 mb-3" role="alert">
<i class="fa-solid fa-circle-exclamation"></i>
<strong>{!! nl2br(e($message)) !!}</strong>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="{{ __('Fermer') }}"></button>
</div>
@endif
@if ($message = Session::get('info', Session::get('bo.info')))
<div class="alert alert-info alert-dismissible fade show m-0 mb-3" role="alert">
<i class="fa-solid fa-circle-info"></i>
<strong>{!! nl2br(e($message)) !!}</strong>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="{{ __('Fermer') }}"></button>
</div>
@endif
@if ($errors->any())
<div class="alert alert-danger alert-dismissible fade show m-0 mb-3" role="alert">
<p class="fw-bold m-0"><i class="fa-solid fa-circle-exclamation"></i>&nbsp;Liste des erreurs :</p>
@if ($errors->any())
<ul class="list-unstyled m-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
@if (!request()->routeIs('login'))
@if ($message = Session::get('success', Session::get('bo.success')))
<div class="alert alert-success alert-dismissible fade show m-0 mb-3" role="alert">
<i class="fa-solid fa-circle-check"></i>
<strong>{!! nl2br(e($message)) !!}</strong>
<button class="btn-close" data-bs-dismiss="alert" type="button" aria-label="{{ __('Fermer') }}"></button>
</div>
@endif
@if ($message = Session::get('error', Session::get('bo.error')))
<div class="alert alert-danger alert-dismissible fade show m-0 mb-3" role="alert">
<i class="fa-solid fa-circle-xmark"></i>
<strong>{!! nl2br(e($message)) !!}</strong>
<button class="btn-close" data-bs-dismiss="alert" type="button" aria-label="{{ __('Fermer') }}"></button>
</div>
@endif
@if ($message = Session::get('warning', Session::get('bo.warning')))
<div class="alert alert-warning alert-dismissible fade show m-0 mb-3" role="alert">
<i class="fa-solid fa-circle-exclamation"></i>
<strong>{!! nl2br(e($message)) !!}</strong>
<button class="btn-close" data-bs-dismiss="alert" type="button" aria-label="{{ __('Fermer') }}"></button>
</div>
@endif
@if ($message = Session::get('info', Session::get('bo.info')))
<div class="alert alert-info alert-dismissible fade show m-0 mb-3" role="alert">
<i class="fa-solid fa-circle-info"></i>
<strong>{!! nl2br(e($message)) !!}</strong>
<button class="btn-close" data-bs-dismiss="alert" type="button" aria-label="{{ __('Fermer') }}"></button>
</div>
@endif
@if ($errors->any())
<div class="alert alert-danger alert-dismissible fade show m-0 mb-3" role="alert">
<p class="fw-bold m-0"><i class="fa-solid fa-circle-exclamation"></i>&nbsp;{{ __('Liste des erreurs :') }}</p>
@if ($errors->any())
<ul class="list-unstyled m-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
@endif
<button class="btn-close" data-bs-dismiss="alert" type="button" aria-label="{{ __('Fermer') }}"></button>
</div>
@endif
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="{{ __('Fermer') }}"></button>
</div>
@endif
@endif

View file

@ -1,8 +1,9 @@
@if($errors->has($inputName))
<div class="col-12">
<small class="text-danger">{{ implode(',', $errors->get($inputName)) }}</small>
</div>
@if ($errors->has($inputName))
<div class="col-12">
<small class="text-danger">{{ implode(',', $errors->get($inputName)) }}</small>
</div>
@endif
@if(isset($helper))
<small @if(isset($helperId)) id="{{ $helperId }}" @endif class="form-text text-body-secondary">{{ $helper }}</small>
@if (isset($helper))
<small class="form-text text-body-secondary"
@if (isset($helperId)) id="{{ $helperId }}" @endif>{{ $helper }}</small>
@endif

View file

@ -1,313 +0,0 @@
{{-- MINI CRUD EDIT WHEN JSON IS TRANSLATABLE --}}
@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::video->value))
@case(intval(App\Enums\InputType::videoVimeo->value))
@case(intval(App\Enums\InputType::videoYoutube->value))
<div class="col-12 col-md-6 mb-3">
<fieldset class="h-100 border 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'],
'hasWordCounter' => true,
'name' => 'data[' . $k . '][value]',
'value' => old("data.{$k}.value", $model->data[$k]['value'] ?? null),
'required' => isset($input['required']) ? !empty($input['required']) : true,
'model' => $model ?? null,
'helper' => match (intval($input['inputType'])) {
intval(App\Enums\InputType::videoYoutube->value) => __('video id eg: keZURbOo4-M'),
intval(App\Enums\InputType::videoVimeo->value) => __('video id eg: 74918975'),
intval(App\Enums\InputType::video->value) => __('video id eg: keZURbOo4-M or 74918975'),
},
])
@include('modules.input-error', [
'inputName' => "data.{$k}.value",
])
</div>
</div>
</fieldset>
</div>
@break
@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="h-100 border 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'],
'hasWordCounter' => true,
'name' => 'data[' . $k . '][value]',
'value' => old("data.{$k}.value", $model->data[$k]['value'] ?? null),
'required' => isset($input['required']) ? !empty($input['required']) : true,
'model' => $model ?? null,
'helper' => __('validation.between.string', [
'attribute' => $input['label'],
'min' => 3,
'max' => 255,
]),
])
@include('modules.input-error', [
'inputName' => "data.{$k}.value",
])
</div>
</div>
</fieldset>
</div>
@break
@case(intval(App\Enums\InputType::number->value))
<div class="row">
<div class="col">
<fieldset class="mb-3 border p-3">
<div class="d-flex justify-content-start align-items-center mb-2 flex-row">
<legend class="m-0 w-auto">
<label class="col-form-label" for="number{{ $k }}">
<b>{{ $input['label'] }}</b>
</label>
</legend>
@if (!empty($input['tooltip']))
<span class="ms-1" data-bs-toggle="tooltip" data-bs-html="true" title="{{ $input['tooltip'] }}">
<i class="fa fa-question-circle"></i>
</span>
@endif
</div>
<div class="row mb-3">
<div class="form-group">
<input class="form-control" id="number{{ $k }}" name="data[{{ $k }}][value]" type="number"
value="{{ old("data.{$k}.value") ?? ($input['value'] ?? '') }}" aria-describedby="NumberHelp{{ $k }}"
step="0.01" placeholder="{{ $input['label'] }}" @if (!isset($input['required']) or $input['required']) required @endif>
@include('back::modules.input-error', [
'inputName' => "data.{$k}.value",
'helperId' => "NumberHelp{$k}",
'helper' => $input['helper'] ?? '',
])
</div>
</div>
</fieldset>
</div>
</div>
@break
@case(intval(App\Enums\InputType::text->value))
<div class="col-12 mb-3">
<fieldset class="border 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' => old("data.{$k}.value", $model->data[$k]['value'] ?? null),
'model' => $model ?? null,
'helper' =>
__('crud.minicrud.text_warning') .
'. ' .
__('validation.min.string', [
'attribute' => $input['label'],
'min' => 3,
]),
])
@include('modules.input-error', [
'inputName' => "data.{$k}.value",
])
</div>
</div>
</fieldset>
</div>
@break
@case(intval(App\Enums\InputType::boolean->value))
<div class="col-12 col-md-6 mb-3">
<fieldset class="border p-3">
<legend>{{ $input['label'] }} *</legend>
<div class="row mb-3">
<div class="col-12">
<label class="col-form-label"
for="{{ Str::slug($input['label']) }}"><b>{{ __('crud.minicrud.visibility_label') }}</b></label>
<div class="form-check form-switch ms-2">
<input class="form-check-input ml-2" id="{{ Str::slug($input['label']) }}" name="data[{{ $k }}][value]"
type="checkbox" value="1" aria-describedby="{{ Str::slug($input['label']) }}Help"
@if (old("data.{$k}.value", old('_token') ? false : $model->data[$k]['value'] ?? (null ?? false))) checked @endif>
</div>
@include('modules.input-error', [
'inputName' => "data.{$k}.value",
'helperId' => Str::slug($input['label']) . 'Help',
'helper' => __('crud.minicrud.visibility_helper'),
])
</div>
</div>
</fieldset>
</div>
@break
@case(intval(App\Enums\InputType::image->value))
<div class="col-12 mb-3">
<fieldset class="h-100 border 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' => __('crud.minicrud.picture_alt_label'),
'hasWordCounter' => true,
'name' => 'data[' . $k . '][alt]',
'value' => old("data.{$k}.alt", $model->data[$k]['alt'] ?? null),
'required' => true,
'model' => $model ?? null,
'helper' =>
__('crud.minicrud.picture_alt_helper') .
'. ' .
__('validation.min.string', [
'attribute' => __('crud.minicrud.picture_alt_label'),
'min' => 3,
]),
])
@include('modules.input-error', [
'inputName' => "data.{$k}.alt",
])
</div>
{{-- PICTURE_TITLE --}}
<div class="col-12 col-md-6 mb-3">
@include('bo.partials.inputs.varchar', [
'id' => Str::slug($input['label']) . '-title',
'label' => __('crud.minicrud.picture_title_label'),
'hasWordCounter' => true,
'name' => 'data[' . $k . '][title]',
'value' => old("data.{$k}.title", $model->data[$k]['title'] ?? null),
'required' => true,
'model' => $model ?? null,
'helper' =>
__('crud.minicrud.picture_title_helper') .
'. ' .
__('validation.min.string', [
'attribute' => __('crud.minicrud.picture_title_label'),
'min' => 3,
]),
])
@include('modules.input-error', [
'inputName' => "data.{$k}.title",
])
</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' => old("data.{$k}.value", $model->data[$k]['value'] ?? null),
'helper' => __('crud.minicrud.dimensions_must_be', [
'width' => $input['dimensions']['width'],
'height' => $input['dimensions']['height'],
]),
'required' => true,
'preview' => true,
])
@include('modules.input-error', [
'inputName' => "data.{$k}.value",
])
</div>
</div>
</fieldset>
</div>
@break
@case(App\Enums\InputType::email->value)
<div class="row">
<div class="col">
<fieldset class="mb-3 border p-3">
<div class="d-flex justify-content-start align-items-center mb-2 flex-row">
<legend class="m-0 w-auto">
<label class="col-form-label" for="title{{ $k }}">
<b>{{ $input['label'] }}</b>
</label>
</legend>
@if (!empty($input['tooltip']))
<span class="ms-1" data-bs-toggle="tooltip" data-bs-html="true" title="{{ $input['tooltip'] }}">
<i class="fa fa-question-circle"></i>
</span>
@endif
</div>
<div class="row mb-3">
<div class="form-group">
<input class="form-control" id="title{{ $k }}" name="data[{{ $k }}][value]" type="email"
value="{{ old("data.{$k}.value") ?? ($input['value'] ?? '') }}" placeholder="{{ $input['label'] }}"
@if (!isset($input['required']) or $input['required']) required @endif>
@include('modules.input-error', [
'inputName' => "data.{$k}.value",
'helperId' => "{$k}StringHelp",
'helper' => $input['helper'] ?? '',
])
</div>
</div>
</fieldset>
</div>
</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="h-100 border p-3">
<legend>{{ $input['label'] }} *</legend>
<div class="row">
<div class="col-12 mb-3">
@include('bo.partials.inputs.tinyint-enum', [
'id' => Str::slug($input['label']),
'label' => __('crud.minicrud.associated_enum', ['enum' => $input['label']]),
'name' => "data[{$k}][value]",
'model' => $model ?? null,
'value' => old("data.{$k}.value", $model->data[$k]['value'] ?? null),
'required' => true,
'associatedModels' => $selectedEnum ?? [],
'helper' => __('crud.minicrud.select', ['entity' => $input['label']]),
])
@include('modules.input-error', [
'inputName' => "data.{$k}.value",
])
</div>
</div>
</fieldset>
</div>
@break
@default
@php throw new Exception('Input type not handled'); @endphp
@endswitch
@endforeach
@push('scripts')
<script nonce="{{ $nonce }}">
document.addEventListener('DOMContentLoaded', function() {
let minicrud = document.getElementById('minicrud').closest('form');
if (minicrud) {
minicrud.addEventListener('submit', function(e) {
document.querySelectorAll('input[type="file"]').forEach(function(input) {
if (input.dataset['old-value'] && !input.value) {
input.setAttribute('type', 'text');
input.value = input.getAttribute('old-value');
}
});
});
}
});
</script>
@endpush

View file

@ -1,4 +1,4 @@
<script @if(isset($nonce)) nonce="{{ $nonce }}" @endif>
<script @if (isset($nonce)) nonce="{{ $nonce }}" @endif>
if (!window.__SYSTEM) {
window.__SYSTEM = {};
}

View file

@ -1,29 +1,37 @@
<!DOCTYPE html>
<html dir="ltr" lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>@yield('title')</title>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>.tracking-wider{letter-spacing:.05em}</style>
<title>@yield('title')</title>
@vite(['resources/sass/fo/fo.scss'])
@stack('scripts')
</head>
<body>
<div class="bg-primary text-primary bg-opacity-25 bg-gradient d-flex align-items-start justify-content-center vh-100 align-items-sm-center pt-sm-0">
<div class="mx-auto px-sm-5">
<div class="text-opacity-75 d-flex align-items-center pt-5 justify-content-sm-start pt-sm-0">
<div class="px-4 display-5 border-primary-end-2 tracking-wider">
@yield('code')
</div>
<style>
.tracking-wider {
letter-spacing: .05em
}
</style>
<div class="text-opacity-75 ms-4 fs-5 text-uppercase tracking-wider">
@yield('message')
</div>
@vite(['resources/sass/fo/fo.scss'])
@stack('scripts')
</head>
<body>
<div
class="bg-primary text-primary bg-gradient d-flex align-items-start justify-content-center vh-100 align-items-sm-center pt-sm-0 bg-opacity-25">
<div class="px-sm-5 mx-auto">
<div class="d-flex align-items-center justify-content-sm-start pt-sm-0 pt-5 text-opacity-75">
<div class="display-5 border-primary-end-2 px-4 tracking-wider">
@yield('code')
</div>
<div class="fs-5 text-uppercase ms-4 tracking-wider text-opacity-75">
@yield('message')
</div>
</div>
</div>
</body>
</div>
</body>
</html>