- Fix miniAcf videoVimeo regex

LOT 3 de merde
This commit is contained in:
Jérémy Munsch 2021-10-09 11:24:41 +02:00
parent ed90f9d1a6
commit 90da93f5c5
No known key found for this signature in database
GPG key ID: 55196BEE445F6049
52 changed files with 1764 additions and 83 deletions

View file

@ -0,0 +1,26 @@
<?php
namespace App\Enums;
use Kwaadpepper\Enum\BaseEnumRoutable;
/**
* @method static self bloc1()
* Text et dropdowns array
*/
final class BreedingBlocType extends BaseEnumRoutable
{
protected static function values(): array
{
return [
'bloc1' => 0,
];
}
protected static function labels(): array
{
return [
'bloc1' => __('Bloc 1, (Text et dropdowns array)')
];
}
}

View file

@ -0,0 +1,47 @@
<?php
namespace App\Enums;
use Illuminate\Support\Str;
use Kwaadpepper\Enum\BaseEnumRoutable;
/**
* @method static self breeding()
* @method static self job()
* @method static self food()
* @method static self health()
*/
final class BreedingPageType extends BaseEnumRoutable
{
protected static function values(): array
{
$labels = self::labels();
return [
'breeding' => Str::slug($labels['breeding']),
'job' => Str::slug($labels['job']),
'food' => Str::slug($labels['food']),
'health' => Str::slug($labels['health']),
];
}
/**
* Attention avant de modifier ceci, celà aura
* un impact sur l'affichage du site puisque
* les labels servent de clé primaire
* au modèle BreedingPage
*
* Les label sont utilisé pour les slug nottament
* mais aussi pour identifier le type de page cf values()
*
* @return array
*/
protected static function labels(): array
{
return [
'breeding' => __('L\'élevage des volailles'),
'job' => __('Le métier d\'éleveur de volailles'),
'food' => __('L\'alimentation des volailles'),
'health' => __('La santé des volailles')
];
}
}

View file

@ -8,6 +8,7 @@ use Kwaadpepper\Enum\BaseEnumRoutable;
* @method static self actu()
* @method static self rsm()
* @method static self poultryPage()
* @method static self breedingPage()
*/
final class GeneralConfigType extends BaseEnumRoutable
{
@ -16,7 +17,8 @@ final class GeneralConfigType extends BaseEnumRoutable
return [
'actu' => 1,
'rsm' => 2,
'poultryPage' => 3
'poultryPage' => 3,
'breedingPage' => 4
];
}
@ -25,7 +27,8 @@ final class GeneralConfigType extends BaseEnumRoutable
return [
'actu' => __('Actualité'),
'rsm' => __('RSM Block'),
'poultryPage' => __('Pages Volaille')
'poultryPage' => __('Pages Volaille'),
'breedingPage' => __('Pages Élevage des volailles')
];
}
}

View file

@ -0,0 +1,83 @@
<?php
namespace App\Http\Controllers\Bo;
use App\Enums\BreedingPageType;
use App\Http\Controllers\Controller;
use App\Http\Requests\StoreBreedingPageRequest;
use App\Http\Requests\UpdateBreedingPageRequest;
use App\Models\BreedingPage;
use App\Traits\UpdateModelStatus;
use Illuminate\Support\Facades\File;
class BreedingPageController extends Controller
{
use UpdateModelStatus;
public function __construct()
{
$this->authorizeResource(BreedingPage::class, 'breeding_page');
}
public function index(BreedingPageType $type = null)
{
$query = BreedingPage::query();
if ($type) {
$query = $query->where('type', $type);
}
$query = $this->sortQuery($query);
$pages = $query->paginate();
$searchFields = trans('Titre, Entête, Contenu');
return view('bo.breeding-page.index', compact('pages', 'type', 'searchFields'));
}
public function create(BreedingPageType $type)
{
return view('bo.breeding-page.create', ['type' => $type]);
}
public function store(StoreBreedingPageRequest $request, BreedingPageType $type)
{
$page = new BreedingPage($request->validated());
$page->type = $type;
$this->storeUploadedImage($request, $page, 'picture');
$page->saveOrFail();
return redirect()->route('bo.breeding-page.edit', $page)
->with('success', 'Enregistré !');
}
public function edit(BreedingPage $page)
{
return view('bo.breeding-page.edit', ['page' => $page]);
}
public function update(UpdateBreedingPageRequest $request, BreedingPage $page)
{
$page->fill($request->validated());
$this->storeUploadedImage($request, $page, 'picture');
$page->saveOrFail();
return redirect()->route('bo.breeding-page.edit', $page)
->with('success', 'Enregistré !');
}
public function destroy(BreedingPage $page)
{
foreach ($page->content as $content) {
if (
isset($content['content']['img']['value']) and
File::exists($content['content']['img']['value'])
) {
// TODO: check it does not delete default image ?
File::delete($content['content']['img']['value']);
}
}
if (!$page->delete()) {
return redirect()->route('bo.breeding-page.edit', $page)
->with('error', 'Le contenu n\'a pas pu être supprimé');
}
return redirect()->route('bo.breeding-page.index', $page->type)
->with('warning', 'Le contenu a bien été supprimé');
}
}

View file

@ -0,0 +1,38 @@
<?php
namespace App\Http\Controllers;
use App\Enums\BreedingPageType;
use App\Enums\GeneralConfigType;
use App\Models\BreedingPage;
use Illuminate\Support\Facades\View;
class BreedingPageController extends Controller
{
public function __construct()
{
$generalConfig = app()->view->getShared()['GeneralConfigGlobal'] ?? null;
if ($generalConfig) {
View::share('generalConfig', $generalConfig
->where('type', GeneralConfigType::breedingPage())
->first());
}
}
public function index()
{
return view('front.breeding-page.index');
}
public function list(BreedingPageType $pagesType)
{
$pages = BreedingPage::where('type', $pagesType)->get();
return view('front.breeding-page.list', compact('pages', 'pagesType'));
}
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed
public function show(BreedingPageType $pagesType, BreedingPage $page)
{
return view('front.breeding-page.show', compact('page', 'pagesType'));
}
}

View file

@ -0,0 +1,79 @@
<?php
namespace App\Http\Requests;
use App\Enums\InputType;
use App\Models\BreedingPage;
use Illuminate\Support\Str;
class StoreBreedingPageRequest extends StoreMiniAcfRequest
{
protected $model = BreedingPage::class;
public function authorize()
{
if (
is_null(request()->breeding_page_type) or
BreedingPage::where('type', request()->breeding_page_type)->count() >= 10
) {
return false;
}
$this->merge([
'status' => $this->status ? true : false
]);
return auth()->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$rules = [
'title' => [
'required', 'string', 'min:7', 'max:255',
function ($attribute, $value, $fail) {
if (BreedingPage::where('slug', Str::slug($value))->exists()) {
$fail(trans('La valeur du champ :attribute est déjà utilisé.', [
'attribute' => $this->attributes()[$attribute]
]));
}
}
],
'seo_title' => 'required|string|min:20|max:60',
'seo_description' => 'required|string|min:130|max:160',
'headerContent' => 'required|string|min:10',
'subtitle' => 'required|string|min:5',
'subtitleContent' => 'required|string|min:10',
'media_type' => 'required|in:' . implode(',', [InputType::image()->value, InputType::videoVimeo()->value]),
// phpcs:ignore Generic.Files.LineLength.TooLong
'picture' => 'required_if:media_type,' . InputType::image()->value . '|image|mimes:jpeg,png,jpg|max:2048|dimensions:height=615,width=575',
'picture_alt' => 'required_if:media_type,' . InputType::image()->value . '|string|min:5',
// phpcs:ignore Generic.Files.LineLength.TooLong
'video' => 'required_if:media_type,' . InputType::videoVimeo()->value . '|url|regex:/^https:\/\/vimeo\.com\/[0-9]{8,10}$/',
'status' => 'required|boolean'
];
return array_merge(
$rules,
$this->generatedRules
);
}
public function attributes()
{
return \array_merge(
[
'menutitle' => \trans('Titre menu'),
'title' => \trans('Titre'),
'metaTitle' => \trans('Titre'),
'metaDescription' => \trans('Description meta'),
'headerContent' => \trans('Contenu entête'),
'status' => \trans('Publié')
],
parent::attributes()
);
}
}

