Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
Jérémy Munsch
d83281f6a6
Closes #34 News 2023-12-22 17:35:39 +01:00
20 changed files with 507 additions and 74 deletions

View file

@ -0,0 +1,45 @@
<?php
namespace App\Http\Controllers\Fo;
use App\Enums\StaticPageType;
use App\Http\Controllers\Controller;
use App\Models\News;
use App\Models\Range;
use App\Models\StaticPage;
class NewsController extends Controller
{
/**
* Display the homepage.
*
* @return \Illuminate\Contracts\View\View
*/
public function index(): \Illuminate\Contracts\View\View
{
$staticPageModel = StaticPage::query()
->where('type', StaticPageType::news)
->firstOrFail();
$rangeModelList = Range::query()->limit(3)->inRandomOrder()->get();
$newsModelList = News::query()->get();
return view('fo.pages.news.index', compact(
'staticPageModel',
'newsModelList',
'rangeModelList'
));
}
/**
* Show a specific resource.
*
* @param \App\Models\News $frontNews
* @return \Illuminate\Contracts\View\View
*/
public function show(News $frontNews): \Illuminate\Contracts\View\View
{
return view('fo.pages.news.show', [
'newsModel' => $frontNews
]);
}
}

View file

@ -42,6 +42,9 @@ class StoreNewsRequest extends FormRequest
public function rules(): array
{
$rules = [
'seo_title' => 'required|between:45,70',
'seo_description' => 'required|between:50,160',
'title' => 'required|string|between:3,100',
'text' => [
'required',
'string',
@ -78,6 +81,9 @@ class StoreNewsRequest extends FormRequest
public function attributes(): array
{
return [
'seo_title' => trans('validation.custom.seo_title'),
'seo_description' => trans('validation.custom.seo_description'),
'title' => trans('validation.attributes.title'),
'text' => trans('validation.attributes.text'),
'picture_alt' => trans('validation.custom.picture_alt'),
'picture_title' => trans('validation.custom.picture_title'),

View file

@ -3,10 +3,17 @@
namespace App\Models;
use App\Lib\Helpers\FileStorageHelper;
use App\Lib\Helpers\ToolboxHelper;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
/**
* @property string $seo_title Utilisé pour la balise title de la page.
* @property string $seo_description Utilisé pour la balise meta description
* de la page.
* @property string $title Titre de la news.
* @property string $slug Slug à partir du titre de la news.
* @property string $picture Path de l'image (308px * 223px).
* @property string $picture_alt Attribut alt de l'image.
* @property string $picture_title Attribut title de l'image.
@ -27,6 +34,10 @@ class News extends Model
* @var array<int, string>
*/
protected $fillable = [
'seo_title',
'seo_description',
'title',
'slug',
'picture',
'picture_alt',
'picture_title',
@ -79,10 +90,30 @@ class News extends Model
*/
private static function manageFields(self $model): void
{
// * ASSERTIONS
self::assertFieldIsUnique('title', $model->title, $model->id);
self::assertFieldIsUnique('slug', Str::slug($model->title), $model->id);
// * TRANSFORMATIONS
$model->title = Str::slug($model->title);
self::makeStatusSense($model);
$model->picture = FileStorageHelper::storeFile($model, $model->picture, true);
}
/**
* Asserts using validation that the field is unique.
*
* @param string $nameField
* @param string $valueField
* @param integer|null $id
* @return void
*/
private static function assertFieldIsUnique(string $nameField, string $valueField, ?int $id = null): void
{
$table = (new self())->getTable();
ToolboxHelper::assertFieldIsUnique($table, $nameField, $valueField, $id);
}
/**
* Adjusts model status using current status and publish dates
*

View file

@ -115,7 +115,7 @@ class Product extends Model
self::assertFieldIsUnique('slug', Str::slug($model->label), $model->id);
// * TRANSFORMATIONS
self::setSlug($model, $model->label);
$model->label = Str::slug($model->label);
$model->picture = FileStorageHelper::storeFile($model, $model->picture, true);
$model->picture_thumbnail = FileStorageHelper::storeFile($model, $model->picture_thumbnail, true);
}
@ -145,19 +145,6 @@ class Product extends Model
ToolboxHelper::assertFieldIsUnique($table, $nameField, $valueField, $id);
}
/**
* 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);
}
// * RELATIONS
/**

View file

@ -48,6 +48,7 @@ class RouteServiceProvider extends ServiceProvider
->group(base_path('routes/web-fo.php'));
});
Route::bind('frontNews', fn ($value) => News::query()->where('slug', $value)->firstOrFail());
Route::model('user', User::class);
Route::model('picto', Picto::class);
Route::model('range', Range::class);

View file

@ -0,0 +1,62 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
$news = DB::table('news')->get();
Schema::table('news', function (Blueprint $table) {
$table->string('seo_title')->after('id')
->comment('Utilisé pour la balise title de la page produit');
$table->string('seo_description')->after('seo_title')
->comment('Utilisé pour la balise meta description de la page produit');
$table->string('title')->after('seo_description')
->comment('Titre de la news');
$table->string('slug')->after('title')
->comment('Slug à partir du titre de la news');
$table->text('text')->change()
->comment('WYSIWYG - Texte de l\'actualité.');
});
$news->each(function (object $news) {
$title = fake()->unique()->jobTitle;
DB::table('news')->where('id', $news->id)
->update([
'seo_title' => fake()->words(3, true),
'seo_description' => fake()->words(7, true),
'title' => $title,
'slug' => Str::slug($title),
]);
});
Schema::table('news', function (Blueprint $table) {
$table->unique('slug');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('news', function (Blueprint $table) {
$table->dropColumn('seo_title');
$table->dropColumn('seo_description');
$table->dropColumn('title');
$table->dropColumn('slug');
$table->text('text')->change()
->comment('WYSIWYG - Texte de l\'actualité. Max 80 mots.');
});
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

View file

@ -12,7 +12,7 @@
}
// N'as rien à faire ici !!
.products, .history, .news {
.products, .history {
h1, h2 {
&::after {
display: block;
@ -39,3 +39,7 @@
opacity: 1 !important;
visibility: visible !important;
}
.color-primary {
color: $color-primary !important;
}

View file

@ -25,6 +25,7 @@
@import './pages/product';
@import './pages/ranges';
@import './pages/range';
@import './pages/news-index';
// * PARTIALS
@import './partials/news-section';

View file

@ -1,4 +1,4 @@
.historypage {
.historypage,.newspage {
.ourproducts {
&::before {
position: relative;
@ -129,7 +129,7 @@
// X:::::X X:::::XL::::::::::::::::::::::L
// XXXXXXX XXXXXXXLLLLLLLLLLLLLLLLLLLLLLLL
@include media-breakpoint-up(xl) {
.historypage {
.historypage,.newspage {
.ourproducts {
.seagull {
top: 2.5rem;

View file

@ -0,0 +1,28 @@
.newspage {
#swiper-news-index {
clip-path: inset(-2rem -50vw 0 0);
// .swiper-slide {
// max-width: 22rem;
// }
.swiper-button-prev-custom, .swiper-button-next-custom {
&:hover {
cursor: pointer;
}
}
}
.link-news::after {
position: relative;
top: -0.5rem;
display: block;
width: 100%;
height: 1rem;
background-image: url('@/images/global/underline-yellow.svg');
background-position: center;
background-repeat: no-repeat;
background-size: 3rem;
content: "";
}
}

View file

@ -47,6 +47,26 @@ document.addEventListener("DOMContentLoaded", function () {
}
// SWIPER
const swiperConfig = {
"swiper-news-index": {
modules: [Navigation],
grabCursor: true,
slidesPerView: 1,
navigation: {
nextEl: ".swiper-button-next-custom",
prevEl: ".swiper-button-prev-custom",
},
breakpoints: {
500: {
slidesPerView: 2,
},
768: {
slidesPerView: 3,
},
1200: {
slidesPerView: 4,
},
},
},
"swiper-news": {
modules: [Navigation],
grabCursor: true,

View file

@ -1,29 +1,103 @@
<div class="row">
{{-- TEXT --}}
<div class="col-12 col-md-6 mb-3">
{{-- SEO --}}
<div class="col-12 pb-3">
<fieldset class="h-100 border p-3">
<legend>{{ Str::ucfirst(__('validation.attributes.text')) }}</legend>
<div class="row">
<div class="col-12">
<legend>{{ Str::ucfirst(__('validation.custom.seo')) }}</legend>
<div class="row mb-3">
{{-- SEO_TITLE --}}
<div class="col-12 col-md-6 m-md-0 mb-3">
@include('bo.partials.inputs.varchar', [
'id' => 'newsText',
'id' => 'newsSeoTitle',
'label' => __(':field :inter:model', [
'field' => Str::ucfirst(__('validation.attributes.text')),
'inter' => __('validation.custom.of_the.vowel'),
'field' => Str::ucfirst(__('validation.custom.seo_title')),
'inter' => __('validation.custom.of_the.male'),
'model' => __('models.classes.news'),
]),
'hasWordCounter' => true,
'name' => 'text',
'name' => 'seo_title',
'required' => true,
'model' => $newsModel ?? null,
'helper' => __('validation.string', [
'helper' => sprintf(
'%s %s',
__('crud.helpers.seo_title'),
__('validation.between.string', [
'attribute' => __(':field :inter:model', [
'field' => Str::ucfirst(__('validation.attributes.text')),
'inter' => __('validation.custom.of_the.vowel'),
'field' => __('validation.custom.seo_title'),
'inter' => __('validation.custom.of_the.female'),
'model' => __('models.classes.news'),
]),
'min' => 45,
'max' => 70,
])),
'placeholder' => __(':field :inter:model', [
'field' => Str::ucfirst(__('validation.custom.seo_title')),
'inter' => __('validation.custom.of_the.male'),
'model' => __('models.classes.news'),
]),
'placeholder' => Str::ucfirst(__('validation.attributes.text')),
])
</div>
{{-- SEO_DESCRIPTION --}}
<div class="col-12 col-md-6 m-md-0 mb-3">
@include('bo.partials.inputs.varchar-multiline', [
'id' => 'newsSeoDescription',
'label' => __(':field :inter:model', [
'field' => Str::ucfirst(__('validation.custom.seo_description')),
'inter' => __('validation.custom.of_the.male'),
'model' => __('models.classes.news'),
]),
'hasWordCounter' => true,
'name' => 'seo_description',
'required' => true,
'model' => $newsModel ?? null,
'helper' => sprintf(
'%s %s',
__('crud.helpers.seo_description'),
__('validation.between.string', [
'attribute' => __(':field :inter:model', [
'field' => __('validation.custom.seo_description'),
'inter' => __('validation.custom.of_the.female'),
'model' => __('models.classes.news'),
]),
'min' => 50,
'max' => 160,
])),
'placeholder' => __(':field :inter:model', [
'field' => Str::ucfirst(__('validation.custom.seo_description')),
'inter' => __('validation.custom.of_the.male'),
'model' => __('models.classes.news'),
]),
])
</div>
</div>
</fieldset>
</div>
{{-- TITLE --}}
<div class="col-12 col-md-6 mb-3">
<fieldset class="h-100 border p-3">
<legend>{{ Str::ucfirst(__('validation.attributes.title')) }}</legend>
<div class="row">
<div class="col-12">
@include('bo.partials.inputs.varchar', [
'id' => 'newsTitle',
'label' => __(':field :inter:model', [
'field' => Str::ucfirst(__('validation.attributes.title')),
'inter' => __('validation.custom.of_the.male'),
'model' => __('models.classes.news'),
]),
'hasWordCounter' => true,
'name' => 'title',
'required' => true,
'model' => $newsModel ?? null,
'helper' => __('validation.between.string', [
'attribute' => __(':field :inter:model', [
'field' => __('validation.attributes.title'),
'inter' => __('validation.custom.of_the.male'),
'model' => __('models.classes.news'),
]),
'min' => 3,
'max' => 100,
]),
'placeholder' => __('Un titre clair et concis'),
])
</div>
</div>
@ -103,6 +177,28 @@
</div>
</fieldset>
</div>
{{-- TEXT --}}
<div class="col-12 mb-3">
<fieldset class="border p-3">
<legend>{{ Str::ucfirst(__('validation.attributes.text')) }}</legend>
<div class="row mb-3">
<div class="col-12">
@include('bo.partials.inputs.text-html', [
'id' => 'newsDescription',
'label' => __(':field :inter:model', [
'field' => Str::ucfirst(__('validation.attributes.text')),
'inter' => __('validation.custom.of_the.male'),
'model' => __('models.classes.news'),
]),
'name' => 'text',
'model' => $newsModel ?? null,
'required' => true,
'helper' => __('crud.minicrud.text_warning'),
])
</div>
</div>
</fieldset>
</div>
{{-- PUBLISHED --}}
<div class="col-12 col-md-6 mb-3">
<fieldset class="h-100 border p-3">

View file

@ -22,7 +22,7 @@
'url' => route('fo.ranges.index'),
'text' => __('Nos produits'),
'title' => __('Nos produits'),
'is_active' => request()->routeIs('fo.ranges.index'),
'is_active' => request()->routeIs('fo.ranges.*'),
'sub_menu_list' => $ranges,
])
</li>
@ -42,6 +42,14 @@
'is_active' => request()->routeIs('fo.commitments.show'),
])
</li>
<li class="nav-item">
@include('fo.layouts.nav-link', [
'url' => route('fo.news.index'),
'text' => __('Nos actualités'),
'title' => __('Nos actualités'),
'is_active' => request()->routeIs('fo.news.*'),
])
</li>
<li class="nav-item">
@include('fo.layouts.nav-link', [
'url' => route('fo.klub.home'),

View file

@ -63,39 +63,7 @@
<div class="historical-milestones-slider" data-json='@json($data)'></div>
</section>
{{-- OUR PRODUCTS --}}
<section class="ourproducts position-relative">
<div class="bg-tertiary px-0 pt-5">
<div class="container">
<div class="row">
<h2 class="col fs-1 text-primary text-center">{{ __('Découvrez nos produits') }}</h2>
</div>
<div class="position-relative d-flex flex-column flex-xl-row justify-content-center">
@foreach ($rangeModels as $key => $rangeModel)
<div class="d-flex flex-column justify-content-center align-items-center mx-md-1 mx-lg-2 mx-xxl-4 m-0">
<div class="position-relative py-3 text-center">
<img class="rounded-circle w-100 h-auto" src="{{ asset($rangeModel->picture_ambiance) }}"
title="{{ $rangeModel->picture_ambiance_title }}" alt="{{ $rangeModel->picture_ambiance_alt }}">
<img class="ourproducts-ellipse position-absolute translate-middle start-50 top-50 h-auto"
alt="cercle fin de couleur blanc"
@if ($key % 2) src="{{ Vite::asset('resources/assets/images/global/ellipse_white.png') }}"
@else
src="{{ Vite::asset('resources/assets/images/global/ellipse_blue.png') }}" @endif>
</div>
<a class="ourproducts-btn btn @if ($key % 2) btn-white btn-rotate-right @else btn-primary btn-rotate-left @endif fs-4 my-2 px-4"
href="{{ route('fo.ranges.show', $rangeModel->slug) }}"
title="{{ __('Voir les produits de la gamme') }} {{ $rangeModel->label }}">
{{ Str::limit(__($rangeModel->label), 30) }}
</a>
</div>
@endforeach
</div>
<div class="d-none d-xl-block seagull-column me-4">
<img class="img-fluid position-absolute end-0" id="seagulls-scroll" data-offset="16"
src="{{ Vite::asset('resources/assets/images/global/mouettes.svg') }}" alt="{{ __('Ombre de mouettes') }}">
</div>
</div>
</div>
</section>
@include('fo.partials.our-products', ['rangeModels' => $rangeModels])
{{-- NEWS --}}
@include('fo.partials.news-section')
</section>

View file

@ -0,0 +1,95 @@
@extends('fo.layout')
@section('title', $staticPageModel->seo_title)
@section('description', $staticPageModel->seo_description)
@section('breadcrumb',
request()->route()->getName())
@section('main-bg-class', 'has-banner newspage')
{{-- @section('banner')
<div class="container-fluid">
<div class="row">
<div class="col g-0">
<img class="img-fluid banner-picture object-fit-cover w-100" src="{{ Vite::asset('resources/assets/images/news/news-bg.jpg') }}"
alt="{{ __('Bannière de la page actualités') }}">
</div>
</div>
</div>
@endsection --}}
@section('banner')
<div class="container-fluid">
<div class="row position-relative bulle-banner">
<div class="col-12 g-0">
<img class="img-fluid banner-picture object-fit-cover w-100 h-100 z-n1 position-relative"
src="{{ Vite::asset('resources/assets/images/news/news-bg.jpg') }}" alt="{{ __('Bannière de la page nos engagements') }}">
</div>
{{-- Nos Engagements header (mobile hide) --}}
<div class="col-12 d-none d-xl-block position-absolute translate-middle-y col-6 g-0 top-50 start-0">
<div class="container">
<div class="row justify-content-center">
<div class="col-7 col-xx-6 div-bulle px-5 py-3">
<div class="p-5">
<div class="text-center">
<h1 class="fs-1 f-intro-head-h-base text-primary text-center">{{ $staticPageModel->title }}</h1>
<img class="img-fluid flex-shrink-1 mb-3 flex-grow-0"
src="{{ Vite::asset('resources/assets/images/global/underline-yellow.svg') }}"
alt="{{ __('Trait souligné') }}">
</div>
<div class="ck-content">{!! clean($staticPageModel->content) !!}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
@section('content')
<section class="bg-light-top-tear container-fluid mt-0 pb-5">
<div class="row justify-content-center pt-5">
<div class="col-12 col-lg-10 g-0">
{{-- SWIPER NEWS --}}
<div class="swiper" id="swiper-news-index">
<div class="swiper-wrapper">
@foreach ($newsModelList as $newsModel)
<div class="swiper-slide">
<div class="card rounded-5 mx-3">
<img class="card-img-top rounded-top-5" src="{{ asset($newsModel->picture) }}"
title="{{ $newsModel->picture_title }}" alt="{{ $newsModel->picture_alt }}">
<div class="card-body">
<p class="card-text">
{{ Str::limit(strip_tags($newsModel->text), 150, '...') }}
</p>
<a class="link-primary fs-5 link-news text-decoration-none d-block fw-bold text-center"
href="{{ route('fo.news.show', $newsModel) }}"
title="{{ __('Aller sur la page d\'actualité :name', ['name' => $newsModel->picture_title]) }}">
{{ __('En savoir plus') }}
</a>
</div>
</div>
</div>
@endforeach
</div>
<div class="d-flex justify-content-start mx-5 mt-4">
<div class="swiper-button swiper-button-prev-custom mx-3">
<button class="btn btn-light color-primary" data-bs-toggle="tooltip" title="{{ __('Voir les news precentes') }}">
<i class="fa-solid fa-chevron-left"></i>
</button>
</div>
<div class="swiper-button swiper-button-next-custom mx-3">
<button class="btn btn-light color-primary" data-bs-toggle="tooltip" title="{{ __('Voir les news suivantes') }}">
<i class="fa-solid fa-chevron-right"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</section>
{{-- OUR PRODUCTS --}}
@include('fo.partials.our-products', ['rangeModels' => $rangeModelList])
@endsection

View file

@ -0,0 +1,42 @@
@extends('fo.layout')
@section('title', __($newsModel->seo_title))
@section('description', __($newsModel->seo_description))
@section('breadcrumb',
request()->route()->getName())
@section('main-bg-class', 'has-banner newspage-show')
@section('banner')
<div class="container-fluid">
<div class="row">
<div class="col g-0">
<img class="img-fluid banner-picture object-fit-cover w-100" src="{{ Vite::asset('resources/assets/images/news/news-bg.jpg') }}"
alt="{{ __('Bannière de la page actualités') }}">
</div>
</div>
</div>
@endsection
@section('content')
<div class="bg-light-top-tear container-fluid mt-0 pb-5">
<div class="col-12 mb-3 text-center">
<h1 class="fs-1 f-intro-head-h-base text-primary">
{{ $newsModel->title }}
</h1>
<img class="img-fluid mb-3" src="{{ Vite::asset('resources/assets/images/global/underline-yellow.svg') }}"
alt="{{ __('Trait souligné') }}">
</div>
<div class="row mb-3">
<div class="col text-center">
<img class="img-fluid" src="{{ asset($newsModel->picture) }}" title="{{ $newsModel->picture_title }}"
alt="{{ $newsModel->picture_alt }}">
</div>
</div>
<div class="row justify-content-center mb-5">
<div class="col-md-11 col-lg-9 ck-content">
{!! clean($newsModel->text) !!}
</div>
</div>
</div>
@endsection

View file

@ -7,9 +7,10 @@
<p>
{{ __('Découvrez les dernières actualités croustillantes de Tre Galette ! Retrouvez tous nos événements très bretons, nos idées de recette et nos conseils très gourmands. Un voyage gourmand en Bretagne vous attend ! ') }}
</p>
{{-- TODO: Changer le lien quand la page actualité index sera faite. --}}
<a class="btn btn-tertiary btn-rotate-left fs-2 px-4" href="#CHANGEME"
title="{{ __('Nos actualités') }}">{{ __('Nos actualités') }}</a>
<a class="btn btn-tertiary btn-rotate-left fs-2 px-4" href="{{ route('fo.news.index') }}"
title="{{ __('Se rendre sur la page Nos actualités') }}">
{{ __('Nos actualités') }}
</a>
</div>
<div class="col-12 col-lg-8">
{{-- SWIPER NEWS --}}
@ -25,7 +26,7 @@
title="{{ $news->picture_title }}" alt="{{ $news->picture_alt }}">
<div class="card-body">
<p class="card-text">
{{ $news->text }}
{{ Str::limit(strip_tags($news->text), 150, '...') }}
</p>
</div>
</div>

View file

@ -0,0 +1,33 @@
<section class="ourproducts position-relative">
<div class="bg-tertiary px-0 pt-5">
<div class="container">
<div class="row">
<h2 class="col fs-1 text-primary text-center">{{ __('Découvrez nos produits') }}</h2>
</div>
<div class="position-relative d-flex flex-column flex-xl-row justify-content-center">
@foreach ($rangeModels as $key => $rangeModel)
<div class="d-flex flex-column justify-content-center align-items-center mx-md-1 mx-lg-2 mx-xxl-4 m-0">
<div class="position-relative py-3 text-center">
<img class="rounded-circle w-100 h-auto" src="{{ asset($rangeModel->picture_ambiance) }}"
title="{{ $rangeModel->picture_ambiance_title }}" alt="{{ $rangeModel->picture_ambiance_alt }}">
<img class="ourproducts-ellipse position-absolute translate-middle start-50 top-50 h-auto"
alt="cercle fin de couleur blanc"
@if ($key % 2) src="{{ Vite::asset('resources/assets/images/global/ellipse_white.png') }}"
@else
src="{{ Vite::asset('resources/assets/images/global/ellipse_blue.png') }}" @endif>
</div>
<a class="ourproducts-btn btn @if ($key % 2) btn-white btn-rotate-right @else btn-primary btn-rotate-left @endif fs-4 my-2 px-4"
href="{{ route('fo.ranges.show', $rangeModel->slug) }}"
title="{{ __('Voir les produits de la gamme') }} {{ $rangeModel->label }}">
{{ Str::limit(__($rangeModel->label), 30) }}
</a>
</div>
@endforeach
</div>
<div class="d-none d-xl-block seagull-column me-4">
<img class="img-fluid position-absolute end-0" id="seagulls-scroll" data-offset="16"
src="{{ Vite::asset('resources/assets/images/global/mouettes.svg') }}" alt="{{ __('Ombre de mouettes') }}">
</div>
</div>
</div>
</section>

View file

@ -1,5 +1,6 @@
<?php
use App\Http\Controllers\Fo\NewsController;
use App\Http\Controllers\Fo\ContactController;
use App\Http\Controllers\Fo\HomeController;
use App\Http\Controllers\Fo\Klub\CustomerController;
@ -55,6 +56,10 @@ Route::middleware(['throttle:credentials'])->name('fo.')->group(function () {
});
});
// * NEWS
Route::get('/actualites', [NewsController::class, 'index'])->name('news.index');
Route::get('/actualites/{frontNews:slug}', [NewsController::class, 'show'])->name('news.show');
// * RANGES
Route::get('/gammes', [RangeController::class, 'index'])->name('ranges.index');
Route::get('/gamme/{slug}', [RangeController::class, 'show'])->name('ranges.show');