fix conflicts and adjust dates & css colors

This commit is contained in:
System User 2026-05-13 13:16:28 +02:00
commit 9b496b7143
82 changed files with 3102 additions and 616 deletions

View file

@ -103,7 +103,8 @@ AXEPTA_APIKEY=
AXEPTA_HMAC=
# GOLDEN CRUSH (ex : 2026-05-24)
GOLDEN_VOTE_START_AT=
GOLDEN_VOTE_END_AT=
GOLDEN_END_PARTICIPATION_END_AT=
GOLDEN_END_GAME_END_AT=
GOLDEN_GAME_START=2026-06-01
GOLDEN_VOTE_START_AT=2026-06-16
GOLDEN_VOTE_END_AT=2026-07-01
GOLDEN_END_PARTICIPATION_END_AT=2026-07-02
GOLDEN_END_GAME_END_AT=2026-07-17

View file

@ -8,20 +8,22 @@ enum InputType: int
{
use BaseEnum;
case boolean = 1;
case dropdownArray = 2;
case email = 3;
case image = 4;
case imageArray = 5;
case labelArray = 6;
case miniblocArray = 7;
case number = 8;
case selectEnum = 9;
case password = 10;
case string = 11;
case text = 12;
case url = 13;
case videoVimeo = 14;
case videoYoutube = 15;
case video = 16;
case boolean = 1;
case dropdownArray = 2;
case email = 3;
case image = 4;
case imageArray = 5;
case labelArray = 6;
case miniblocArray = 7;
case number = 8;
case selectEnum = 9;
case password = 10;
case string = 11;
case text = 12;
case url = 13;
case videoVimeo = 14;
case videoYoutube = 15;
case video = 16;
case slider = 17;
case selectImageVideo = 18;
}

View file

@ -33,6 +33,7 @@ enum StaticPageType: int
case exitOutside = 23;
case ouiCBon = 24;
case ourFarms = 25;
case tdf = 26;
/**
* Optionnal labels definition.
@ -64,7 +65,8 @@ enum StaticPageType: int
self::rules->name => 'Règlement du jeu',
self::exitOutside->name => 'Sortir à l\'extérieur',
self::ouiCBon->name => 'Oui c\'est bon',
self::ourFarms->name => 'Nos élevages'
self::ourFarms->name => 'Nos élevages',
self::tdf->name => 'Tour de France'
];
/**

View file

@ -43,9 +43,19 @@ class StaticPageController extends Controller
public function update(UpdateStaticPageRequest $request, StaticPage $static_page): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request, $static_page) {
$validated = $request->validated();
$data = $static_page->data;
foreach ($validated['data'] as $key => $input) {
if (isset($input['value']) && is_array($input['value'])) {
$data[$key]['value'] = $input['value'];
}
}
$static_page->data = $data;
$static_page->fill(array_replace_recursive(
$static_page->getFillableFields($static_page),
$request->validated()
$validated
));
if ($static_page->saveOrFail()) {
@ -73,7 +83,7 @@ class StaticPageController extends Controller
->map(fn($page) => $page->data['common_section'] ?? null)
->filter()
->first();
return view('bo.pages.static_pages.common_section.edit', [
'commonSection' => $commonSection,
]);
@ -88,17 +98,17 @@ class StaticPageController extends Controller
public function updateCommonSection(UpdateCommonSectionRequest $request): RedirectResponse
{
$pages = StaticPage::whereIn('type', StaticPageType::getBreedingValues())->get();
try {
DB::transaction(function () use ($pages, $request) {
foreach ($pages as $page) {
$data = $page->data ?? [];
$data['common_section'] = [
'title' => $request->validated('title'),
'content' => $request->validated('content'),
];
$page->data = $data;
$page->saveOrFail();
}
@ -110,7 +120,7 @@ class StaticPageController extends Controller
->with('error', __('crud.messages.cannot_be_updated', [
'model' => Str::ucfirst(__('validation.custom.common_section_part'))]));
}
return redirect()
->route('bo.static_page.sections.edit')
->with('success', __('crud.messages.has_been_updated', [

View file

@ -2,6 +2,7 @@
namespace App\Http\Controllers\Club;
use App\Enums\Shop\ContactFormCivility;
use App\Enums\Shop\OrderStatus;
use App\Enums\Shop\OrderType;
use App\Exceptions\CBPayementError;
@ -69,6 +70,7 @@ class ShopController extends Controller
$order->payementType = OrderType::make(intval($request->payementMethod));
$order->status = OrderStatus::waiting;
$order->customer_id = $customerModel->getKey();
$order->civility = ContactFormCivility::m; // FIXME: Remove this field
$order->fill($request->coords);
$order->saveOrFail();
} catch (QueryException $e) {

View file

@ -39,13 +39,16 @@ class BreedingController extends Controller
$ocbBreederModels = OcbBreeder::getOcbBreederCards();
$staticPage = StaticPage::query()->where('type', StaticPageType::ouiCBon)->first();
$categoryApproachModels = CategoryApproach::all();
$sections = SectionApproach::query()->where('page_id', $staticPage->id)->get();
$sectionApproachModels = CollectionHelper::mapItemsToCards($sections->toArray(), $categoryApproachModels->toArray());
$sections = SectionApproach::query()
->with('category')
->where('page_id', $staticPage->id)
->get()
->groupBy(fn($section) => $section->category?->name);
return view('fo.pages.breeding.oui-c-est-bon', [
'ocbBreederModels' => $ocbBreederModels,
'staticPageModel' => $staticPage,
'categoryApproachModels' => $categoryApproachModels,
'sectionApproachModels' => $sectionApproachModels
'sections' => $sections
]);
}
@ -75,24 +78,27 @@ class BreedingController extends Controller
]);
}
/**
* Display the given breeding page.
*
* @return \Illuminate\Contracts\View\View
*/
/**
* Display the given breeding page.
*
* @return \Illuminate\Contracts\View\View
*/
public function exitOutsidePage(): \Illuminate\Contracts\View\View
{
$staticPage = StaticPage::query()->where('type', StaticPageType::exitOutside)->first();
$sliderImages = CollectionHelper::mapSlidesToFields($staticPage->data);
$categoryApproachModels = CategoryApproach::all();
$sections = SectionApproach::query()->where('page_id', $staticPage->id)->get();
$sectionApproachModels = CollectionHelper::mapItemsToCards($sections->toArray(), $categoryApproachModels->toArray());
$sections = SectionApproach::query()
->with('category')
->where('page_id', $staticPage->id)
->get()
->groupBy(fn($section) => $section->category?->name);
return view('fo.pages.breeding.sortant-a-l-exterieur', [
'staticPageModel' => $staticPage,
'sliderImages' => $sliderImages,
'staticPageModel' => $staticPage,
'sliderImages' => $sliderImages,
'categoryApproachModels' => $categoryApproachModels,
'sectionApproachModels' => $sectionApproachModels
'sections' => $sections,
]);
}

View file

@ -3,6 +3,7 @@
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
use App\Lib\Helpers\GamePeriodHelper;
use App\Models\GoldenCrushGame;
class GoldenCrushController extends Controller
@ -14,7 +15,8 @@ class GoldenCrushController extends Controller
*/
public function index(): \Illuminate\Contracts\View\View
{
return view('fo.pages.goldenCrush.golden-crush');
$startVote = GamePeriodHelper::isGamePeriod();
return view('fo.pages.goldenCrush.golden-crush', ['startVote' => $startVote]);
}
/**

View file

@ -141,4 +141,15 @@ class StaticPageController extends Controller
$videoModels = Video::get6PublishedVideosOrderedWithProducts();
return view('fo.pages.saga', compact('staticPageModel', 'videoModels'));
}
/**
* TDF page.
*
* @return \Illuminate\Contracts\View\View
*/
public function tdf(): \Illuminate\Contracts\View\View
{
$staticPageModel = StaticPage::getCachedStaticPage(StaticPageType::tdf);
return view('fo.pages.tdf', compact('staticPageModel'));
}
}

View file

@ -20,6 +20,7 @@ class RedirectToGoldenIfVoteOpen
$isClubContext = str_starts_with($request->route()->getName(), 'club.');
$targetRoute = match ($currentState) {
'start_game' => 'club.home.show',
'vote' => $isClubContext ? 'club.golden-crush' : 'fo.golden-crush',
'end_participation' => $isClubContext ? 'club.golden-crush.end-of-participation' : 'fo.participation-ended',
'end_game' => $isClubContext ? 'club.golden-crush.end-of-game' : 'fo.game-ended',

View file

@ -5,6 +5,7 @@ namespace App\Http\Requests\Bo;
use App\Enums\InputType;
use App\Lib\Helpers\ToolboxHelper;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Arr;
use Illuminate\Validation\ValidationException;
abstract class UpdateMiniCrudRequest extends FormRequest
@ -203,6 +204,36 @@ abstract class UpdateMiniCrudRequest extends FormRequest
$rules = array_merge($rules, [
"data.$iptName.value" => 'boolean'
]);
break;
case InputType::slider->value:
foreach ($input['columns'] as $column) {
$columnId = $column['id'];
$validation = $column['validation'] ?? '';
if (!empty($validation)) {
$rules["data.$iptName.value.*.$columnId"] = $validation;
}
}
break;
case InputType::selectImageVideo->value:
if (Arr::exists($this->input("data.$iptName.value"), 'picture')) {
$rules = array_merge($rules, [
"data.$iptName.value.picture" => "required|array",
"data.$iptName.value.picture.path" => "required|image|mimes:png,jpg,jpeg|dimensions:width=620,height=348",
"data.$iptName.value.picture.alt" => "required|string|between:3,255",
"data.$iptName.value.picture.title" => "required|string|between:3,255",
]);
}
if (Arr::exists($this->input("data.$iptName.value"), 'video')) {
$rules = array_merge($rules, [
"data.$iptName.value.video" => "required|array",
"data.$iptName.value.video.id" => "required|string",
"data.$iptName.value.video.alt" => "required|string|between:3,255",
"data.$iptName.value.video.title" => "required|string|between:3,255",
]);
}
break;
} //end switch
} //end foreach

View file

@ -118,89 +118,5 @@ class CollectionHelper
])
->values()
->toArray();
}
/**
* Transform and merge 2 arrays to get homogeneous result
*
* @param array $items sections array
* @param array $categories categories array
* @return array
*/
public static function mapItemsToCards(array $items, array $categories): array
{
$categoriesById = collect($categories)->keyBy('id');
$result = [];
foreach ($items as $item) {
$category = $categoriesById->get($item['category_id']);
if (!$category) {
continue;
}
$categoryKey = $category['name'];
$parsed = self::parseContent($item['content']);
$result[$categoryKey][] = [
'category' => $item['title'],
'icon' => [
'path' => $item['picture'],
'alt' => $item['picture_alt'],
'description' => $item['picture_title'],
],
'content' => [
[
'title' => $parsed['title'],
'points' => $parsed['points'],
'asterisc' => $parsed['asterisc'],
],
],
'class' => 'card-template-sm',
];
}//end foreach
return $result;
}
private static function parseContent(string $html): array
{
$dom = new \DOMDocument();
@$dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
// Extract h3
$title = '';
$h3 = $dom->getElementsByTagName('h3');
if ($h3->length > 0) {
$title = $h3->item(0)->textContent;
}
// Extract li
$points = [];
$liNodes = $dom->getElementsByTagName('li');
foreach ($liNodes as $li) {
$points[] = trim($li->textContent);
}
// Extract last <p> *
$lastAsterisc = null;
$pNodes = $dom->getElementsByTagName('p');
foreach ($pNodes as $p) {
$text = trim($p->textContent);
if (str_starts_with($text, '*')) {
$lastAsterisc = $text;
}
}
// if nothing to extract
if (empty($title) && empty($points)) {
$body = $dom->getElementsByTagName('body')->item(0);
$rawText = trim($body ? $body->textContent : strip_tags($html));
if (!empty($rawText)) {
$points[] = $rawText;
}
}
return [
'title' => $title,
'points' => $points,
'asterisc' => $lastAsterisc ?? '',
];
}
}
}

View file