View file

@ -135,7 +135,7 @@ class StoreMiniAcfRequest extends FormRequest
private function handleVideoVimeo(string $inputKey)
{
return ["$inputKey.value" => 'required|url|regex:/^https:\/\/vimeo\.com\/[0-9]{9}$/'];
return ["$inputKey.value" => 'required|url|regex:/^https:\/\/vimeo\.com\/[0-9]{8,10}$/'];
}
private function handleImageArray(array $coords, string $inputKey, array $ipt): array

View file

@ -0,0 +1,73 @@
<?php
namespace App\Http\Requests;
use App\Enums\InputType;
use App\Models\BreedingPage;
use Illuminate\Support\Str;
class UpdateBreedingPageRequest extends UpdateMiniAcfRequest
{
protected $modelVarName = 'breeding_page';
public function authorize()
{
$this->merge([
'status' => $this->status ? true : false
]);
return auth()->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$rules = [
'title' => [
'required', 'string', 'min:7', 'max:255',
function ($attribute, $value, $fail) {
if (BreedingPage::where('slug', Str::slug($value))->where('id', '!=', $this->breeding_page->id)->exists()) {
$fail(trans('La valeur du champ :attribute est déjà utilisé.', [
'attribute' => $this->attributes()[$attribute]
]));
}
}
],
'seo_title' => 'required|string|min:20|max:60',
'seo_description' => 'required|string|min:130|max:160',
'headerContent' => 'required|string|min:10',
'subtitle' => 'required|string|min:5',
'subtitleContent' => 'required|string|min:10',
'media_type' => 'required|in:' . implode(',', [InputType::image()->value, InputType::videoVimeo()->value]),
// phpcs:ignore Generic.Files.LineLength.TooLong
'picture' => 'sometimes|image|mimes:jpeg,png,jpg|max:2048|dimensions:height=615,width=575',
'picture_alt' => 'required_if:media_type,' . InputType::image()->value . '|string|min:5',
// phpcs:ignore Generic.Files.LineLength.TooLong
'video' => 'required_if:media_type,' . InputType::videoVimeo()->value . '|url|regex:/^https:\/\/vimeo\.com\/[0-9]{8,10}$/',
'status' => 'required|boolean'
];
return \array_merge_recursive_distinct(
$rules,
$this->generatedRules
);
}
public function attributes()
{
return \array_merge(
[
'menutitle' => \trans('Titre menu'),
'title' => \trans('Titre'),
'metaTitle' => \trans('Titre'),
'metaDescription' => \trans('Description meta'),
'headerContent' => \trans('Contenu entête'),
'status' => \trans('Publié')
],
parent::attributes()
);
}
}

View file

@ -0,0 +1,71 @@
<?php
namespace App\Models;
use App\Enums\BreedingBlocType;
use App\Enums\BreedingPageType;
use App\Enums\InputType;
use App\Traits\MiniAcfModel;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use Kwaadpepper\Enum\Traits\CastsEnums;
class BreedingPage extends Model
{
use CastsEnums;
use MiniAcfModel;
protected $enumCasts = [
'type' => BreedingPageType::class,
'media_type' => InputType::class
];
protected $casts = [
'content' => 'array',
];
protected $fillable = [
'title', 'headerContent',
'seo_title', 'seo_description',
'headerContent', 'subtitle',
'subtitleContent', 'media_type',
'picture', 'picture_alt',
'video', 'content', 'status'
];
protected static function booted()
{
static::creating(function (BreedingPage $page) {
$page->slug = Str::slug($page->title);
});
static::updating(function (BreedingPage $page) {
$page->slug = Str::slug($page->title);
});
}
public function getRouteKeyName()
{
return 'slug';
}
/**
* Get Blocks Template Data
*
* @return array
*/
public static function getBlocks(): array
{
return [
BreedingBlocType::bloc1()->value => [
'type' => BreedingBlocType::bloc1(),
'content' => [
'dropdownArray' => [
'label' => 'Dropdowns',
'inputType' => InputType::dropdownArray(),
'value' => []
]
]
]
];
}
}

View file

@ -0,0 +1,86 @@
<?php
namespace App\Policies;
use App\Models\BreedingPage;
use App\User;
use Illuminate\Auth\Access\HandlesAuthorization;
class BreedingPagePolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view any models.
*
* @param \App\Models\User $user
* @return mixed
*/
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found
public function viewAny(User $user)
{
return auth()->check();
}
/**
* Determine whether the user can view the model.
*
* @param \App\Models\User $user
* @param \App\Models\BreedingPage $page
* @return mixed
*/
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed
public function view(User $user, BreedingPage $page)
{
return auth()->check();
}
/**
* Determine whether the user can create models.
*
* @param \App\Models\User $user
* @return mixed
*/
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found
public function create(User $user)
{
if (
!is_null(request()->breeding_page_type) and
BreedingPage::where('type', request()->breeding_page_type)->count() >= 10
) {
response()->redirectToRoute('bo.breeding-page.index', request()->breeding_page_type->value)
->with('error', \trans('Il n\'est pas possible de créer plus de 10 pages par type.'))
->throwResponse();
}
return auth()->check() and !is_null(request()->breeding_page_type);
}
/**
* Determine whether the user can update the model.
*
* @param \App\Models\User $user
* @param \App\Models\BreedingPage $page
* @return mixed
*/
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed
public function update(User $user, BreedingPage $page)
{
return auth()->check();
}
/**
* Determine whether the user can delete the model.
*
* @param \App\Models\User $user
* @param \App\Models\BreedingPage $page
* @return mixed
*/
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed
public function delete(User $user, BreedingPage $page)
{
return auth()->check();
}
}

View file

