feat: Make static pages banner manageable

This commit is contained in:
Noah Lancien 2025-02-20 17:28:04 +01:00
parent 546f955171
commit 8d4b48c03e
12 changed files with 287 additions and 29 deletions

View file

@ -77,4 +77,22 @@ enum StaticPageType: int
self::we_listen => true,
};
}
/**
* Does the static page need to fill its 'picture' column ?
*
* @return boolean
*/
public function containsBanner(): bool
{
return match ($this) {
self::unveil,
self::we_hire,
self::we_commit,
self::we_move,
self::we_produce,
self::we_listen => true,
default => false,
};
}
}

View file

@ -2,12 +2,15 @@
namespace App\Http\Requests\Bo\StaticPages;
use App\Traits\Requests\HasPicture;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Str;
class UpdateStaticPageRequest extends FormRequest
{
use HasPicture;
/**
* Determine if the user is authorized to make this request.
*
@ -30,6 +33,7 @@ class UpdateStaticPageRequest extends FormRequest
null :
Str::of($this->input('content'))->value()
]);
$this->mergePicture('picture');
}
/**
@ -48,6 +52,16 @@ class UpdateStaticPageRequest extends FormRequest
if (request()->route()->parameters()['static_page']->type->containsContent()) {
$rules = array_merge($rules, ['content' => 'required|string|min:15']);
}
if (request()->route()->parameters()['static_page']->type->containsBanner()) {
$rules = array_merge(
$rules,
$this->pictureRules('picture', 1920, 1080, 1920, 1080, false),
[
'picture_alt' => 'required|string|between:3,255',
'picture_title' => 'required|string|between:3,255',
]
);
}
return $rules;
}
@ -63,6 +77,9 @@ class UpdateStaticPageRequest extends FormRequest
'seo_description' => trans('validation.custom.seo_description'),
'title' => trans('validation.attributes.title'),
'content' => trans('validation.attributes.content'),
'picture' => trans('validation.custom.banner'),
'picture_alt' => trans('validation.custom.attribute_alt'),
'picture_title' => trans('validation.custom.attribute_title'),
];
}
}

View file

@ -3,6 +3,7 @@
namespace App\Models;
use App\Enums\StaticPageType;
use App\Lib\Helpers\FileStorageHelper;
use App\Lib\Helpers\ToolboxHelper;
use App\Traits\Models\ActivityLog;
use Illuminate\Database\Eloquent\Factories\HasFactory;
@ -15,6 +16,9 @@ use Illuminate\Support\Str;
* @property string $seo_description Seo description about 160 chars as recommended.
* @property string $title Title for the page.
* @property string $slug Slug of the title for the page.
* @property string $picture Static page banner path.
* @property string $picture_alt Banner alt attribute.
* @property string $picture_title Banner title attribute.
* @property string $content WYSIWYG text content using ckeditor.
* @property-read \Illuminate\Support\Carbon $created_at Created date.
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
@ -35,6 +39,9 @@ class StaticPage extends Model
'seo_title',
'seo_description',
'title',
'picture',
'picture_alt',
'picture_title',
'content',
];
@ -55,16 +62,16 @@ class StaticPage extends Model
protected static function booted(): void
{
static::creating(function (self $model) {
// * ASSERTIONS
self::assertTitleIsUnique($model->title);
// * CHANGES
$model->slug = Str::slug($model->title);
self::manageFields($model);
});
static::updating(function (self $model) {
// * ASSERTIONS
self::assertTitleIsUnique($model->title, $model->id);
// * CHANGES
$model->slug = Str::slug($model->title);
self::manageFields($model);
});
static::updated(function (self $model) {
FileStorageHelper::removeOldFile($model, 'picture');
});
static::deleted(function (self $model) {
FileStorageHelper::removeFile($model, 'picture');
});
}
@ -96,6 +103,39 @@ class StaticPage extends Model
// * METHODS
/**
* Manage model fields.
*
* @param self $model
* @return void
*/
private static function manageFields(self $model): void
{
// * ASSERTIONS
self::assertTitleIsUnique($model->title, $model->id);
if ($model->content) {
ToolboxHelper::assertNoInternalBoUrls('content', $model->content);
$model->content = clean($model->content);
}
// * TRANSFORMATIONS
self::setSlug($model, $model->title);
$model->picture = FileStorageHelper::storeFile($model, $model->picture, true);
}
/**
* Set the slug.
*
* @param self $model
* @param string $original
*
* @return void
*/
private static function setSlug(self $model, string $original): void
{
$model->slug = Str::slug($original);
}
/**
* Asserts using validation that the title is unique
*

View file

@ -0,0 +1,106 @@
<?php
use App\Enums\StaticPageType;
use App\Lib\Helpers\FileStorageHelper;
use App\Models\StaticPage;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up(): void
{
Schema::table('static_pages', function (Blueprint $table) {
$table->string('picture')->nullable()->comment('Static page banner.')->after('slug');
$table->string('picture_alt')->nullable()->comment('Banner alt attribute.')->after('picture');
$table->string('picture_title')->nullable()->comment('Banner title attribute.')->after('picture_alt');
});
if ($page = StaticPage::query()->where('type', StaticPageType::unveil)->firstOrFail()) {
$page->picture = FileStorageHelper::storeFile(
$page,
new \SplFileInfo(\resource_path(
'/assets/images/banners/we_unveil.jpeg'
))
);
$page->picture_alt = 'Image de fond';
$page->picture_title = 'Paysage d\'un champs de blé au soleil couchant avec une lisière en fond de tableau';
$page->saveOrFail();
}
if ($page = StaticPage::query()->where('type', StaticPageType::we_hire)->firstOrFail()) {
$page->picture = FileStorageHelper::storeFile(
$page,
new \SplFileInfo(\resource_path(
'/assets/images/banners/alternative_banner_reworked.jpg'
))
);
$page->picture_alt = 'Image de fond';
$page->picture_title = 'Paysage d\'un champs de blé au soleil couchant avec une lisière en fond de tableau';
$page->saveOrFail();
}
if ($page = StaticPage::query()->where('type', StaticPageType::we_commit)->firstOrFail()) {
$page->picture = FileStorageHelper::storeFile(
$page,
new \SplFileInfo(\resource_path(
'/assets/images/banners/we_commit.png'
))
);
$page->picture_alt = 'Image de fond';
$page->picture_title = 'Paysage d\'un champs de blé au soleil couchant avec une lisière en fond de tableau';
$page->saveOrFail();
}
if ($page = StaticPage::query()->where('type', StaticPageType::we_move)->firstOrFail()) {
$page->picture = FileStorageHelper::storeFile(
$page,
new \SplFileInfo(\resource_path(
'/assets/images/banners/we_move.jpg'
))
);
$page->picture_alt = 'Image de fond';
$page->picture_title = 'Paysage d\'un champs de blé au soleil couchant avec une lisière en fond de tableau';
$page->saveOrFail();
}
if ($page = StaticPage::query()->where('type', StaticPageType::we_produce)->firstOrFail()) {
$page->picture = FileStorageHelper::storeFile(
$page,
new \SplFileInfo(\resource_path(
'/assets/images/banners/we_produce.png'
))
);
$page->picture_alt = 'Image de fond';
$page->picture_title = 'Paysage d\'un champs de blé au soleil couchant avec une lisière en fond de tableau';
$page->saveOrFail();
}
if ($page = StaticPage::query()->where('type', StaticPageType::we_listen)->firstOrFail()) {
$page->picture = FileStorageHelper::storeFile(
$page,
new \SplFileInfo(\resource_path(
'/assets/images/banners/we_listen.png'
))
);
$page->picture_alt = 'Image de fond';
$page->picture_title = 'Paysage d\'un champs de blé au soleil couchant avec une lisière en fond de tableau';
$page->saveOrFail();
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down(): void
{
Schema::table('static_pages', function (Blueprint $table) {
$table->dropColumn('picture');
$table->dropColumn('picture_alt');
$table->dropColumn('picture_title');
});
}
};

View file

@ -293,5 +293,6 @@ return [
'society' => 'entreprise',
'object' => 'objet',
'message' => 'message',
'banner' => 'bannière',
],
];

View file

@ -51,7 +51,7 @@
<div class="row">
<div class="col-12 mb-3">
@include('bo.partials.inputs.varchar', [
'id' => 'staticPagesSeoTitle',
'id' => 'staticPageSeoTitle',
'label' => __(':field :inter:model', [
'field' => Str::ucfirst(__('validation.custom.seo_title')),
'inter' => __('validation.custom.of_the.female'),
@ -87,7 +87,7 @@
<div class="row">
<div class="col-12">
@include('bo.partials.inputs.varchar-multiline', [
'id' => 'staticPagesSeoDescription',
'id' => 'staticPageSeoDescription',
'label' => __(':field :inter:model', [
'field' => Str::ucfirst(__('validation.custom.seo_description')),
'inter' => __('validation.custom.of_the.female'),
@ -123,7 +123,7 @@
<div class="row mb-3">
<div class="col-12">
@include('bo.partials.inputs.text-html', [
'id' => 'articleContent',
'id' => 'staticPageContent',
'label' => __(':field :inter:model', [
'field' => Str::ucfirst(__('validation.attributes.content')),
'inter' => __('validation.custom.of_the.female'),
@ -139,6 +139,82 @@
</fieldset>
</div>
@endif
{{-- PICTURE --}}
@if ($staticPageModel->type->containsBanner())
<div class="col-12 pb-3">
<fieldset class="h-100 border p-3">
<legend>{{ Str::ucfirst(__('validation.custom.banner')) }}</legend>
<div class="row mb-3">
{{-- PICTURE_ALT --}}
<div class="col-12 col-md-6 m-md-0 mb-3">
@include('bo.partials.inputs.varchar', [
'id' => 'staticPagePictureAlt',
'label' => __(':field1 :inter1:field2 :inter2:model', [
'field1' => Str::ucfirst(__('validation.custom.alt_attribute')),
'inter1' => __('validation.custom.of_the.female'),
'field2' => __('validation.custom.banner'),
'inter2' => __('validation.custom.of_the.female'),
'model' => trans_choice('models.classes.static_page', 1),
]),
'hasWordCounter' => true,
'name' => 'picture_alt',
'required' => true,
'model' => $staticPageModel ?? null,
'helper' => __('crud.minicrud.picture_alt_helper'),
'placeholder' => __(':field1 :inter1:field2 :inter2:model', [
'field1' => Str::ucfirst(__('validation.custom.alt_attribute')),
'inter1' => __('validation.custom.of_the.female'),
'field2' => __('validation.custom.banner'),
'inter2' => __('validation.custom.of_the.female'),
'model' => trans_choice('models.classes.static_page', 1),
]),
])
</div>
{{-- PICTURE_TITLE --}}
<div class="col-12 col-md-6 mb-3">
@include('bo.partials.inputs.varchar', [
'id' => 'staticPagePictureTitle',
'label' => __(':field1 :inter1:field2 :inter2:model', [
'field1' => Str::ucfirst(__('validation.custom.title_attribute')),
'inter1' => __('validation.custom.of_the.female'),
'field2' => __('validation.custom.banner'),
'inter2' => __('validation.custom.of_the.female'),
'model' => trans_choice('models.classes.static_page', 1),
]),
'hasWordCounter' => true,
'name' => 'picture_title',
'required' => true,
'model' => $staticPageModel ?? null,
'helper' => __('crud.minicrud.picture_title_helper'),
'placeholder' => __(':field1 :inter1:field2 :inter2:model', [
'field1' => Str::ucfirst(__('validation.custom.title_attribute')),
'inter1' => __('validation.custom.of_the.female'),
'field2' => __('validation.custom.banner'),
'inter2' => __('validation.custom.of_the.female'),
'model' => trans_choice('models.classes.static_page', 1),
]),
])
</div>
{{-- PICTURE --}}
<div class="col-12">
@include('bo.partials.inputs.varchar-picture', [
'id' => 'staticPagePicture',
'name' => 'picture',
'width' => 1920,
'height' => 1080,
'model' => $staticPageModel ?? null,
'helper' => __('crud.minicrud.dimensions_must_be', [
'widthpx' => '1920px',
'heightpx' => '1080px',
]),
'required' => true,
'preview' => true,
])
</div>
</div>
</fieldset>
</div>
@endif
<div class="col-12 text-center">
<p><b>{{ __('* Champs obligatoires') }}</b></p>
</div>

View file

@ -7,9 +7,9 @@
@section('banner')
@include('fo.layouts.banner', [
'h1' => __($staticPageModel->title),
'asset' => Vite::asset('resources/assets/images/banners/we_commit.png'),
'title' => __('Paysage d\'un champs de blé au soleil couchant avec une lisière en fond de tableau'),
'alt' => __('Image de fond'),
'asset' => asset($staticPageModel->picture),
'title' => __($staticPageModel->picture_title),
'alt' => __($staticPageModel->picture_alt),
'displayArrow' => true,
'buttonLink' => '#introduction',
])

View file

@ -7,9 +7,9 @@
@section('banner')
@include('fo.layouts.banner', [
'h1' => __($staticPageModel->title),
'asset' => Vite::asset('resources/assets/images/banners/alternative_banner_reworked.jpg'),
'title' => __('Paysage d\'un champs de blé au soleil couchant avec une lisière en fond de tableau'),
'alt' => __('Image de fond'),
'asset' => asset($staticPageModel->picture),
'title' => __($staticPageModel->picture_title),
'alt' => __($staticPageModel->picture_alt),
'displayArrow' => true,
'buttonLink' => '#company-life',
])

View file

@ -7,9 +7,9 @@
@section('banner')
@include('fo.layouts.banner', [
'h1' => __($staticPageModel->title),
'asset' => Vite::asset('resources/assets/images/banners/we_listen.png'),
'title' => __('Paysage d\'un champs de blé au soleil couchant avec une lisière en fond de tableau'),
'alt' => __('Image de fond'),
'asset' => asset($staticPageModel->picture),
'title' => __($staticPageModel->picture_title),
'alt' => __($staticPageModel->picture_alt),
'displayArrow' => true,
'buttonLink' => '#listen',
])

View file

@ -7,9 +7,9 @@
@section('banner')
@include('fo.layouts.banner', [
'h1' => __($staticPageModel->title),
'asset' => Vite::asset('resources/assets/images/banners/we_move.jpg'),
'title' => __('Paysage d\'un champs de blé au soleil couchant avec une lisière en fond de tableau'),
'alt' => __('Image de fond'),
'asset' => asset($staticPageModel->picture),
'title' => __($staticPageModel->picture_title),
'alt' => __($staticPageModel->picture_alt),
'displayArrow' => true,
'buttonLink' => '#life',
])

View file

@ -7,9 +7,9 @@
@section('banner')
@include('fo.layouts.banner', [
'h1' => __($staticPageModel->title),
'asset' => Vite::asset('resources/assets/images/banners/we_produce.png'),
'title' => __('Paysage d\'un champs de blé au soleil couchant avec une lisière en fond de tableau'),
'alt' => __('Image de fond'),
'asset' => asset($staticPageModel->picture),
'title' => __($staticPageModel->picture_title),
'alt' => __($staticPageModel->picture_alt),
'displayArrow' => true,
'buttonLink' => '#local',
])

View file

@ -7,9 +7,9 @@
@section('banner')
@include('fo.layouts.banner', [
'h1' => __($staticPageModel->title),
'asset' => Vite::asset('resources/assets/images/banners/we_unveil.jpeg'),
'title' => __('Paysage d\'un champs de blé au soleil couchant avec une lisière en fond de tableau'),
'alt' => __('Image de fond'),
'asset' => asset($staticPageModel->picture),
'title' => __($staticPageModel->picture_title),
'alt' => __($staticPageModel->picture_alt),
'displayArrow' => true,
'buttonLink' => '#key-numbers',
])