@ -3,9 +3,15 @@
namespace App\Lib\Helpers;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
class GamePeriodHelper
{
public static function startGameAt(): Carbon
{
return Carbon::parse(config('goldencrush.start_game_at'))->startOfDay();
}
public static function voteStartAt(): Carbon
{
return Carbon::parse(config('goldencrush.vote_start_at'))->startOfDay();
@ -46,12 +52,16 @@ class GamePeriodHelper
{
if (! self::hasValidPeriods()) {
\Log::error('Config des dates invalide ! ');
Log::error('Config des dates invalide ! ');
return 'closed';
}
$today = now();
if ($today->betweenIncluded(self::startGameAt(), self::voteStartAt())) {
return 'start_game';
}
if ($today->betweenIncluded(self::voteStartAt(), self::voteEndAt())) {
return 'vote';
}
@ -88,6 +98,7 @@ class GamePeriodHelper
public static function isGameVisible(): bool
{
return in_array(self::state(), [
'start_game',
'vote',
'end_participation',
'end_game',

View file

@ -136,6 +136,7 @@ class ViewServiceProvider extends ServiceProvider
['name' => 'exitOutsideStaticPageModel', 'value' => StaticPage::getCachedStaticPage(StaticPageType::exitOutside)],
['name' => 'ouiCestBonStaticPageModel', 'value' => StaticPage::getCachedStaticPage(StaticPageType::ouiCBon)],
['name' => 'ourFarmsStaticPageModel', 'value' => StaticPage::getCachedStaticPage(StaticPageType::ourFarms)],
['name' => 'tdfStaticPageModel', 'value' => StaticPage::getCachedStaticPage(StaticPageType::tdf)],
])->map(function ($array) {
View::share($array['name'], (function () use ($array) {
return $array['value'] ?: null;

View file

@ -171,6 +171,20 @@ trait MiniCrudModel
case InputType::url->value:
ToolboxHelper::assertNoInternalBoUrls('content', $input['value']);
break;
case InputType::slider->value:
if (!is_array($data[$o]['value'])) break;
foreach ($data[$o]['value'] as $index => $item) {
if (isset($item['picture']) && $item['picture'] instanceof \Illuminate\Http\UploadedFile) {
$data[$o]['value'][$index]['picture'] = \preg_replace(
'/^\/|^/',
'',
FileStorageHelper::storeFile($this, $item['picture'], true)
);
}
}
break;
case InputType::selectImageVideo->value:
break;
default:
throw new \ErrorException(sprintf(
'Unknown input Type %s',

View file

@ -1,6 +1,7 @@
<?php
return [
'start_game_at' => env('GOLDEN_GAME_START'),
'vote_start_at' => env('GOLDEN_VOTE_START_AT'),
'vote_end_at' => env('GOLDEN_VOTE_END_AT'),

View file

@ -0,0 +1,612 @@
<?php
use App\Enums\InputType;
use App\Enums\StaticPageType;
use App\Models\StaticPage;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
// TDF
$data = [
'highlight_text' => [
'label' => 'Texte de l\'encart',
'inputType' => InputType::string->value,
'value' => 'TOUR DE FRANCE 2025',
'validate' => 'required|string|between:3,20',
'required' => true
],
'banner_title' => [
'label' => 'Titre de la bannière',
'inputType' => InputType::string->value,
'value' => 'Le Gaulois en selle pour le tour de France',
'validate' => 'required|string|between:3,255',
'required' => true
],
'banner_picture' => [
'label' => 'Logo de la bannière',
'inputType' => 4,
'dimensions' => [
'width' => 100,
'height' => 300
],
'alt' => 'Logo volaille officielle de Le Gaulois et le Tour de France',
'title' => 'Logo volaille officielle de Le Gaulois et le Tour de France',
'value' => '',
'validate' => 'required',
'required' => true
],
'banner_button_title' => [
'label' => 'Titre du bouton n°1',
'inputType' => InputType::string->value,
'value' => 'Le Gaulois et le Tour de France',
'validate' => 'required|string|between:3,255',
'required' => true
],
'banner_button_title_2' => [
'label' => 'Titre du bouton n°2',
'inputType' => InputType::string->value,
'value' => 'Au cœur de la caravane le Gaulois',
'validate' => 'required|string|between:3,255',
'required' => true
],
'banner_picture_author' => [
'label' => 'Nom du photographe',
'inputType' => InputType::string->value,
'value' => 'Crédit photo - ASO Aurélien Vialatte',
'validate' => 'required|string|between:3,255',
'required' => true
],
'play_title' => [
'label' => 'Titre de la section n°2',
'inputType' => InputType::string->value,
'value' => 'Jouez et tentez de gagner !',
'validate' => 'required|string|between:3,255',
'required' => true
],
'play_description' => [
'label' => 'Description de la section n°2',
'inputType' => InputType::text->value,
'value' => '<p>Participez à notre jeu 100% gagnant Le Gaulois pendant le Tour de France 2025.</p>',
'validate' => 'required|string|min:15',
'required' => true
],
'play_picture' => [
'label' => 'Logo de la section n°2',
'inputType' => 4,
'dimensions' => [
'width' => 200,
'height' => 125
],
'alt' => '100% Gagnant',
'title' => '100% Gagnant',
'value' => '',
'validate' => 'required',
'required' => true
],
'play_btn_text' => [
'label' => 'Texte du bouton',
'inputType' => InputType::string->value,
'value' => 'Je tente ma chance !',
'validate' => 'required|string|between:3,255',
'required' => true
],
'play_btn_url' => [
'label' => 'Lien du bouton',
'inputType' => InputType::url->value,
"value" => "https://www.legauloistourdefrance.fr",
"validate" => "required|string|url:http,https",
'required' => true
],
'prize_title_1' => [
'label' => 'Texte du lot n°1',
'inputType' => InputType::string->value,
'value' => 'Ensembles TV + Home Cinema',
'validate' => 'required|string|between:3,255',
'required' => true
],
'prize_picture_1' => [
'label' => 'Image du lot n°1',
'inputType' => 4,
'dimensions' => [
'width' => 130,
'height' => 100
],
'alt' => 'Ensemble TV-Home cinéma à gagner pendant le jeu TDF 100% gagnant Le Gaulois',
'title' => '5 Ensembles TV-Home cinéma à gagner',
'value' => '',
'validate' => 'required',
'required' => true
],
'prize_title_2' => [
'label' => 'Texte du lot n°2',
'inputType' => InputType::string->value,
'value' => 'Casques audios oreilles libres',
'validate' => 'required|string|between:3,255',
'required' => true
],
'prize_picture_2' => [
'label' => 'Image du lot n°2',
'inputType' => 4,
'dimensions' => [
'width' => 130,
'height' => 100
],
'alt' => 'Casques audios oreilles libres à gagner pendant le jeu TDF 100% gagnant Le Gaulois',
'title' => '40 Casques audios oreilles libres à gagner',
'value' => '',
'validate' => 'required',
'required' => true
],
'prize_title_3' => [
'label' => 'Texte du lot n°3',
'inputType' => InputType::string->value,
'value' => 'Bons d\'achat',
'validate' => 'required|string|between:3,255',
'required' => true
],
'prize_picture_3' => [
'label' => 'Image du lot n°3',
'inputType' => 4,
'dimensions' => [
'width' => 130,
'height' => 100
],
'alt' => 'Bons de réduction à gagner pendant le jeu TDF 100% gagnant Le Gaulois',
'title' => 'Milliers de bons d\'achat à gagner',
'value' => '',
'validate' => 'required',
'required' => true
],
"play_display_section" => [
"label" => "Afficher la section n°2",
"inputType" => InputType::boolean->value,
"value" => true,
"validate" => "required|boolean",
'required' => true
],
'find_us_title' => [
'label' => 'Titre de la section n°3',
'inputType' => InputType::string->value,
'value' => 'Venez nous retrouver sur le parcours du Tour de France',
'validate' => 'required|string|between:3,255',
'required' => true
],
'find_us_description' => [
'label' => 'Description de la section n°3',
'inputType' => InputType::text->value,
'value' => '<p>Participez à notre jeu 100% gagnant Le Gaulois pendant le Tour de France 2025.</p>',
'validate' => 'required|string|min:15',
'required' => true
],
'find_us_picture' => [
'label' => 'Pictogramme de la section n°3',
'inputType' => 4,
'dimensions' => [
'width' => 50,
'height' => 70
],
'alt' => 'Point d\'exclamation',
'title' => 'Point d\'exclamation',
'value' => '',
'validate' => 'required',
'required' => true
],
'find_us_btn_text_1' => [
'label' => 'Texte du bouton n°1',
'inputType' => InputType::string->value,
'value' => 'Télécharger la pancarte',
'validate' => 'required|string|between:3,255',
'required' => true
],
'find_us_btn_url_1' => [
'label' => 'Lien du bouton n°1',
'inputType' => InputType::url->value,
"value" => "https://www.legaulois.fr/tdf-downloads/Pancarte.pdf",
"validate" => "required|string|url:http,https",
'required' => true
],
'find_us_btn_text_2' => [
'label' => 'Texte du bouton n°2',
'inputType' => InputType::string->value,
'value' => 'Télécharger des coloriages',
'validate' => 'required|string|between:3,255',
'required' => true
],
'find_us_btn_url_2' => [
'label' => 'Lien du bouton n°2',
'inputType' => InputType::url->value,
"value" => "https://www.legaulois.fr/tdf-downloads/COLORIAGE-Avril-2024.pdf",
"validate" => "required|string|url:http,https",
'required' => true
],
'find_us_picture_1' => [
'label' => 'Image n°1 de la section n°3',
'inputType' => 4,
'dimensions' => [
'width' => 300,
'height' => 220
],
'alt' => 'Chars de la caravane Le Gaulois',
'title' => 'Caravane Le Gaulois au mileu des supporters du Tour de France',
'value' => '',
'validate' => 'required',
'required' => true
],
'find_us_picture_2' => [
'label' => 'Image n°2 de la section n°3',
'inputType' => 4,
'dimensions' => [
'width' => 300,
'height' => 220
],
'alt' => 'Char Cuisson Express Le Gaulois',
'title' => 'Char cocotte Cuisson Express traversant un pont lors d\'une étape du Tour de France',
'value' => '',
'validate' => 'required',
'required' => true
],
'find_us_picture_author' => [
'label' => 'Nom du photographe',
'inputType' => InputType::string->value,
'value' => 'Crédit photo - ASO Aurélien Vialatte',
'validate' => 'required|string|between:3,255',
'required' => true
],
'tdf_title' => [
'label' => 'Titre de la section n°4',
'inputType' => InputType::string->value,
'value' => 'Le Gaulois et le Tour de France',
'validate' => 'required|string|between:3,255',
'required' => true
],
'tdf_subtitle_1' => [
'label' => 'Sous-titre n°1 de la section n°4',
'inputType' => InputType::string->value,
'value' => 'Plus de 10 années',
'validate' => 'required|string|between:3,255',
'required' => true
],
'tdf_subtitle_2' => [
'label' => 'Sous-titre n°2 de la section n°4',
'inputType' => InputType::string->value,
'value' => ' de complicité avec le public',
'validate' => 'required|string|between:3,255',
'required' => true
],
'tdf_description' => [
'label' => 'Description de la section n°4',
'inputType' => InputType::text->value,
'value' => '<p><strong>Les chars « Cocottes » sont devenus emblématiques de la caravane du Tour de France.</strong> <strong>Dix-huit caravaniers passionnés</strong>, dont huit femmes et dix hommes de tous âges et venus de différentes régions de France, auront l\'opportunité unique de piloter les mythiques « Cocottes » à travers le pays. Représentant <strong>la diversité et l\'esprit de partage</strong>, ces caravaniers formeront une <strong>véritable famille</strong> pendant toute la durée du Tour, <strong>unis par leur amour du sport et leur engagement envers Le Gaulois.</strong> <br> <br>Les huit chars Le Gaulois, représentant les produits phares de la marque, offrent au public l\'occasion de découvrir ou redécouvrir la diversité des produits proposés : <strong>Crousty Chicken, Oui c\'est Bon !, Cordon Bleu, Filets de Poulet Rôti, Blanc de Poulet Sortant à l\'Extérieur, et Le Filet de Poulet Tranché Cuisson Express</strong> seront à l\'honneur. Deux chars multiproduits, mettant en avant la diversité de la gamme, défileront également en tête de cortège avec à leur bord l\'animateur Arthur pour enflammer les foules gauloises. En fin de défilé, le char « Roule ma Poule » viendra clore le spectacle, un clin d\'œil toujours apprécié du public. <br><br> Les chars iront à la rencontre des Français pour distribuer plus de 600 000 goodies Le Gaulois dans une atmosphère joyeuse et conviviale. Cette année, la marque offrira des <strong>capes supporters, des magnets décapsuleurs, et des milliers de bons de réduction</strong> pour découvrir les produits Le Gaulois en magasin.</p>',
'validate' => 'required|string|min:15',
'required' => true
],
'tdf_media' => [
'label' => 'Media de la section n°3',
'inputType' => InputType::selectImageVideo->value,
'value' => '',
'validate' => 'required|array',
'required' => true
],
'discover_title_1' => [
'label' => 'Titre n°1 de la section n°5',
'inputType' => InputType::string->value,
'value' => 'Découvrez',
'validate' => 'required|string|between:3,255',
'required' => true
],
'discover_title_2' => [
'label' => 'Titre n°2 de la section n°5',
'inputType' => InputType::string->value,
'value' => 'nos chars "cocottes"',
'validate' => 'required|string|between:3,255',
'required' => true
],
'discover_items' => [
'label' => 'Slider de la section n°5',
'inputType' => InputType::slider->value,
'value' => '',
'validate' => 'required|array|between:2,10',
'required' => true,
'columns' => [
[
'id' => 'picture',
'type' => 'picture',
'placeholder' => Str::ucFirst(__('validation.custom.picture')),
'validation' => 'required',
'required' => true
],
[
'id' => 'picture_alt',
'type' => 'text',
'placeholder' => Str::ucFirst(__('validation.custom.picture_alt')),
'validation' => 'required|string|between:3,255',
'required' => true
],
[
'id' => 'picture_title',
'type' => 'text',
'placeholder' => Str::ucFirst(__('validation.custom.picture_title')),
'validation' => 'required|string|between:3,255',
'required' => true
],
[
'id' => 'subtitle',
'type' => 'text',
'placeholder' => Str::ucFirst(__('validation.custom.subtitle')),
'validation' => 'sometimes|string|between:3,255',
'required' => true
],
[
'id' => 'description',
'type' => 'wysiwyg',
'placeholder' => Str::ucFirst(__('validation.attributes.description')),
'validation' => 'required|string|min:15',
'required' => true
],
],
'itemLimit' => [2, 10],
'imageSizes' => [600, 450],
],
'heart_title' => [
'label' => 'Titre de la section n°6',
'inputType' => InputType::string->value,
'value' => 'Au cœur de la caravane Le Gaulois',
'validate' => 'required|string|between:3,255',
'required' => true
],
'heart_subtitle' => [
'label' => 'Sous-titre de la section n°6',
'inputType' => InputType::string->value,
'value' => 'Nos petites anecdotes',
'validate' => 'required|string|between:3,255',
'required' => true
],
'heart_picture' => [
'label' => 'Image de fond de la section n°6',
'inputType' => 4,
'dimensions' => [
'width' => 1020,
'height' => 680
],
'alt' => 'Char \'La crousty mobile\' qui traverse un village français pendant le Tour de France',
'title' => 'Char de la caravane Le Gaulois',
'value' => '',
'validate' => 'required',
'required' => true
],
'heart_picture_author' => [
'label' => 'Nom du photographe',
'inputType' => InputType::string->value,
'value' => 'Crédit photo - ASO Aurélien Vialatte',
'validate' => 'required|string|between:3,255',
'required' => true
],
'fun_facts_title_1' => [
'label' => 'Titre de l\'anecdote n°1',
'inputType' => InputType::string->value,
'value' => 'La caravane par tous les temps !',
'validate' => 'required|string|between:3,255',
'required' => true
],
'fun_facts_description_1' => [
'label' => 'Description de l\'anecdote n°1',
'inputType' => InputType::text->value,
'value' => '<p>Le 26 juillet 2019, lors de l\'étape Saint-Jean-de-Maurienne et Tignes, les chars terminent leur parade quand un orage de grêle s\'invite et entraîne une coulée de boue qui bloque la route et l\'accès aux cyclistes. L\'organisation décide l\'arrêt de l\'étape et marquera l\'histoire du Tour de France.</p>',
'validate' => 'required|string|min:15',
'required' => true
],
'fun_facts_picture_1' => [
'label' => 'Pictogramme de l\'anecdote n°1',
'inputType' => 4,
'dimensions' => [
'width' => 80,
'height' => 80
],
'alt' => 'Pictogramme d\'un soleil pour les anecdoctes météo sur le Tour de France',
'title' => 'Pictogramme d\'un soleil',
'value' => '',
'validate' => 'required',
'required' => true
],
'fun_facts_title_2' => [
'label' => 'Titre de l\'anecdote n°2',
'inputType' => InputType::string->value,
'value' => 'La transmission d\'une passion entre Père & Fils !',
'validate' => 'required|string|between:3,255',
'required' => true
],
'fun_facts_description_2' => [
'label' => 'Description de l\'anecdote n°2',
'inputType' => InputType::text->value,
'value' => '<p>Avec plus de 10 tours de France à son actif, Jean-Marie a transmis sa passion à son fils. Léo assure : « Sur le Tour, nous sommes collègues, mais il y a toujours cette fierté personnelle de partager ces moments ensemble sur les routes de France. ».</p>',
'validate' => 'required|string|min:15',
'required' => true
],
'fun_facts_picture_2' => [
'label' => 'Pictogramme de l\'anecdote n°2',
'inputType' => 4,
'dimensions' => [
'width' => 80,
'height' => 80
],
'alt' => 'Pictogramme d\'une tête d\'enfant pour les liens de parenté au sein de l\'équipe des caravaniers',
'title' => 'Pictogramme d\'un enfant',
'value' => '',
'validate' => 'required',
'required' => true
],
'fun_facts_title_3' => [
'label' => 'Titre de l\'anecdote n°3',
'inputType' => InputType::string->value,
'value' => 'Histoire de poulet',
'validate' => 'required|string|between:3,255',
'required' => true
],
'fun_facts_description_3' => [
'label' => 'Description de l\'anecdote n°3',
'inputType' => InputType::text->value,
'value' => '<p>Avec un sens de l\'humour aguerri, Cocotte rencontre <a href="https://www.youtube.com/watch?v=reI-Z8UE3lM" target="_blank">un sympathique collègue</a> au détour d\'un passage dans un village sur les routes du Tour de France.</p>',
'validate' => 'required|string|min:15',
'required' => true
],
'fun_facts_picture_3' => [
'label' => 'Pictogramme de l\'anecdote n°3',
'inputType' => 4,
'dimensions' => [
'width' => 80,
'height' => 80
],
'alt' => 'Pictogramme d\'un poulet policier pour les histoires poulets-policiers pendants le Tour de France',
'title' => 'Pictogramme d\'un poulet policier',
'value' => '',
'validate' => 'required',
'required' => true
],
'fun_facts_title_4' => [
'label' => 'Titre de l\'anecdote n°4',
'inputType' => InputType::string->value,
'value' => 'Un pompier en tant que chauffeur d\'un char Le Gaulois !',
'validate' => 'required|string|between:3,255',
'required' => true
],
'fun_facts_description_4' => [
'label' => 'Description de l\'anecdote n°4',
'inputType' => InputType::text->value,
'value' => '<p>Nicolas, pompier engagé, a procédé à une intervention de secours pour une jeune caravanière Le Gaulois. Depuis, Nicolas, rebaptisé Pimpon Le Gaulois, sillonne toujours les routes de France à bord d\'un char Cocotte.</p>',
'validate' => 'required|string|min:15',
'required' => true
],
'fun_facts_picture_4' => [
'label' => 'Pictogramme de l\'anecdote n°4',
'inputType' => 4,
'dimensions' => [
'width' => 80,
'height' => 80
],
'alt' => 'Pictogramme d\'une sirène d\'alarme pour les anecdoctes insolites pendant le Tour de France',
'title' => 'Pictorgramme d\'une alarme',
'value' => '',
'validate' => 'required',
'required' => true
],
'testimonials_title' => [
'label' => 'Titre de la section n°7',
'inputType' => InputType::string->value,
'value' => 'Les témoignages des caravaniers',
'validate' => 'required|string|between:3,255',
'required' => true
],
'testimonials_items' => [
'label' => 'Slider de la section n°7',
'inputType' => InputType::slider->value,
'value' => '',
'validate' => 'required|array|between:2,6',
'required' => true,
'columns' => [
[
'id' => 'picture',
'type' => 'picture',
'placeholder' => Str::ucFirst(__('validation.custom.picture')),
'validation' => 'required',
'required' => true
],
[
'id' => 'picture_alt',
'type' => 'text',
'placeholder' => Str::ucFirst(__('validation.custom.picture_alt')),
'validation' => 'required|string|between:3,255',
'required' => true
],
[
'id' => 'picture_title',
'type' => 'text',
'placeholder' => Str::ucFirst(__('validation.custom.picture_title')),
'validation' => 'required|string|between:3,255',
'required' => true
],
[
'id' => 'picture_author',
'type' => 'text',
'placeholder' => Str::ucFirst(__('validation.custom.picture_author')),
'validation' => 'required|string|between:3,255',
'required' => true
],
[
'id' => 'title',
'type' => 'text',
'placeholder' => Str::ucFirst(__('validation.attributes.title')),
'validation' => 'required|string|between:3,255',
'required' => true
],
[
'id' => 'subtitle',
'type' => 'text',
'placeholder' => Str::ucFirst(__('validation.custom.subtitle')),
'validation' => 'nullable|string|between:3,255',
'required' => false
],
[
'id' => 'description',
'type' => 'wysiwyg',
'placeholder' => Str::ucFirst(__('validation.attributes.description')),
'validation' => 'required|string|min:15',
'required' => true
],
[
'id' => 'subtitle_2',
'type' => 'text',
'placeholder' => Str::ucFirst(__('validation.custom.subtitle')),
'validation' => 'required|string|between:3,255',
'required' => true
],
[
'id' => 'description_2',
'type' => 'wysiwyg',
'placeholder' => Str::ucFirst(__('validation.attributes.description')),
'validation' => 'required|string|min:15',
'required' => true
],
],
'itemLimit' => [2, 6],
'imageSizes' => [500, 333],
],
];
$staticPage = StaticPage::where('type', StaticPageType::tdf)->first();
if ($staticPage) {
$staticPage->data = $data;
$staticPage->saveQuietly();
} else {
StaticPage::query()->forceCreateQuietly(
[
'type' => StaticPageType::tdf->value(),
'seo_title' => 'Le Gaulois | Volaille officielle du Tour de France',
'seo_description' => 'Immergez-vous dans l\'ambiance du Tour de France avec Le Gaulois. Découvrez le jeu concours, les photos, anecdotes et témoignages de notre équipe.',
'title' => 'Le Gaulois Le sponsor du Tour de France',
'slug' => 'tour-de-france',
'data' => $data
]
);
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('static_pages', function () {
$staticPage = StaticPage::query()->where('type', StaticPageType::tdf)->first();
$staticPage->data = [];
$staticPage->saveQuietly();
});
}
};

View file

@ -0,0 +1,58 @@
<?php
use App\Enums\StaticPageType;
use App\Models\StaticPage;
use Illuminate\Database\Migrations\Migration;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$data = [
'search_title' => [
'label' => 'Rechercher un éleveur : Titre',
'inputType' => 11,
'value' => 'retrouvez tous nos éleveurs oui c\'est bon !',
'validate' => 'required|string|between:3,255',
'required' => true
],
'search_description' => [
'label' => 'Rechercher un éleveur : Description',
'inputType' => 12,
'value' => '<p>Parce que nous sommes fiers de notre savoir-faire français et de l\'origine France de nos produits, nous vous dévoilons les éleveurs partenaires et engagés au quotidien dans notre démarche Oui c\'est Bon Le Gaulois</p>',
'validate' => 'required|string|min:15',
'required' => true
],
];
$staticPage = StaticPage::where('type', StaticPageType::ouiCBon)->first();
if ($staticPage && !empty($staticPage->data)) {
$staticPage->data = array_merge($staticPage->data, $data);
$staticPage->saveQuietly();
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
$staticPage = StaticPage::where('type', StaticPageType::ouiCBon)->first();
if ($staticPage && !empty($staticPage->data)) {
$data = $staticPage->data;
unset(
$data['search_title'],
$data['search_description']
);
$staticPage->data = $data;
$staticPage->saveQuietly();
}
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

File diff suppressed because it is too large Load diff

View file

@ -72,6 +72,10 @@ return [
'picture_title_label' => 'Title attribute of the image',
'picture_alt_helper' => 'Must describe your image for search engines and blind people (5 to 6 words).',
'picture_alt_label' => 'Alt attribute of the image',
'video_title_helper' => 'Useful for users, displayed by moving the mouse over the video',
'video_title_label' => 'Title attribute of the video',
'video_alt_helper' => 'Must describe your video for search engines and blind people (5 to 6 words).',
'video_alt_label' => 'Alt attribute of the video',
'text_warning' => 'Proofread your content before publishing it',
],

View file

@ -328,6 +328,12 @@ return [
'salt' => 'salt',
],
'breeding_section_card' => 'Common breeding section',
'common_section_part' => 'common section'
'common_section_part' => 'common section',
'picture' => 'image',
'picture_author' => 'image author',
'picture_alt' => 'image alternative text',
'picture_title' => 'image title',
'video_alt' => 'video alternative text',
'video_title' => 'video title',
],
];

View file

@ -76,6 +76,11 @@ return [
'picture_alt_helper' => 'Doit décrire votre image pour les moteurs de recherche et
les personnes malvoyantes (5 à 6 mots).',
'picture_alt_label' => 'Attribut Alt de l\'image',
'video_title_helper' => 'Utile pour les utilisateurs, s\'affiche en passant la souris sur la vidéo.',
'video_title_label' => 'Attribut du titre de la vidéo',
'video_alt_helper' => 'Doit décrire votre vidéo pour les moteurs de recherche et
les personnes malvoyantes (5 à 6 mots).',
'video_alt_label' => 'Attribut Alt de la vidéo',
'text_warning' => 'Relisez votre contenu avant de le publier.',
],

View file

@ -347,6 +347,12 @@ return [
],
'breeding_section_card' => 'section commune des élevages',
'common_section_part' => 'section commune',
'rules_accepted' => 'réglement du jeux'
'rules_accepted' => 'réglement du jeux',
'picture' => 'image',
'picture_author' => 'auteur de l\'image',
'picture_alt' => 'texte alternatif de l\'image',
'picture_title' => 'titre de l\'image',
'video_alt' => 'texte alternatif de la vidéo',
'video_title' => 'titre de la vidéo',
],
];

View file

@ -58,7 +58,7 @@
padding: 18px 76px 18px 1px;
background: #fff;
clip-path: polygon(-1px 4.17%, 38.25% 11px, 70.5% -0.66%, 100% 0, 100.00% 91.67%, 0 94.17%);
color: #4E3238;
color: $color-hex-gc-brown;
}
.vote-section .vote-card-footer--readonly {
@ -83,7 +83,7 @@
height: 42px;
align-items: center;
justify-content: center;
border: 5px solid #4E3238;
border: 5px solid $color-hex-gc-brown;
border-radius: 4px;
color: transparent;
font-size: 28px;
@ -93,7 +93,7 @@
/* Checked state */
.vote-section .vote-card-input:checked + .vote-card-inner .vote-card-footer {
background: #D45805;
background: $color-hex-gc-dark-orange;
color: #fff;
}
@ -199,8 +199,8 @@
align-items: center;
justify-content: center;
padding: 18px;
background: #efa82b;
color: #0F437E;
background: $color-hex-gc-dark-yellow;
color: $color-hex-dark-blue;
font-family: BourtonBase, sans-serif;
font-size: 22px;
letter-spacing: .08em;
@ -225,7 +225,7 @@
}
.vote-section .vote-submit-label:hover {
background: #D45805;
background: $color-hex-gc-dark-orange;
color: #fff;
}
@ -261,7 +261,7 @@
top: -20px;
left: -44px;
border-width: 4px 40px 18px 0;
border-color: transparent #fdd106 transparent transparent;
border-color: transparent $color-hex-gc-yellow transparent transparent;
transform: rotate(-45deg);
}
@ -269,7 +269,7 @@
top: -4px;
right: -60px;
border-width: 4px 0 40px 28px;
border-color: transparent transparent transparent #fdd106;
border-color: transparent transparent transparent $color-hex-gc-yellow;
transform: rotate(-70deg);
}
@ -293,7 +293,7 @@
}
.vote-section .vote-already-modal-text {
color: #fdd106;
color: $color-hex-gc-yellow;
font-family: BourtonBase, sans-serif;
font-size: 44px;
letter-spacing: .01em;

View file

@ -1,7 +1,7 @@
#cta .gldc-cta-block {
position: relative;
padding: 80px 0 50px;
background: #0F437E;
background: $color-hex-dark-blue;
}
.idea-wave {
@ -28,7 +28,7 @@
}
#cta .gldc-cta-block-title {
color: #efa82b;
color: $color-hex-gc-dark-yellow;
font-family: BourtonBase, sans-serif;
font-size: 54px;
letter-spacing: 0.08em;
@ -71,9 +71,9 @@
align-items: center;
justify-content: center;
padding: 18px 32px;
background: #efa82b;
background: $color-hex-gc-dark-yellow;
box-shadow: 0 10px 20px rgb(0 0 0 / 18%);
color: #0F437E;
color: $color-hex-dark-blue;
font-family: BourtonBase, sans-serif;
font-size: 1.25rem;
gap: 10px;
@ -99,7 +99,7 @@
}
#cta .gldc-cta-block-bottom-text span {
color: #efa82b;
color: $color-hex-gc-dark-yellow;
text-decoration: underline;
text-underline-offset: 4px;
}

View file

@ -14,7 +14,7 @@
.gc-info-title span,
.gc-info-description span {
color: #efa82b;
color: $color-hex-gc-dark-yellow;
}
.gc-info-underline {
@ -62,13 +62,13 @@
}
.gc-info-btn--orange {
background: #D45805;
background: $color-hex-gc-dark-orange;
color: #fff;
}
.gc-info-btn--orange:hover {
background: #efa82b;
color: #0F437E;
background: $color-hex-gc-dark-yellow;
color: $color-hex-dark-blue;
}
.gc-info-deco {
@ -108,7 +108,7 @@
margin: 0 6px;
background: #fff;
clip-path: polygon(0 0, -0.78% -0.25%, 45.41% 6px, 100% 8%, 95.08% 52.28%, 100% 100%, 49.87% 90.69%, 1px 100%, 5.93% 62.2%);
color: #0F437E;
color: $color-hex-dark-blue;
font-family: BourtonBase, sans-serif;
font-size: 22px;
font-weight: normal;
@ -126,9 +126,9 @@
padding: 14px 32px;
margin: 20px auto 28px;
margin-right: 20px;
background: #efa82b;
background: $color-hex-gc-dark-yellow;
clip-path: polygon(31% 7%,73% 1%,100% 10%,100% 100%,44% 97%,0% 100%,0% 0%);
color: #0F437E;
color: $color-hex-dark-blue;
filter: drop-shadow(0 4px 4px rgb(0 0 0 / 25%));
font-family: BourtonBase, sans-serif;
font-size: 34px;

View file

@ -35,9 +35,9 @@
width: 290px;
height: 100px;
padding: 30px;
background: #efa82b;
background: $color-hex-gc-dark-yellow;
clip-path: polygon(0 0, 38.33% 8.55%, 58.94% 10px, 100% 8%, 97.31% 52.28%, 100% 100%, 49.87% 90.69%, 1px 100%, 3.7% 56.07%);
color: #0F437E;
color: $color-hex-dark-blue;
font-family: BourtonBase, sans-serif;
font-size: 42px;
line-height: 1;
@ -75,7 +75,7 @@
bottom: -24px;
left: -54px;
border-width: 16px 38px 16px 0;
border-color: transparent #fdd106 transparent transparent;
border-color: transparent $color-hex-gc-yellow transparent transparent;
transform: rotate(12deg);
}
@ -83,7 +83,7 @@
top: 24px;
right: -41px;
border-width: 0 0 20px 38px;
border-color: transparent transparent transparent #fdd106;
border-color: transparent transparent transparent $color-hex-gc-yellow;
transform: rotate(-25deg) scaleX(-1);
}
@ -168,7 +168,7 @@
top: 48px;
left: 44px;
border-width: 0 0 50px 28px;
border-color: transparent transparent #fdd106;
border-color: transparent transparent $color-hex-gc-yellow;
transform: rotate(113deg);
}
@ -185,7 +185,7 @@
top: 56px;
right: 51px;
border-width: 0 32px 50px 0;
border-color: transparent #fdd106 transparent transparent;
border-color: transparent $color-hex-gc-yellow transparent transparent;
transform: rotate(250deg) scaleY(-1);
}
@ -194,7 +194,7 @@
bottom: 48px;
left: 39px;
border-width: 50px 0 0 34px;
border-color: transparent transparent transparent #fdd106;
border-color: transparent transparent transparent $color-hex-gc-yellow;
transform: rotate(33deg) scaleX(-1);
}
@ -236,7 +236,7 @@
}
#play-section .play-description span {
color: #efa82b;
color: $color-hex-gc-dark-yellow;
}
/* =========================

View file

@ -9,7 +9,7 @@
.v-soc .gldc-social-videos {
padding: 70px 0 80px;
padding-top: 30px;
background: #0F437E;
background: $color-hex-dark-blue;
}
.v-soc .carousel-item {
@ -40,14 +40,14 @@
}
.v-soc .gldc-social-badge--orange {
background: #d45805;
background: $color-hex-gc-dark-orange;
color: #fff;
transform: rotate(-3deg);
}
.v-soc .gldc-social-badge--gold {
background: #efa82b;
color: #0F437E;
background: $color-hex-gc-dark-yellow;
color: $color-hex-dark-blue;
transform: rotate(3deg);
}
@ -103,7 +103,7 @@
justify-content: center;
border: 0;
background: transparent;
color: #4E3238;
color: $color-hex-gc-brown;
cursor: pointer;
font-size: 72px;
inset: 0;
@ -111,7 +111,7 @@
}
.v-soc .gldc-video-card-play:hover {
color: #efa82b;
color: $color-hex-gc-dark-yellow;
transform: scale(1.1);
}
@ -177,7 +177,7 @@
}
.v-soc .gldc-carousel-controls .carousel-indicators .active {
background-color: #fdd106;
background-color: $color-hex-gc-yellow;
}
.v-soc .gldc-carousel-arrow {
@ -188,8 +188,8 @@
justify-content: center;
border: 0;
border-radius: 50%;
background: #fdd106;
color: #0F437E;
background: $color-hex-gc-yellow;
color: $color-hex-dark-blue;
font-size: 24px;
line-height: 1;
}

View file

@ -52,3 +52,11 @@
.form-control::file-selector-button {
font-family: #{$btn-font-family} !important;
}
.mt-16 {
margin-top: 4rem;
}
.mt-24 {
margin-top: 6.25rem;
}

View file

@ -13,7 +13,7 @@
width: 112%;
padding: 110px 0;
margin-left: -6%;
background: #d45805;
background: $color-hex-gc-dark-orange;
text-align: center;
transform: rotate(-2deg);
}

View file

@ -69,7 +69,7 @@
top: 22px;
left: 37px;
border-width: 0 0 52px 32px;
border-color: transparent transparent #0F437E;
border-color: transparent transparent $color-hex-dark-blue;
transform: rotate(140deg);
}
@ -77,7 +77,7 @@
top: 50px;
left: 29px;
border-width: 0 0 50px 26px;
border-color: transparent transparent #fdd106;
border-color: transparent transparent $color-hex-gc-yellow;
transform: rotate(112deg);
}
@ -86,7 +86,7 @@
right: 59px;
bottom: 6px;
border-width: 60px 48px 0 0;
border-color: #fdd106 transparent transparent;
border-color: $color-hex-gc-yellow transparent transparent;
transform: rotate(-220deg);
}
@ -94,7 +94,7 @@
right: 49px;
bottom: 40px;
border-width: 45px 28px 0 0;
border-color: #0F437E transparent transparent;
border-color: $color-hex-dark-blue transparent transparent;
transform: rotate(-248deg);
}
/* stylelint-enable selector-class-pattern */
@ -119,7 +119,7 @@
.promo-card-title {
margin-top: 30px;
margin-bottom: 20px;
color: #D45805;
color: $color-hex-gc-dark-orange;
font-family: BourtonBase, sans-serif;
font-size: 30px;
line-height: 1.1;
@ -129,7 +129,7 @@
.promo-card-desc {
width: 344px;
padding-bottom: 20px;
color: #4E3238;
color: $color-hex-gc-brown;
font-family: BourtonBase, sans-serif;
font-size: 16px;
letter-spacing: 0.01em;
@ -146,7 +146,7 @@
justify-content: center;
padding: 10px 15px;
margin: auto auto 60px;
background: #4E3238;
background: $color-hex-gc-brown;
color: #fff;
font-family: BourtonBase, sans-serif;
font-size: 16px;
@ -156,7 +156,7 @@
}
.promo-card-btn:hover {
background: #D45805;
background: $color-hex-gc-dark-orange;
color: #fff;
}

View file

@ -6,7 +6,7 @@
position: relative;
overflow: hidden;
padding: 1rem 0 2.5rem;
background: #0F437E;
background: $color-hex-dark-blue;
}
.gldc .idea-top-separator,
@ -14,7 +14,7 @@
position: relative;
z-index: 1;
width: 100%;
background: #0F437E;
background: $color-hex-dark-blue;
}
.gldc .idea-top-separator {
@ -44,12 +44,12 @@
}
.gldc .idea-subtitle span {
color: #efa82b;
color: $color-hex-gc-dark-yellow;
font-size: 58px;
}
.gldc .idea-title {
color: #efa82b;
color: $color-hex-gc-dark-yellow;
font-family: BourtonBase, sans-serif;
font-size: 58px;
letter-spacing: 0.08em;
@ -82,7 +82,7 @@
}
.gldc .idea-steps span {
color: #efa82b;
color: $color-hex-gc-dark-yellow;
font-family: BourtonBase, sans-serif;
font-size: 24px;
}
@ -101,8 +101,8 @@
justify-content: center;
padding: 16px 40px;
border: 0;
background: #efa82b;
color: #0F437E;
background: $color-hex-gc-dark-yellow;
color: $color-hex-dark-blue;
font-family: BourtonBase, sans-serif;
font-size: clamp(1rem, 2vw, 1.2rem);
gap: 12px;
@ -113,7 +113,7 @@
.gldc .idea-btn:hover {
box-shadow: 0 10px 20px rgb(0 0 0 / 15%);
color: #0F437E;
color: $color-hex-dark-blue;
transform: scale(1.35);
}