@ -2,7 +2,9 @@
namespace App\Providers;
use App\Models\BreedingPage;
use App\Models\Tag;
use App\Policies\BreedingPagePolicy;
use App\Policies\TagPolicy;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
@ -16,6 +18,7 @@ class AuthServiceProvider extends ServiceProvider
*/
protected $policies = [
Tag::class => TagPolicy::class,
BreedingPage::class => BreedingPagePolicy::class,
];
/**

View file

@ -3,11 +3,13 @@
namespace App\Providers;
use App\Enums\ArticleCategory;
use App\Enums\BreedingPageType;
use App\Enums\GeneralConfigType;
use App\Models\Actu;
use App\Models\Ads;
use App\Models\Articles;
use App\Models\BreederPortrait;
use App\Models\BreedingPage;
use App\Models\ConsumptionTimes;
use App\Models\Engagement;
use App\Models\FaqQuestions;
@ -135,6 +137,8 @@ class RouteServiceProvider extends ServiceProvider
Route::model('poultry_page', PoultryPage::class);
Route::model('ocb', OCBContent::class);
Route::model('tag', Tag::class);
Route::model('breeding_page_type', BreedingPageType::class);
Route::model('breeding_page', BreedingPage::class);
Route::bind('general_config', function ($value) {
try {
$value = \ctype_digit($value) ? \intval($value) : $value;

View file

@ -265,7 +265,9 @@ return [
'NutritionBlocType' => \App\Enums\NutritionBlocType::class,
'PoultryPage' => \App\Models\PoultryPage::class,
'PoultryPageType' => \App\Enums\PoultryPageType::class,
'PoultryBlocType' => \App\Enums\PoultryBlocType::class
'PoultryBlocType' => \App\Enums\PoultryBlocType::class,
'BreedingPageType' => \App\Enums\BreedingPageType::class,
'BreedingPage' => \App\Models\BreedingPage::class,
],
];

View file

@ -122,5 +122,8 @@ return [
'inCanvas' => true,
'keepRatio' => true
],
'breedingWebp' => [
'format' => 'webp'
],
]
];

View file

@ -0,0 +1,65 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use App\Enums\BreedingBlocType;
use App\Enums\InputType;
use App\Models\BreedingPage;
use Faker\Generator as Faker;
/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| This directory should contain each of the model factory definitions for
| your application. Factories provide a convenient way to generate new
| model instances for testing / seeding your application's database.
|
*/
$i = 1;
$factory->define(BreedingPage::class, function (Faker $faker) use (&$i) {
$title = implode(' ', $faker->unique()->words(rand(6, 12)));
$front = ($i++ <= 3 ? true : false);
return [
'title' => $title,
'seo_title' => implode(' ', $faker->words(8)),
'seo_description' => implode(' ', $faker->words(25)),
'slug' => \Illuminate\Support\Str::slug($title),
'headerContent' => $faker->text(300),
'media_type' => rand(0, 1) ? InputType::image() : InputType::videoVimeo(),
'picture' => '/assets/images/pages_elevages/breeding-page.jpg',
'picture_alt' => 'Image donnée par la créa pas au bonnes dimensions',
'video' => 'https://vimeo.com/537775766',
'subtitle' => implode(' ', $faker->words(5)),
'subtitleContent' => $faker->text(300),
'content' => [
array_replace_recursive(
BreedingPage::getBlocks()[BreedingBlocType::bloc1()->value],
[
'type' => BreedingBlocType::bloc1(),
'content' => [
'dropdownArray' => [
'value' => (function () use ($faker) {
$out = [];
$max = rand(1, 3);
for ($i = 0; $i < $max; $i++) {
$out[] = [
'title' => $faker->sentence(8),
'html' =>
// phpcs:ignore Generic.Files.LineLength.TooLong
'<a href="#">En savoir + sur chenilles à pattes de poulets</a>&nbsp;'
. $faker->text(620)
];
}
return $out;
})()
]
]
]
),
],
'status' => $front ?: (bool)rand(0, 1)
];
});

View file

@ -0,0 +1,136 @@
<?php
use App\Enums\BreedingPageType;
use App\Enums\GeneralConfigType;
use App\Enums\InputType;
use App\Models\GeneralConfig;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateBreedingPagesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('breeding_pages', function (Blueprint $table) {
$table->id();
/** \App\Enums\BreedingPageType */
$table->string('type');
$table->string('slug')->unique();
$table->string('seo_title');
$table->string('seo_description');
$table->string('title');
$table->text('headerContent');
// Enums InputType
$table->smallInteger('media_type');
$table->string('picture');
$table->string('picture_alt');
$table->string('video');
$table->string('subtitle');
$table->text('subtitleContent');
// contient un tableau de blocks (json)
$table->mediumText('content');
$table->boolean('status');
$table->timestamps();
});
// Create General config for Breeding Page
$config = new GeneralConfig([
'type' => GeneralConfigType::breedingPage(),
'data' => [
'breeding_header_img' => [
'dimensions' => 'largeur 1920,hauteur 440',
'label' => 'Image d\'entête pages volailles',
'inputType' => InputType::image(),
'alt' => 'Image d\'entête actualités',
'value' => '/assets/images/pages_elevages/breeding_page_banner.jpg'
],
'breeding_header_title' => [
'label' => 'Titre entête',
'inputType' => InputType::string(),
'value' => 'Élevage et alimentation des volailles'
],
'breeding_sub_header_text' => [
'label' => 'Sous entête page index',
'inputType' => InputType::text(),
// phpcs:ignore Generic.Files.LineLength.TooLong
'text' => 'Lorem ipsum, quiche lorem',
'validate' => 'string|min:10'
],
'breeding_page_1_text' => [
'label' => 'Titre bloc haut gauche + titre menu',
'type' => BreedingPageType::breeding(),
'inputType' => InputType::string(),
'value' => 'L\'élevage des volailles'
],
'breeding_page_1_img' => [
'dimensions' => 'largeur 559,hauteur 277',
'label' => 'Image bloc haut gauche',
'inputType' => InputType::image(),
'value' => '/assets/images/pages_elevages/Elevage-Volaille.jpg'
],
'breeding_page_2_text' => [
'label' => 'Titre bloc haut droit + titre menu',
'type' => BreedingPageType::job(),
'inputType' => InputType::string(),
'value' => 'Le métier d\'éleveur de volailles'
],
'breeding_page_2_img' => [
'dimensions' => 'largeur 559,hauteur 277',
'label' => 'Image bloc haut droit',
'inputType' => InputType::image(),
'value' => '/assets/images/pages_elevages/Eleveur-LG.jpg'
],
'breeding_page_3_text' => [
'label' => 'Titre bloc bas gauche + titre menu',
'type' => BreedingPageType::food(),
'inputType' => InputType::string(),
'value' => 'L\'alimentation des volailles'
],
'breeding_page_3_img' => [
'dimensions' => 'largeur 559,hauteur 277',
'label' => 'Image bloc bas gauche',
'inputType' => InputType::image(),
'value' => '/assets/images/pages_elevages/Alimentation-Volaille.jpg'
],
'breeding_page_4_text' => [
'label' => 'Titre bloc bas droite + titre menu',
'type' => BreedingPageType::health(),
'inputType' => InputType::string(),
'value' => 'La santé des volailles'
],
'breeding_page_4_img' => [
'dimensions' => 'largeur 559,hauteur 277',
'label' => 'Image bloc bas droite',
'inputType' => InputType::image(),
'value' => '/assets/images/pages_elevages/Sante-Volaille.jpg'
],
]
]);
$config->title = 'Configuration pages élevage des volailles';
$config->saveOrFail();
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('breeding_pages');
GeneralConfig::where('type', GeneralConfigType::breedingPage())->delete();
}
}

View file

