Merge branch 'sprint_2' into 'develop'

Retour sprint 2

See merge request service-web-lab/loue!7
This commit is contained in:
Vincent BRIDIER 2022-08-26 10:26:44 +00:00
commit aa01a88379
17 changed files with 856 additions and 496 deletions

View file

@ -7,9 +7,12 @@ use Kwaadpepper\Enum\BaseEnum;
/**
* @method static self bio()
* @method static self lr()
* @method static self bea()
* @method static self nutriscore()
* @method static self bea_a()
* @method static self bea_b()
* @method static self nutriscore_a()
* @method static self nutriscore_b()
* @method static self planetscore()
* @method static self igp()
*/
final class ProductLabelEnum extends BaseEnum
{
@ -23,9 +26,12 @@ final class ProductLabelEnum extends BaseEnum
return [
'bio' => 0,
'lr' => 1,
'bea' => 2,
'nutriscore' => 3,
'planetscore' => 4
'bea_a' => 2,
'bea_b' => 3,
'nutriscore_a' => 4,
'nutriscore_b' => 5,
'planetscore' => 6,
'igp' => 7
];
}
@ -39,9 +45,12 @@ final class ProductLabelEnum extends BaseEnum
return [
'bio' => trans('Bio'),
'lr' => trans('Label Rouge'),
'bea' => trans('Bea'),
'nutriscore' => trans('Nutriscore'),
'bea_a' => trans('Bea A'),
'bea_b' => trans('Bea B'),
'nutriscore_a' => trans('Nutriscore A'),
'nutriscore_b' => trans('Nutriscore B'),
'planetscore' => trans('PlanetScore'),
'igp' => trans('IGP')
];
}
}

View file

@ -8,6 +8,7 @@ use Kwaadpepper\Enum\BaseEnum;
* @method static self poultry()
* @method static self egg()
* @method static self partners()
* @method static self fields()
*/
final class RangeCategoryEnum extends BaseEnum
{
@ -21,7 +22,8 @@ final class RangeCategoryEnum extends BaseEnum
return [
'poultry' => 0,
'egg' => 1,
'partners' => 2
'partners' => 2,
'fields' => 3
];
}
@ -33,9 +35,10 @@ final class RangeCategoryEnum extends BaseEnum
protected static function labels(): array
{
return [
'poultry' => trans('🐔 Vollaille'),
'poultry' => trans('🐔 Volaille'),
'egg' => trans('🥚 Oeuf'),
'partners' => trans('🤝 Produits partenaires'),
'fields' => trans('🌳 Plein champs'),
];
}
}

View file

@ -70,6 +70,7 @@ class StoreProductRequest extends FormRequest
'status' => 'required|boolean',
'range_id' => 'required|exists:ranges,id',
'ref_article' => 'required|numeric|min:0',
'ingredients' => 'required|string|min:15',
'preparation_advices' => 'required|string|min:15',
'sales_pitch' => 'required|string|min:15',
@ -97,6 +98,9 @@ class StoreProductRequest extends FormRequest
'saturated_fatty_acids' => 'required|numeric',
'dietary_fiber' => 'required|numeric',
'salt' => 'required|numeric',
'link1' => self::getUrlValidationRules(),
'link2' => self::getUrlValidationRules(),
],
$this->pictureRules('picture', 700, 700, 700, 700),
$this->pictureRules('picture_thumb', 300, 300, 300, 300)
@ -136,6 +140,35 @@ class StoreProductRequest extends FormRequest
'nutritional.saturated_fatty_acids' => trans('acides gras saturés'),
'nutritional.dietary_fiber' => trans('fibres alimentaires'),
'nutritional.salt' => trans('sel'),
'link1' => trans('lien 1'),
'link2' => trans('lien 2'),
];
}
/**
* Url validation rules
* Validates an internal url format
*
* @return array
*/
public static function getUrlValidationRules(): array
{
return ['nullable', function ($attribute, $value, $fail) {
$params = collect(\explode('#', \ltrim(\rtrim($value, '#'), '#')));
if (
!\in_array(
$params->get(0),
[Breeder::class, Recipe::class]
)
) {
$fail(trans('Invalid internal url'));
return;
}
// Check if model id exists. Param 0 is class, 1 is id.
if (!\forward_static_call([$params->get(0), 'find'], $params->get(1))) {
$fail(trans("$attribute n\'est plus un lien valide."));
}
}];
}
}

View file

