diff --git a/app/Http/Requests/Bo/Sites/StoreSiteRequest.php b/app/Http/Requests/Bo/Sites/StoreSiteRequest.php index 49734d1..20b75e9 100644 --- a/app/Http/Requests/Bo/Sites/StoreSiteRequest.php +++ b/app/Http/Requests/Bo/Sites/StoreSiteRequest.php @@ -65,6 +65,8 @@ class StoreSiteRequest extends FormRequest 'highlights' => 'nullable|string|min:15', 'latitude' => 'required|numeric|between:-90,90', 'longitude' => 'required|numeric|between:-180,180', + 'sticky_title' => 'required_with:sticky_link|nullable|string|between:3,255', + 'sticky_link' => 'required_with:sticky_title|nullable|string|between:3,255', 'logo_alt' => 'required|string|between:3,255', 'logo_title' => 'required|string|between:3,255', 'picture_1_alt' => 'required|string|between:3,255', @@ -115,6 +117,8 @@ class StoreSiteRequest extends FormRequest 'highlights' => Str::plural(trans('validation.custom.highlight')), 'latitude' => trans('validation.custom.latitude'), 'longitude' => trans('validation.custom.longitude'), + 'sticky_title' => trans('validation.custom.sticky_item.title'), + 'sticky_link' => trans('validation.custom.sticky_item.link'), 'logos' => Str::plural(trans('models.classes.logo')), 'logos.*' => trans('models.classes.logo'), 'logo_alt' => trans(':field :inter:model', [ diff --git a/app/Models/Site.php b/app/Models/Site.php index c20da96..8ba109d 100644 --- a/app/Models/Site.php +++ b/app/Models/Site.php @@ -81,6 +81,8 @@ class Site extends Model implements Sitemapable 'highlights', 'latitude', 'longitude', + 'sticky_title', + 'sticky_link', 'logo', 'logo_alt', 'logo_title', diff --git a/database/migrations/2026_03_05_110744_add_sticky_sites_table.php b/database/migrations/2026_03_05_110744_add_sticky_sites_table.php new file mode 100644 index 0000000..bdacdba --- /dev/null +++ b/database/migrations/2026_03_05_110744_add_sticky_sites_table.php @@ -0,0 +1,30 @@ +string('sticky_title')->nullable()->comment('Sticky item title')->after('longitude'); + $table->string('sticky_link')->nullable()->comment('Sticky item link')->after('sticky_title'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('sites', function (Blueprint $table) { + $table->dropColumn('sticky_title'); + $table->dropColumn('sticky_link'); + }); + } +}; diff --git a/resources/lang/fr/validation.php b/resources/lang/fr/validation.php index d8d8285..c9b10c4 100644 --- a/resources/lang/fr/validation.php +++ b/resources/lang/fr/validation.php @@ -296,5 +296,9 @@ return [ 'message' => 'message', 'banner' => 'bannière', 'subtitle' => 'sous-titre', + 'sticky_item' => [ + 'title' => 'titre de l\'ancre', + 'link' => 'lien de l\'ancre', + ], ], ]; diff --git a/resources/sass/fo/pages/_site.scss b/resources/sass/fo/pages/_site.scss index 7c55318..1163503 100644 --- a/resources/sass/fo/pages/_site.scss +++ b/resources/sass/fo/pages/_site.scss @@ -20,4 +20,45 @@ } } } + + .site-navigation { + @include media-breakpoint-up(md) { + position: fixed; + z-index: 10; + bottom: 4rem; + left: 4rem; + max-width: 15rem; + + &-wrapper { + height: 0; + opacity: 0; + transform: translateY(25%); + transition: .3s; + visibility: hidden; + + &.show { + height: auto; + opacity: 1; + transform: translateY(0); + visibility: visible; + } + } + } + + .col-md-12 { + @include media-breakpoint-up(md) { + width: fit-content; + } + + .badge { + width: .5rem; + height: .5rem; + + @include media-breakpoint-up(md) { + width: 1rem; + height: 1rem; + } + } + } + } } diff --git a/resources/ts/fo/fo.ts b/resources/ts/fo/fo.ts index be0e1f6..0136a00 100644 --- a/resources/ts/fo/fo.ts +++ b/resources/ts/fo/fo.ts @@ -21,4 +21,5 @@ import "./base/layout"; // PAGES import "./pages/commitments"; import "./pages/unveil"; +import "./pages/site"; diff --git a/resources/ts/fo/pages/site.ts b/resources/ts/fo/pages/site.ts new file mode 100644 index 0000000..1f60eed --- /dev/null +++ b/resources/ts/fo/pages/site.ts @@ -0,0 +1,17 @@ +document.addEventListener("DOMContentLoaded", function () { + const site = document.querySelector("section.site"); + if (site === null) { + return; + } + + const button = document.querySelector(".site-navigation .btn") as HTMLButtonElement; + const navWrapper = document.querySelectorAll(".site-navigation-wrapper "); + button.addEventListener("click", () => { + navWrapper.forEach((element: Element) => { + element.classList.toggle("show"); + }); + document.querySelectorAll(".site-navigation .btn svg").forEach(icon => { + icon.classList.toggle("d-none"); + }); + }); +}); diff --git a/resources/views/bo/pages/sites/form.blade.php b/resources/views/bo/pages/sites/form.blade.php index efac1b6..1acf33d 100644 --- a/resources/views/bo/pages/sites/form.blade.php +++ b/resources/views/bo/pages/sites/form.blade.php @@ -532,6 +532,72 @@ + {{-- STICKY --}} +
+
+ {{ Str::ucfirst(trans_choice('validation.custom.sticky', 0)) }} +
+ {{-- STICKY_TITLE --}} +
+ @include('bo.partials.inputs.varchar', [ + 'id' => 'siteStickyTitle', + 'label' => __(':field :inter :model', [ + 'field' => Str::ucfirst(__('validation.custom.sticky_item.title')), + 'inter' => __('validation.custom.of_the.male'), + 'model' => trans_choice('models.classes.site', 1), + ]), + 'hasWordCounter' => true, + 'name' => 'sticky_title', + 'required' => false, + 'model' => $siteModel ?? null, + 'helper' => __('validation.between.string', [ + 'attribute' => __(':field :inter:model', [ + 'field' => __('validation.custom.sticky_item.title'), + 'inter' => __('validation.custom.of_the.male'), + 'model' => trans_choice('models.classes.site', 1), + ]), + 'min' => 3, + 'max' => 255, + ]), + 'placeholder' => __(':field :inter :model', [ + 'field' => Str::ucfirst(__('validation.custom.sticky_item.title')), + 'inter' => __('validation.custom.of_the.male'), + 'model' => trans_choice('models.classes.site', 1), + ]), + ]) +
+ {{-- STICKY_LINK --}} +
+ @include('bo.partials.inputs.varchar', [ + 'id' => 'siteStickyLink', + 'label' => __(':field :inter :model', [ + 'field' => Str::ucfirst(__('validation.custom.sticky_item.link')), + 'inter' => __('validation.custom.of_the.male'), + 'model' => trans_choice('models.classes.site', 1), + ]), + 'hasWordCounter' => true, + 'name' => 'sticky_link', + 'required' => false, + 'model' => $siteModel ?? null, + 'helper' => __('validation.between.string', [ + 'attribute' => __(':field :inter:model', [ + 'field' => __('validation.custom.sticky_item.link'), + 'inter' => __('validation.custom.of_the.male'), + 'model' => trans_choice('models.classes.site', 1), + ]), + 'min' => 3, + 'max' => 255, + ]), + 'placeholder' => __(':field :inter :model', [ + 'field' => Str::ucfirst(__('validation.custom.sticky_item.link')), + 'inter' => __('validation.custom.of_the.male'), + 'model' => trans_choice('models.classes.site', 1), + ]), + ]) +
+
+
+
{{-- LOGO --}}
diff --git a/resources/views/fo/pages/site.blade.php b/resources/views/fo/pages/site.blade.php index aa78bc4..c4cf9da 100644 --- a/resources/views/fo/pages/site.blade.php +++ b/resources/views/fo/pages/site.blade.php @@ -6,6 +6,28 @@ @section('content')
+ @if ($siteModel->sticky_title && $siteModel->sticky_link) + + @endif