@ -0,0 +1,26 @@
<?php
use App\Enums\BreedingPageType;
use App\Models\BreedingPage;
use Illuminate\Database\Seeder;
// phpcs:ignore PSR1.Classes.ClassDeclaration.MissingNamespace
class BreedingPageSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
BreedingPage::truncate();
foreach (BreedingPageType::toArray() as $type) {
factory(BreedingPage::class, rand(2, 10))->make()
->each(function ($page) use ($type) {
$page->type = $type;
$page->saveOrFail();
});
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View file

@ -90,6 +90,9 @@ $healthColor: #ABCCB7;
// POULTRY PAGE
$subtitleColor: #EE7C28;
// Breeding Colo
$breedingColor: #366;
// Bourse
$gives: #CF1D40;
$wants: darken(adjust-hue($orange, -5), 10%);

View file

@ -1969,6 +1969,68 @@
}
}
.sub_header_breedingPage {
width: 100%;
margin-top: 5rem;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
height: 50vw;
max-height: 26.33rem;
min-height: 21rem;
background-image: url("~@/images/marque/marque_background.jpg");
.content-breeding {
height: 100%;
width: 100%;
& .title {
position: absolute;
top: 38%;
left: 50%;
text-align: center;
line-height: 1em;
font-size: 6.5em;
font-family: "Veneer";
color: white;
transform: translateX(-50%) translateY(-50%);
z-index: 1;
@include max-width($desktop) {
font-size: 5.5em;
}
@include max-width($mobile) {
font-size: 4.5em;
}
}
& img {
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
left: 50%;
@include min-width($large_screen) {
width: 100%;
}
}
@include max-width($large_screen) {
background-position: center 88%;
}
@include max-width($desktop) {
background-position: center 84%;
}
@include max-width($tablet) {
background-image: none;
}
h1 {
color: white;
text-align: center;
}
}
}
.sub_header_health_nutrition {
background-image: url('~@/images/sante-nutrition/nutrition_bg.jpg');
width: 100%;

View file

@ -0,0 +1,71 @@
.super-nav {
margin-top: 3.732rem;
width: 100%;
margin-left: auto;
margin-right: auto;
@include max-width($tablet) {
& > ul {
flex-wrap: wrap !important;
& > li {
width: 50% !important;
border-bottom: 5px solid #e5d5c7 !important;
}
}
}
@include max-width($mobile) {
& > ul {
flex-flow: column !important;
& > li {
width: 100% !important;
}
}
}
&>ul {
display: flex;
justify-content: center;
flex-direction: row;
z-index: 20;
list-style: none;
width: 100%;
&>li {
background-color: white;
z-index: 21;
flex-grow: 1;
height: 70px;
box-sizing: border-box;
border-bottom: 5px solid transparent;
border-right: 1px solid #e5d5c7;
&>a {
display: flex;
align-items: center;
justify-content: center;
text-align: center;
font-family: 'Catamaran-Bold';
color: $color5;
font-size: 1.4em;
font-weight: 700;
text-transform: uppercase;
padding: 10px;
width: 100%;
height: 65px;
margin-top: 5px;
}
&:hover {
border-bottom: 5px solid #ffb400;
}
&:nth-last-child(1) {
border-right: 0;
}
}
}
& .active {
border-bottom: 5px solid #ffb400 !important;
}
}

View file

@ -7,6 +7,7 @@
}
.txtsaga {
font-size: 2em;
text-align: center;
h3{
margin:20px;

View file

@ -3,52 +3,20 @@
width: 100%;
margin-left: auto;
margin-right: auto;
@include max-width($tablet) {
position: relative;
}
&>ul {
display: flex;
justify-content: center;
flex-direction: row;
z-index: 20;
list-style: none;
margin-left: 0.5%;
@include max-width($tablet) {
flex-direction: column;
}
&>li {
background-color: #FFF;
z-index: 21;
width: 33%;
height: 70px;
box-sizing: border-box;
border-bottom: 5px solid transparent;
@include max-width($tablet) {
width: 100%;
}
&.active {
border-bottom: 5px solid $orange !important;
}
&>a {
display: flex;
align-items: center;
justify-content: center;
text-align: center;
font-family: 'Catamaran-Bold';
color: $color5;
font-size: 1.4em;
font-weight: 700;
text-transform: uppercase;
padding: 10px;
width: 100%;
height: 65px;
margin-top: 5px;
}
&:hover {

View file

@ -0,0 +1,117 @@
.content.breedingPageIndex {
.headerText {
font-family: 'Catamaran-Regular';
font-size: 1.3rem;
line-height: 1.6rem;
color: $color5;
margin-bottom: 4rem;
text-align: center;
}
.cards {
position: relative;
width: 100%;
background-color: #FFF;
padding: 1rem 0.5rem 1.2rem 0.5rem;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 0.5rem;
margin-bottom: 6rem;
@include max-width($tablet) {
grid-template-columns: repeat(1, 1fr);
}
& > .card {
position: relative;
& > a:first-child {
position: relative;
display: block;
.hoverFigure {
background-color: $breedingColor;
z-index: 2;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
opacity: 0;
display: flex;
justify-content: center;
align-items: center;
transition: opacity 500ms ease 0s;
cursor: pointer;
&:hover {
opacity: 0.88;
}
span {
display: block;
user-select: none;
color: #ffffff;
font-size: 2.534rem;
position: relative;
font-family: 'CreamyScriptRegular';
&:before {
background-image: url('~@/images/recette/hoverRecette.png');
display: inline-block;
content: "";
width: 2.5em;
height: 1em;
position: absolute;
top: -0.8em;
left: 50%;
transform: translateX(-50%);
}
&:after {
background-image: url('~@/images/recette/hoverRecette.png');
display: inline-block;
content: "";
width: 2.5em;
height: 1em;
transform: rotate(180deg) translateX(54%);
position: absolute;
top: 1em;
left: 50%;
}
}
}
& > picture > img {
object-fit: contain;
width: 100%;
}
}
& > h2 {
position: absolute;
left: 1rem;
bottom: 3rem;
width: 95%;
color: #FFF;
font-weight: 900;
font-family: 'Catamaran-Bold';
text-transform: uppercase;
font-size: 2.4rem;
text-shadow: 0 0 10px #000;
line-height: 2.2rem;
@include max-width($mobile) {
font-size: 1.7rem;
}
}
& > a:not(:first-child) {
display: inline-block;
position: absolute;
left: 1rem;
bottom: 0.5rem;
padding: 0.2rem 1.3rem 0.3rem 1.3rem;
background-color: $breedingColor;
font-family: 'Catamaran';
color: #FFF;
font-size: 1.1rem;
border-radius: 1rem;
@include max-width($mobile) {
font-size: 0.9rem;
}
}
}
}
}

View file

@ -0,0 +1,102 @@
@import "./_nav";
.content.breedingPageList {
position: relative;
& .articles {
display: flex;
flex-direction: column;
margin-bottom: 3rem;
& > article {
display: flex;
flex-direction: row;
background-color: #FFF;
padding: 0.6rem;
&:not(:first-child) {
margin-top: 2rem;
}
&.right {
flex-direction: row-reverse;
}
& > picture {
& > img {
width: 37.3296rem;
height: 18.39816rem;
object-fit: cover;
}
}
& > section {
position: relative;
padding: 1.2rem;
& > h2 {
font-family: 'Veneer';
color: $color5;
line-height: 2.6rem;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
max-width: 38rem;
}
& > span {
font-family: 'CreamyScriptRegular';
font-size: 2.5rem;
color: $breedingColor;
}
& > .content {
font-family: 'Catamaran-Regular';
font-size: 1.3rem;
line-height: 1.6rem;
color: $color5;
}
& > a.link {
display: inline-block;
position: absolute;
right: 1rem;
bottom: 0.5rem;
padding: 0.2rem 1.3rem 0.3rem 1.3rem;
background-color: $breedingColor;
font-family: 'Catamaran';
color: #FFF;
font-size: 1.1rem;
border-radius: 0.75rem;
@include max-width($mobile) {
font-size: 0.9rem;
}
}
}
}
@include max-width($big_screen) {
& > article {
margin-left: 1rem;
margin-right: 1rem;
& > picture {
& > img {
width: auto;
height: 18.39816rem;
max-width: 18.39816rem;
}
}
}
}
@include max-width($tablet + 132px) {
& > article {
flex-direction: column !important;
& > picture {
margin: 0 auto;
& > img {
width: 77vw;
max-width: inherit;
}
}
& > section > a.link {
position: relative;
bottom: 0;
margin-top: 1rem;
right: inherit;
}
}
}
}
}

View file

@ -0,0 +1,33 @@
.nav-breeding {
position: relative;
top: -8rem;
margin-top: inherit;
width: 100%;
margin-left: auto;
margin-right: auto;
@include max-width($tablet) {
top: -4rem;
}
&>ul {
&>li {
&.active {
border-bottom: 5px solid $breedingColor !important;
}
&>a {
text-align: center;
font-family: 'Catamaran-Bold';
color: $color5;
font-size: 1.4em;
font-weight: 700;
text-transform: uppercase;
}
&:hover {
border-bottom: 5px solid $breedingColor;
}
}
}
}

View file

@ -0,0 +1,212 @@
.content.breedingPageShow {
position: relative;
& > article {
padding: 1rem;
margin-bottom: 4rem;
& > header {
text-align: center;
margin-bottom: 4rem;
& > h1 {
font-family: "Veneer";
font-size: 3.3rem;
line-height: 3.6rem;
}
& > .headerContent {
margin-top: 2rem;
font-family: "Catamaran-Regular";
font-size: 1.3rem;
line-height: 1.6rem;
color: $color5;
text-align: center;
}
}
& > .blocs {
position: relative;
display: flex;
flex-direction: row-reverse;
align-items: flex-start;
min-height: 42rem;
& > .video.vimeo, & > picture {
position: absolute;
margin-top: 1.932rem;
left: 0;
object-fit: contain;
width: 40%;
border-radius: 0.3rem;
z-index: 1;
& iframe {
min-height: 18rem;
min-width: 31.5rem;
}
& > img {
width: 100%;
object-fit: contain;
min-width: 38.3295rem;
min-height: 40.9959rem;
}
}
& > .content {
position: relative;
right: 0;
min-width: 52.794rem;
border-radius: 0.333rem;
color: $color5;
background-color: #fff;
padding: 2.799rem 3.466rem 1.732rem 14.799rem;
width: 55%;
// custom links blue
& a {
font-family: 'Catamaran-Bold';
color: $breedingColor;
text-decoration: underline;
}
& > h2 {
font-size: 2rem;
line-height: 2.3rem;
color: $breedingColor;
}
& > .content {
padding-top: 1.6rem;
padding-bottom: 4.266rem;
font-family: "Catamaran-Regular";
font-size: 1.199rem;
line-height: 1.733rem;
}
& > .dropdowns {
position: relative;
padding-top: 4.266rem;
display: flex;
flex-direction: column;
justify-content: space-between;
&::before {
position: absolute;
display: block;
content: " ";
top: 0;
left: 0;
width: 4.266rem;
height: 0.199rem;
background-color: $breedingColor;
}
& > .dropdown {
color: $color5;
overflow: hidden;
&:not(:first-child) {
margin-top: 1.599rem;
}
& > input {
position: absolute;
opacity: 0;
z-index: -1;
}
& > label {
position: relative;
display: block;
padding: 0 0.799rem;
padding-bottom: 1.066rem;
padding-right: 0.799rem + 0.933rem;
cursor: pointer;
transition: border-bottom-color 0.35s;
& > h3 {
font-family: CreamyScriptRegular;
line-height: 2.399rem;
font-size: 1.999rem;
color: $breedingColor;
}
&:after {
position: absolute;
top: 10%;
right: 10px;
font-family: "icomoon";
content: "";
font-size: 0.933rem;
text-align: center;
transition: transform 0.35s;
transform: rotate(-180deg);
}
}
& > div {
font-family: "Catamaran-Regular";
font-size: 1.199rem;
line-height: 1.733rem;
transition: all 0.35s;
transition-property: "max-height", padding;
opacity: 0;
max-height: 0;
padding: 0;
padding-bottom: 1.066rem * 2;
& > * {
display: none;
}
}
& input:checked ~ div {
opacity: 1;
max-height: 199rem;
padding: 0 0.799rem;
padding-bottom: 1.066rem * 2;
& > * {
display: inherit;
}
}
& input:checked + label:after {
transform: rotate(0deg);
}
}
}
}
@include max-width($big_screen) {
flex-direction: column;
& > .video.vimeo, & > picture {
position: relative;
margin: 0 auto;
z-index: 1;
width: inherit;
}
& > picture > img {
min-width: inherit;
min-height: inherit;
border-radius: 0.3rem;
}
& > .content {
margin: 0 auto;
margin-top: -1rem;
width: inherit;
max-width: 55%;
padding: 2.799rem 2.466rem 1.732rem 2.466rem;
}
}
@include max-width ($tablet + 80px) {
& > .content {
min-width: inherit;
width: 100%;
max-width: inherit;
}
}
@include max-width ($mobile) {
& .video.vimeo {
width: 100%;
iframe {
min-height: 18rem;
min-width: inherit;
width: 100%;
}
}
& > .content {
padding: 2rem 1rem;
}
}
}
}
}

View file

@ -7,65 +7,22 @@
width: 100%;
margin-left: auto;
margin-right: auto;
margin-top: inherit;
@include max-width($tablet) {
& > ul {
flex-wrap: wrap !important;
& > li {
width: 50% !important;
border-bottom: 5px solid #e5d5c7 !important;
}
}
}
@include max-width($mobile) {
& > ul {
flex-flow: column !important;
& > li {
width: 100% !important;
}
}
}
&>ul {
display: flex;
justify-content: center;
flex-direction: row;
z-index: 20;
list-style: none;
width: 100%;
&>li {
background-color: white;
z-index: 21;
flex-grow: 1;
height: 70px;
box-sizing: border-box;
border-bottom: 5px solid transparent;
border-right: 1px solid #e5d5c7;
&>a {
display: flex;
align-items: center;
justify-content: center;
text-align: center;
font-family: 'Catamaran-Bold';
color: $color5;
font-size: 1.4em;
font-weight: 700;
text-transform: uppercase;
padding: 10px;
width: 100%;
height: 65px;
margin-top: 5px;
}
&:hover {
border-bottom: 5px solid #abccb7;
}
&:nth-last-child(1) {
border-right: 0;
}
}
}

View file

@ -18,6 +18,7 @@
@import "front/modules/ldcweb-cn";
@import "front/modules/ckvideo";
@import "front/modules/ckEditorContent";
@import "front/modules/super-nav";
@import "front/body";
@import "front/header";
@ -61,6 +62,10 @@
@import "front/pages/health-nutrition/bloc4";
@import "front/pages/health-nutrition/bloc5";
@import "front/pages/breeding-page/index";
@import "front/pages/breeding-page/list";
@import "front/pages/breeding-page/show";
@import "front/pages/login";
@import "front/pages/register";
@import "front/pages/reinit-pwd";

View file

@ -0,0 +1,24 @@
@extends('layouts.bo')
@section('content')
<div class="card">
<div class="card-header">
{{ __('Création d\'une page élevage - :type', ['type' => $type->label]) }}
<a href="{{route('bo.breeding-page.index', $type)}}" class="btn btn-sm btn-primary float-right ml-2">{{ __('Retour') }}</a>
</div>
<div class="card-body">
<form id="actuForm" action="{{route('bo.breeding-page.store', $type)}}" method="POST" enctype="multipart/form-data">
@csrf
<div class="row">
<div class="col-md-8 offset-md-2">
@include('bo.breeding-page.form-inputs')
<div class="form-group text-center">
<button type="submit" class="btn btn-secondary">{{ __('Créer') }}</button>
</div>
</div>
</div>
</form>
</div>
</div>
@endsection

View file

@ -0,0 +1,30 @@
@extends('layouts.bo')
@section('content')
<div class="card">
<div class="card-header">
{{ __('Modification d\'une page élevage - :type', ['type' => $page->type->label]) }}
<a href="{{route('bo.breeding-page.index', $page->type)}}" class="btn btn-sm btn-primary float-right ml-2">{{ __('Retour') }}</a>
<form action="{{ route('bo.breeding-page.destroy', $page) }}" method="POST" class="d-inline confirmDeleteJS">
@method('DELETE')
@csrf
<input type="submit" class="btn btn-sm btn-danger float-right" value="{{ __('Supprimer') }}">
</form>
</div>
<div class="card-body">
<form id="breedingPageForm" action="{{route('bo.breeding-page.update', $page)}}" method="POST" enctype="multipart/form-data">
@method('PUT')
@csrf
<div class="row">
<div class="col-md-8 offset-md-2">
@include('bo.breeding-page.form-inputs')
<div class="form-group text-center">
<button type="submit" class="btn btn-secondary">{{ __('Modifier') }}</button>
</div>
</div>
</div>
</form>
</div>
</div>
@endsection

View file

@ -0,0 +1,119 @@
<h4>{{ __('Partie entête') }}</h4>
<div class="form-group">
<label for="title"><small>{{ __('Titre') }} *</small></label>
@include('bo.modules.input-error', ['inputName' => 'title'])
<input id="title" type="text" class="form-control" name="title" placeholder="{{ __('Titre') }}" value="{{ old('title') ?? $page->title ?? '' }}" required>
</div>
<div class="form-group">
<label for="seo_title"><small>{{ __('Seo titre') }} *</small></label>
@include('bo.modules.input-error', ['inputName' => 'seo_title'])
<input id="seo_title" type="text" class="form-control" name="seo_title" placeholder="{{ __('Seo titre') }}" value="{{old('seo_title') ?? $page->seo_title ?? ''}}">
</div>
<div class="form-group">
<label for="seo_description"><small>{{ __('Seo description') }} *</small></label>
@include('bo.modules.input-error', ['inputName' => 'seo_description'])
<input id="seo_description" type="text" class="form-control" name="seo_description" placeholder="{{ __('Seo description') }}" value="{{old('seo_description') ?? $page->seo_description ?? ''}}">
</div>
<div class="form-group vueComponent">
<label class="col-form-label">{{ __('Entête') }} *</label>
@include('bo.modules.input-error', ['inputName' => 'headerContent'])
<custom-ckeditor
name="headerContent"
csrf="{{ csrf_token() }}"
dbtext="{{ old('headerContent') ?? $page->headerContent ?? '' }}"></custom-ckeditor>
</div>
<hr>
<h4>{{ __('Partie contenu') }}</h4>
<div class="form-group">
<label for="mediaType" class="col-form-label col-md-3">{{ __('Type de média') }}</label>
<select class="custom-select col-md-9" id="mediaType" name="media_type">
@foreach ([InputType::image(), InputType::videoVimeo()] as $inputType)
<option value="{{$inputType->value}}" @if(old('media_type') === $inputType->value or $page->media_type->equals($inputType))selected @endif>{{
$inputType->label
}}</option>
@endforeach
</select>
</div>
<div class="form-group" id="mainImage">
<h6>{{ __('Image') }}</h6>
<span id="imageSpan">{{ __('Visuel * de type JPEG/PNG/SVG - 2Mo max.')}} - {{ __('Dimensions largeur 575 px,hauteur 615 px') }}</span>
<div class="input-group mb-3">
<div class="custom-file">
<input id="imageFile" type="file" class="custom-file-input" name="picture" accept="image/png,image/jpeg,.svg" aria-describedby="imageSpan">
<label class="custom-file-label" for="imageFile">{{ __('Choisir un fichier') }}</label>
</div>
</div>
<br>
<label for="imageAlt"><small>{{ __('Texte alternatif') }} *</small></label>
<input id="imageAlt" type="text" class="form-control" name="picture_alt" placeholder="{{ __('Texte alternatif à l\'image') }}" value="{{ old('picture_alt') ?? $page->picture_alt ?? '' }}">
<br>
@if(isset($page->picture) and strlen($page->picture))
<img src="{{ $page->picture }}" alt="image" style="max-height:200px;max-width:100%;object-fit:contain;margin:0 auto;display:block;">
@endif
</div>
<div class="form-group" id="mainVideo">
<label for="video"><small>{{ __('Video') }} *</small></label>
@include('bo.modules.input-error', ['inputName' => 'video'])
<input id="video" type="text" class="form-control vimeoVideo" name="video" placeholder="https://vimeo.com/xxxxxxxxx" value="{{ old('video') ?? $page->video ?? '' }}" required>
</div>
<hr>
<div class="form-group">
<label for="subtitle"><small>{{ __('Sous-titre') }} *</small></label>
@include('bo.modules.input-error', ['inputName' => 'subtitle'])
<input id="subtitle" type="text" class="form-control" name="subtitle" placeholder="{{ __('Sous-titre') }}" value="{{old('subtitle') ?? $page->subtitle ?? ''}}">
</div>
<div class="form-group vueComponent">
<label class="col-form-label">{{ __('Contenu sous-titre') }} *</label>
@include('bo.modules.input-error', ['inputName' => 'subtitleContent'])
<custom-ckeditor
name="subtitleContent"
csrf="{{ csrf_token() }}"
dbtext="{{ old('subtitleContent') ?? $page->subtitleContent ?? '' }}"></custom-ckeditor>
</div>
@include('bo.modules.mini-acf.form-inputs', ['content' => old('content') ? array_replace_recursive(BreedingPage::getBlocks(), old("content")) : ($page->content ?? BreedingPage::getBlocks())])
<div class="form-group">
<label>
<input type="checkbox" name="status" value="1" @if ((old('status') ?? $page->status ?? 0))checked @endif>
{{ __('Publié ?') }}
</label>
</div>
@push('scripts')
<script>
if(!__MINIACF) {
var __MINIACF = {};
}
if(!__MINIACF.vimeoVideo) {
__MINIACF.vimeoVideo = true;
$(document).ready(function() {
$('.vimeoVideo').on('change', function() {
const parentDiv = $(this).parent()
const regex = /vimeo\.com\/[0-9]{8,10}/;
console.log(regex.exec($(this).val()) != null)
if(regex.exec($(this).val()) != null) {
console.log('toto')
$(parentDiv).find('small')
.text('Video *')
.removeClass('text-danger')
} else {
$(parentDiv).find('small')
.text('Video * : doit être un lien vimeo valide')
.addClass('text-danger')
}
});
var __switchMediaType = function() {
if($('#mediaType').val() == {{ is_string(InputType::videoVimeo()->value) ? "{InputType::videoVimeo()->value}" : InputType::videoVimeo()->value }}) {
$('#mainImage').hide()
$('#imageAlt,#imageFile').prop('disabled', true);
$('#mainVideo').show().find('input').prop('disabled', false);
} else {
$('#mainImage').show()
$('#imageAlt,#imageFile').prop('disabled', false);
$('#mainVideo').hide().find('input').prop('disabled', true);
}
};
$('#mediaType').on('change', __switchMediaType);
__switchMediaType();
});
}
</script>
@endpush

View file

@ -0,0 +1,47 @@
@extends('layouts.bo')
@section('content')
<div class="card">
<div class="card-header">
{{ __('Liste des pages élevage - :type', ['type' => $type->label ?? trans('Toutes')]) }}
@if(isset($type))
<a href="{{route('bo.breeding-page.create', $type)}}" class="btn btn-sm btn-primary float-right">{{ __('Ajouter') }}</a>
@endif
</div>
<div class="card-body">
@include('bo.modules.searchBar')
{{ $pages->withQueryString()->links() }}
<table class="table text-center">
<thead class="thead-dark">
@include('bo.modules.tableColSorter', [
'cols' => [
'title' => 'Titre',
'updated_at' => 'Modifié le',
'status' => 'Publié ?'
]
])
</thead>
<tbody>
@foreach($pages as $page)
<tr>
<td>{{ Str::limit($page->title, 25) }}</td>
<td>{{ $page->updated_at->formatLocalized('%d %B %Y') }}</td>
<td>
<a href="{{route('bo.breeding-page.change-published', $page)}}" class="btn-link">
@if ($page->status)
<i class="fas fa-check check-green"></i>
@else
<i class="fas fa-times cross-red"></i>
@endif
</a>
</td>
<td><a href="{{ route('bo.breeding-page.edit', $page) }}" class="btn btn-sm btn-primary">{{ __('Éditer') }}</a></td>
</tr>
@endforeach
</tbody>
</table>
{{ $pages->withQueryString()->links() }}
</div>
</div>
@endsection

View file

@ -12,6 +12,7 @@
<thead class="thead-dark">
@include('bo.modules.tableColSorter', [
'cols' => [
'title' => 'Nom',
'type' => 'Type'
]
])
@ -19,6 +20,7 @@
<tbody>
@foreach($configs as $config)
<tr>
<td>{{$config->title}}</td>
<td>{{$config->type}}</td>
<td><a href="{{route('bo.general-configs.edit', $config)}}" class="btn btn-sm btn-primary">{{ __('Éditer') }}</a></td>
</tr>

View file

@ -14,7 +14,7 @@ if(!__MINIACF.vimeoVideo) {
$(document).ready(function() {
$('.vimeoVideo').on('change', function() {
const parentDiv = $(this).parent()
const regex = /vimeo\.com\/[0-9]{9}/gm;
const regex = /vimeo\.com\/[0-9]{8,10}/gm;
if(regex.exec($(this).val()) !== null) {
console.log($(this).val() + ' is valid')
} else {

View file

@ -1,4 +1,4 @@
<div class="nav">
<div class="super-nav nav">
<ul>
<li @if(isset($poultry))class="active"@endif><a href="{{ route('brand.poultry') }}">
{{ $GeneralConfigGlobal->where('type', GeneralConfigType::poultryPage())->first()->data['poultry_header_title']['value'] }}

View file

@ -0,0 +1,21 @@
<article @if(isset($loop) and $loop->even) class="right" @endif>
@if($page->media_type->equals(InputType::videoVimeo()))
<picture>
<img src="https://vumbnail.com/{{ parse_url($page->video, PHP_URL_PATH) }}.jpg" width="559" alt="{{ $page->picture_alt }}">
</picture>
@else
<picture>
<source srcset="{{ url(resizePublic($page->picture, 'breedingWebp')) }}" type="image/webp">
<img src="{{ url(resizePublic($page->picture, 'actuFront')) }}" width="559" alt="{{ $page->picture_alt }}">
</picture>
@endif
<section>
<h2>{{ $page->title }}</h2>
<span>{{ $page->subtitle }}</span>
<div class="content">{{ Str::limit($page->subtitleContent, 300) }}</div>
<a class="link" href="{{ route('breeding-page.show', [
'breeding_page_type' => $page->type->value,
'breeding_page' => $page
]) }}">{{ __('En savoir +') }}</a>
</section>
</article>

View file

@ -0,0 +1,6 @@
<div class="dropdown">
@php $rId = Str::uuid(); @endphp
<input id="{{$rId}}" type="checkbox" @if(isset($openned) and $openned)checked @endif>
<label for="{{$rId}}" class="title"><h3>{!! clean($dropdown['title']) !!}</h3></label>
<div class="ck-content">{!! clean($dropdown['html']) !!}</div>
</div>

View file

@ -0,0 +1,38 @@
@extends('layouts.app')
@section('title', $generalConfig->data['breeding_header_title']['value'])
@section('description', $generalConfig->data['breeding_header_title']['value'])
@section('sub_header')
<div class="sub_header sub_header_breedingPage" @if(isset($generalConfig->data['breeding_header_img']['value'])) style="background-image: url({{ $generalConfig->data['breeding_header_img']['value'] }});" @endif>
<div class="content-breeding">
<h1 class="title">{{ $generalConfig->data['breeding_header_title']['value'] }}</h1>
</div>
</div>
@endsection
@section('content')
<div class="content breedingPageIndex">
<div class="headerText">
<b>{!! clean($generalConfig->data['breeding_sub_header_text']['text']) !!}</b>
</div>
<div class="cards">
@php $breederPageTypes = collect($generalConfig->data)->filter(function($v, $key) {
return strpos($key, 'breeding_page_') === 0 and isset($v['type']) and $v['inputType']['value'] === InputType::string()->value;
}); @endphp
@foreach($breederPageTypes as $key => $pageType)
@php $img = $generalConfig->data[str_replace('_text', '_img', $key)]; @endphp
<div class="card">
<a href="{{ route('breeding-page.list', BreedingPageType::make($pageType['type']['value'])) }}">
<div class="hoverFigure"><span>{{ __('En savoir +') }}</span></div>
<picture>
<source srcset="{{ url(resizePublic($img['value'], 'breedingWebp')) }}" type="image/webp">
<img src="{{ url($img['value']) }}" width="559" alt="Le Gaulois - {{ $pageType['value'] }}">
</picture>
</a>
<h2>{{ $pageType['value'] }}</h2>
<a href="{{ route('breeding-page.list', BreedingPageType::make($pageType['type']['value'])) }}">{{ _('En savoir +') }}</a>
</div>
@endforeach
</div>
</div>
@endsection

View file

@ -0,0 +1,22 @@
@extends('layouts.app')
@section('title', $generalConfig->data['breeding_header_title']['value'])
@section('description', $generalConfig->data['breeding_header_title']['value'] . ' - ' . $pagesType->label)
@section('sub_header')
<div class="sub_header sub_header_breedingPage" @if(isset($generalConfig->data['breeding_header_img']['value'])) style="background-image: url({{ $generalConfig->data['breeding_header_img']['value'] }});" @endif>
<div class="content-breeding">
<h1 class="title">{{ $generalConfig->data['breeding_header_title']['value'] }}</h1>
</div>
</div>
@endsection
@section('content')
<div class="content breedingPageList">
@include('front.breeding-page.nav')
<div class="articles">
@foreach($pages as $page)
@include('front.breeding-page.card')
@endforeach
</div>
</div>
@endsection

View file

@ -0,0 +1,13 @@
<div class="super-nav nav-breeding">
<ul>
@php $breederPageTypes = collect($generalConfig->data)->filter(function($v, $key) {
return strpos($key, 'breeding_page_') === 0 and isset($v['type']) and $v['inputType']['value'] === InputType::string()->value;
}); @endphp
@foreach ($breederPageTypes as $type)
<li @if($pagesType->equals(BreedingPageType::make($type['type']['value'])))class="active"@endif>
<a href="{{ route('breeding-page.list', $type['type']['value']) }}">{{
$type['value']
}}</a></li>
@endforeach
</ul>
</div>

View file

@ -0,0 +1,47 @@
@extends('layouts.app')
@section('title', $page->seo_title)
@section('description', $page->seo_description)
@section('sub_header')
<div class="sub_header sub_header_breedingPage" @if(isset($generalConfig->data['breeding_header_img']['value'])) style="background-image: url({{ $generalConfig->data['breeding_header_img']['value'] }});" @endif>
<div class="content-breeding">
<h1 class="title">{{ $generalConfig->data['breeding_header_title']['value'] }}</h1>
</div>
</div>
@endsection
@section('content')
<div class="content breedingPageShow">
@include('front.breeding-page.nav')
<article>
<header>
<h1>{{ $page->title }}</h1>
<div class="headerContent">{!! clean($page->headerContent) !!}</div>
</header>
<section class="blocs">
@if($page->media_type->equals(InputType::videoVimeo()))
<div class="video vimeo" data-authorize="0">
<iframe src="/frame/vimeo" data-src="https://player.vimeo.com/video{{ parse_url($page->video, PHP_URL_PATH) }}" width="100%" height="100%" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
@else
<picture>
<source srcset="{{ url(resizePublic($page->picture, 'breedingWebp')) }}" type="image/webp">
<img src="{{ url(resizePublic($page->picture, 'actuFront')) }}" width="559" alt="{{ $page->picture_alt }}">
</picture>
@endif
<div class="content">
<h2>{{ $page->subtitle }}</h2>
<div class="content ck-content">{!! clean($page->subtitleContent) !!}</div>
<div class="dropdowns">
@foreach($page->content[0]['content']['dropdownArray']['value'] as $dropdown)
@include('front.breeding-page.dropdown', [
'dropdown' => $dropdown,
'openned' => $loop->first
])
@endforeach
</div>
</div>
</section>
</article>
</div>
@endsection

View file

@ -1,4 +1,4 @@
<div class="nutrition-nav">
<div class="super-nav nutrition-nav">
<ul>
<li @if($page->type->equals(NutritionPageType::poultry()))class="active"@endif><a href="{{ route('kitchen-side.health-nutrition.nutrition-poultry') }}">{{
$nutritionPageMenu->where('type', NutritionPageType::poultry())->first()->menutitle

View file

@ -147,6 +147,7 @@
</ul>
</div>
</li>
<li><a href="{{ route('breeding-page.index') }}">{{ __('Élevage') }}</a></li>
@if ($momentFiche !== false)
<li><a href="{{ route('moment', $momentFiche) }}">{{ __('En ce moment') }}</a></li>
@endif

View file

@ -94,6 +94,18 @@
<a class="dropdown-item" href="{{route('bo.actus.create')}}">{{ __('Ajouter') }}</a>
</div>
</li>
{{-- Élevage des volailles --}}
<li class="nav-item dropdown btn btn-sm btn-dark mb-1">
<a class="nav-link dropdown-toggle text-white" data-toggle="dropdown" href="#" role="button">{{ __('Élevage des volailles') }}</a>
<div class="dropdown-menu">
<a class="dropdown-item" href="{{route('bo.general-configs.edit', GeneralConfigType::breedingPage()->value)}}">{{ __('Configuration') }}</a>
@foreach(BreedingPageType::toArray() as $type)
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="{{route('bo.breeding-page.index', $type)}}">{{ __('Pages :type', ['type' => $type->label]) }}</a>
<a class="dropdown-item" href="{{route('bo.faq-questions.create')}}">{{ __('Ajouter') }}</a>
@endforeach
</div>
</li>
{{-- En ce moment --}}
<li class="nav-item dropdown btn btn-sm btn-dark mb-1">
<a class="nav-link dropdown-toggle text-white" data-toggle="dropdown" href="#" role="button">{{ __('En ce moment') }}</a>

View file

@ -4,6 +4,7 @@ use App\Http\Controllers\Bo\ActuController;
use App\Http\Controllers\Bo\AdsController;
use App\Http\Controllers\Bo\ArticlesController;
use App\Http\Controllers\Bo\BreederPortraitController;
use App\Http\Controllers\Bo\BreedingPageController;
use App\Http\Controllers\Bo\ConsumptionTimesController;
use App\Http\Controllers\Bo\OCBBreedersController;
use App\Http\Controllers\Bo\OCBContentController;
@ -92,6 +93,9 @@ Route::prefix('bo')
Route::resource('poultry-page', PoultryPageController::class)->except(['show', 'create', 'store', 'destroy'])
->withoutMiddleware('xss')
->middleware('xss:headerContent,html');
Route::resource('breeding-page', BreedingPageController::class)->except(['index', 'show', 'create', 'store'])
->withoutMiddleware('xss')
->middleware('xss:headerContent,html');
});
Route::get('/', [DashboardController::class, 'index'])->name('dashboard');
@ -137,6 +141,12 @@ Route::prefix('bo')
Route::get('/products/{product}/copyincopicture', [ProductsController::class, 'copyXmlIncoPicture'])->name('products.copyXmlIncoPicture');
Route::get('/products/{product}/copyincopicture', [ProductsController::class, 'copyXmlIncoPicture'])->name('products.copyXmlIncoPicture');
Route::get('/products/{product}/show-rsm', [ProductsController::class, 'showRsm'])->name('products.show-rsm');
Route::get('/breeding-page/change-published/{breeding_page}', [BreedingPageController::class, 'changePublished'])->name('breeding-page.change-published');
Route::get('/breeding-page/{breeding_page_type}/create', [BreedingPageController::class, 'create'])->name('breeding-page.create');
Route::get('/breeding-page/{breeding_page_type}', [BreedingPageController::class, 'index'])->name('breeding-page.index');
Route::post('/breeding-page/{breeding_page_type}', [BreedingPageController::class, 'store'])->name('breeding-page.store')
->withoutMiddleware('xss')
->middleware('xss:headerContent,html');
Route::post('/ajax/reductions/save', [ReductionsController::class, 'saveDatas']);
Route::post('/products/{product}/setinco', [ProductsController::class, 'setXmlInco'])->name('products.setXmlInco');
Route::post('/upload', [UploadController::class, 'uploadFile'])->name('upload');

View file

@ -1,9 +1,11 @@
<?php
use App\Enums\GeneralConfigType;
use App\Http\Controllers\ActuController;
use App\Http\Controllers\BourseController;
use App\Http\Controllers\BoutiqueController;
use App\Http\Controllers\BrandController;
use App\Http\Controllers\BreedingPageController;
use App\Http\Controllers\ClubController;
use App\Http\Controllers\ContactController;
use App\Http\Controllers\CustomerController;
@ -22,10 +24,12 @@ use App\Http\Middleware\Authenticate;
use App\Http\Middleware\EncryptCookies;
use App\Http\Middleware\VerifyCsrfToken;
use App\Http\Middleware\XssSanitizer;
use App\Models\GeneralConfig;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Str;
use Illuminate\View\Middleware\ShareErrorsFromSession;
/*
@ -193,6 +197,15 @@ Route::prefix('/on-s-engage')
});
});
Route::prefix(Str::slug(GeneralConfig::where('type', GeneralConfigType::breedingPage())
->first()->data['breeding_header_title']['value']))
->name('breeding-page.')
->group(function () {
Route::get('/', [BreedingPageController::class, 'index'])->name('index');
Route::get('/{breeding_page_type}', [BreedingPageController::class, 'list'])->name('list');
Route::get('/{breeding_page_type}/{breeding_page}', [BreedingPageController::class, 'show'])->name('show');
});
// Route ajax pour Single Optin
Route::post('/optin', [HomeController::class, 'addOptIn'])->name('add-single-optin');