@ -57,6 +57,7 @@ class StoreRangeRequest extends FormRequest
'seo_title' => 'required|min:45|max:70',
'seo_description' => 'required|min:50|max:160',
'description' => 'required|string|min:15',
'argumentation' => 'required|string|min:15',
'picture_alt' => 'required_with:picture|nullable|string|min:6|max:255',
'picture_title' => 'required_with:picture|nullable|string|min:6|max:255',
'picture_thumb_alt' => 'required_with:picture_thumb|nullable|string|min:6|max:255',
@ -85,6 +86,7 @@ class StoreRangeRequest extends FormRequest
'seo_title' => trans('title') . ' seo',
'seo_description' => trans('description') . ' seo',
'description' => trans('description'),
'argumentation' => trans('argumentation'),
'picture' => trans('illustration'),
'picture_alt' => trans('Texte alternatif de l\'illustration'),
'picture_title' => trans('Titre de l\'illustration'),
@ -107,7 +109,6 @@ class StoreRangeRequest extends FormRequest
*/
public static function getUrlValidationRules(): array
{
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
return ['nullable', function ($attribute, $value, $fail) {
$params = collect(\explode('#', \ltrim(\rtrim($value, '#'), '#')));
if (

View file

@ -31,6 +31,7 @@ class Product extends Model
'picture_thumb_title',
'picture_thumb_alt',
'labels',
'ref_article',
'ingredients',
'preparation_advices',
'sales_pitch',
@ -45,7 +46,9 @@ class Product extends Model
'show_sales_pitch',
'show_allergen_list',
'show_nutrionnal_values',
'show_portions'
'show_portions',
'link1',
'link2'
];
/**
@ -94,6 +97,12 @@ class Product extends Model
} else {
$model->unpublish_at = null;
}
if ($model->link1) {
self::validateLinkAttribute('link1', $model->link1);
}
if ($model->link2) {
self::validateLinkAttribute('link2', $model->link2);
}
});
static::updating(function (self $model) {
static::assertTitleIsUnique($model->title, $model->id);
@ -118,6 +127,12 @@ class Product extends Model
if ($model->picture_thumb != $model->getOriginal('picture_thumb')) {
$model->picture_thumb = ToolboxHelper::storeImage($model, $model->picture_thumb);
}
if ($model->link1) {
self::validateLinkAttribute('link1', $model->link1);
}
if ($model->link2) {
self::validateLinkAttribute('link2', $model->link2);
}
});
static::updated(function (self $model) {
ToolboxHelper::removeUnusedImagesOnCkEditor($model, 'description');

View file

@ -27,6 +27,7 @@ class Range extends Model
'seo_title',
'seo_description',
'description',
'argumentation',
'category',
'picture',
'picture_title',
@ -38,7 +39,7 @@ class Range extends Model
'publish_at',
'unpublish_at',
'link1',
'link2',
'link2'
];
/**
@ -73,8 +74,10 @@ class Range extends Model
static::creating(function (self $model) {
static::assertTitleIsUnique($model->title);
ToolboxHelper::assertNoInternalBoUrls('description', $model->description);
ToolboxHelper::assertNoInternalBoUrls('argumentation', $model->argumentation);
$model->slug = Str::slug($model->title);
$model->description = clean($model->description);
$model->argumentation = clean($model->argumentation);
$model->picture = ToolboxHelper::storeImage($model, $model->picture);
$model->picture_thumb = ToolboxHelper::storeImage($model, $model->picture_thumb);
if (!$model->status) {
@ -92,6 +95,7 @@ class Range extends Model
static::updating(function (self $model) {
static::assertTitleIsUnique($model->title, $model->id);
ToolboxHelper::assertNoInternalBoUrls('description', $model->description);
ToolboxHelper::assertNoInternalBoUrls('argumentation', $model->argumentation);
if ($model->picture != $model->getOriginal('picture')) {
$model->picture = ToolboxHelper::storeImage($model, $model->picture);
}

View file

@ -27,7 +27,7 @@ class ProductFactory extends Factory
'title' => $title,
'slug' => \Illuminate\Support\Str::slug($title),
'seo_title' => $this->faker->words(8, true),
'seo_description' => $this->faker->words(25, true),
'seo_description' => $this->faker->words(20, true),
'description' => $this->faker->words(25, true),
'picture' => '/assets/images/products/product_fake_700_700.jpg',
'picture_title' => $this->faker->words(8, true),
@ -36,6 +36,7 @@ class ProductFactory extends Factory
'picture_thumb_title' => $this->faker->words(8, true),
'picture_thumb_alt' => $this->faker->words(8, true),
'labels' => collect(ProductLabelEnum::toArray())->random(rand(0, 4))->all(),
'ref_article' => $this->faker->numberBetween(0, 1000000000),
'ingredients' => $this->faker->words(8, true),
'preparation_advices' => $this->faker->text(\mt_rand(15, 150)),
'sales_pitch' => $this->faker->text(\mt_rand(15, 150)),

View file

@ -28,8 +28,9 @@ class RangeFactory extends Factory
'title' => $title,
'slug' => Str::slug($title),
'seo_title' => $this->faker->words(8, true),
'seo_description' => $this->faker->words(25, true),
'seo_description' => $this->faker->words(20, true),
'description' => $this->faker->words(25, true),
'argumentation' => $this->faker->words(25, true),
'category' => collect(RangeCategoryEnum::toArray())->random(1)->get(0),
'picture' => '/assets/images/ranges/range_fake_700_700.jpg',
'picture_title' => $this->faker->words(8, true),

View file

@ -25,6 +25,7 @@ class CreateRangesTable extends Migration
->comment('Utilisé pour la balise méta description de la gamme. De 50 à 160 chars recommandés.');
$table->text('description')->comment('Description de la gamme');
$table->text('argumentation')->comment('Argumentation sur les labels');
$table->unsignedTinyInteger('category')->comment('Enum Ranges\\RangeCategoryEnum');

View file

@ -37,6 +37,7 @@ class CreateProductsTable extends Migration
$table->json('labels')->comment('List of Products\\ProductLabelEnum');
$table->text('ref_article')->comment('Ref. Article Inco');
$table->text('ingredients')->comment('Ingredients');
$table->text('preparation_advices')->comment('Preparation advices');
$table->text('sales_pitch')->comment('Arguments de vente');
@ -57,6 +58,11 @@ class CreateProductsTable extends Migration
$table->timestamp('unpublish_at')->nullable()
->comment('The date where the product status state should be set off.');
$table->string('link1')->nullable()
->comment('Category Link 1 #App\Models\Model#ID#, Sould be validated on store and update');
$table->string('link2')->nullable()
->comment('Category Link 2 #App\Models\Model#ID#, Sould be validated on store and update');
$table->foreignIdFor(Range::class)->constrained();
$table->timestamps();

2
package-lock.json generated
View file

@ -16988,4 +16988,4 @@
"dev": true
}
}
}
}

View file

@ -12,16 +12,14 @@
:filterable="true"
:searchable="true"
>
<template v-slot:option="{ option }: { option: VSelectProps }">
<template v-slot:option="{ label }: { label: string }">
{{
option.label.length >= _maxLength
? option.label.substring(0, _maxLength) + ".."
: option.label
label.length >= _maxLength
? label.substring(0, _maxLength) + ".."
: label
}}
</template>
<template
v-slot:no-options="{ search, searching }: { search: string, searching: boolean }"
>
<template v-slot:no-options="{ search, searching }: { search: string, searching: boolean }">
<template v-if="searching">
{{ __("Aucun résultat pour") }}
<em>{{ search }}</em> .
@ -218,8 +216,8 @@ export default defineComponent({
let label = String(response.data as string);
label =
label.length >= this._maxLength
? label.substring(0, this._maxLength) + ".."
: label;
? label.substring(0, this._maxLength) + ".."
: label;
if (label) {
this._value = this.parseResource({
class: model[0],

View file

@ -6,25 +6,30 @@
<div class="col-12 col-md-6 form-group">
<label for="productModelTitle" class="col-form-label"><b>{{ __('Titre') }}</b></label>
<div class="word-counter" data-json='@json(['id' => 'productModelTitle'])'></div>
<input name="title" type="text" value="{{ old('title', $productModel->title ?? '') }}" class="form-control"
id="productModelTitle" aria-describedby="productModelTitleHelp" placeholder="{{ __('Un titre beau et explicite') }}" required>
<input name="title" type="text" value="{{ old('title', $productModel->title ?? '') }}"
class="form-control" id="productModelTitle" aria-describedby="productModelTitleHelp"
placeholder="{{ __('Un titre beau et explicite') }}" required>
@include('back.modules.input-error', [
'inputName' => 'title', 'helperId' => 'productModelTitleHelp' , 'helper' => __('Doit décrire précisément le produit')
])
@include('back.modules.input-error', [
'inputName' => 'slug'
'inputName' => 'title',
'helperId' => 'productModelTitleHelp',
'helper' => __('Doit décrire précisément le produit'),
])
</div>
<div class="col-12 col-md-6 form-group">
<label for="productModelType" class="col-form-label"><b>{{ __('Gamme') }}</b></label>
<select id="productModelType" class="form-select" name="range_id" aria-describedby="productModelTypeHelp" required>
<option value="" @if(is_null(old('range_id', $productModel->range_id ?? null))) selected @endif disabled>{{ __('Séléctionnez une gamme') }}</option>
@foreach($ranges as $range)
<option value="{{ $range->id }}" @if(old('range_id', optional($productModel ?? null)->range_id) == $range->id) selected @endif>{{ $range->title }}</option>
<select id="productModelType" class="form-select" name="range_id"
aria-describedby="productModelTypeHelp" required>
<option value="" @if (is_null(old('range_id', $productModel->range_id ?? null))) selected @endif disabled>
{{ __('Séléctionnez une gamme') }}</option>
@foreach ($ranges as $range)
<option value="{{ $range->id }}" @if (old('range_id', optional($productModel ?? null)->range_id) == $range->id) selected @endif>
{{ $range->title }}</option>
@endforeach
</select>
@include('back.modules.input-error', [
'inputName' => 'range_id', 'helperId' => 'productModelTypeHelp' , 'helper' => __('La gamme du produit')
'inputName' => 'range_id',
'helperId' => 'productModelTypeHelp',
'helper' => __('La gamme du produit'),
])
</div>
</div>
@ -40,28 +45,40 @@
<div class="col-12 col-md-6 form-group">
<label for="productModelSeoTitle" class="col-form-label"><b>{{ __('Titre seo') }}</b></label>
<div class="word-counter" data-json='@json(['id' => 'productModelSeoTitle'])'></div>
<input name="seo_title" type="text" value="{{ old('seo_title', $productModel->seo_title ?? '') }}" class="form-control"
id="productModelSeoTitle" aria-describedby="productModelSeoTitleHelp" placeholder="{{ __('Un titre en 70 caractères maximum') }}" required>
<input name="seo_title" type="text"
value="{{ old('seo_title', $productModel->seo_title ?? '') }}" class="form-control"
id="productModelSeoTitle" aria-describedby="productModelSeoTitleHelp"
placeholder="{{ __('Un titre en 70 caractères maximum') }}" required>
@include('back.modules.input-error', [
'inputName' => 'seo_title', 'helperId' => 'productModelSeoTitleHelp' , 'helper' => __('Doit décrire précisément le produit, recommandation pour un positionnement optimal dans les moteurs de recherche : entre 53 et 60 caractères, balise <title> ')
'inputName' => 'seo_title',
'helperId' => 'productModelSeoTitleHelp',
'helper' => __(
'Doit décrire précisément le produit, recommandation pour un positionnement optimal dans les moteurs de recherche : entre 53 et 60 caractères, balise <title> '
),
])
</div>
<div class="col-12 col-md-6 form-group">
<label for="productModelSeoDescription" class="col-form-label"><b>{{ __('Description seo') }}</b></label>
<label for="productModelSeoDescription" class="col-form-label">
<b>{{ __('Description seo') }}</b>
</label>
@php
$data = [
'id' => 'productModelSeoDescription',
'class' => 'form-control',
'name' => 'seo_description',
'placeholder' => __('Une description du produit pour les moteurs de recherche'),
'ariaDescribedby' => 'productModelSeoDescriptionHelp',
'required' => true,
'value' => old('seo_description', $productModel->seo_description ?? '')
];
$data = [
'id' => 'productModelSeoDescription',
'class' => 'form-control',
'name' => 'seo_description',
'placeholder' => __('Une description du produit pour les moteurs de recherche'),
'ariaDescribedby' => 'productModelSeoDescriptionHelp',
'required' => true,
'value' => old('seo_description', $productModel->seo_description ?? ''),
];
@endphp
<div id="input-text-auto" data-json='@json($data)'></div>
@include('back.modules.input-error', [
'inputName' => 'seo_description', 'helperId' => 'productModelSeoDescriptionHelp' , 'helper' => __(' Doit décrire précisément le produit, requiert entre 50 et 160 caractères, balise <meta> description')
'inputName' => 'seo_description',
'helperId' => 'productModelSeoDescriptionHelp',
'helper' => __(
' Doit décrire précisément le produit, requiert entre 50 et 160 caractères, balise <meta> description'
),
])
</div>
</div>
@ -76,15 +93,17 @@
<div class="row mb-3">
<div class="col-12 form-group">
@php
$data = [
'name' => 'labels',
'value' => old('labels', $productModel->labels ?? []),
'tags' => App\Enums\Products\ProductLabelEnum::toArray(),
];
$data = [
'name' => 'labels',
'value' => old('labels', $productModel->labels ?? []),
'tags' => App\Enums\Products\ProductLabelEnum::toArray(),
];
@endphp
<div id="enum-tag-dropdown" data-json='@json($data)'></div>
@include('back.modules.input-error', [
'inputName' => 'labels', 'helperId' => 'newsModelTagsHelp' , 'helper' => __('Les labels associés au produit')
'inputName' => 'labels',
'helperId' => 'newsModelTagsHelp',
'helper' => __('Les labels associés au produit'),
])
</div>
</div>
@ -100,18 +119,33 @@
<div class="col">
<div class="form-group">
<label for="productPublishedAt"><b>{{ __('Date de publication (Europe/Paris)') }}</b></label>
<input id="productPublishedAt" name="publish_at" class="form-control publishTime" type="datetime-local" data-form-type="date" aria-describedby="productPublishAtHelp" value="{{ old('publish_at', ((isset($productModel) and $productModel->publish_at) ? $productModel->publish_at->format('Y-m-d\TH:i') : '')) }}">
<input id="productPublishedAt" name="publish_at" class="form-control publishTime"
type="datetime-local" data-form-type="date" aria-describedby="productPublishAtHelp"
value="{{ old('publish_at', (isset($productModel) and $productModel->publish_at) ? $productModel->publish_at->format('Y-m-d\TH:i') : '') }}">
@include('back.modules.input-error', [
'inputName' => 'publish_at', 'helperId' => 'productPublishAtHelp' , 'helper' => (isset($productModel) and $productModel->publish_at) ? __('Laisser vide pour un affichage immédiat du produit.') : __('Vider pour un affichage immédiat du produit')
'inputName' => 'publish_at',
'helperId' => 'productPublishAtHelp',
'helper' =>
(isset($productModel) and $productModel->publish_at)
? __('Laisser vide pour un affichage immédiat du produit.')
: __('Vider pour un affichage immédiat du produit'),
])
</div>
</div>
<div class="col">
<div class="form-group">
<label for="productUnPublishedAt"><b>{{ __('Date de fin de publication (Europe/Paris)') }}</b></label>
<input id="productUnPublishedAt" name="unpublish_at" class="form-control publishTime" type="datetime-local" data-form-type="date" aria-describedby="productUnPublishAtHelp" value="{{ old('unpublish_at', ((isset($productModel) and $productModel->unpublish_at) ? $productModel->unpublish_at->format('Y-m-d\TH:i') : '')) }}">
<label
for="productUnPublishedAt"><b>{{ __('Date de fin de publication (Europe/Paris)') }}</b></label>
<input id="productUnPublishedAt" name="unpublish_at" class="form-control publishTime"
type="datetime-local" data-form-type="date" aria-describedby="productUnPublishAtHelp"
value="{{ old('unpublish_at', (isset($productModel) and $productModel->unpublish_at) ? $productModel->unpublish_at->format('Y-m-d\TH:i') : '') }}">
@include('back.modules.input-error', [
'inputName' => 'unpublish_at', 'helperId' => 'productUnPublishAtHelp' , 'helper' => (isset($productModel) and $productModel->unpublish_at) ? __('Laisser vide pour un affichage permanent du produit.') : __('Vider pour un affichage permanent du produit')
'inputName' => 'unpublish_at',
'helperId' => 'productUnPublishAtHelp',
'helper' =>
(isset($productModel) and $productModel->unpublish_at)
? __('Laisser vide pour un affichage permanent du produit.')
: __('Vider pour un affichage permanent du produit'),
])
</div>
</div>
@ -126,37 +160,53 @@
<legend>{{ __('Illustration') }}</legend>
<div class="row mb-3">
<div class="col-12 col-md-6 form-group">
<label for="productPictureAlt" class="col-form-label"><b>{{ __('Texte alternatif de l\'image') }}</b></label>
<label for="productPictureAlt" class="col-form-label">
<b>{{ __('Texte alternatif de l\'image') }}</b>
</label>
<div class="word-counter" data-json='@json(['id' => 'productPictureAlt'])'></div>
<input name="picture_alt" type="text" value="{{ old('picture_alt', $productModel->picture_alt ?? '') }}" class="form-control"
id="productPictureAlt" aria-describedby="productPictureAltHelp" placeholder="{{ __('Une image de petits chatons') }}" required>
<input name="picture_alt" type="text"
value="{{ old('picture_alt', $productModel->picture_alt ?? '') }}" class="form-control"
id="productPictureAlt" aria-describedby="productPictureAltHelp"
placeholder="{{ __('Une image de petits chatons') }}" required>
@include('back.modules.input-error', [
'inputName' => 'picture_alt', 'helperId' => 'productPictureAltHelp' , 'helper' => __('Doit décrire votre image pour les moteurs de recherches et les non voyants (5 à 6 mots)')
'inputName' => 'picture_alt',
'helperId' => 'productPictureAltHelp',
'helper' => __(
'Doit décrire votre image pour les moteurs de recherches et les non voyants (5 à 6 mots)'
),
])
</div>
<div class="col-12 col-md-6 form-group">
<label for="productPictureTitle" class="col-form-label"><b>{{ __('Titre de l\'image') }}</b></label>
<label for="productPictureTitle" class="col-form-label">
<b>{{ __('Titre de l\'image') }}</b>
</label>
<div class="word-counter" data-json='@json(['id' => 'productPictureTitle'])'></div>
<input name="picture_title" type="text" value="{{ old('picture_title', $productModel->picture_title ?? '') }}" class="form-control"
id="productPictureTitle" aria-describedby="productPictureTitleHelp" placeholder="{{ __('Une description du produit pour les moteurs de recherche') }}" required>
<input name="picture_title" type="text"
value="{{ old('picture_title', $productModel->picture_title ?? '') }}" class="form-control"
id="productPictureTitle" aria-describedby="productPictureTitleHelp"
placeholder="{{ __('Une description du produit pour les moteurs de recherche') }}" required>
@include('back.modules.input-error', [
'inputName' => 'picture_title', 'helperId' => 'productPictureTitleHelp' , 'helper' => __('Utile pour les utilisateurs, s\'affiche en passant la souris sur l\'image.')
'inputName' => 'picture_title',
'helperId' => 'productPictureTitleHelp',
'helper' => __(
'Utile pour les utilisateurs, s\'affiche en passant la souris sur l\'image.'
),
])
</div>
</div>
<div class="row">
<div class="col-12">
@php
$data = [
'id' => 'productModelPicture',
'name' => 'picture',
'helper' => __('L\'image qui va servir de vignette à le produit, doit être de 700px (hauteur) par 700px (largeur)'),
'width' => 700,
'height' => 700,
'value' => $productModel->picture ?? '',
];
$data = [
'id' => 'productModelPicture',
'name' => 'picture',
'helper' => __('L\'image qui va servir de vignette à le produit, doit être de 700px (hauteur) par 700px (largeur)'),
'width' => 700,
'height' => 700,
'value' => $productModel->picture ?? '',
];
@endphp
@include('back.modules.input-error', [ 'inputName' => 'picture'])
@include('back.modules.input-error', ['inputName' => 'picture'])
<div class="image-input" data-json='@json($data)'></div>
</div>
</div>
@ -170,37 +220,55 @@
<legend>{{ __('Vignette') }}</legend>
<div class="row mb-3">
<div class="col-12 col-md-6 form-group">
<label for="productPictureThumbAlt" class="col-form-label"><b>{{ __('Texte alternatif de l\'image') }}</b></label>
<label for="productPictureThumbAlt" class="col-form-label">
<b>{{ __('Texte alternatif de l\'image') }}</b>
</label>
<div class="word-counter" data-json='@json(['id' => 'productPictureThumbAlt'])'></div>
<input name="picture_thumb_alt" type="text" value="{{ old('picture_thumb_alt', $productModel->picture_thumb_alt ?? '') }}" class="form-control"
id="productPictureThumbAlt" aria-describedby="productPictureThumbAltHelp" placeholder="{{ __('Une image de petits chatons') }}" required>
<input name="picture_thumb_alt" type="text"
value="{{ old('picture_thumb_alt', $productModel->picture_thumb_alt ?? '') }}"
class="form-control" id="productPictureThumbAlt"
aria-describedby="productPictureThumbAltHelp"
placeholder="{{ __('Une image de petits chatons') }}" required>
@include('back.modules.input-error', [
'inputName' => 'picture_thumb_alt', 'helperId' => 'productPictureThumbAltHelp' , 'helper' => __('Doit décrire votre image pour les moteurs de recherches et les non voyants (5 à 6 mots)')
'inputName' => 'picture_thumb_alt',
'helperId' => 'productPictureThumbAltHelp',
'helper' => __(
'Doit décrire votre image pour les moteurs de recherches et les non voyants (5 à 6 mots)'
),
])
</div>
<div class="col-12 col-md-6 form-group">
<label for="productPictureThumbTitle" class="col-form-label"><b>{{ __('Titre de l\'image') }}</b></label>
<label for="productPictureThumbTitle" class="col-form-label">
<b>{{ __('Titre de l\'image') }}</b>
</label>
<div class="word-counter" data-json='@json(['id' => 'productPictureThumbTitle'])'></div>
<input name="picture_thumb_title" type="text" value="{{ old('picture_thumb_title', $productModel->picture_thumb_title ?? '') }}" class="form-control"
id="productPictureThumbTitle" aria-describedby="productPictureThumbTitleHelp" placeholder="{{ __('Une description du produit pour les moteurs de recherche') }}" required>
<input name="picture_thumb_title" type="text"
value="{{ old('picture_thumb_title', $productModel->picture_thumb_title ?? '') }}"
class="form-control" id="productPictureThumbTitle"
aria-describedby="productPictureThumbTitleHelp"
placeholder="{{ __('Une description du produit pour les moteurs de recherche') }}" required>
@include('back.modules.input-error', [
'inputName' => 'picture_thumb_title', 'helperId' => 'productPictureThumbTitleHelp' , 'helper' => __('Utile pour les utilisateurs, s\'affiche en passant la souris sur l\'image.')
'inputName' => 'picture_thumb_title',
'helperId' => 'productPictureThumbTitleHelp',
'helper' => __(
'Utile pour les utilisateurs, s\'affiche en passant la souris sur l\'image.'
),
])
</div>
</div>
<div class="row">
<div class="col-12">
@php
$data = [
'id' => 'productModelThumbPicture',
'name' => 'picture_thumb',
'helper' => __('L\'image qui va servir de vignette à le produit, doit être de 300px (hauteur) par 300px (largeur)'),
'width' => 300,
'height' => 300,
'value' => $productModel->picture_thumb ?? '',
];
$data = [
'id' => 'productModelThumbPicture',
'name' => 'picture_thumb',
'helper' => __('L\'image qui va servir de vignette à le produit, doit être de 300px (hauteur) par 300px (largeur)'),
'width' => 300,
'height' => 300,
'value' => $productModel->picture_thumb ?? '',
];
@endphp
@include('back.modules.input-error', [ 'inputName' => 'picture_thumb'])
@include('back.modules.input-error', ['inputName' => 'picture_thumb'])
<div class="image-input" data-json='@json($data)'></div>
</div>
</div>
@ -215,13 +283,15 @@
<div class="row mb-3">
<div class="col-12 form-group">
@include('back.modules.input-error', [
'inputName' => 'description', 'helperId' => 'productModelDescriptionHelp' , 'helper' => __('Relisez bien votre description avant de la publier.')
'inputName' => 'description',
'helperId' => 'productModelDescriptionHelp',
'helper' => __('Relisez bien votre description avant de la publier.'),
])
@php
$data = [
'name' => 'description',
'text' => old('description', $productModel->description ?? ''),
];
$data = [
'name' => 'description',
'text' => old('description', $productModel->description ?? ''),
];
@endphp
<div class="ck-editor-bo" data-json='@json($data)'></div>
</div>
@ -234,44 +304,71 @@
<div class="col">
<fieldset class="border p-3 mb-3">
<legend>{{ __('Informations Inco') }}</legend>
@php $attributes = [
'ingredients' => __('Ingrédients'),
'preparation_advices' => __('Conseils de préparation'),
'sales_pitch' => __('Arguments de vente'),
'allergen_list' => __('Liste d\'allergènes')
]; @endphp
@foreach($attributes as $attribute => $helperText)
<div class="row mb-3">
<div class="col-12 form-group">
<span class="h6 fw-bold d-inline-block mb-2">{{ $helperText }}</span>
<div class="form-check form-switch d-inline-block ms-5">
<input class="form-check-input" name="{{ "show_{$attribute}" }}" type="checkbox" role="switch" id="{{ "{$attribute}Switch" }}" value="1" @if(old("show_{$attribute}", $productModel->{"show_{$attribute}"} ?? null)) checked @endif>
<label class="form-check-label" for="{{ "{$attribute}Switch" }}"><span class="fw-bold fst-italic">{{ __('Afficher ? ') }}</span></label>
</div>
@include('back.modules.input-error', [
'inputName' => $attribute
])
@php
$data = [
'name' => $attribute,
'text' => old($attribute, $productModel->{$attribute} ?? ''),
];
@endphp
<div class="ck-editor-bo" data-json='@json($data)'></div>
</div>
<div class="col-12 col-md-6 form-group">
<label for="productModelPortions"
class="col-form-label d-inline-block"><b>{{ __('Ref. Article INCO') }}</b></label>
<input name="ref_article" type="number"
value="{{ old('ref_article', $productModel->ref_article ?? 0) }}" class="form-control"
id="productModelPortions" aria-describedby="productModelPortionsHelp" min="0"
step="1" required>
@include('back.modules.input-error', [
'inputName' => 'ref_article',
'helperId' => 'productModelRefHelp',
'helper' => __('Code de l\'article dans la base INCO'),
])
</div>
@php
$attributes = [
'ingredients' => __('Ingrédients'),
'preparation_advices' => __('Conseils de préparation'),
'sales_pitch' => __('Arguments de vente'),
'allergen_list' => __('Liste d\'allergènes'),
];
@endphp
@foreach ($attributes as $attribute => $helperText)
<div class="row mb-3">
<div class="col-12 form-group">
<span class="h6 fw-bold d-inline-block mb-2">{{ $helperText }}</span>
<div class="form-check form-switch d-inline-block ms-5">
<input class="form-check-input" name="{{ "show_{$attribute}" }}" type="checkbox"
role="switch" id="{{ "{$attribute}Switch" }}" value="1"
@if (old("show_{$attribute}", $productModel->{"show_{$attribute}"} ?? null)) checked @endif>
<label class="form-check-label" for="{{ "{$attribute}Switch" }}">
<span class="fw-bold fst-italic">{{ __('Afficher ? ') }}</span>
</label>
</div>
@include('back.modules.input-error', [
'inputName' => $attribute,
])
@php
$data = [
'name' => $attribute,
'text' => old($attribute, $productModel->{$attribute} ?? ''),
];
@endphp
<div class="ck-editor-bo" data-json='@json($data)'></div>
</div>
</div>
@endforeach
<div class="row mb-3">
<div class="col-12 col-md-6 form-group">
<label for="productModelPortions" class="col-form-label d-inline-block"><b>{{ __('Nombre de portions') }}</b></label>
<label for="productModelPortions"
class="col-form-label d-inline-block"><b>{{ __('Nombre de portions') }}</b></label>
<div class="form-check form-switch d-inline-block ms-5">
<input class="form-check-input" name="show_portions" type="checkbox" role="switch" id="portionsSwitch" value="1" @if(old('show_portions', $productModel->show_portions ?? null)) checked @endif>
<label class="form-check-label" for="portionsSwitch"><span class="fw-bold fst-italic">{{ __('Afficher ? ') }}</span></label>
<input class="form-check-input" name="show_portions" type="checkbox" role="switch"
id="portionsSwitch" value="1" @if (old('show_portions', $productModel->show_portions ?? null)) checked @endif>
<label class="form-check-label" for="portionsSwitch">
<span class="fw-bold fst-italic">{{ __('Afficher ? ') }}</span>
</label>
</div>
<input name="number_portion" type="number" value="{{ old('number_portion', $productModel->number_portion ?? 0) }}" class="form-control"
id="productModelPortions" aria-describedby="productModelPortionsHelp" min="0" step="1" required>
<input name="number_portion" type="number"
value="{{ old('number_portion', $productModel->number_portion ?? 0) }}" class="form-control"
id="productModelPortions" aria-describedby="productModelPortionsHelp" min="0"
step="1" required>
@include('back.modules.input-error', [
'inputName' => 'number_portion', 'helperId' => 'productModelPortionsHelp' , 'helper' => __('Nombre de portions du produit')
'inputName' => 'number_portion',
'helperId' => 'productModelPortionsHelp',
'helper' => __('Nombre de portions du produit'),
])
</div>
</div>
@ -279,11 +376,14 @@
<div class="row">
<label class="h6 fw-bold d-inline-block">{{ __('Valeurs nutritionelles') }}</label>
<div class="form-check form-switch d-inline-block ms-5">
<input class="form-check-input" name="show_nutrionnal_values" type="checkbox" role="switch" id="nutrionnaSwitch" value="1" @if(old('show_nutrionnal_values', $productModel->show_nutrionnal_values ?? null)) checked @endif>
<label class="form-check-label" for="nutrionnaSwitch"><span class="fw-bold fst-italic">{{ __('Afficher ? ') }}</span></label>
<input class="form-check-input" name="show_nutrionnal_values" type="checkbox" role="switch"
id="nutrionnaSwitch" value="1" @if (old('show_nutrionnal_values', $productModel->show_nutrionnal_values ?? null)) checked @endif>
<label class="form-check-label" for="nutrionnaSwitch">
<span class="fw-bold fst-italic">{{ __('Afficher ? ') }}</span>
</label>
</div>
@php
$incoNut = (isset($productModel) and $productModel->xmlInco) ? json_decode($productModel->xmlInco->nutritional_values) : null;
$incoNut = (isset($productModel) and $productModel->xmlInco) ? json_decode($productModel->xmlInco->nutritional_values) : null;
@endphp
<div class="table-responsive">
<table class="table table-light text-center table-sm table-bordered table-striped">
@ -291,56 +391,118 @@
<tr>
<th scope="col">Nutriment</th>
<th scope="col">Valeur</th>
@if(isset($incoNut))
<th scope="col">Val. Source Inco</th>
@if (isset($incoNut))
<th scope="col">Val. Source Inco</th>
@endif
</tr>
</thead>
<tbody class="table-group-divider">
@php $incoValues = [
'Poids de référence (en g)' => ['product' => 'weight', 'inco' => ''],
'Énergie (en kCal)' => ['product' => 'energy', 'inco' => 'val_energ_kcal_r'],
'Énergie (en kJ)' => ['product' => 'energy_kj', 'inco' => 'val_energ_kj_r'],
'Protéines (en g)' => ['product' => 'protein', 'inco' => 'proteine_r'],
'Glucides (en g)' => ['product' => 'carbohydrates', 'inco' => 'glucides_r'],
'Sucres (en g)' => ['product' => 'sugar', 'inco' => 'sucre_r'],
'Matière grasse (en g)' => ['product' => 'fat', 'inco' => 'mat_grass_r'],
'Acides Gras Saturés (en g)' => ['product' => 'saturated_fatty_acids', 'inco' => 'ags_r'],
'Fibres alimentaires (en g)' => ['product' => 'dietary_fiber', 'inco' => 'fib_alim_r'],
'Sel (en g)' => ['product' => 'salt', 'inco' => 'sel_r']
]; @endphp
@foreach($incoValues as $title => $incoValue)
<tr>
<td class="w-50">{{ $title }}</td>
<td class="w-25"><input class="form-control form-control-sm w-100 h-100" type="number" step="1" name="{{ $incoValue['product'] }}" value="{{ old($incoValue['product'], isset($productModel->incoNutritionalValues->{$incoValue['product']}) ? str_replace(',', '.', (string)$productModel->incoNutritionalValues->{$incoValue['product']}) : 0) }}"></td>
@if(isset($incoNut))
<td class="w-25"><span class="text-danger">{{ isset($incoNut->{$incoValue['inco']}) ? str_replace(',', '.', $incoNut->{$incoValue['inco']}) : 0 }}</span></td>
@endif
</tr>
@php
$incoValues = [
'Poids de référence (en g)' => ['product' => 'weight', 'inco' => ''],
'Énergie (en kCal)' => ['product' => 'energy', 'inco' => 'val_energ_kcal_r'],
'Énergie (en kJ)' => ['product' => 'energy_kj', 'inco' => 'val_energ_kj_r'],
'Protéines (en g)' => ['product' => 'protein', 'inco' => 'proteine_r'],
'Glucides (en g)' => ['product' => 'carbohydrates', 'inco' => 'glucides_r'],
'Sucres (en g)' => ['product' => 'sugar', 'inco' => 'sucre_r'],
'Matière grasse (en g)' => ['product' => 'fat', 'inco' => 'mat_grass_r'],
'Acides Gras Saturés (en g)' => ['product' => 'saturated_fatty_acids', 'inco' => 'ags_r'],
'Fibres alimentaires (en g)' => ['product' => 'dietary_fiber', 'inco' => 'fib_alim_r'],
'Sel (en g)' => ['product' => 'salt', 'inco' => 'sel_r'],
];
@endphp
@foreach ($incoValues as $title => $incoValue)
<tr>
<td class="w-50">
{{ $title }}
</td>
<td class="w-25">
<input class="form-control form-control-sm w-100 h-100" type="number"
step="1" name="{{ $incoValue['product'] }}"
value="{{ old($incoValue['product'], isset($productModel->incoNutritionalValues->{$incoValue['product']}) ? str_replace(',', '.', (string) $productModel->incoNutritionalValues->{$incoValue['product']}) : 0) }}">
</td>
@if (isset($incoNut))
<td class="w-25">
<span class="text-danger">
{{ isset($incoNut->{$incoValue['inco']}) ? str_replace(',', '.', $incoNut->{$incoValue['inco']}) : 0 }}
</span>
</td>
@endif
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@if(isset($productModel) and isset($productModel->xmlInco))
<div class="row justify-content-center">
<div class="col-12 col-md-5 text-center">
<a href="#" class="btn btn-danger confirmJS">{{ __('Copier les Valeurs nutritionelles') }}</a>
@if (isset($productModel) and isset($productModel->xmlInco))
<div class="row justify-content-center">
<div class="col-12 col-md-5 text-center">
<a href="#" class="btn btn-danger confirmJS">
{{ __('Copier les Valeurs nutritionelles') }}
</a>
</div>
</div>
</div>
@endif
</div>
</fieldset>
</div>
</div>
<div class="row">
<div class="col">
<fieldset class="border p-3 mb-3">
<legend>{{ __('Liens') }}</legend>
<div class="row mb-3">
<div class="col-12 form-group">
@include('back.modules.input-error', [
'inputName' => 'link1',
'helperId' => 'productModelLink1Help',
'helper' => __('Lien à afficher sur la gamme'),
])
@php
$data = [
'name' => 'link1',
'placeholder' => __('lien numéro 1'),
'value' => old('link1', $productModel->link1 ?? null),
];
@endphp
<div class="model-link" data-json='@json($data)'></div>
</div>
</div>
<div class="row mb-3">
<div class="col-12 form-group">
@include('back.modules.input-error', [
'inputName' => 'link2',
'helperId' => 'productModelLink1Help',
'helper' => __('Lien à afficher sur la gamme'),
])
@php
$data = [
'name' => 'link2',
'placeholder' => __('lien numéro 2'),
'value' => old('link2', $productModel->link2 ?? null),
];
@endphp
<div class="model-link" data-json='@json($data)'></div>
</div>
</div>
</fieldset>
</div>
</div>
<div class="row mb-3">
<div class="col-12 col-md-6">
<div class="form-check">
<input name="status" class="form-check-input mt-2" type="checkbox" id="productStatus" aria-describedby="productStatusHelp" value="1" @if(old('status', $productModel->status ?? ''))checked @endif>
<label class="form-check-label user-select-none pt-1" for="productStatus"><b>{{ __('Publié') }}</b></label><br>
<input name="status" class="form-check-input mt-2" type="checkbox" id="productStatus"
aria-describedby="productStatusHelp" value="1" @if (old('status', $productModel->status ?? '')) checked @endif>
<label class="form-check-label user-select-none pt-1" for="productStatus">
<b>{{ __('Publié') }}</b>
</label>
<br>
@include('back.modules.input-error', [
'inputName' => 'status', 'helperId' => 'productStatusHelp' , 'helper' => __('Le produit est visible ou non')
'inputName' => 'status',
'helperId' => 'productStatusHelp',
'helper' => __('Le produit est visible ou non'),
])
</div>
</div>
@ -348,68 +510,69 @@
@push('scripts')
<script nonce="{{ $nonce }}">
document.addEventListener("DOMContentLoaded", () => {
// Publish times
let publishTimes = document.getElementsByClassName('publishTime');
for (let input of publishTimes) {
let parent = input.parentNode,
dates = {
start: 0,
end: 0
};
input.originalValue = (new Date(input.value)).valueOf();
if(input.originalValue === NaN) {
input.originalValue = 0
}
if(input.id === 'productPublishedAt') {
dates.start = input.originalValue;
} else {
dates.end = input.originalValue;
}
let getEuropeParisTime = () => {
return new Date((new Date()).getTime() + (60000*((new Date()).getTimezoneOffset()+60)));
};
let setDateHelpers = (input, parent) => {
let small = parent.children.productPublishAtHelp ? parent.children.productPublishAtHelp : parent.children.productUnPublishAtHelp;
let isPlanned = false;
if(input.id === 'productPublishedAt') {
isPlanned = dates.start > dates.end && dates.end != 0;
} else {
isPlanned = dates.start < dates.end && dates.start != 0;
<script nonce="{{ $nonce }}">
document.addEventListener("DOMContentLoaded", () => {
// Publish times
let publishTimes = document.getElementsByClassName('publishTime');
for (let input of publishTimes) {
let parent = input.parentNode,
dates = {
start: 0,
end: 0
};
input.originalValue = (new Date(input.value)).valueOf();
if (input.originalValue === NaN) {
input.originalValue = 0
}
if (input.id === 'productPublishedAt') {
dates.start = input.originalValue;
} else {
dates.end = input.originalValue;
}
let getEuropeParisTime = () => {
return new Date((new Date()).getTime() + (60000 * ((new Date()).getTimezoneOffset() + 60)));
};
let setDateHelpers = (input, parent) => {
let small = parent.children.productPublishAtHelp ? parent.children.productPublishAtHelp :
parent.children.productUnPublishAtHelp;
let isPlanned = false;
if (input.id === 'productPublishedAt') {
isPlanned = dates.start > dates.end && dates.end != 0;
} else {
isPlanned = dates.start < dates.end && dates.start != 0;
}
if (isPlanned || getEuropeParisTime().valueOf() < (new Date(input.value)).valueOf()) {
let date = new Date(input.value);
// small.textContent = "{{ __('Planifié pour le ') }}" + date.toLocaleString();
small.textContent = input.id === 'productPublishedAt' ?
"{{ __('Vider pour un affichage immédiat du produit.') }}" :
"{{ __('Vider pour un affichage permanent du produit.') }}";
} else {
// small.textContent = input.id === 'productPublishedAt' ?
// "{{ __('Uniquement pour planifier la publication') }}" :
// "{{ __('Uniquement pour planifier la fin de la publication') }}";
small.textContent = input.id === 'productPublishedAt' ?
"{{ __('Laisser vide pour un affichage immédiat du produit.') }}" :
"{{ __('Laisser vide pour un affichage permanent du produit.') }}";
}
};
setDateHelpers(input, parent);
input.addEventListener('change', (event) => {
let parent = event.target.parentNode,
input = event.target,
value;
value = (new Date(input.value)).valueOf();
if (input.originalValue === NaN) {
value = 0
}
if (input.id === 'productPublishedAt') {
dates.start = value;
} else {
dates.end = value;
}
setDateHelpers(input, parent);
});
}
if (isPlanned || getEuropeParisTime().valueOf() < (new Date(input.value)).valueOf()) {
let date = new Date(input.value);
// small.textContent = "{{ __('Planifié pour le ') }}" + date.toLocaleString();
small.textContent = input.id === 'productPublishedAt' ?
"{{ __('Vider pour un affichage immédiat du produit.') }}" :
"{{ __('Vider pour un affichage permanent du produit.') }}";
} else {
// small.textContent = input.id === 'productPublishedAt' ?
// "{{ __('Uniquement pour planifier la publication') }}" :
// "{{ __('Uniquement pour planifier la fin de la publication') }}";
small.textContent = input.id === 'productPublishedAt' ?
"{{ __('Laisser vide pour un affichage immédiat du produit.') }}" :
"{{ __('Laisser vide pour un affichage permanent du produit.') }}";
}
};
setDateHelpers(input, parent);
input.addEventListener('change', (event) => {
let parent = event.target.parentNode,
input = event.target, value;
value = (new Date(input.value)).valueOf();
if(input.originalValue === NaN) {
value = 0
}
if(input.id === 'productPublishedAt') {
dates.start = value;
} else {
dates.end = value;
}
setDateHelpers(input, parent);
});
}
});
</script>
</script>
@endpush

View file

@ -2,7 +2,8 @@
@section('title', sprintf('%s - %s %s', __('models.classes.ranges'), Str::ucfirst(__('édition')), $rangeModel->title))
@section('breadcrumb', request()->route()->getName())
@section('breadcrumb',
request()->route()->getName())
@section('content')
<div class="card">
@ -10,31 +11,43 @@
<div class="row">
<div class="col-12">
@include('back.breadcrumb.breadcrumb-body', [
'brParam' => $rangeModel
'brParam' => $rangeModel,
])
</div>
</div>
<div class="row">
<div class="col">
<h1 class="col h4">
<a href="{{ route('bo.ranges.index') }}" class="text-decoration-none btn btn-sm btn-primary" role="button" aria-roledescription="{{ _('Revenir en arrière') }}"><i class="fa-solid fa-arrow-left-long"></i></a>
<a href="{{ route('bo.ranges.index') }}" class="text-decoration-none btn btn-sm btn-primary"
role="button" aria-roledescription="{{ _('Revenir en arrière') }}">
<i class="fa-solid fa-arrow-left-long"></i>
</a>
<span>&nbsp;{{ __('models.classes.ranges') }}&nbsp;{{ __('édition') }}</span>
</h1>
</div>
<div class="col text-end">
<form action="{{ route('bo.ranges.destroy', $rangeModel->id) }}" method="POST" class="d-inline confirmDeleteJS">
<form action="{{ route('bo.ranges.destroy', $rangeModel->id) }}" method="POST"
class="d-inline confirmDeleteJS">
@method('DELETE')
@csrf
<div class="btn-group" role="group">
{{-- Public View Page --}}
@if($rangeModel->status)
<a class="btn btn-warning" href="" target="_blank" title="{{ __('Visualiser :model', [
'model' => Str::singular(__('models.classes.ranges'))
]) }}" data-bs-toggle="tooltip"><i class="fa-solid fa-eye"></i></a>
@if ($rangeModel->status)
<a class="btn btn-warning" href="" target="_blank"
title="{{ __('Visualiser :model', [
'model' => Str::singular(__('models.classes.ranges')),
]) }}"
data-bs-toggle="tooltip">
<i class="fa-solid fa-eye"></i>
</a>
@endif
<button class="btn btn-danger" title="{{ __('Supprimer :model', [
'model' => Str::singular(__('models.classes.ranges'))
]) }}" data-bs-toggle="tooltip"><i class="fa-solid fa-trash"></i></button>
<button class="btn btn-danger"
title="{{ __('Supprimer :model', [
'model' => Str::singular(__('models.classes.ranges')),
]) }}"
data-bs-toggle="tooltip">
<i class="fa-solid fa-trash"></i>
</button>
</div>
</form>
</div>
@ -45,9 +58,11 @@
@csrf
@method('PUT')
@include('back.ranges.form', compact('rangeModel'))
<button type="submit" class="btn btn-primary" title="{{ __('Enregister :model en base', [
'model' => Str::singular(__('models.classes.ranges'))
]) }}" data-bs-toggle="tooltip">{{ __('Enregister') }}</button>
<button type="submit" class="btn btn-primary"
title="{{ __('Enregister :model en base', [
'model' => Str::singular(__('models.classes.ranges')),
]) }}"
data-bs-toggle="tooltip">{{ __('Enregister') }}</button>
</form>
</div>
</div>

View file

@ -6,25 +6,33 @@
<div class="col-12 col-md-6 form-group">
<label for="rangeModelTitle" class="col-form-label"><b>{{ __('Titre') }}</b></label>
<div class="word-counter" data-json='@json(['id' => 'rangeModelTitle'])'></div>
<input name="title" type="text" value="{{ old('title', $rangeModel->title ?? '') }}" class="form-control"
id="rangeModelTitle" aria-describedby="rangeModelTitleHelp" placeholder="{{ __('Un titre beau et explicite') }}" required>
<input name="title" type="text" value="{{ old('title', $rangeModel->title ?? '') }}"
class="form-control" id="rangeModelTitle" aria-describedby="rangeModelTitleHelp"
placeholder="{{ __('Un titre beau et explicite') }}" required>
@include('back.modules.input-error', [
'inputName' => 'title', 'helperId' => 'rangeModelTitleHelp' , 'helper' => __('Doit décrire précisément la gamme')
'inputName' => 'title',
'helperId' => 'rangeModelTitleHelp',
'helper' => __('Doit décrire précisément la gamme'),
])
@include('back.modules.input-error', [
'inputName' => 'slug'
'inputName' => 'slug',
])
</div>
<div class="col-12 col-md-6 form-group">
<label for="rangeCategory" class="col-form-label"><b>{{ __('Catégorie de la gamme') }}</b></label>
<select id="rangeCategory" class="form-select" name="category" aria-describedby="rangeCategoryHelp" required>
<option value="" @if(is_null(old('category', $rangeModel->category ?? null))) selected @endif disabled>{{ __('Séléctionnez une catégorie') }}</option>
@foreach(App\Enums\Ranges\RangeCategoryEnum::toArray() as $category)
<option value="{{ $category->value }}" @if(old('type', optional($rangeModel->category ?? null)->value) == $category->value) selected @endif>{{ $category->label }}</option>
<select id="rangeCategory" class="form-select" name="category" aria-describedby="rangeCategoryHelp"
required>
<option value="" @if (is_null(old('category', $rangeModel->category ?? null))) selected @endif disabled>
{{ __('Séléctionnez une catégorie') }}</option>
@foreach (App\Enums\Ranges\RangeCategoryEnum::toArray() as $category)
<option value="{{ $category->value }}" @if (old('type', optional($rangeModel->category ?? null)->value) == $category->value) selected @endif>
{{ $category->label }}</option>
@endforeach
</select>
@include('back.modules.input-error', [
'inputName' => 'category', 'helperId' => 'rangeCategoryHelp' , 'helper' => __('Le type de gamme')
'inputName' => 'category',
'helperId' => 'rangeCategoryHelp',
'helper' => __('Le type de gamme'),
])
</div>
</div>
@ -40,28 +48,38 @@
<div class="col-12 col-md-6 form-group">
<label for="rangeModelSeoTitle" class="col-form-label"><b>{{ __('Titre seo') }}</b></label>
<div class="word-counter" data-json='@json(['id' => 'rangeModelSeoTitle'])'></div>
<input name="seo_title" type="text" value="{{ old('seo_title', $rangeModel->seo_title ?? '') }}" class="form-control"
id="rangeModelSeoTitle" aria-describedby="rangeModelSeoTitleHelp" placeholder="{{ __('Un titre en 70 caractères maximum') }}" required>
<input name="seo_title" type="text" value="{{ old('seo_title', $rangeModel->seo_title ?? '') }}"
class="form-control" id="rangeModelSeoTitle" aria-describedby="rangeModelSeoTitleHelp"
placeholder="{{ __('Un titre en 70 caractères maximum') }}" required>
@include('back.modules.input-error', [
'inputName' => 'seo_title', 'helperId' => 'rangeModelSeoTitleHelp' , 'helper' => __('Doit décrire précisément la gamme, recommandation pour un positionnement optimal dans les moteurs de recherche : entre 53 et 60 caractères, balise <title> ')
'inputName' => 'seo_title',
'helperId' => 'rangeModelSeoTitleHelp',
'helper' => __(
'Doit décrire précisément la gamme, recommandation pour un positionnement optimal dans les moteurs de recherche : entre 53 et 60 caractères, balise <title> '
),
])
</div>
<div class="col-12 col-md-6 form-group">
<label for="rangeModelSeoDescription" class="col-form-label"><b>{{ __('Description seo') }}</b></label>
<label for="rangeModelSeoDescription"
class="col-form-label"><b>{{ __('Description seo') }}</b></label>
@php
$data = [
'id' => 'rangeModelSeoDescription',
'class' => 'form-control',
'name' => 'seo_description',
'placeholder' => __('Une description de la gamme pour les moteurs de recherche'),
'ariaDescribedby' => 'rangeModelSeoDescriptionHelp',
'required' => true,
'value' => old('seo_description', $rangeModel->seo_description ?? '')
];
$data = [
'id' => 'rangeModelSeoDescription',
'class' => 'form-control',
'name' => 'seo_description',
'placeholder' => __('Une description de la gamme pour les moteurs de recherche'),
'ariaDescribedby' => 'rangeModelSeoDescriptionHelp',
'required' => true,
'value' => old('seo_description', $rangeModel->seo_description ?? ''),
];
@endphp
<div id="input-text-auto" data-json='@json($data)'></div>
@include('back.modules.input-error', [
'inputName' => 'seo_description', 'helperId' => 'rangeModelSeoDescriptionHelp' , 'helper' => __(' Doit décrire précisément la gamme, requiert entre 50 et 160 caractères, balise <meta> description')
'inputName' => 'seo_description',
'helperId' => 'rangeModelSeoDescriptionHelp',
'helper' => __(
'Doit décrire précisément la gamme, requiert entre 50 et 160 caractères, balise <meta> description'
),
])
</div>
</div>
@ -77,18 +95,33 @@
<div class="col">
<div class="form-group">
<label for="rangePublishedAt"><b>{{ __('Date de publication (Europe/Paris)') }}</b></label>
<input id="rangePublishedAt" name="publish_at" class="form-control publishTime" type="datetime-local" data-form-type="date" aria-describedby="rangePublishAtHelp" value="{{ old('publish_at', ((isset($rangeModel) and $rangeModel->publish_at) ? $rangeModel->publish_at->format('Y-m-d\TH:i') : '')) }}">
<input id="rangePublishedAt" name="publish_at" class="form-control publishTime"
type="datetime-local" data-form-type="date" aria-describedby="rangePublishAtHelp"
value="{{ old('publish_at', (isset($rangeModel) and $rangeModel->publish_at) ? $rangeModel->publish_at->format('Y-m-d\TH:i') : '') }}">
@include('back.modules.input-error', [
'inputName' => 'publish_at', 'helperId' => 'rangePublishAtHelp' , 'helper' => (isset($rangeModel) and $rangeModel->publish_at) ? __('Laisser vide pour un affichage immédiat de la gamme.') : __('Vider pour un affichage immédiat de la gamme')
'inputName' => 'publish_at',
'helperId' => 'rangePublishAtHelp',
'helper' =>
(isset($rangeModel) and $rangeModel->publish_at)
? __('Laisser vide pour un affichage immédiat de la gamme.')
: __('Vider pour un affichage immédiat de la gamme'),
])
</div>
</div>
<div class="col">
<div class="form-group">
<label for="rangeUnPublishedAt"><b>{{ __('Date de fin de publication (Europe/Paris)') }}</b></label>
<input id="rangeUnPublishedAt" name="unpublish_at" class="form-control publishTime" type="datetime-local" data-form-type="date" aria-describedby="rangeUnPublishAtHelp" value="{{ old('unpublish_at', ((isset($rangeModel) and $rangeModel->unpublish_at) ? $rangeModel->unpublish_at->format('Y-m-d\TH:i') : '')) }}">
<label
for="rangeUnPublishedAt"><b>{{ __('Date de fin de publication (Europe/Paris)') }}</b></label>
<input id="rangeUnPublishedAt" name="unpublish_at" class="form-control publishTime"
type="datetime-local" data-form-type="date" aria-describedby="rangeUnPublishAtHelp"
value="{{ old('unpublish_at', (isset($rangeModel) and $rangeModel->unpublish_at) ? $rangeModel->unpublish_at->format('Y-m-d\TH:i') : '') }}">
@include('back.modules.input-error', [
'inputName' => 'unpublish_at', 'helperId' => 'rangeUnPublishAtHelp' , 'helper' => (isset($rangeModel) and $rangeModel->unpublish_at) ? __('Laisser vide pour un affichage permanent de la gamme.') : __('Vider pour un affichage permanent de la gamme')
'inputName' => 'unpublish_at',
'helperId' => 'rangeUnPublishAtHelp',
'helper' =>
(isset($rangeModel) and $rangeModel->unpublish_at)
? __('Laisser vide pour un affichage permanent de la gamme.')
: __('Vider pour un affichage permanent de la gamme'),
])
</div>
</div>
@ -103,37 +136,50 @@
<legend>{{ __('Illustration') }}</legend>
<div class="row mb-3">
<div class="col-12 col-md-6 form-group">
<label for="rangePictureAlt" class="col-form-label"><b>{{ __('Texte alternatif de l\'image') }}</b></label>
<label for="rangePictureAlt"
class="col-form-label"><b>{{ __('Texte alternatif de l\'image') }}</b></label>
<div class="word-counter" data-json='@json(['id' => 'rangePictureAlt'])'></div>
<input name="picture_alt" type="text" value="{{ old('picture_alt', $rangeModel->picture_alt ?? '') }}" class="form-control"
id="rangePictureAlt" aria-describedby="rangePictureAltHelp" placeholder="{{ __('Une image de petits chatons') }}" required>
<input name="picture_alt" type="text"
value="{{ old('picture_alt', $rangeModel->picture_alt ?? '') }}" class="form-control"
id="rangePictureAlt" aria-describedby="rangePictureAltHelp"
placeholder="{{ __('Une image de petits chatons') }}" required>
@include('back.modules.input-error', [
'inputName' => 'picture_alt', 'helperId' => 'rangePictureAltHelp' , 'helper' => __('Doit décrire votre image pour les moteurs de recherches et les non voyants (5 à 6 mots)')
'inputName' => 'picture_alt',
'helperId' => 'rangePictureAltHelp',
'helper' => __(
'Doit décrire votre image pour les moteurs de recherches et les non voyants (5 à 6 mots)'
),
])
</div>
<div class="col-12 col-md-6 form-group">
<label for="rangePictureTitle" class="col-form-label"><b>{{ __('Titre de l\'image') }}</b></label>
<div class="word-counter" data-json='@json(['id' => 'rangePictureTitle'])'></div>
<input name="picture_title" type="text" value="{{ old('picture_title', $rangeModel->picture_title ?? '') }}" class="form-control"
id="rangePictureTitle" aria-describedby="rangePictureTitleHelp" placeholder="{{ __('Une description de la gamme pour les moteurs de recherche') }}" required>
<input name="picture_title" type="text"
value="{{ old('picture_title', $rangeModel->picture_title ?? '') }}" class="form-control"
id="rangePictureTitle" aria-describedby="rangePictureTitleHelp"
placeholder="{{ __('Une description de la gamme pour les moteurs de recherche') }}" required>
@include('back.modules.input-error', [
'inputName' => 'picture_title', 'helperId' => 'rangePictureTitleHelp' , 'helper' => __('Utile pour les utilisateurs, s\'affiche en passant la souris sur l\'image.')
'inputName' => 'picture_title',
'helperId' => 'rangePictureTitleHelp',
'helper' => __(
'Utile pour les utilisateurs, s\'affiche en passant la souris sur l\'image.'
),
])
</div>
</div>
<div class="row">
<div class="col-12">
@php
$data = [
'id' => 'rangeModelPicture',
'name' => 'picture',
'helper' => __('L\'image qui va servir de vignette à la gamme, doit être de 700px (hauteur) par 700px (largeur)'),
'width' => 700,
'height' => 700,
'value' => $rangeModel->picture ?? '',
];
$data = [
'id' => 'rangeModelPicture',
'name' => 'picture',
'helper' => __('L\'image qui va servir de vignette à la gamme, doit être de 700px (hauteur) par 700px (largeur)'),
'width' => 700,
'height' => 700,
'value' => $rangeModel->picture ?? '',
];
@endphp
@include('back.modules.input-error', [ 'inputName' => 'picture'])
@include('back.modules.input-error', ['inputName' => 'picture'])
<div class="image-input" data-json='@json($data)'></div>
</div>
</div>
@ -147,37 +193,52 @@
<legend>{{ __('Vignette') }}</legend>
<div class="row mb-3">
<div class="col-12 col-md-6 form-group">
<label for="rangePictureThumbAlt" class="col-form-label"><b>{{ __('Texte alternatif de l\'image') }}</b></label>
<label for="rangePictureThumbAlt"
class="col-form-label"><b>{{ __('Texte alternatif de l\'image') }}</b></label>
<div class="word-counter" data-json='@json(['id' => 'rangePictureThumbAlt'])'></div>
<input name="picture_thumb_alt" type="text" value="{{ old('picture_thumb_alt', $rangeModel->picture_thumb_alt ?? '') }}" class="form-control"
id="rangePictureThumbAlt" aria-describedby="rangePictureThumbAltHelp" placeholder="{{ __('Une image de petits chatons') }}" required>
<input name="picture_thumb_alt" type="text"
value="{{ old('picture_thumb_alt', $rangeModel->picture_thumb_alt ?? '') }}"
class="form-control" id="rangePictureThumbAlt" aria-describedby="rangePictureThumbAltHelp"
placeholder="{{ __('Une image de petits chatons') }}" required>
@include('back.modules.input-error', [
'inputName' => 'picture_thumb_alt', 'helperId' => 'rangePictureThumbAltHelp' , 'helper' => __('Doit décrire votre image pour les moteurs de recherches et les non voyants (5 à 6 mots)')
'inputName' => 'picture_thumb_alt',
'helperId' => 'rangePictureThumbAltHelp',
'helper' => __(
'Doit décrire votre image pour les moteurs de recherches et les non voyants (5 à 6 mots)'
),
])
</div>
<div class="col-12 col-md-6 form-group">
<label for="rangePictureThumbTitle" class="col-form-label"><b>{{ __('Titre de l\'image') }}</b></label>
<label for="rangePictureThumbTitle"
class="col-form-label"><b>{{ __('Titre de l\'image') }}</b></label>
<div class="word-counter" data-json='@json(['id' => 'rangePictureThumbTitle'])'></div>
<input name="picture_thumb_title" type="text" value="{{ old('picture_thumb_title', $rangeModel->picture_thumb_title ?? '') }}" class="form-control"
id="rangePictureThumbTitle" aria-describedby="rangePictureThumbTitleHelp" placeholder="{{ __('Une description de la gamme pour les moteurs de recherche') }}" required>
<input name="picture_thumb_title" type="text"
value="{{ old('picture_thumb_title', $rangeModel->picture_thumb_title ?? '') }}"
class="form-control" id="rangePictureThumbTitle"
aria-describedby="rangePictureThumbTitleHelp"
placeholder="{{ __('Une description de la gamme pour les moteurs de recherche') }}" required>
@include('back.modules.input-error', [
'inputName' => 'picture_thumb_title', 'helperId' => 'rangePictureThumbTitleHelp' , 'helper' => __('Utile pour les utilisateurs, s\'affiche en passant la souris sur l\'image.')
'inputName' => 'picture_thumb_title',
'helperId' => 'rangePictureThumbTitleHelp',
'helper' => __(
'Utile pour les utilisateurs, s\'affiche en passant la souris sur l\'image.'
),
])
</div>
</div>
<div class="row">
<div class="col-12">
@php
$data = [
'id' => 'rangeModelThumbPicture',
'name' => 'picture_thumb',
'helper' => __('L\'image qui va servir de vignette à la gamme, doit être de 300px (hauteur) par 300px (largeur)'),
'width' => 300,
'height' => 300,
'value' => $rangeModel->picture_thumb ?? '',
];
$data = [
'id' => 'rangeModelThumbPicture',
'name' => 'picture_thumb',
'helper' => __('L\'image qui va servir de vignette à la gamme, doit être de 300px (hauteur) par 300px (largeur)'),
'width' => 300,
'height' => 300,
'value' => $rangeModel->picture_thumb ?? '',
];
@endphp
@include('back.modules.input-error', [ 'inputName' => 'picture_thumb'])
@include('back.modules.input-error', ['inputName' => 'picture_thumb'])
<div class="image-input" data-json='@json($data)'></div>
</div>
</div>
@ -192,16 +253,38 @@
<div class="row mb-3">
<div class="col-12 form-group">
@include('back.modules.input-error', [
'inputName' => 'description', 'helperId' => 'rangeModelDescriptionHelp' , 'helper' => __('Relisez bien votre description avant de la publier.')
'inputName' => 'description',
'helperId' => 'rangeModelDescriptionHelp',
'helper' => __('Relisez bien votre description avant de la publier.'),
])
@php
$data = [
'name' => 'description',
'csrf' => csrf_token(),
'text' => old('description', $rangeModel->description ?? ''),
];
$data = [
'name' => 'description',
'csrf' => csrf_token(),
'text' => old('description', $rangeModel->description ?? ''),
];
@endphp
<div id="ck-editor-bo" data-json='@json($data)'></div>
<div class="ck-editor-bo" data-json='@json($data)'></div>
</div>
</div>
</fieldset>
<fieldset class="border p-3 mb-3">
<legend>{{ __('Argumentaire sur les labels') }}</legend>
<div class="row mb-3">
<div class="col-12 form-group">
@include('back.modules.input-error', [
'inputName' => 'argumentation',
'helperId' => 'rangeModelArgumentationHelp',
'helper' => __('Relisez bien votre argumentation avant de la publier.'),
])
@php
$data = [
'name' => 'argumentation',
'csrf' => csrf_token(),
'text' => old('argumentation', $rangeModel->argumentation ?? ''),
];
@endphp
<div class="ck-editor-bo" data-json='@json($data)'></div>
</div>
</div>
</fieldset>
@ -215,14 +298,16 @@
<div class="row mb-3">
<div class="col-12 form-group">
@include('back.modules.input-error', [
'inputName' => 'link1', 'helperId' => 'rangeModelLink1Help' , 'helper' => __('Lien à afficher sur la gamme')
'inputName' => 'link1',
'helperId' => 'rangeModelLink1Help',
'helper' => __('Lien à afficher sur la gamme'),
])
@php
$data = [
'name' => 'link1',
'placeholder' => __('lien numéro 1'),
'value' => old('link1', $rangeModel->link1 ?? null),
];
$data = [
'name' => 'link1',
'placeholder' => __('lien numéro 1'),
'value' => old('link1', $rangeModel->link1 ?? null),
];
@endphp
<div class="model-link" data-json='@json($data)'></div>
</div>
@ -230,14 +315,16 @@
<div class="row mb-3">
<div class="col-12 form-group">
@include('back.modules.input-error', [
'inputName' => 'link2', 'helperId' => 'rangeModelLink1Help' , 'helper' => __('Lien à afficher sur la gamme')
'inputName' => 'link2',
'helperId' => 'rangeModelLink1Help',
'helper' => __('Lien à afficher sur la gamme'),
])
@php
$data = [
'name' => 'link2',
'placeholder' => __('lien numéro 2'),
'value' => old('link2', $rangeModel->link2 ?? null),
];
$data = [
'name' => 'link2',
'placeholder' => __('lien numéro 2'),
'value' => old('link2', $rangeModel->link2 ?? null),
];
@endphp
<div class="model-link" data-json='@json($data)'></div>
</div>
@ -249,10 +336,14 @@
<div class="row mb-3">
<div class="col-12 col-md-6">
<div class="form-check">
<input name="status" class="form-check-input mt-2" type="checkbox" id="rangeStatus" aria-describedby="rangeStatusHelp" value="1" @if(old('status', $rangeModel->status ?? ''))checked @endif>
<label class="form-check-label user-select-none pt-1" for="rangeStatus"><b>{{ __('Publié') }}</b></label><br>
<input name="status" class="form-check-input mt-2" type="checkbox" id="rangeStatus"
aria-describedby="rangeStatusHelp" value="1" @if (old('status', $rangeModel->status ?? '')) checked @endif>
<label class="form-check-label user-select-none pt-1"
for="rangeStatus"><b>{{ __('Publié') }}</b></label><br>
@include('back.modules.input-error', [
'inputName' => 'status', 'helperId' => 'rangeStatusHelp' , 'helper' => __('La gamme est visible ou non')
'inputName' => 'status',
'helperId' => 'rangeStatusHelp',
'helper' => __('La gamme est visible ou non'),
])
</div>
</div>
@ -260,68 +351,70 @@
@push('scripts')
<script nonce="{{ $nonce }}">
document.addEventListener("DOMContentLoaded", () => {
<script nonce="{{ $nonce }}">
document.addEventListener("DOMContentLoaded", () => {
// Publish times
let publishTimes = document.getElementsByClassName('publishTime');
for (let input of publishTimes) {
let parent = input.parentNode,
dates = {
start: 0,
end: 0
};
input.originalValue = (new Date(input.value)).valueOf();
if(input.originalValue === NaN) {
input.originalValue = 0
}
if(input.id === 'rangePublishedAt') {
dates.start = input.originalValue;
} else {
dates.end = input.originalValue;
}
let getEuropeParisTime = () => {
return new Date((new Date()).getTime() + (60000*((new Date()).getTimezoneOffset()+60)));
};
let setDateHelpers = (input, parent) => {
let small = parent.children.rangePublishAtHelp ? parent.children.rangePublishAtHelp : parent.children.rangeUnPublishAtHelp;
let isPlanned = false;
if(input.id === 'rangePublishedAt') {
isPlanned = dates.start > dates.end && dates.end != 0;
} else {
isPlanned = dates.start < dates.end && dates.start != 0;
// Publish times
let publishTimes = document.getElementsByClassName('publishTime');
for (let input of publishTimes) {
let parent = input.parentNode,
dates = {
start: 0,
end: 0
};
input.originalValue = (new Date(input.value)).valueOf();
if (input.originalValue === NaN) {
input.originalValue = 0
}
if (input.id === 'rangePublishedAt') {
dates.start = input.originalValue;
} else {
dates.end = input.originalValue;
}
let getEuropeParisTime = () => {
return new Date((new Date()).getTime() + (60000 * ((new Date()).getTimezoneOffset() + 60)));
};
let setDateHelpers = (input, parent) => {
let small = parent.children.rangePublishAtHelp ? parent.children.rangePublishAtHelp : parent
.children.rangeUnPublishAtHelp;
let isPlanned = false;
if (input.id === 'rangePublishedAt') {
isPlanned = dates.start > dates.end && dates.end != 0;
} else {
isPlanned = dates.start < dates.end && dates.start != 0;
}
if (isPlanned || getEuropeParisTime().valueOf() < (new Date(input.value)).valueOf()) {
let date = new Date(input.value);
// small.textContent = "{{ __('Planifié pour le ') }}" + date.toLocaleString();
small.textContent = input.id === 'rangePublishedAt' ?
"{{ __('Vider pour un affichage immédiat de la gamme.') }}" :
"{{ __('Vider pour un affichage permanent de la gamme.') }}";
} else {
// small.textContent = input.id === 'rangePublishedAt' ?
// "{{ __('Uniquement pour planifier la publication') }}" :
// "{{ __('Uniquement pour planifier la fin de la publication') }}";
small.textContent = input.id === 'rangePublishedAt' ?
"{{ __('Laisser vide pour un affichage immédiat de la gamme.') }}" :
"{{ __('Laisser vide pour un affichage permanent de la gamme.') }}";
}
};
setDateHelpers(input, parent);
input.addEventListener('change', (event) => {
let parent = event.target.parentNode,
input = event.target,
value;
value = (new Date(input.value)).valueOf();
if (input.originalValue === NaN) {
value = 0
}
if (input.id === 'rangePublishedAt') {
dates.start = value;
} else {
dates.end = value;
}
setDateHelpers(input, parent);
});
}
if (isPlanned || getEuropeParisTime().valueOf() < (new Date(input.value)).valueOf()) {
let date = new Date(input.value);
// small.textContent = "{{ __('Planifié pour le ') }}" + date.toLocaleString();
small.textContent = input.id === 'rangePublishedAt' ?
"{{ __('Vider pour un affichage immédiat de la gamme.') }}" :
"{{ __('Vider pour un affichage permanent de la gamme.') }}";
} else {
// small.textContent = input.id === 'rangePublishedAt' ?
// "{{ __('Uniquement pour planifier la publication') }}" :
// "{{ __('Uniquement pour planifier la fin de la publication') }}";
small.textContent = input.id === 'rangePublishedAt' ?
"{{ __('Laisser vide pour un affichage immédiat de la gamme.') }}" :
"{{ __('Laisser vide pour un affichage permanent de la gamme.') }}";
}
};
setDateHelpers(input, parent);
input.addEventListener('change', (event) => {
let parent = event.target.parentNode,
input = event.target, value;
value = (new Date(input.value)).valueOf();
if(input.originalValue === NaN) {
value = 0
}
if(input.id === 'rangePublishedAt') {
dates.start = value;
} else {
dates.end = value;
}
setDateHelpers(input, parent);
});
}
});
</script>
</script>
@endpush

View file

@ -1,106 +1,123 @@
@extends('layouts.back')
@extends('layouts.back')
@section('title', sprintf('%s - %s', __('models.classes.ranges'), Str::ucfirst(__('liste'))))
@section('title', sprintf('%s - %s', __('models.classes.ranges'), Str::ucfirst(__('liste'))))
@section('breadcrumb', request()->route()->getName())
@section('breadcrumb',
request()->route()->getName())
@section('content')
<div class="card">
<div class="card-header">
<div class="row">
<div class="col-12">
@include('back.breadcrumb.breadcrumb-body')
</div>
</div>
<div class="row">
<div class="col">
<h1 class="h2">{{ __('models.classes.ranges') }}&nbsp;{{ Str::ucfirst(__('liste')) }}</h1>
</div>
<div class="col-md-3">
<div class="input-group justify-content-end">
<a href="{{ route('bo.ranges.create') }}" class="btn btn-primary" title="{{ __('Ajouter une :model', [
'model' => Str::singular(__('models.classes.ranges'))
]) }}" data-bs-toggle="tooltip"><i class="fa-solid fa-plus"></i></a>
</div>
</div>
</div>
</div>
<div class="card-body">
@include('back.modules.searchBar')
<div class="row justify-content-center">
<div class="col-12 col-md-6 p-0 p-md-3">
{{ $ranges->withQueryString()->onEachSide(1)->links() }}
</div>
</div>
<div class="row">
<div class="col">
<div class="table-responsive">
<table class="table fixAction">
<thead>
@php
$cols = ['title' => __('Titre'), 'category' => __('Categorie'), 'description' => __('Description'), 'status' => __('Publication'), 'updated_at' => __('Mis à jour le')];
@endphp
@include('back.modules.tableColSorter', [ 'cols' => $cols, 'mobileHide' => ['status']])
</thead>
<tbody>
@if($ranges->count())
@foreach ($ranges as $rangeModel)
<tr>
<td>
<span>{{ $rangeModel->title }}</span>
</td>
<td>
<span>{{ $rangeModel->category->label }}</span>
</td>
<td>
<span>{{ Str::limit(strip_tags($rangeModel->description)) }}</span>
</td>
<td class="d-none d-md-table-cell">
<form action="{{ route('bo.ranges.change-published', $rangeModel->id) }}" method="POST">
@csrf
<button type="submit" class="btn btn-sm" title="{{ __(':action :model', [
'action' => $rangeModel->status ? __('Dépublier') : __('Publier'),
'model' => Str::singular(__('models.classes.ranges'))
]) }}" data-bs-toggle="tooltip">
<i class="fas @if($rangeModel->status)fa-check check-green @else fa-times cross-red @endif"></i>
</button>
</form>
</td>
<td>
<span>{{ $rangeModel->updated_at->formatLocalized('%d/%m/%Y à %I:%M') }}</span>
</td>
<td>
<div class="btn-group">
{{-- Public View Page --}}
@if($rangeModel->status)
<a class="btn btn-sm btn-warning" href="" target="_blank" title="{{ __('Visualiser :model', [
'model' => Str::singular(__('models.classes.ranges'))
]) }}" data-bs-toggle="tooltip"><i class="fa-solid fa-eye"></i></a>
@endif
<a class="btn btn-sm btn-primary" href="{{ route('bo.ranges.edit', $rangeModel->id) }}" title="{{ __('Modifier :model', [
'model' => Str::singular(__('models.classes.ranges'))
]) }}" data-bs-toggle="tooltip"><i class="fa-solid fa-pencil"></i></a>
</div>
</td>
</tr>
@endforeach
@else
<tr>
<td colspan="5" class="text-center"><span class="h3">{{
__('Aucun résultat pour les :models', ['models' => __('models.classes.ranges')])
}}</span></td>
</tr>
@endif
</tbody>
</table>
</div>
</div>
</div>
<div class="row justify-content-center">
<div class="col-12 col-md-6 p-0 p-md-3">
{{ $ranges->withQueryString()->onEachSide(1)->links() }}
</div>
</div>
</div>
</div>
@endsection
@section('content')
<div class="card">
<div class="card-header">
<div class="row">
<div class="col-12">
@include('back.breadcrumb.breadcrumb-body')
</div>
</div>
<div class="row">
<div class="col">
<h1 class="h2">{{ __('models.classes.ranges') }}&nbsp;{{ Str::ucfirst(__('liste')) }}</h1>
</div>
<div class="col-md-3">
<div class="input-group justify-content-end">
<a href="{{ route('bo.ranges.create') }}" class="btn btn-primary"
title="{{ __('Ajouter une :model', [
'model' => Str::singular(__('models.classes.ranges')),
]) }}"
data-bs-toggle="tooltip"><i class="fa-solid fa-plus"></i></a>
</div>
</div>
</div>
</div>
<div class="card-body">
@include('back.modules.searchBar')
<div class="row justify-content-center">
<div class="col-12 col-md-6 p-0 p-md-3">
{{ $ranges->withQueryString()->onEachSide(1)->links() }}
</div>
</div>
<div class="row">
<div class="col">
<div class="table-responsive">
<table class="table fixAction">
<thead>
@php
$cols = ['title' => __('Titre'), 'category' => __('Categorie'), 'description' => __('Description'), 'status' => __('Publication'), 'updated_at' => __('Mis à jour le')];
@endphp
@include('back.modules.tableColSorter', [
'cols' => $cols,
'mobileHide' => ['status'],
])
</thead>
<tbody>
@if ($ranges->count())
@foreach ($ranges as $rangeModel)
<tr>
<td>
<span>{{ $rangeModel->title }}</span>
</td>
<td>
<span>{{ $rangeModel->category->label }}</span>
</td>
<td>
<span>{{ Str::limit(strip_tags($rangeModel->description)) }}</span>
</td>
<td class="d-none d-md-table-cell">
<form action="{{ route('bo.ranges.change-published', $rangeModel->id) }}"
method="POST">
@csrf
<button type="submit" class="btn btn-sm"
title="{{ __(':action :model', [
'action' => $rangeModel->status ? __('Dépublier') : __('Publier'),
'model' => Str::singular(__('models.classes.ranges')),
]) }}"
data-bs-toggle="tooltip">
<i
class="fas @if ($rangeModel->status) fa-check check-green @else fa-times cross-red @endif"></i>
</button>
</form>
</td>
<td>
<span>{{ $rangeModel->updated_at->formatLocalized('%d/%m/%Y à %I:%M') }}</span>
</td>
<td>
<div class="btn-group">
{{-- Public View Page --}}
@if ($rangeModel->status)
<a class="btn btn-sm btn-warning" href="" target="_blank"
title="{{ __('Visualiser :model', [
'model' => Str::singular(__('models.classes.ranges')),
]) }}"
data-bs-toggle="tooltip"><i class="fa-solid fa-eye"></i></a>
@endif
<a class="btn btn-sm btn-primary"
href="{{ route('bo.ranges.edit', $rangeModel->id) }}"
title="{{ __('Modifier :model', [
'model' => Str::singular(__('models.classes.ranges')),
]) }}"
data-bs-toggle="tooltip"><i class="fa-solid fa-pencil"></i></a>
</div>
</td>
</tr>
@endforeach
@else
<tr>
<td colspan="5" class="text-center">
<span
class="h3">{{ __('Aucun résultat pour les :models', ['models' => __('models.classes.ranges')]) }}
</span>
</td>
</tr>
@endif
</tbody>
</table>
</div>
</div>
</div>
<div class="row justify-content-center">
<div class="col-12 col-md-6 p-0 p-md-3">
{{ $ranges->withQueryString()->onEachSide(1)->links() }}
</div>
</div>
</div>
</div>
@endsection

View file

@ -24,28 +24,28 @@ Route::prefix('bo')->name('bo.')->group(function () {
// * SLIDERS
Route::resource('sliders', SliderController::class)->except(['show']);
Route::post('/sliders/{slider}/change-order', [SliderController::class, 'changeOrder'])
->name('sliders.change-order');
->name('sliders.change-order');
Route::post('/sliders/{slider}/change-published', [SliderController::class, 'changePublished'])
->name('sliders.change-published');
->name('sliders.change-published');
// * RANGES
Route::resource('ranges', RangeController::class)->except(['show'])
->withoutMiddleware('htmlsanitize')
->middleware('htmlsanitize:description');
->withoutMiddleware('htmlsanitize')
->middleware('htmlsanitize:description,argumentation');
Route::post('/ranges/{range}/change-published', [RangeController::class, 'changePublished'])
->name('ranges.change-published');
->name('ranges.change-published');
// * Ranges PAGE SEARCH
Route::get('/ranges/search-uri', [RangeController::class, 'searchUri'])
->name('ranges.search-uri');
->name('ranges.search-uri');
Route::get('/ranges/model-title', [RangeController::class, 'modelTitle'])
->name('ranges.model-title');
->name('ranges.model-title');
// * PRODUCTS
Route::resource('products', ProductController::class)->except(['show'])
->withoutMiddleware('htmlsanitize')
->middleware('htmlsanitize:description,ingredients,preparation_advices,sales_pitch,allergen_list');
->withoutMiddleware('htmlsanitize')
->middleware('htmlsanitize:description,ingredients,preparation_advices,sales_pitch,allergen_list');
Route::post('/products/{product}/change-published', [ProductController::class, 'changePublished'])
->name('products.change-published');
->name('products.change-published');
// * TAGS
Route::resource('tags', TagController::class)->except(['show']);