View file

@ -50,7 +50,7 @@ body.page-golden-crush {
height: 92px;
padding: 28px;
border: 0;
background: #d45805;
background: $color-hex-gc-dark-orange;
box-shadow: 3px 4px 0 #c04800;
clip-path: polygon(0 0,38.33% 8.55%,58.94% 10px,100% 8%,97.31% 52.28%,100% 100%,49.87% 90.69%,1px 100%,3.7% 56.07%);
color: #fff;
@ -74,7 +74,7 @@ body.page-golden-crush {
/* Textes */
.hero-text-sub {
margin: 0;
color: #4E3238;
color: $color-hex-gc-brown;
font-family: BourtonBase, sans-serif;
font-size: 28px;
line-height:34px;
@ -83,7 +83,7 @@ body.page-golden-crush {
.hero-text-title {
width: max-content;
margin: 0;
color: #d45805;
color: $color-hex-gc-dark-orange;
font-family: BourtonBase, sans-serif;
font-size: 40px;
line-height: 57px;
@ -131,7 +131,7 @@ body.page-golden-crush {
align-items: center;
padding: 16px 44px;
border: 0;
background: #4E3238;
background: $color-hex-gc-brown;
color: #fff;
font-family: BourtonBase, sans-serif;
font-size: 24px;
@ -148,7 +148,7 @@ body.page-golden-crush {
.gldc .gc-hero-paper-title {
margin: 0;
color: #4E3238;
color: $color-hex-gc-brown;
font-family: BourtonBase, sans-serif;
font-size: 28px;
line-height: 28px;
@ -156,7 +156,7 @@ body.page-golden-crush {
}
.gldc .gc-hero-paper-title span {
color: #D45805;
color: $color-hex-gc-dark-orange;
font-size: 52px;
line-height: 1.55;
}
@ -164,7 +164,7 @@ body.page-golden-crush {
.gldc .gc-hero-paper-desc {
max-width: 520px;
margin: 24px auto;
color: #4E3238;
color: $color-hex-gc-brown;
font-family: BourtonBase, sans-serif;
font-size: 24px;
line-height: 31px;
@ -172,7 +172,7 @@ body.page-golden-crush {
}
.gldc .gc-hero-paper-desc span {
color: #D45805;
color: $color-hex-gc-dark-orange;
}
.gldc .gc-hero-date-badge {
@ -183,7 +183,7 @@ body.page-golden-crush {
justify-content: center;
padding: 35px;
margin: 0 6px;
background: #D45805;
background: $color-hex-gc-dark-orange;
clip-path: polygon(0 0, 45% 8%, 100% 6%, 95% 52%, 100% 100%, 50% 91%, 0 100%, 6% 62%);
color: #fff;
font-family: BourtonBase, sans-serif;
@ -192,8 +192,8 @@ body.page-golden-crush {
}
.gldc .gc-hero-date-badge:hover {
background: #fdd106;
color: #0f437e;
background: $color-hex-gc-yellow;
color: $color-hex-dark-blue;
pointer-events: none;
}
@ -208,7 +208,7 @@ body.page-golden-crush {
align-items: center;
justify-content: center;
padding: 16px 28px;
background: #D45805;
background: $color-hex-gc-dark-orange;
clip-path: polygon(38% 9%, 73% 1%, 100% 10%, 100% 100%, 54% 92%, 0% 100%, 0% 0%);
color: #fff;
font-family: BourtonBase, sans-serif;
@ -226,9 +226,9 @@ body.page-golden-crush {
max-width: 280px;
padding: 10px;
margin-right: 10px;
background: #efa82b;
background: $color-hex-gc-dark-yellow;
clip-path: polygon(31% 7%,73% 1%,100% 10%,100% 100%,44% 97%,0% 100%,0% 0%);
color: #0F437E;
color: $color-hex-dark-blue;
font-family: BourtonBase, sans-serif;
font-size: 34px;
overflow-wrap: break-word;

View file

@ -230,6 +230,50 @@
}
}
}
#cards-container-outside {
/* GRID */
.card-grid {
display: grid;
width: 100%;
gap: 48px 18px;
grid-template-columns: repeat(2, minmax(0, 1fr));
}
/* CARD */
.light-card {
width: 100%;
}
/* CONTENT */
.light-card-content.ck-content {
h1,h2,h3 {
margin-bottom: 0.5rem;
font-family: inherit;
font-size: 1.25rem;
font-weight: 600;
line-height: 1.059;
}
p {
padding-right: 1rem;
margin-bottom: 0.7rem;
}
ul {
padding-left: 1.2rem;
margin-bottom: 1rem;
}
small {
display: block;
padding-right: 1rem;
color: #666;
font-size: 0.875rem;
font-style: italic;
}
}
}
}
#les-elevages {
@ -258,6 +302,13 @@
}
}
@media (width <= 767.98px) {
#cards-container-outside .card-grid {
gap: 32px;
grid-template-columns: 1fr;
}
}
.breeding-header-translate-right {
@include media-breakpoint-up(lg) {
right: -18rem !important;

View file

@ -399,9 +399,13 @@
&-reversed {
top: -3rem;
right: 2rem;
right: -2rem;
left: auto;
width: 6rem;
@include media-breakpoint-up(xxl) {
right: 2rem;
}
}
}

View file

@ -23,7 +23,7 @@
}
.end-part {
background: #0F437E;
background: $color-hex-dark-blue;
}
.idea-section-wrapper {
@ -46,6 +46,7 @@
.deco {
position: absolute;
z-index: 50;
transition: transform .3s ease;
}
.deco-top {

View file

@ -24,3 +24,9 @@ $color-base-map-outline: #fff;
$color-base-map-focus: $color-hex-medium-blue;
$color-collection-vintage: #ce6118;
$color-collection-actual: #974c99;
// * Golden crush
$color-hex-gc-yellow: #fdd106;
$color-hex-gc-dark-yellow: #EFA82B;
$color-hex-gc-dark-orange: #D45805;
$color-hex-gc-brown: #4E3238;

View file

@ -1,11 +1,13 @@
// ASSETS
/// <reference types="vite/client" />
import.meta.glob(["./../../assets/images/**"]);
import { initMediaSelector } from "./utilities/media-selector";
// UTILITIES
import "./utilities/bootstrap";
import "./utilities/fontawesome";
import "./utilities/vue-bo";
window.initMediaSelector = initMediaSelector;
// MODULES
import "./../modules/sweetalert";

View file

@ -0,0 +1,285 @@
<template>
<div
:class="`slider-component slider-${inputParameters.name}`"
ref="slider"
>
<div
v-if="itemParameters.list.length > 0"
>
<div
class="border rounded-3 p-3 mb-3"
v-for="(item, itemIndex) of itemParameters.list"
:key="itemIndex"
>
<div
class="d-flex justify-content-between align-items-center"
>
<legend class="w-fit me-2 mb-0">
Slide n°{{ itemIndex + 1 }}
</legend>
<div
v-if="buttonsDisplayParameters.remove"
class="align-bottom"
>
<button
@click.stop.prevent="removeLine(itemIndex)"
class="btn btn-sm btn-danger"
:title="trans.methods.__('Supprimer la ligne')"
data-bs-toggle="tooltip"
>
<i class="fa-solid fa-trash" />
</button>
</div>
</div>
<div
class="row"
>
<div
class="col-6 mb-3"
v-for="(column, columnIndex) of itemParameters.columns"
:key="columnIndex"
>
<label class="py-2">
<b>{{ column.placeholder + (column.required ? '*' : '') }}</b>
</label>
<div
v-if="itemParameters.columns[columnIndex].type == 'wysiwyg'"
:class="(getErrorMessage(itemIndex, column.id) !== null) ? 'is-invalid' : ''"
>
<CkEditorComponent
:name="`data[${inputParameters.name}][value][${String(itemIndex)}][${column.id}]`"
:placeholder="itemParameters.columns[columnIndex].placeholder"
:dbtext="String(item[column.id as keyof typeof item] ?? '')"
:required="true"
:errors="allErrors"
:editor-config="itemParameters.wysiwygConfig"
/>
</div>
<div
v-else-if="itemParameters.columns[columnIndex].type == 'picture'"
:class="(getErrorMessage(itemIndex, column.id) !== null) ? 'is-invalid' : ''"
>
<ImageInputComponent
:id="'picture-input-' + inputParameters.name + '-' + column.id + '-' + itemIndex"
:required="itemParameters.columns[columnIndex].required"
:show-labels="true"
:name="`data[${inputParameters.name}][value][${String(itemIndex)}][${column.id}]`"
:helper="trans.methods.__('crud.minicrud.dimensions_must_be', {
widthpx: (itemParameters.imageSizes[0] ?? String(500)) + 'px',
heightpx: (itemParameters.imageSizes[1] ?? String(500)) + 'px',
})"
:width="itemParameters.imageSizes[0] ?? 500"
:height="itemParameters.imageSizes[1] ?? 500"
:value="item[column.id as keyof typeof item] ? String(item[column.id as keyof typeof item]) : undefined"
:preview="false"
:browse-event="false"
/>
</div>
<div
v-else
>
<WordCounter
:id="'text-input-' + inputParameters.name + '-' + column.id + '-' + itemIndex"
class="ck-word-count"
/>
<input
:id="'text-input-' + inputParameters.name + '-' + column.id + '-' + itemIndex"
:class="['form-control', (getErrorMessage(itemIndex, column.id) !== null) ? 'is-invalid' : '']"
:name="`data[${inputParameters.name}][value][${String(itemIndex)}][${column.id}]`"
:type="itemParameters.columns[columnIndex].type"
v-model="item[column.id as keyof typeof item]"
:placeholder="itemParameters.columns[columnIndex].placeholder"
:required="itemParameters.columns[columnIndex].required"
>
</div>
<small class="text-danger m-0">
{{ getErrorMessage(itemIndex, column.id) }}
</small>
</div>
</div>
</div>
</div>
<div v-else>
<p>{{ trans.methods.__("Aucun élément renseigné(s).") }}</p>
</div>
<div
v-if="buttonsDisplayParameters.add"
class="text-center mt-1"
>
<button
@click.prevent="addLine"
class="btn btn-sm btn-primary"
type="button"
:title="trans.methods.__('Ajouter une ligne')"
data-bs-toggle="tooltip"
>
<i class="fa-solid fa-plus" />
</button>
</div>
</div>
</template>
<script lang="ts" setup>
import { computed, defineOptions, onMounted, reactive, ref, useAttrs } from "vue";
import parseLaravelErrorMessages from "./../../modules/parseLaravelErrorMessages";
import trans from "./../../modules/trans";
import { Tooltips } from "./../../modules/bsTooltips";
import CkEditorComponent from "./CkEditorComponent.vue";
import ImageInputComponent from "./ImageInputComponent.vue";
import WordCounter from "./WordCounterComponent.vue";
defineOptions({
name: "SliderComponent"
});
// * ATTRIBUTES
const attrs = useAttrs();
// * REFS
const slider = ref<HTMLDivElement|null>(null);
// * DATA
const tooltips = ref<Tooltips | null>(null);
const allErrors = ref<LaravelValidationErrors>({});
interface Column {
id: string;
type: "picture" | "text" | "wysiwyg";
placeholder: string;
validation: string;
required: boolean;
}
/** Input parameters. */
const inputParameters = reactive<{
id: string,
name: string,
}>({
id: "string",
name: "",
});
/** Item parameters. */
const itemParameters = reactive<{
list: Array<Object>,
columns: Array<Column>,
limits: Array<number>,
wysiwygConfig: string,
imageSizes: Array<number>,
}>({
list: [{}],
columns: [],
limits: [0, 0],
wysiwygConfig: "",
imageSizes: [500, 500],
});
/** Buttons parameters. */
const buttonsDisplayParameters = reactive<{
add: boolean,
remove: boolean,
}>({
add: true,
remove: true,
});
// * COMPUTED
const isUsedWithProps = computed<boolean>(() => attrs.json === undefined);
// * LIFECYCLE
onMounted(() => {
const json = String(attrs.json ?? "{}"),
data = JSON.parse(json);
if (!isUsedWithProps.value) {
/** Input parameters. */
inputParameters.name = data.inputName;
/** Item parameters. */
itemParameters.list = Array.isArray(data.itemList) ? data.itemList : [];
itemParameters.columns = data.columns;
itemParameters.limits = data.itemLimit;
itemParameters.wysiwygConfig = data.wysiwygConfig;
itemParameters.imageSizes = data.imageSizes;
/** Global parameters */
allErrors.value = data.errors;
}
setDefaultLines();
checkLengthList();
initTooltips();
});
// * METHODS
/**
* Set default line(s)
* according to the minimum limit defined.
*/
function setDefaultLines(): void {
while (itemParameters.list.length < itemParameters.limits[0]) {
addLine();
}
}
/**
* Add a new line to the <table>,
* add a new element to the array,
* show remove line button.
*/
function addLine(): void {
itemParameters.list.push({});
if (buttonsDisplayParameters.remove == false) {
buttonsDisplayParameters.remove = true;
}
checkLengthList();
tooltips.value?.closeBootstrapTooltip();
initTooltips();
}
/**
* Remove a specific line from the <table>,
* remove a specific element to the array,
* show adding line button.
*/
function removeLine(itemIndex: number): void {
itemParameters.list.splice(itemIndex, 1);
if (buttonsDisplayParameters.add == false) {
buttonsDisplayParameters.add = true;
}
checkLengthList();
tooltips.value?.closeBootstrapTooltip();
initTooltips();
}
/**
* Check the length of the list,
* update variables accordingly.
*/
function checkLengthList(): void {
/** Length minimum */
if (itemParameters.list.length <= itemParameters.limits[0]) {
buttonsDisplayParameters.remove = false;
}
/** Length maximum */
if (itemParameters.list.length >= itemParameters.limits[1]) {
buttonsDisplayParameters.add = false;
}
}
/** Return error message or null. */
function getErrorMessage(itemIndex: number, column: string): string|null {
return parseLaravelErrorMessages.methods.parseValidationInput(
`${inputParameters.name}.${String(itemIndex)}.${column}`,
allErrors.value
);
}
/** Initialise all tooltips in the component. */
function initTooltips(): void {
setTimeout(() => {
tooltips.value = Tooltips.make({
type: "dom",
elements: slider.value!.querySelectorAll("[data-bs-toggle=\"tooltip\"]")
});
}, 500);
}
</script>

View file

@ -85,7 +85,10 @@ import {
faUndoAlt,
faUserTie,
faUtensils,
faWandMagic
faWandMagic,
faBicycle,
faChevronDown,
faChevronUp
} from "@fortawesome/free-solid-svg-icons";
config.autoReplaceSvg = false;
@ -175,5 +178,8 @@ library.add(faComments);
library.add(faRug);
library.add(faBasketShopping);
library.add(faArrowTurnUp);
library.add(faBicycle);
library.add(faChevronDown);
library.add(faChevronUp);
dom.watch();

View file

@ -0,0 +1,49 @@
export function initMediaSelector(id: string) {
const container = document.getElementById(`${id}Section`);
if (container === null) {
return;
}
const mediaVideo = document.getElementById("mediaSelectorVideo") as HTMLInputElement,
mediaImage = document.getElementById("mediaSelectorImage") as HTMLInputElement,
mediaEmpty = document.getElementById("mediaSelectorEmpty") as HTMLInputElement;
mediaVideo?.addEventListener("change", function() {
hideFormPart(`.${id}Picture`);
showFormPart(`.${id}Video`);
hideFormPart(`.${id}None`);
});
mediaImage?.addEventListener("change", function() {
hideFormPart(`.${id}Video`);
showFormPart(`.${id}Picture`);
hideFormPart(`.${id}None`);
});
mediaEmpty?.addEventListener("change", function() {
hideFormPart(`.${id}Video`);
hideFormPart(`.${id}Picture`);
showFormPart(`.${id}None`);
});
}
function hideFormPart(id: string) {
const parts = document.querySelectorAll(id);
parts.forEach(partToHide => {
partToHide.classList.add("d-none");
const inputs = partToHide.querySelectorAll("input");
for (const input of inputs) {
input.disabled = true;
}
});
}
function showFormPart(id: string) {
const parts = document.querySelectorAll(id);
parts.forEach(partToShow => {
partToShow.classList.remove("d-none");
const inputs = partToShow.querySelectorAll("input");
for (const input of inputs) {
input.disabled = false;
}
});
}

View file

@ -5,6 +5,7 @@ import { AxiosStatic } from "axios";
import type Swiper from "swiper";
import type { DepStatus as DepStatusEnum } from "./club/enums";
import type { MenuNodeInterface } from "./types/models/MenuNode";
import { initMediaSelector } from "./bo/utilities/media-selector";
// * Enum
interface EnumInterface {
@ -141,6 +142,7 @@ declare global {
Swal: Function;
shop: ClubShop;
vueDebug: boolean | undefined;
initMediaSelector: initMediaSelector;
__SLIDERS: Map<string, SwiperSlider>,
__SYSTEM: {
_asset: Record<string, string>;

View file

@ -1176,7 +1176,7 @@
</button>
<ul class="dropdown-menu">
{{-- PAGE SORTIR-A-L-EXTERIEUR --}}
@if (isset($exitOutsideStaticPageModel))
@if (isset($exitOutsideStaticPageModel))
<li>
<a href="{{ route('bo.static_pages.edit', $exitOutsideStaticPageModel) }}" @class([
'dropdown-item px-3 py-2',
@ -1195,14 +1195,14 @@
</li>
@endif
{{-- OUI-C-BON --}}
@if (isset($ouiCestBonStaticPageModel))
@if (isset($ouiCestBonStaticPageModel))
<li>
<a href="{{ route('bo.static_pages.edit', $ouiCestBonStaticPageModel ) }}" @class([
'dropdown-item px-3 py-2',
'fw-bold text-bg-secondary' =>
url()->current() ===
route('bo.static_pages.edit', $ouiCestBonStaticPageModel),
])>
<i @class([
'fa-solid fa-file fa-fw fa-fw',
@ -1242,6 +1242,25 @@
</li>
</ul>
</div>
{{-- TDF PAGE --}}
@if (isset($tdfStaticPageModel))
<a data-bs-toggle="tooltip" href="{{ route('bo.static_pages.edit', $tdfStaticPageModel) }}"
title="{{ __('crud.helpers.update_model', ['model' => $tdfStaticPageModel->type->label()]) }}" role="button"
@class([
'btn btn-primary w-100 text-start mt-1',
'fw-bold active' =>
url()->current() ===
route('bo.static_pages.edit', $tdfStaticPageModel->type->value()),
])>
<i @class([
'fa-solid fa-bicycle fa-fw',
'fa-lg' =>
url()->current() ===
route('bo.static_pages.edit', $tdfStaticPageModel->type->value()),
])></i>
{{ $tdfStaticPageModel->type->label() }}
</a>
@endif
<hr>
{{-- CONTACT --}}
@if(isset($contactStaticPageModel))

View file

@ -246,6 +246,58 @@
</div>
@break
@case(intval(\App\Enums\InputType::selectImageVideo->value))
<div class="minicrud-input col-12 mb-3">
<fieldset class="border p-3">
<legend>{{ $input['label'] }}*</legend>
<div class="row mb-3">
<div class="col-12">
@include('bo.partials.inputs.media-selector', [
'id' => Str::camel($k),
'name' => $k,
'value' => old("data.{$k}.value", $input['value'] ?? null),
'required' => isset($input['required']) ? !empty($input['required']) : true,
'model' => $model ?? null,
'helper' =>
__('crud.minicrud.text_warning') .
'. ' .
__('validation.min.string', [
'attribute' => $input['label'],
'min' => 3,
]),
])
@include('modules.input-error', [
'inputName' => "data.{$k}.value",
])
</div>
</div>
</fieldset>
</div>
@break
@case(intval(\App\Enums\InputType::slider->value))
<div class="minicrud-input col-12 mb-3">
<fieldset class="h-100 border p-3">
<legend>{{ $input['label'] }}*</legend>
<div class="row">
<div class="col-12">
@include('bo.partials.inputs.slider', [
'id' => Str::camel($k),
'name' => $k,
'value' => old("data.{$k}.value", $input['value'] ?? null),
'model' => $model ?? null,
'columns' => $input['columns'],
'itemLimit' => $input['itemLimit'],
'imageSizes' => $input['imageSizes'],
'required' => isset($input['required']) ? !empty($input['required']) : true,
'helper' => '',
])
</div>
</div>
</fieldset>
</div>
@break
@default
@php throw new Exception('Input type not handled'); @endphp
@endswitch

View file

@ -1,10 +1,13 @@
@extends('bo.layout', ['brParam' => $sectionApproachModel])
<?php $condition = trans_choice('models.classes.sectionApproach', 1); ?>
@php
$condition = trans_choice('models.classes.sectionApproach', 1);
$inter = __('validation.custom.of_the.female');
@endphp
@section('title', __('Édition :inter :model', ['model' => $condition]))
@section('description', __('Édition :inter :model',
['model' => $condition, 'inter' => __('validation.custom.female') ]))
@section('title', __('Édition :inter :model', ['model' => $condition, 'inter' => $inter]))
@section('description', __('Édition :inter :model', ['model' => $condition, 'inter' => __('validation.custom.female')]))
@section('breadcrumb', request()->route()->getName())
@section('content')
@ -16,7 +19,7 @@
<i class="fa-solid fa-arrow-left"></i>
</a>
@include('modules.breadcrumbs.breadcrumb-body', [
'brParam' => $sectionApproachModel
'brParam' => $sectionApproachModel,
])
</div>
<div class="mb-md-0 mb-2">
@ -26,9 +29,8 @@
</button>
</div>
</div>
<form
action="{{ route('bo.sections.approaches.update', $sectionApproachModel) }}"
method="POST" enctype="multipart/form-data">
<form action="{{ route('bo.sections.approaches.update', $sectionApproachModel) }}" method="POST"
enctype="multipart/form-data">
@csrf
@method('PUT')
@include('bo.pages.sections_approaches.form')
@ -36,7 +38,7 @@
<div class="row mt-3">
<div class="col text-center">
<button class="btn btn-primary" id="formSubmit" data-bs-toggle="tooltip" type="submit"
title="{{ __('crud.helpers.save_model', ['model' => $condition ]) }}">
title="{{ __('crud.helpers.save_model', ['model' => $condition]) }}">
{{ str(__('crud.actions.save'))->ucfirst() }}
</button>
</div>

View file

@ -0,0 +1,163 @@
<div id="{{ sprintf("%sSection", $id)}}" class="row">
{{-- BUTTONS SELECTOR --}}
<div class="col-12 col-md-6 mb-3">
<div class="input-group justify-content-center align-items-center h-100">
<input class="btn-check" id="mediaSelectorVideo" name="mediaSelector" type="radio" autocomplete="off"
@checked(isset($model->data[$name]['value']['video']))>
<label class="btn btn-secondary rounded-start" for="mediaSelectorVideo">{{ __('Vidéo') }}</label>
<input class="btn-check" id="mediaSelectorImage" name="mediaSelector" type="radio" autocomplete="off"
@checked(isset($model->data[$name]['value']['picture']))>
<label class="btn btn-secondary" for="mediaSelectorImage">{{ __('Image') }}</label>
@if (!$required)
<input class="btn-check" id="mediaSelectorEmpty" name="mediaSelector" type="radio" autocomplete="off"
@checked(!$required && empty($model->data[$name]['value']['video']) && empty($model->data[$name]['value']['picture']))>
<label class="btn btn-secondary" for="mediaSelectorEmpty">{{ __('Rien') }}</label>
@endif
</div>
</div>
{{-- HIDDEN EMPTY MEDIA INPUT --}}
<input name="value[]" value="" hidden>
{{-- VIDEO --}}
<div @class([
sprintf('%sVideo', $id) . ' col-12 col-md-6 mb-3',
'd-none' => empty($model->data[$name]['value']['video']),
])>
{{-- VIDEO ID --}}
@include('bo.partials.inputs.varchar', [
'id' => sprintf("%sVideoId", $id),
'label' => Str::ucFirst(__('validation.custom.video_id')),
'hasWordCounter' => true,
'name' => "data[$name][value][video][id]",
'required' => true,
'disabled' => empty($model->data[$name]['value']['video']),
'value' => $model->data[$name]['value']['video']['id'] ?? null,
'helper' => Str::ucFirst(__('validation.custom.video_id')),
'placeholder' => Str::ucFirst(__('validation.custom.video_id')),
])
</div>
{{-- VIDEO_ALT --}}
<div @class([
sprintf('%sVideo', $id) . ' col-12 col-md-6 mb-3',
'd-none' => empty($model->data[$name]['value']['video']),
])>
@include('bo.partials.inputs.varchar', [
'id' => sprintf("%sVideoAlt", $id),
'label' => Str::ucFirst(__('validation.custom.video_alt')),
'hasWordCounter' => true,
'name' => "data[$name][value][video][alt]",
'required' => true,
'model' => $model ?? null,
'disabled' => empty($model->data[$name]['value']['video']['alt']),
'value' => $model->data[$name]['value']['video']['alt'] ?? '',
'helper' => __('crud.minicrud.video_alt_helper') . ' ' . __('validation.between.string', [
'attribute' => Str::ucFirst(__('validation.custom.video_alt')),
'min' => 6,
'max' => 255
]),
'placeholder' => Str::ucFirst(__('validation.custom.video_alt')),
])
</div>
{{-- VIDEO_TITLE --}}
<div @class([
sprintf('%sVideo', $id) . ' col-12 col-md-6 mb-3',
'd-none' => empty($model->data[$name]['value']['video']),
])>
@include('bo.partials.inputs.varchar', [
'id' => sprintf("%sVideoTitle", $id),
'label' => Str::ucFirst(__('validation.custom.video_title')),
'hasWordCounter' => true,
'name' => "data[$name][value][video][title]",
'required' => true,
'model' => $model ?? null,
'disabled' => empty($model->data[$name]['value']['video']['title']),
'value' => $model->data[$name]['value']['video']['title'] ?? '',
'helper' => __('crud.minicrud.video_title_helper') . ' ' . __('validation.between.string', [
'attribute' => Str::ucFirst(__('validation.custom.video_title')),
'min' => 6,
'max' => 255
]),
'placeholder' => Str::ucFirst(__('validation.custom.video_title')),
])
</div>
{{-- PICTURE --}}
<div @class([
sprintf('%sPicture', $id) . ' col-12 col-md-6 mb-3',
'd-none' => empty($model->data[$name]['value']['picture']),
])>
@include('bo.partials.inputs.varchar-picture', [
'id' => sprintf("%sPicture", $id),
'name' => "data[$name][value][picture][path]",
'width' => 500,
'height' => 500,
'model' => $model ?? null,
'value' => $model->data[$name]['value']['picture']['path'] ?? null,
'helper' => __('crud.minicrud.dimensions_must_be', [
'width' => 500,
'height' => 500,
]),
'required' => true,
'preview' => false,
])
</div>
{{-- PICTURE_ALT --}}
<div @class([
sprintf('%sPicture', $id) . ' col-12 col-md-6 mb-3',
'd-none' => empty($model->data[$name]['value']['picture']),
])>
@include('bo.partials.inputs.varchar', [
'id' => sprintf("%sPictureAlt", $id),
'label' => Str::ucFirst(__('validation.custom.picture_alt')),
'hasWordCounter' => true,
'name' => "data[$name][value][picture][alt]",
'required' => true,
'model' => $model ?? null,
'disabled' => empty($model->data[$name]['value']['picture']['alt']),
'value' => $model->data[$name]['value']['picture']['alt'] ?? '',
'helper' => __('crud.minicrud.picture_alt_helper') . ' ' . __('validation.between.string', [
'attribute' => Str::ucFirst(__('validation.custom.picture_alt')),
'min' => 6,
'max' => 255
]),
'placeholder' => Str::ucFirst(__('validation.custom.picture_alt')),
])
</div>
{{-- PICTURE_TITLE --}}
<div @class([
sprintf('%sPicture', $id) . ' col-12 col-md-6 mb-3',
'd-none' => empty($model->data[$name]['value']['picture']),
])>
@include('bo.partials.inputs.varchar', [
'id' => sprintf("%sPictureTitle", $id),
'label' => Str::ucFirst(__('validation.custom.picture_title')),
'hasWordCounter' => true,
'name' => "data[$name][value][picture][title]",
'required' => true,
'model' => $model ?? null,
'disabled' => empty($model->data[$name]['value']['picture']['title']),
'value' => $model->data[$name]['value']['picture']['title'] ?? '',
'helper' => __('crud.minicrud.picture_title_helper') . ' ' . __('validation.between.string', [
'attribute' => Str::ucFirst(__('validation.custom.picture_title')),
'min' => 6,
'max' => 255
]),
'placeholder' => Str::ucFirst(__('validation.custom.picture_title')),
])
</div>
{{-- NOTHING SELECTED --}}
<div @class([
sprintf('%sNone', $id) . ' col-12 col-md-6',
'd-none' => !empty($model->data[$name]['value']['picture']) || !empty($model->data[$name]['value']['video']),
])>
<p class="text-center text-body-secondary m-0">{{ __('Aucun média n\'est sélectionné') }}</p>
</div>
</div>
@push('scripts')
<script nonce="{{ $nonce }}">
document.addEventListener("DOMContentLoaded", function () {
initMediaSelector("{{ $id }}");
});
</script>
@endpush

View file

@ -0,0 +1,18 @@
@php
$data = [
'itemList' => old($name, $value ?? []) ?? [],
'columns' => $columns,
'itemLimit' => $itemLimit ?? [],
'inputName' => $name,
'imageSizes' => $imageSizes ?? [],
'wysiwygConfig' => $wysiwygConfig ?? 'basic',
'header' => $header ?? false,
'errors' => $errors->getBag('default')->getMessages() ?? [],
];
@endphp
<div class="slider" data-json='@json($data)'></div>
@include('modules.input-error', [
'inputName' => $name,
'helperId' => "{$id}Help",
'helper' => $helper,
])

View file

@ -81,7 +81,7 @@
<span class="thanks-for">Merci pour votre participation.</span><br>
Nous comptabilisons actuellement toutes les participations...<br><br>
Nous annoncerons le
<span class="badge-wrap"><strong class="gc-info-date-badge">28 MAI</strong></span>
<span class="badge-wrap"><strong class="gc-info-date-badge">03 juillet</strong></span>
quelle recette a remporté votre préférence !
</p>
</div>

View file

@ -77,7 +77,7 @@
notre idée de cocréer ce pané a commencé sur nos réseaux sociaux, portée par <span>2 créateurs</span>
</x-club.title-section>
<x-club.social-videos-section left-badge="@ LOREM IPSUM" right-badge="@ LOREM IPSUM"
<x-club.social-videos-section
description="redécouvrez notre campagne à travers quelques contenus." :videos="$videos" />
<x-club.play-section subtitle="à vous" button-label="de jouer"

View file

@ -88,7 +88,7 @@
<div class="gc-info-btn-shadow">
<div class="gc-info-btn gc-info-btn--orange">
les gagnants du tirage au sort<br>
seront contactés le 4 juin 2026
seront contactés le 7 juillet 2026
</div>
<div class="gc-info-btn-shadow">
</x-slot:button>

View file

@ -1,6 +1,6 @@
@props([
'leftBadge' => '@ LOREM IPSUM',
'rightBadge' => '@ LOREM IPSUM',
'leftBadge' => '@studiodanielle',
'rightBadge' => '@jesta_hillmann',
'description' => '',
'videos' => [],
'carouselId' => 'gldcSocialVideosCarousel',

View file

@ -1,29 +1,11 @@
<div @class(['mt-md-0 mt-5', $class ?? ''])>
<div @class([$class ?? ''])>
<div class="light-card">
<img class="img-fluid light-card-icon" src="{{ asset($icon['path']) }}" title="{{ $icon['description'] }}"
alt="{{ $icon['alt'] }}">
<span class="text-uppercase bg-secondary text-light fw-semibold right-rotate-sm">{{ $category }}</span>
<div class="bg-light position-relative line-border-small light-card-content mt-3">
@foreach ($content as $section)
@if(isset($section['title']))
<h3 class="fs-5 fw-semibold f-catamaran">{{ $section['title'] }}</h3>
@endif
@if (array_key_exists('points', $section) && !empty($section['points']))
<ul>
@foreach ($section['points'] as $point)
<li>{!! $point !!}</li>
@endforeach
</ul>
@endif
@if (array_key_exists('text', $section) && !empty($section['text']))
<p class="pr-3">{{ $section['text'] }}</p>
@endif
@if (array_key_exists('asterisc', $section) && !empty($section['asterisc']))
<small class="fst-italic fs-7 pr-3">{{ $section['asterisc'] }}</small>
@endif
@endforeach
<div class="bg-light position-relative line-border-small light-card-content mt-3 fs-5 f-catamaran ck-content">
{!! clean($content) !!}
</div>
</div>

View file

@ -14,30 +14,30 @@
<hgroup>
@if (isset($badge) && !empty($badge))
<div class="f-bourton-base mt-4 w-fit px-2 py-1 text-white" style="background-color:{{ $badge->color }}">
{{ $badge->label }}
{!! clean($badge->label) !!}
</div>
@endif
<div class="d-flex align-items-center">
@if (isset($badge) && !empty($picto))
<img class="img-fluid my-3 me-2" id="header-banner-picto" src="{{ $picto }}" title="{{ $picto_title }}"
<img class="img-fluid my-3 me-2" id="header-banner-picto" src="{{ $picto }}" title="{!! clean($picto->picto_title) !!}"
alt="{{ $picto_alt }}">
@endif
<h1 class="my-3">{{ $title }}</h1>
<h1 class="my-3">{!! clean($title) !!}</h1>
</div>
<p>{{ $subtitle }}
<p>{!! clean($subtitle) !!}
</p>
</hgroup>
</div>
<div class="d-none d-xl-block col-6 col-xxl-4">
<div class="header-image-wrapper breeding-header-translate-right">
<img class="img-fluid" src="{{ asset($image) }}"
title="{{ $title_img }}" alt="{{ $alt_img }}">
title="{!! clean($title_img) !!}" alt="{!! clean($alt_img) !!}">
</div>
</div>
<div class="col-12 col-md-8 position-relative z-1 mx-auto mt-4">
<div class="d-xl-none header-image-wrapper">
<img class="img-fluid" src="{{ asset($image) }}"
title="{{ $title_img }}" alt="{{ $alt_img }}">
title="{!! clean($title_img) !!}" alt="{!! clean($alt_img) !!}">
</div>
</div>
</div>

View file

@ -20,9 +20,9 @@
</div>
</div>
<p class="w-lg-50 mx-auto text-center">
{{ __(strip_tags($staticPageModel->data['description']['value'])) }}
</p>
<div class="w-lg-50 mx-auto text-center">
{!! clean($staticPageModel->data['description']['value']) !!}
</div>
</div>
</div>
@ -45,13 +45,14 @@
<div style="display: contents" data-category="{{ $categoryKey }}">
@foreach ($categoryItems as $item)
<x-fo.breeding.light-card
:category="$item['category']"
:icon="$item['icon']"
:content="$item['content']"
:class="$item['class']"
data-category="{{ $categoryKey }}"
/>
<div class="{{ $loop->first ? 'mt-5 mt-md-0' : '' }}">
<x-fo.breeding.light-card :category="$item->title" :icon="[
'path' => $item->picture,
'alt' => $item->picture_alt,
'description' => $item->picture_title,
]" :content="$item->content"
class="card-template-sm" data-category="{{ $categoryKey }}" />
</div>
@endforeach
</div>
@endforeach

View file

@ -1,13 +1,13 @@
@props(['titleSearch' => '', 'descriptionSearch' => '', 'ocbBreederModels'])
<div class="container position-relative pb-5">
<div class="row justify-content-center">
<div class="col-12">
<h2 class="h1 f-intro-head-h-base section-title pb-2 text-center">
{{ __('Retrouvez tous nos éleveurs Oui c\'est Bon !') }}
{!! clean(__($titleSearch)) !!}
</h2>
</div>
<div class="col-12 col-md-6 text-center">
<p class="mb-0">{{ __('Parce que nous sommes fiers de notre savoir-faire français et de l\'origine France de nos produits,
nous vous dévoilons les éleveurs partenaires et engagés au quotidien dans notre démarche Oui c\'est Bon Le Gaulois') }}</p>
<p class="mb-0">{!! clean(__($descriptionSearch)) !!}</p>
</div>
<div class="col-12">
@php

View file

@ -22,19 +22,16 @@
</div>
</div>
</div>
<p class="w-lg-50 mx-auto text-center">
{{ __(strip_tags($staticPageModel->data['description']['value'])) }}
</p>
<div class="w-lg-50 mx-auto text-center">
{!! clean($staticPageModel->data['description']['value']) !!}
</div>
</div>
</div>
{{-- Buttons --}}
<div class="d-flex justify-content-center gap-md-4 gap-5">
<div class="d-flex justify-content-center gap-md-4 gap-5 mb-5 mb-md-0">
@foreach ($items as $categoryKey => $categoryItems)
<button
class="btn btn-secondary fs-6 d-block category-btn"
type="button"
data-category="{{ $categoryKey }}"
>
<button class="btn btn-secondary fs-6 d-block category-btn" type="button"
data-category="{{ $categoryKey }}">
{{ $categoryKey }}
</button>
@endforeach
@ -43,16 +40,16 @@
<div class="row mb-5 mt-5" id="cards-container-outside">
<div class="card-grid">
@foreach ($items as $categoryKey => $categoryItems)
<div style="display: contents" data-category="{{ $categoryKey }}">
@foreach ($categoryItems as $item)
<x-fo.breeding.light-card
:category="$item['category']"
:icon="$item['icon']"
:content="$item['content']"
:class="$item['class']"
data-category="{{ $categoryKey }}"
/>
<div class="{{ $loop->first ? 'mt-5 mt-md-0' : '' }}">
<x-fo.breeding.light-card :category="$item->title" :icon="[
'path' => $item->picture,
'alt' => $item->picture_alt,
'description' => $item->picture_title,
]" :content="$item->content"
class="card-template-sm" data-category="{{ $categoryKey }}" />
</div>
@endforeach
</div>
@endforeach

View file

@ -1,10 +1,10 @@
@props(['sliderImages' => []])
@props(['sliderImages' => [], 'title'])
<section class="position-relative negative-margin-sm overflow-hidden">
<div class="position-absolute h-100 w-100 top-0 z-0">
<div class="bg-white-wood-reverse h-100 w-100" id="slider-galery-outside-bg"></div>
</div>
<div class="container-fluid position-relative container mt-5">
<h3 class="mw-75 text-uppercase fs-1 fs-bold mx-auto text-center">{{ __("Galerie sortant à l'extérieur") }}</h3>
<h3 class="mw-75 text-uppercase fs-1 fs-bold mx-auto text-center">{!! clean(__($title)) !!}<h3>
<div class="position-relative" id="swiper-breeding-galery">
<div class="position-relative justify-content-between my-3 px-2">

View file

@ -1,12 +1,10 @@
@props(['startVote' => true])
<div class="idea-wrapper position-relative overflow-hidden">
{{-- Décors --}}
<img src="{{ Vite::asset('resources/assets/images/golden-crush/right-nuggets.png') }}" alt=""
aria-hidden="true" class="idea-nuggets idea-nuggets-top">
<img src="{{ Vite::asset('resources/assets/images/golden-crush/left-nuggets.png') }}" alt="" aria-hidden="true"
class="idea-nuggets idea-nuggets-bottom-left">
<img src="{{ Vite::asset('resources/assets/images/golden-crush/cb.png') }}" alt="" aria-hidden="true"
class="idea-nuggets idea-nuggets-bottom-right">
@ -34,8 +32,7 @@
</div>
<div class="idea-wave mx-auto mb-4 mb-md-5"></div>
<a href="{{ route('club.golden-crush') }}" class="idea-btn">
<a href="{{ $startVote ? route('club.golden-crush') : "#" }}" class="idea-btn">
JE PARTICIPE <i class="fa-solid fa-arrow-right"></i>
</a>
</div>

View file

@ -1,62 +1,74 @@
@php
$anecdotes = [
[
'picto_url' => Vite::asset('resources/assets/images/page-tdf/caravane/Picto-soleil-jaune-météo.svg'),
'picto_alt' => 'Pictogramme d\'un soleil pour les anecdoctes météo sur le Tour de France',
'picto_title' => 'Pictogramme d\'un soleil',
'title' => 'La caravane par tous les temps !',
'content' =>
'Le 26 juillet 2019, lors de l\'étape Saint-Jean-de-Maurienne et Tignes, les chars terminent leur parade quand un orage de grêle s\'invite et entraîne une coulée de boue qui bloque la route et l’accès aux cyclistes. L’organisation décide l\'arrêt de l’étape et marquera l’histoire du Tour de France.',
'picto_url' => asset($model->data['fun_facts_picture_1']['value']),
'picto_alt' => $model->data['fun_facts_picture_1']['alt'],
'picto_title' => $model->data['fun_facts_picture_1']['title'],
'title' => $model->data['fun_facts_title_1']['value'],
'content' => $model->data['fun_facts_description_1']['value'],
],
[
'picto_url' => Vite::asset('resources/assets/images/page-tdf/caravane/Picto-enfant-brun-famille.svg'),
'picto_alt' => 'Pictogramme d\'une tête d\'enfant pour les liens de parenté au sein de l\'équipe des caravaniers',
'picto_title' => 'Pictogramme d\'un enfant',
'title' => 'La transmission d’une passion entre Père & Fils !',
'content' =>
'Avec plus de 10 tours de France à son actif, Jean-Marie a transmis sa passion à son fils. Léo assure : « Sur le Tour, nous sommes collègues, mais il y a toujours cette fierté personnelle de partager ces moments ensemble sur les routes de France. ».',
'picto_url' => asset($model->data['fun_facts_picture_2']['value']),
'picto_alt' => $model->data['fun_facts_picture_2']['alt'],
'picto_title' => $model->data['fun_facts_picture_2']['title'],
'title' => $model->data['fun_facts_title_2']['value'],
'content' => $model->data['fun_facts_description_2']['value'],
],
[
'picto_url' => Vite::asset('resources/assets/images/page-tdf/caravane/Picto-poulet-policier-bleu.svg'),
'picto_alt' => 'Pictogramme d\'un poulet policier pour les histoires poulets-policiers pendants le Tour de France',
'picto_title' => 'Pictogramme d\'un poulet policier',
'title' => 'Histoire de poulet',
'content' =>
'Avec un sens de l’humour aguerri, Cocotte rencontre <a href="https://www.youtube.com/watch?v=reI-Z8UE3lM" target="_blank">un sympathique collègue</a> au détour d’un passage dans un village sur les routes du Tour de France.',
'picto_url' => asset($model->data['fun_facts_picture_3']['value']),
'picto_alt' => $model->data['fun_facts_picture_3']['alt'],
'picto_title' => $model->data['fun_facts_picture_3']['title'],
'title' => $model->data['fun_facts_title_3']['value'],
'content' => $model->data['fun_facts_description_3']['value'],
],
[
'picto_url' => Vite::asset('resources/assets/images/page-tdf/caravane/Picto-sirène-pompier-rouge.svg'),
'picto_alt' => 'Pictogramme d\'une sirène d\'alarme pour les anecdoctes insolites pendant le Tour de France',
'picto_title' => 'Pictorgramme d\'une alarme',
'title' => 'Un pompier en tant que chauffeur d’un char Le Gaulois !',
'content' =>
'Nicolas, pompier engagé, a procédé à une intervention de secours pour une jeune caravanière Le Gaulois. Depuis, Nicolas, rebaptisé Pimpon Le Gaulois, sillonne toujours les routes de France à bord d\'un char Cocotte.',
'picto_url' => asset($model->data['fun_facts_picture_4']['value']),
'picto_alt' => $model->data['fun_facts_picture_4']['alt'],
'picto_title' => $model->data['fun_facts_picture_4']['title'],
'title' => $model->data['fun_facts_title_4']['value'],
'content' => $model->data['fun_facts_description_4']['value'],
],
];
@endphp
<section id="au-coeur-de-la-caravane">
<h2 class="fw-bold text-uppercase mb-md-5 mb-0 text-center">Au cœur de la caravane Le Gaulois</h2>
<h2 class="fw-bold text-uppercase mb-md-5 mb-0 text-center">
{{ $model->data['heart_title']['value'] }}
</h2>
<div class="position-relative line-border-large">
<div class="position-absolute left-100 w-100 d-none d-md-block start-0 z-0">
<img class="img-fluid w-100 h-auto" src="{{ Vite::asset('resources/assets/images/page-tdf/caravane/TDF2033-caravaniers.jpg') }}"
title="Char de la caravane Le Gaulois" alt="Char 'La crousty mobile' qui traverse un village français pendant le Tour de France" />
<img
class="img-fluid w-100 h-auto"
src="{{ asset($model->data['heart_picture']['value']) }}"
title="{{ $model->data['heart_picture']['title'] }}"
alt="{{ $model->data['heart_picture']['alt'] }}"
/>
</div>
<div class="position-relative z-1 anecdote-container container">
<div class="row align-items-center">
<div class="col-lg-7">
<div class="rounded-3 position-relative line-border-medium bg-white p-4 shadow">
<h4 class="fw-bold fs-2 text-uppercase mb-5 text-center">Nos petites anecdotes</h4>
<div class="">
<h4 class="fw-bold fs-2 text-uppercase mb-5 text-center">
{{ $model->data['heart_subtitle']['value'] }}
</h4>
<div>
@foreach ($anecdotes as $a)
<div class="row mb-3">
<div class="col-3 d-flex flex-column justify-content-center">
<img class="w-50 mx-auto mb-2" src="{{ $a['picto_url'] }}" title="{{ $a['picto_title'] }}"
alt="{{ $a['picto_alt'] }}">
<img
class="w-50 mx-auto mb-2"
src="{{ $a['picto_url'] }}"
title="{{ $a['picto_title'] }}"
alt="{{ $a['picto_alt'] }}"
/>
</div>
<div class="col-9">
<div class="fw-bold text-uppercase fs-6 text-start">{{ $a['title'] }}</div>
<p class="f-bakerie-rough fs-4 fw-normal">{!! $a['content'] !!}</p>
<div class="fw-bold text-uppercase fs-6 text-start">
{!! clean($a['title']) !!}
</div>
<div class="f-bakerie-rough fs-4 fw-normal">
{!! clean($a['content']) !!}
</div>
</div>
</div>
@endforeach
@ -68,5 +80,5 @@
</div>
</section>
<div class="ms-md-5 mt-4 d-none d-md-block">
<small>Crédit photo - ASO Aurélien Vialatte</small>
<small>{{ $model->data['heart_picture_author']['value'] }}</small>
</div>

View file

@ -1,74 +1,5 @@
@php
$sliders = [
[
'img' => Vite::asset('resources/assets/images/page-tdf/chars-slider/Char-cocotte-roule-ma-poule-Le-Gaulois.png'),
'alt' =>
'"Char" La cocotte multiproduits" avec les packagings du filet de canard, du poulet à la mexicaine et des gésiers de volaille Le Gaulois',
'title_img' => '"Char" La cocotte multiproduits" Le Gaulois',
'title' => 'La Cocotte multiproduits',
'content' =>
"Variée et savoureuse, la Cocotte mutiproduits présente les incontournables de votre frigo, pour toute la famille et pour toute l'année. Et vous, quel est votre produit préféré Le Gaulois ?",
],
[
'img' => Vite::asset('resources/assets/images/page-tdf/chars-slider/Char-cocotte-cordon-bleu-Le-Gaulois.png'),
'alt' => 'Char "La cocotte panée"avec le packaging du cordon bleu de poulet Le Gaulois',
'title_img' => 'Char "La cocotte panée" Le Gaulois',
'title' => 'La Cocotte Panée',
'content' =>
'Moelleuse, croustillante et fondante, la Cocotte Panée arpente les régions françaises à la découverte du nouveau Cordon Bleu culinaire ! Quel sera le nouveau chef cuisinier du Tour de France ?',
],
[
'img' => Vite::asset('resources/assets/images/page-tdf/chars-slider/Char-cocotte-crousty-chicken-Le-Gaulois.png'),
'alt' => 'Char "La crousty mobile" avec une box de crousty chicken Le Gaulois',
'title_img' => 'Char "La crousty mobile" Le Gaulois',
'title' => 'La Crousty Mobile',
'content' =>
'Généreuse et gourmande, la Crousty Mobile saura vous régaler ! Et vous, à quelle occasion mangeriez-vous les Crousty Chicken ?',
],
[
'img' => Vite::asset('resources/assets/images/page-tdf/chars-slider/Char-cocotte-cuisson-express-poulet-Le-Gaulois.png'),
'alt' => 'Char "La cocotte express"avec le packaging du filet de poulet tranché Cuisson Express Le Gaulois',
'title_img' => 'Char "La cocotte express" Le Gaulois',
'title' => 'La Cocotte Express',
'content' =>
'Rapide à cuisiner, la Cocotte Express est dans la course ! Battra-t\'elle suffisamment des ailes pour décrocher le maillot jaune ?',
],
[
'img' => Vite::asset(
'resources/assets/images/page-tdf/chars-slider/Char-cocotte-blanc-poulet-sortant à l\'extérieur-Le-Gaulois.png',
),
'alt' => 'Char " La cocotte Sortant à l\'Extérieur" avec le packaging du blanc de poulet sortant à l\'extérieur Le Gaulois',
'title_img' => 'Char " La cocotte Sortant à l\'Extérieur" Le Gaulois',
'title' => 'La Cocotte Sortant à l\'extérieur',
'content' =>
'Sortant à l\'extérieur, la Cocotte profite de la lumière et de la nature pour observer nos plus belles régions de France. Selon vous, quelle est la meilleure étape du Tour ?',
],
[
'img' => Vite::asset('resources/assets/images/page-tdf/chars-slider/Char-cocotte-filet-poulet-rôti-Le-Gaulois.png'),
'alt' => 'Char "La cocotte rôtie"avec le packaging du filet de poulet rôti Le Gaulois',
'title_img' => 'Char " La cocotte rôtie" Le Gaulois',
'title' => 'La Cocotte Rôtie',
'content' =>
"Prête à consommer chaud ou froid, la Cocotte rôtie profite du Tour de France pour renforcer son bronzage. Et oui, c'est ça le secret du poulet rôti Le Gaulois !",
],
[
'img' => Vite::asset('resources/assets/images/page-tdf/chars-slider/Char-cocotte-multiproduits-Le-Gaulois.png'),
'alt' =>
'Char " La cocotte roule ma poule" avec les packagings du poulet fumé, des brochettes de dinde, du crousty chicken et de la belle escalope Le Gaulois',
'title_img' => 'Char " La cocotte roule ma poule" Le Gaulois',
'title' => 'La Cocotte Roule ma poule',
'content' =>
'Sain et gourmand, le panier plaisir défile les étapes du Tour de France pour vous accompagner à mieux manger. Et vous, quelle est votre produit préféré Le Gaulois ?',
],
[
'img' => Vite::asset('resources/assets/images/page-tdf/chars-slider/Char-cocotte-filet-poulet-Oui c\'est bon-Le-Gaulois.png'),
'alt' => 'Char "La cocotte Oui c\'est Bon"avec le packaging du filet de poulet Oui c\'est Bon Le Gaulois',
'title_img' => 'Char "La cocotte Oui c\'est Bon" Le Gaulois',
'title' => 'La Cocotte Oui c\'est Bon',
'content' =>
'Tendre et de qualité, la Cocotte Oui c\'est Bon s\'adapte à tous les repas du quotidien, pour les petits et les grands ! Alors avez-vous retrouvé votre éleveur grâce à la traçabilité ?',
],
];
$sliders = $model->data['discover_items']['value'];
@endphp
<section class="position-relative bg-white-wood">
@ -76,9 +7,8 @@
<div class="row align-items-center justify-content-center">
<div class="col-md-5"></div>
<div class="col-md-4">
<h2 class="fw-bold text-uppercase mb-4">Découvrez <span class="text-danger">nos
chars</span>
<span class="text-danger">"cocottes"</span>
<h2 class="fw-bold text-uppercase mb-4">{{ $model->data['discover_title_1']['value'] }}
<span class="text-danger">{{ $model->data['discover_title_2']['value'] }}</span>
</h2>
</div>
</div>
@ -90,13 +20,15 @@
<div class="swiper-slide">
<div class="row align-items-center justify-content-center">
<div class="col-md-6 text-center">
<img class="img-fluid mb-3 increase-width" src="{{ $slide['img'] }}" title="{{ $slide['title_img'] }}"
alt="{{ $slide['alt'] }}">
<img class="img-fluid mb-3 increase-width" src="{{ asset($slide['picture']) }}" title="{{ $slide['picture_title'] }}"
alt="{{ $slide['picture_alt'] }}">
</div>
<div class="col-md-4">
<div class="rounded-3 line-border-small bg-white p-4">
<h4 class="text-uppercase text-danger mb-2">{{ $slide['title'] }}</h4>
<p class="mb-0">{{ $slide['content'] }}</p>
<h4 class="text-uppercase text-danger mb-2">{{ $slide['subtitle'] }}</h4>
<div>
{!! clean($slide['description']) !!}
</div>
</div>
</div>
</div>

View file

@ -1,93 +1,112 @@
<section class="bg-white-wood-big-reverse jeu-concours-section position-relative">
<div class="d-flex justify-content-center jeu-concours-section-height container">
<div @class([
'd-flex justify-content-center jeu-concours-section-height container',
'mt-16' => !$model->data['play_display_section']['value']
])>
<div class="row g-4 align-items-center">
<div class="col-12 col-md-6">
<div class="position-relative">
<div class="d-flex justify-content-end w-100">
<div class="position-relative game-100-percent-image-wrapper z-2">
<img src="{{ Vite::asset('resources/assets/images/page-tdf/jeux-TDF-100% gagnant.svg') }}" alt="100% Gagnant">
@if ($model->data['play_display_section']['value'])
<div class="col-12 col-md-6">
<div class="position-relative">
<div class="d-flex justify-content-end w-100">
<div class="position-relative game-100-percent-image-wrapper z-2">
<img
src="{{ asset($model->data['play_picture']['value']) }}"
alt="{{ $model->data['play_picture']['alt'] }}"
title="{{ $model->data['play_picture']['title'] }}"
/>
</div>
</div>
</div>
<div class="w-100 rounded-3 line-border-medium position-relative z-1 bg-white p-5 shadow">
<h3 class="fw-bold text-uppercase mb-2">Jouez et tentez de gagner !</h3>
<p class="mb-3">Participez à notre <a class="text-decoration-underline"
href="https://www.legauloistourdefrance.fr/reglement" target="_blank"><strong>jeu 100% gagnant
</strong></a> Le Gaulois pendant le
Tour de France 2025.</p>
<a class="btn btn-danger text-uppercase mb-4" href="https://www.legauloistourdefrance.fr" target="_blank">Je tente
ma chance
!</a>
<div class="row text-center">
<div class="col-4">
<img class="images-100-percent mb-1"
src="{{ Vite::asset('resources/assets/images/page-tdf/TV-home-cinéma.png') }}"
title="5 Ensembles TV-Home cinéma à gagner"
alt="Ensemble TV-Home cinéma à gagner pendant le jeu TDF 100% gagnant Le Gaulois">
<div class="fw-bold text-uppercase">Ensembles TV + Home Cinema</div>
<div class="w-100 rounded-3 line-border-medium position-relative z-1 bg-white p-5 shadow">
<h3 class="fw-bold text-uppercase mb-2">{{ $model->data['play_title']['value'] }}</h3>
<div class="mb-3">
{!! clean($model->data['play_description']['value']) !!}
</div>
<div class="col-4">
<img class="images-100-percent mb-1"
src="{{ Vite::asset('resources/assets/images/page-tdf/Casque-audios-oreilles-libres.png') }}"
title="40 Casques audios oreilles libres à gagner"
alt="Casques audios oreilles libres à gagner pendant le jeu TDF 100% gagnant Le Gaulois">
<div class="fw-bold text-uppercase">casques audios oreilles libres</div>
</div>
<div class="col-4">
<img class="images-100-percent mb-1"
src="{{ Vite::asset('resources/assets/images/page-tdf/Bons-d-achat.png') }}"
title="Milliers de bons d'achat à gagner"
alt=" Bons de réduction à gagner pendant le jeu TDF 100% gagnant Le Gaulois">
<div class="fw-bold text-uppercase">Bons d'achat</div>
<a class="btn btn-danger text-uppercase mb-4" href="{{ $model->data['play_btn_url']['value'] }}" target="_blank">
{{ $model->data['play_btn_text']['value'] }}
</a>
<div class="row text-center">
<div class="col-4">
<img class="images-100-percent mb-1"
src="{{ asset($model->data['prize_picture_1']['value']) }}"
title="{{ $model->data['prize_picture_1']['title'] }}"
alt="{{ $model->data['prize_picture_1']['alt'] }}">
<div class="fw-bold text-uppercase">{{ $model->data['prize_title_1']['value'] }}</div>
</div>
<div class="col-4">
<img class="images-100-percent mb-1"
src="{{ asset($model->data['prize_picture_2']['value']) }}"
title="{{ $model->data['prize_picture_2']['title'] }}"
alt="{{ $model->data['prize_picture_2']['alt'] }}">
<div class="fw-bold text-uppercase">{{ $model->data['prize_title_2']['value'] }}</div>
</div>
<div class="col-4">
<img class="images-100-percent mb-1"
src="{{ asset($model->data['prize_picture_3']['value']) }}"
title="{{ $model->data['prize_picture_3']['title'] }}"
alt="{{ $model->data['prize_picture_3']['alt'] }}">
<div class="fw-bold text-uppercase">{{ $model->data['prize_title_3']['value'] }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-12 col-md-6 d-flex flex-column position-relative" id="come-section">
<div class="ms-md-5 position-relative z-2 bg-white shadow" id="come">
@endif
<div class="col-12 col-md-6 d-flex flex-column position-relative mx-auto" id="come-section">
<div @class([
'position-relative z-2 bg-white shadow',
'ms-md-5' => $model->data['play_display_section']['value']
]) id="come">
<div class="d-flex align-items-center mb-2">
<div class="point-exclamation me-3">
<img src="{{ Vite::asset('resources/assets/images/page-tdf/point-exclamation.svg') }}"
title="Point d'exclamation" alt="Point d'exclamation">
<img
src="{{ asset($model->data['find_us_picture']['value']) }}"
title="{{ $model->data['find_us_picture']['title'] }}"
alt="{{ $model->data['find_us_picture']['alt'] }}"
/>
</div>
<span class="fw-bold text-uppercase fs-4">Venez nous retrouver sur le parcours du Tour de France</span>
<span class="fw-bold text-uppercase fs-4">{{ $model->data['find_us_title']['value'] }}</span>
</div>
<div class="mb-3">
{!! $model->data['find_us_description']['value'] !!}
</div>
<p class="mb-2"><b>Télécharger notre pancarte et retrouver nous sur la route&nbsp;du tour de France !</b></p>
<p class="mb-3">Le Tour de France est un rendez-vous immanquable qui marque le début de la pause estivale. Venez
nous rejoindre au bord des routes avec votre <strong>pancarte Cocotte Le Gaulois !</strong> Lorsque l’animateur du
char
d’ouverture de la caravane, Arthur, et ses acolytes caravaniers et caravanières vous repèrent, ils vous
enverront des petits cadeaux.</p>
<p><strong>Petit conseil :</strong> En agitant fièrement votre pancarte, vous augmenterez vos chances de recevoir
des cadeaux !</p>
<div class="d-flex flex-wrap gap-3">
<a class="btn btn-secondary" href="{{ asset('tdf-downloads/Pancarte.pdf') }}" download>
<a class="btn btn-secondary" href="{{ $model->data['find_us_btn_url_1']['value'] }}" download>
<i class="fa-solid fa-arrow-down"></i>
<span>Télécharger la pancarte</span>
<span>{{ $model->data['find_us_btn_text_1']['value'] }}</span>
</a>
<a class="btn btn-light border" href="{{ asset('tdf-downloads/COLORIAGE - Avril 2024.pdf') }}" target="_blank">
<a class="btn btn-light border" href="{{ $model->data['find_us_btn_url_2']['value'] }}" target="_blank">
<i class="fa-solid fa-arrow-down"></i>
<span>Télécharger des coloriages</span>
<span>{{ $model->data['find_us_btn_text_2']['value'] }}</span>
</a>
</div>
</div>
<div class="d-none d-md-block img-1-wrapper line-border-small position-absolute z-1 bg-white p-2">
<div class="line-border-small">
<img class="img-fluid" src="{{ Vite::asset('resources/assets/images/page-tdf/char.jpg') }}"
title="Caravane Le Gaulois au mileu des supporters du Tour de France" alt="Chars de la caravane Le Gaulois">
<img
class="img-fluid"
src="{{ asset($model->data['find_us_picture_1']['value']) }}"
title="{{ $model->data['find_us_picture_1']['title'] }}"
alt="{{ $model->data['find_us_picture_1']['alt'] }}"
/>
</div>
</div>
<div class="d-none d-md-block img-2-wrapper line-border-small position-absolute z-1 bg-white p-2">
<div class="line-border-small">
<img class="img-fluid" src="{{ Vite::asset('resources/assets/images/page-tdf/char-cuisson-express.jpg') }}"
title="Char cocotte Cuisson Express traversant un pont lors d'une étape du Tour de France"
alt="Char Cuisson Express Le Gaulois">
<img
class="img-fluid"
src="{{ asset($model->data['find_us_picture_2']['value']) }}"
title="{{ $model->data['find_us_picture_2']['title'] }}"
alt="{{ $model->data['find_us_picture_2']['alt'] }}"
/>
</div>
</div>
</div>
<div class="d-lg-flex d-none justify-content-end w-75">
<div @class([
'd-lg-flex d-none justify-content-end w-75',
'mt-24' => !$model->data['play_display_section']['value']
])>
<div class="d-flex justify-content-center w-25">
<small>Crédit photo - ASO Aurélien Vialatte</small>
<small>{{ $model->data['find_us_picture_author']['value'] }}</small>
</div>
</div>
</div>

View file

@ -2,39 +2,29 @@
<div class="position-relative d-flex flex-column justify-content-center hero-section container pb-5 pt-5">
<div class="row justify-content-center pt-5">
<div class="col-12 col-lg-10 rounded-3 position-relative line-border-medium bg-white p-5 shadow">
<span class="badge bg-warning fs-5 mb-2 p-2 text-white">TOUR DE FRANCE 2025</span>
<div class="text-muted small mb-2">Accueil / Le Gaulois Le sponsor du Tour de France</div>
<span class="badge bg-warning fs-5 mb-2 p-2 text-white">{{ $model->data['highlight_text']['value'] }}</span>
<div class="text-muted small mb-2">{{ $model->subtitle }}</div>
<div class="d-flex mb-1">
<h1 class="fw-bold text-uppercase fs-1">Le Gaulois en selle pour le tour de
France</h1>
<h1 class="fw-bold text-uppercase fs-1">{{ $model->data['banner_title']['value'] }}</h1>
</div>
<div class="d-flex justify-content-around align-items-center mb-1">
<p class="w-md-75 mb-3 w-100">
Depuis 2015, Le Gaulois est fier d’être <strong>la volaille officielle du Tour de France</strong>. Un évènement
populaire marquant le début de la pause estivale qui s’adresse à tous les Français, un rendez-vous immanquable pour des
milliers de passionnés aux bords des routes ou devant leur télévision. <strong>La convivialité, le partage et la bonne
humeur</strong>
sont au rendez-vous et c’est ce <strong>bon vivre à la française</strong> que la caravane Le Gaulois véhicule en
sillonnant les routes de
France chaque année. Des milliers de cadeaux sont distribués pour ravir les petits comme les plus grands. La
participation à cet évènement est également l’occasion de réaffirmer auprès du public, <strong>l’engagement sur
l’origine 100%
française des volailles Le Gaulois !</strong>
</p>
<div class="w-md-75 mb-3 w-100">
{!! clean($model->content) !!}
</div>
<div class="d-flex align-items-center logo-tdf">
<img src="{{ Vite::asset('resources/assets/images/page-tdf/logo-gaulois-tdf.jpg') }}"
title="Logo volaille officielle de Le Gaulois et le Tour de France"
alt="Logo volaille officielle de Le Gaulois et le Tour de France">
<img src="{{ asset($model->data['banner_picture']['value']) }}"
title="{{ $model->data['banner_picture']['title'] }}"
alt="{{ $model->data['banner_picture']['alt'] }}">
</div>
</div>
<div class="d-flex justify-content-center flex-wrap gap-3">
<a class="btn btn-tertiary" href="#le-gaulois-et-le-tour-de-france">Le Gaulois et le Tour de France</a>
<a class="btn btn-tertiary" href="#au-coeur-de-la-caravane">Au cœur de la caravane le Gaulois</a>
<a class="btn btn-tertiary" href="#le-gaulois-et-le-tour-de-france">{{ $model->data['banner_button_title']['value'] }}</a>
<a class="btn btn-tertiary" href="#au-coeur-de-la-caravane">{{ $model->data['banner_button_title_2']['value'] }}</a>
</div>
</div>
</div>
</div>
</section>
<div class="ms-md-5 mt-4 d-none d-md-block">
<small>Crédit photo - ASO Aurélien Vialatte</small>
<small>{{ $model->data['find_us_picture_author']['value'] }}</small>
</div>

View file

@ -1,45 +1,48 @@
<section class="bg-light pb-5" id="le-gaulois-et-le-tour-de-france">
<div class="container">
<h2 class="fw-bold text-uppercase mb-5 text-center">Le Gaulois et le Tour de France</h2>
<h2 class="fw-bold text-uppercase mb-5 text-center">{{ $model->data['tdf_title']['value'] }}</h2>
<div class="row align-items-center">
<div class="col-md-6">
<h3 class="fw-bold mb-4">Plus de 10 années <span class="text-danger"> de complicité avec le
public</span>
<h3 class="fw-bold mb-4">
{{ $model->data['tdf_subtitle_1']['value'] }}
<span class="text-danger">{{ $model->data['tdf_subtitle_2']['value'] }}</span>
</h3>
<p class="fs-5"><strong>Les chars « Cocottes » sont devenus emblématiques de la caravane du Tour de France.</strong>
<strong>Dix-huit
caravaniers passionnés</strong>,
dont huit femmes et dix hommes de tous âges et venus de différentes régions de France, auront l’opportunité unique
de piloter les mythiques « Cocottes » à travers le pays. Représentant <strong>la diversité et l’esprit de
partage</strong>, ces
caravaniers formeront une <strong>véritable famille</strong> pendant toute la durée du Tour, <strong>unis par leur
amour du sport et leur
engagement envers Le Gaulois.</strong> <br /> <br />
Les huit chars Le Gaulois, représentant les produits phares de la marque, offrent au public l'occasion de découvrir
ou redécouvrir la diversité des produits proposés : <strong>Crousty Chicken, Oui c’est Bon !, Cordon Bleu, Filets de
Poulet
Rôti, Blanc de Poulet Sortant à l’Extérieur, et Le Filet de Poulet Tranché Cuisson Express</strong> seront à
l’honneur. Deux
chars multiproduits, mettant en avant la diversité de la gamme, défileront également en tête de cortège avec à leur
bord l’animateur Arthur pour enflammer les foules gauloises. En fin de défilé, le char « Roule ma Poule » viendra
clore le spectacle, un clin d’œil toujours apprécié du public. <br /><br />
Les chars iront à la rencontre des Français pour distribuer plus de 600 000 goodies Le Gaulois dans une atmosphère
joyeuse et conviviale. Cette année, la marque offrira des <strong>capes supporters, des magnets décapsuleurs, et des
milliers de bons de réduction</strong> pour découvrir les produits Le Gaulois en magasin.
</p>
<div class="fs-5">
{!! clean($model->data['tdf_description']['value']) !!}
</div>
</div>
<div class="col-md-6 text-center">
<div class="position-relative bg-white p-2 shadow">
<div class="ratio ratio-16x9 position-relative d-inline-block line-border-small w-100">
@if (\App\Rules\IsValidYoutubeId::validates('hY0WPbkf4Ow'))
<div class="video-inlaid h-100" type="youtube"
href="https://www.youtube.com/embed/hY0WPbkf4Ow?autoplay=0&loop=1">
<a class="cn-cookie-link" id="youtube-warning" href="" rel="nofollow">
<strong class="text-underline text-bold text-normal text-danger">
{{ __('cookie-notice.custom.youtube.warning') }}
</strong>
</a>
</div>
@if (!empty($model->data['tdf_media']['value']['video']))
@php
$videoId = $model->data['tdf_media']['value']['video']['id'];
@endphp
@if (\App\Rules\IsValidYoutubeId::validates($videoId))
<div class="video-inlaid h-100" type="youtube"
href="{{ sprintf("https://www.youtube.com/embed/%s?autoplay=0&loop=1", $videoId) }}">
<a class="cn-cookie-link" id="youtube-warning" href="" rel="nofollow">
<strong class="text-underline text-bold text-normal text-danger">
{{ __('cookie-notice.custom.youtube.warning') }}
</strong>
</a>
</div>
@elseif (\App\Rules\IsValidVimeoId::validates($videoId))
<div class="video-inlaid h-100" type="vimeo"
href="{{ sprintf("https://player.vimeo.com/video/%s", $videoId) }}">
<a class="cn-cookie-link" id="vimeo-warning" href="" rel="nofollow">
<strong class="text-underline text-bold text-normal text-danger">
{{ __('cookie-notice.custom.vimeo.warning') }}
</strong>
</a>
</div>
@endif
@else
<img
src="{{ asset($model->data['tdf_media']['value']['picture']['path']) }}"
alt="{{ $model->data['tdf_media']['value']['picture']['alt'] }}"
title="{{ $model->data['tdf_media']['value']['picture']['title'] }}"
/>
@endif
</div>
</div>

View file

@ -1,78 +1,15 @@
@php
$slides = [
[
'name' => 'Nicolas',
'alias' => 'Pimpom',
'sign' => 'L\'ambianceur',
'anecdote' =>
'Nous cherchions un cri de guerre pour se motiver pour les étapes. Après avoir trouvé celui-ci, je ne sais pas pourquoi j’ai conclu par un cri de coq ! Résultat : il est resté jusqu\'à la fin du tour et même plus, il est passé au JT 19/20 sur France 3 Rhône-Alpes Auvergne.',
'adventure' =>
'Cette année 2023, je l’avoue, ce fût le meilleur de tous, grâce à une équipe hyper soudée, bosseuse et jamais fatiguée.',
'img_url' => Vite::asset(
'resources/assets/images/page-tdf/testimonials/Nicolas-Joly-caravanier-Le-Gaulois-Etienne-Coudret.jpg',
),
'img_alt' => 'Photo de Nicolas en tenue de caravanier Le Gaulois',
'img_title' => 'Nicolas Joly caravanier Le Gaulois',
'advice' =>
'Etre à 200% du matin au soir, avoir le sourire en permanence et surtout ne pas avoir peur d’aller vers les autres !',
'credit' => 'Crédit photo - Etienne Coudret',
],
[
'name' => 'Mylène',
'alias' => null,
'sign' => 'Le boute-en-train',
'anecdote' => "
Dans mes meilleurs moments de cette année, il y a le moment de convivialité entre nous sur le parking de l’hôtel après avoir terminé le rechargement des cadeaux pour l’étape du lendemain. Nous avons mis la musique sur une enceinte et nous avons fait la chenille sur le parking. Tout le monde s’est pris au jeu et c’était vraiment un bon moment de rigolade. Il faut savoir que la chenille était notre danse de l’année avec les caravaniers Le Gaulois, on a lancé des chenilles un peu partout et même à une fête de village.",
'adventure' =>
'Faire partie de la caravane du Tour de France est avant tout une aventure humaine inoubliable. On y fait la rencontre de personnes toutes différentes mais avec la même envie de travailler dans la bonne humeur pendant 3 semaines de folie ! Le retour à la réalité a d’ailleurs été assez compliqué quand j’ai quitté les copains de la caravane Le Gaulois pour rentrer chez moi.',
'img_url' => Vite::asset('resources/assets/images/page-tdf/testimonials/Mylène-Cornillet-caravaniere-Le-Gaulois.jpeg'),
'img_alt' => 'Photo de Mylène sur un char Cocotte Le Gaulois',
'img_title' => 'Mylène Cornillet caravanière Le Gaulois',
'advice' =>
'Je dirais que si c’est vraiment une expérience que l’on a envie de vivre, il faut persévérer et ne pas s’arrêter au premier refus. Il faut aussi se démarquer des autres candidats qui sont souvent très nombreux avec un CV qui attire le regard ou une lettre de motivation qui sort du lot. Mais le plus important, c’est surtout d’être authentique et de montrer sa véritable personnalité !',
'credit' => 'Crédit photo - ASO Aurélien Vialatte',
],
[
'name' => 'Thierry',
'alias' => 'Titi',
'sign' => 'Le sage',
'anecdote' => "
Sur une étape du Tour féminin, ma coéquipière est photographiée à proximité de Marion ROUSSE et elle ne la reconnait pas !! A l'arrivée du Tour féminin, je m'aperçois que j'ai fait tout le Tour avec mon accréditation du Tour de France masculin (signé Titi).",
'adventure' =>
'C\'est une chance de pouvoir vivre cet événement exceptionnel de l\'intérieur avec une équipe conviviale, soudée et sympathique.',
'img_url' => Vite::asset(
'resources/assets/images/page-tdf/testimonials/Thierry-Gilles-caravanier-Le-Gaulois-Etienne-Coudret.jpg',
),
'img_alt' => 'Photo de Thierry sur le parking des chars Le Gaulois',
'img_title' => 'Thierry Gilles caravanier Le Gaulois',
'advice' =>
'Même si vous n\'y participez qu\'une seule fois, profitez de vivre ce moment exceptionnel tout en suivant attentivement les directives de l\'encadrement.',
'credit' => 'Crédit photo - Etienne Coudret',
],
[
'name' => 'Justine',
'alias' => 'Ça percute !',
'sign' => 'La floflo de Florence Foresti',
'anecdote' => "
Comme scène marquante, je dirais le nombre de spectateurs sur la route nous regardant comme des « stars ». Je n'ai pas de scène drôle en particulier dans ma tête, mais tous les soirs au « cul du camion » comme nous le disons, un débrief avec rigolade et humour est organisé avec toute l'équipe.",
'adventure' => 'Une expérience INOUBLIABLE, INCROYABLE, MAGIQUE, MAGNIFIQUE',
'img_url' => Vite::asset(
'resources/assets/images/page-tdf/testimonials/Justine-Le-Guillou-caravanière-Le-Gaulois-A.S.O-Aurélien-Vialatte.jpg',
),
'img_alt' => 'Photo de Justine entourée de l\'équipe des caravaniers Le Gaulois',
'img_title' => 'Justine Le Guillou caravanière Le Gaulois',
'advice' => 'D’être soi-même, profiter pleinement de son aventure, d’être dynamique et avoir l’esprit d’équipe.',
'credit' => 'Crédit photo - ASO Aurélien Vialatte',
],
];
$slides = $model->data['testimonials_items']['value'];
@endphp
<section class="position-relative bg-white-wood-big-reverse pt-lg-5 pt-1" id="testimonial-section">
<div class="container-fluid">
<h2 class="fw-bold text-uppercase mb-5 text-center">Les témoignages des caravaniers</h2>
<h2 class="fw-bold text-uppercase mb-5 text-center">
{{ $model->data['testimonials_title']['value'] }}
</h2>
<div class="d-flex justify-content-center mb-5 flex-wrap gap-4" id="swiper-anecdote-tdf-badges">
@foreach ($slides as $index => $slide)
<button class="btn text-uppercase fs-5 fw-medium text-secondary px-4 py-1 shadow-none" data-slide-index="{{ $index }}">
{{ $slide['name'] }}
{{ $slide['title'] }}
</button>
@endforeach
</div>
@ -86,42 +23,34 @@
<div class="row align-items-center mb-4">
<div class="col-md-5">
<div class="position-relative line-border-small bg-white p-2">
<img class="img-fluid position-relative line-border-small w-100" src="{{ $slide['img_url'] }}"
title="{{ $slide['img_title'] }}" alt="{{ $slide['img_alt'] }}">
<img class="img-fluid position-relative line-border-small w-100" src="{{ asset($slide['picture']) }}"
title="{{ $slide['picture_title'] }}" alt="{{ $slide['picture_alt'] }}">
</div>
<div class="ms-md-5 mt-lg-4 mt-0 mb-4 mb-lg-0">
<small>{{ $slide['credit'] }}</small>
<small>{{ $slide['picture_author'] }}</small>
</div>
</div>
<div class="col-md-7">
<div class="d-flex align-items-end gap-2">
<h5 class="fs-2 text-uppercase fw-semibold">{{ $slide['name'] }}</h5>
@if (!empty($slide['alias']))
<div class="fs-3 text-muted f-bakerie-rough mb-2">alias {{ $slide['alias'] }}</div>
<h5 class="fs-2 text-uppercase fw-semibold">{{ $slide['title'] }}</h5>
@if (!empty($slide['subtitle']))
<div class="fs-3 text-muted f-bakerie-rough mb-2">{{ $slide['subtitle'] }}</div>
@endif
</div>
<div class="fs-5">
<p><span class="text-uppercase"><b>Son signe distinctif</b></span> : {{ $slide['sign'] }}</p>
<div>
<p class="text-uppercase"><b>Son anecdote du Tour de France</b> :</p>
<p>{{ $slide['anecdote'] }}</p>
</div>
{!! clean($slide['description']) !!}
</div>
<p class="text-uppercase fs-5 fw-bold">{{ _('Son aventure Le Gaulois') }}</p>
<p class="fs-5">{{ $slide['adventure'] }}</p>
</div>
</div>
<div class="rounded-3 position-relative line-border-large bg-white p-5">
<div>
<p class="text-uppercase">
<strong>Le conseil de <span class="mb-0 bg-secondary px-3 py-1 text-white">
{{ $slide['name'] }}</span></strong>
<strong>{{ $slide['subtitle_2'] }} <span class="mb-0 bg-secondary px-3 py-1 text-white">
{{ $slide['title'] }}</span></strong>
<br />
<br />
</p>
{{ $slide['advice'] }}
{!! clean($slide['description_2']) !!}
</div>
</div>
</div>

View file

@ -12,8 +12,10 @@
<div class="bg-green-wood h-100 w-100" id="demarche-bg"></div>
</div>
<x-fo.breeding.section.oui-c-est-bon.cahier-des-charges-section :staticPageModel="$staticPageModel" :onglets="$categoryApproachModels"
:sections="$sectionApproachModels" />
<x-fo.breeding.section.oui-c-est-bon.search-breeders-section :ocbBreederModels="$ocbBreederModels" />
:sections="$sections" />
<x-fo.breeding.section.oui-c-est-bon.search-breeders-section :ocbBreederModels="$ocbBreederModels"
:titleSearch="$staticPageModel->data['search_title']['value']" :descriptionSearch="$staticPageModel->data['search_description']['value']"
/>
<x-fo.breeding.section.oui-c-est-bon.our-breeder-section />
</section>
{{-- <section class="pb-3 pt-5" id="breeder-map-section">

View file

@ -8,8 +8,8 @@
alt_img="{{ $staticPageModel->picture_alt }}" title_img="{{ $staticPageModel->picture_title }}" />
<section id="sortant-a-l-exterieur">
<x-fo.breeding.section.sortant-a-l-exterieur.cahier-des-charges-section :staticPageModel="$staticPageModel" :onglets="$categoryApproachModels"
:sections="$sectionApproachModels" />
<x-fo.breeding.section.sortant-a-l-exterieur.galery-section :sliderImages="$sliderImages" />
:sections="$sections" />
<x-fo.breeding.section.sortant-a-l-exterieur.galery-section :sliderImages="$sliderImages" title="{{ $staticPageModel->data['galery_title']['value'] }}" />
</section>
{{-- <section class="pb-3 pt-5" id="breeder-map-section">
<div class="pt-5">

View file

@ -75,7 +75,7 @@
portée par <span>2 créateurs</span>
</x-club.title-section>
<x-club.social-videos-section left-badge="@ LOREM IPSUM" right-badge="@ LOREM IPSUM"
<x-club.social-videos-section
description="redécouvrez notre campagne à travers quelques contenus." :videos="$videos" />
<div class="content">

View file

@ -25,7 +25,7 @@
<div class="gc-hero-paper-desc">
<p>
<span>Nous comptabilisons actuellement toutes les participations...</span><br><br>
Nous annoncerons le 28 MAI <span>quelle recette a remporté votre préférence ! </span>
Nous annoncerons le 03 juillet <span>quelle recette a remporté votre préférence ! </span>
</p>
</div>
@ -50,7 +50,7 @@
notre idée de cocréer ce pané a commencé sur nos réseaux sociaux, portée par <span>2 créateurs</span>
</x-club.title-section>
<x-club.social-videos-section left-badge="@ LOREM IPSUM" right-badge="@ LOREM IPSUM"
<x-club.social-videos-section
description="redécouvrez notre campagne à travers quelques contenus." :videos="$videos" />
<div class="content ">

View file

@ -11,7 +11,7 @@
:product-image="Vite::asset('resources/assets/images/golden-crush/dotation_ninja.png')"
:logo-image="Vite::asset('resources/assets/images/golden-crush/ninja_noir.svg')"
button-label="je participe"
:button-href="route('club.golden-crush')"
:button-href="$startVote ? route('club.golden-crush') : null"
>
<x-fo.page-golden-crush.paper-card
class="hero-card mx-auto"
@ -34,7 +34,7 @@
class="hero-swirl img-fluid mx-auto d-block d-md-none" alt="">
</x-fo.page-golden-crush.paper-card>
</x-fo.page-golden-crush.hero>
<x-fo.page-golden-crush.concept />
<x-fo.page-golden-crush.concept :startVote="$startVote"/>
<x-fo.page-golden-crush.cards />
</div>
@endsection

View file

@ -1,17 +1,16 @@
@extends('fo.layout')
@extends('fo.layout', ['brParam' => $staticPageModel])
@section('title', 'Le Gaulois | Volaille officielle du Tour de France')
@section('description', 'Immergez-vous dans l\'ambiance du Tour de France avec Le Gaulois. Découvrez le jeu concours, les photos, anecdotes
et témoignages de notre équipe.')
@section('title', $staticPageModel->seo_title)
@section('description', $staticPageModel->seo_description)
@section('bg-offset', true)
@section('content')
<div id="tdf">
<x-fo.page-tdf.hero />
<x-fo.page-tdf.game />
<x-fo.page-tdf.ten-years />
<x-fo.page-tdf.char-slider />
<x-fo.page-tdf.au-coeur-de-la-caravane />
<x-fo.page-tdf.testimonials />
<x-fo.page-tdf.hero :model="$staticPageModel" />
<x-fo.page-tdf.game :model="$staticPageModel" />
<x-fo.page-tdf.ten-years :model="$staticPageModel" />
<x-fo.page-tdf.char-slider :model="$staticPageModel" />
<x-fo.page-tdf.au-coeur-de-la-caravane :model="$staticPageModel" />
<x-fo.page-tdf.testimonials :model="$staticPageModel" />
</div>
@endsection

View file

@ -186,13 +186,13 @@ Route::middleware(['throttle:web'])->name('fo.')->group(function () {
->name('ratings.store');
// * OTHERS
Route::view('/tour-de-france', 'fo.pages.tdf')->name('tdf');
Route::get('/tour-de-france', [StaticPageController::class, 'tdf'])->name('tdf');
// * OP GOLDEN CRUSH
Route::controller(GoldenCrushController::class)->group(function () {
Route::get('/grand-vote-des-panes', 'index')
->middleware('golden.period:vote')
->middleware(['golden.period:start_game'])
->name('golden-crush');
Route::get('/end-of-participation', 'endParticipation')
->middleware('golden.period:end_participation')