Merge branch 'home' into 'develop'
feat: ✨ set home in dynamic page
See merge request ldc-web/projets/ldc!107
This commit is contained in:
commit
ebefe52231
49 changed files with 756 additions and 1127 deletions
|
|
@ -123,7 +123,6 @@ class DynamicPageController extends Controller
|
|||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$dynamicPageModel = new DynamicPage();
|
||||
|
||||
$dynamicPageModel->inertiaFill($request->validated());
|
||||
|
||||
if ($dynamicPageModel->saveOrFail()) {
|
||||
|
|
|
|||
|
|
@ -120,15 +120,15 @@ class InputsController extends Controller
|
|||
*
|
||||
* @param integer $modelId Id of the target model.
|
||||
* @param integer $modelName Name of the target model.
|
||||
* @return string
|
||||
* @return string|null
|
||||
*/
|
||||
private function getAccessModel(int $modelId, string $modelName): string
|
||||
private function getAccessModel(int $modelId, string $modelName): string|null
|
||||
{
|
||||
$targetModel = $this->getClassFromTableName($modelName)::getModelsCached()->firstWhere('id', $modelId);
|
||||
if (!$targetModel) {
|
||||
return null;
|
||||
}
|
||||
return route("front.$modelName.show", $targetModel->slug);
|
||||
return parse_url(route("front.$modelName.show", $targetModel->slug), PHP_URL_PATH) ?? "/";
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -16,13 +16,23 @@ use LDC\LDCCRM\Models\SingleOptin;
|
|||
|
||||
class ContactController
|
||||
{
|
||||
public function index()
|
||||
/**
|
||||
* Show contact index page.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$types = ContactFormType::toArray();
|
||||
return view('front.pages.contact.index', compact('types'));
|
||||
}
|
||||
|
||||
public function show(string $slug)
|
||||
/**
|
||||
* Show contact show page.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(string $slug): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$enumType = collect(ContactFormType::all())->first(function ($enum) use ($slug) {
|
||||
return $enum->slug() === $slug;
|
||||
|
|
@ -33,13 +43,18 @@ class ContactController
|
|||
return view('front.pages.contact.show', compact('enumType'));
|
||||
}
|
||||
|
||||
public function send(ContactRequest $request)
|
||||
/**
|
||||
* Contact send.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function send(ContactRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$data = $request->validated();
|
||||
$messageContact = new MailContactData($data);
|
||||
$contactMessage = "";
|
||||
$hasContactError = false;
|
||||
$newsletterMessage = null;
|
||||
$data = $request->validated();
|
||||
$messageContact = new MailContactData($data);
|
||||
$contactMessage = "";
|
||||
$hasContactError = false;
|
||||
$newsletterMessage = null;
|
||||
$hasNewsletterError = false;
|
||||
try {
|
||||
dispatch(new SendContactMail($messageContact))
|
||||
|
|
@ -50,7 +65,7 @@ class ContactController
|
|||
'exception' => $e
|
||||
]);
|
||||
$hasContactError = true;
|
||||
$contactMessage = trans('Une erreur est survenue lors de l\'envoi du message de contact.');
|
||||
$contactMessage = trans('Une erreur est survenue lors de l\'envoi du message de contact.');
|
||||
}
|
||||
if (!empty($data['newsletter']) && $data['newsletter']) {
|
||||
try {
|
||||
|
|
@ -62,21 +77,21 @@ class ContactController
|
|||
}
|
||||
report($e);
|
||||
$hasNewsletterError = true;
|
||||
$newsletterMessage = trans('Une erreur est survenue lors de l\'inscription à la newsletter, merci de réessayer ultérieurement.');
|
||||
$newsletterMessage = trans('Une erreur est survenue lors de l\'inscription à la newsletter, merci de réessayer ultérieurement.');
|
||||
} catch (CrmException $e) {
|
||||
report($e);
|
||||
$hasNewsletterError = true;
|
||||
$newsletterMessage = trans('Une erreur est survenue lors de l\'inscription à la newsletter, merci de réessayer ultérieurement.');
|
||||
$newsletterMessage = trans('Une erreur est survenue lors de l\'inscription à la newsletter, merci de réessayer ultérieurement.');
|
||||
}
|
||||
}
|
||||
ContactCount::updateOrInsert(
|
||||
['type' => $data['enumType']],
|
||||
['type' => $data['enumType']],
|
||||
['submissions' => \DB::raw('submissions + 1')]
|
||||
);
|
||||
|
||||
$contactMessage = trans('Votre message a bien été envoyé.');
|
||||
$message = $newsletterMessage ? $contactMessage. ' <br /> ' . $newsletterMessage : $contactMessage;
|
||||
$message = $newsletterMessage ? $contactMessage. ' <br /> ' . $newsletterMessage : $contactMessage;
|
||||
return redirect()->back()
|
||||
->with($hasContactError || $hasNewsletterError ? 'info' : 'success', new \Illuminate\Support\HtmlString($message));
|
||||
->with($hasContactError || $hasNewsletterError ? 'info' : 'success', new \Illuminate\Support\HtmlString($message));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,17 +14,6 @@ use Uwil\LaravelCommon\Controllers\Controller;
|
|||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show home page.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function homepage(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('front.pages.home');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* unsubscribeNewsletter method
|
||||
*
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ use Uwil\LaravelCommon\Controllers\Controller;
|
|||
|
||||
class NewsController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('front.pages.news.index');
|
||||
}
|
||||
|
||||
public function show(News $news)
|
||||
/**
|
||||
* Show news show page.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(News $news): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('front.pages.news.show', ['model' => $news->load('categories')]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ class StoreDynamicPageRequest extends UpdateDynamicFieldRequest
|
|||
$this->merge([
|
||||
'config_id' => $this->config_id != 0 ? $this->config_id : null,
|
||||
'isLocked' => $this->boolean('isLocked'),
|
||||
'isRoot' => $this->boolean('isRoot'),
|
||||
'slug' => $this->boolean('isRoot') ? "" : $this->slug,
|
||||
]);
|
||||
if ($this->config_id) {
|
||||
parent::prepareForValidation();
|
||||
|
|
@ -50,12 +52,19 @@ class StoreDynamicPageRequest extends UpdateDynamicFieldRequest
|
|||
{
|
||||
$rules = [
|
||||
'title' => 'required|string|between:3,255',
|
||||
'slug' => 'required|string|regex:/^[-A-Za-z0-9]{3,255}$/',
|
||||
'page_id' => 'sometimes|nullable|numeric|exists:dynamic_pages,id',
|
||||
'config_id' => 'sometimes|nullable|numeric|exists:page_configs,id',
|
||||
'status' => ['required', new Enum(PageStatusEnum::class)],
|
||||
'isLocked' => 'required|boolean',
|
||||
'isRoot' => 'required|boolean',
|
||||
];
|
||||
|
||||
if ($this->boolean('isRoot')) {
|
||||
$rules['slug'] = ['present', 'nullable'];
|
||||
} else {
|
||||
$rules['slug'] = ['required', 'string', 'regex:/^[-A-Za-z0-9]{3,255}$/'];
|
||||
}
|
||||
|
||||
if ($this->config_id) {
|
||||
$rules = \array_merge(
|
||||
['content' => 'required|array|min:1'],
|
||||
|
|
@ -67,6 +76,7 @@ class StoreDynamicPageRequest extends UpdateDynamicFieldRequest
|
|||
'content' => ['required', 'string', new WysiwygLength()],
|
||||
], $rules);
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
|
|
@ -83,6 +93,7 @@ class StoreDynamicPageRequest extends UpdateDynamicFieldRequest
|
|||
'config_id' => trans_choice('models.classes.page-config', 1),
|
||||
'status' => trans('validation.custom.status'),
|
||||
'isLocked' => trans('validation.custom.locked'),
|
||||
'isRoot' => trans('validation.custom.root'),
|
||||
];
|
||||
if ($this->config_id) {
|
||||
$attributes = \array_merge(
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ use Uwil\LaravelCommon\Helpers\FileHelper;
|
|||
* @property integer|null $page_id Page associated to the dynamic page.
|
||||
* @property \App\Enums\DynamicPages\PageStatusEnum $status Status of the dynamic page.
|
||||
* @property boolean $isLocked Locked status of dynamic page.
|
||||
* @property boolean $isRoot Root status of dynamic page.
|
||||
* @property-read \Illuminate\Support\Carbon $created_at Date on which the dynamic page was created.
|
||||
* @property-read \Illuminate\Support\Carbon $updated_at Date on which the dynamic page was updated.
|
||||
* @property-read \Illuminate\Support\Carbon $deleted_at Date on which the dynamic page was updated.
|
||||
|
|
@ -58,6 +59,7 @@ class DynamicPage extends Model implements TranslatableModel
|
|||
'config_id',
|
||||
'status',
|
||||
'isLocked',
|
||||
'isRoot',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -69,6 +71,7 @@ class DynamicPage extends Model implements TranslatableModel
|
|||
'content' => 'array',
|
||||
'status' => PageStatusEnum::class,
|
||||
'isLocked' => 'boolean',
|
||||
'isRoot' => 'boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -102,7 +105,10 @@ class DynamicPage extends Model implements TranslatableModel
|
|||
{
|
||||
static::creating(function (self $model) {
|
||||
self::manageFields($model);
|
||||
$model->id_key = $model->slug;
|
||||
// Set id_key from slug or title when the dynamic page is root.
|
||||
$model->id_key = isset($model->slug) && !empty($model->slug)
|
||||
? $model->slug
|
||||
: Str::slug($model->title);
|
||||
});
|
||||
static::updating(function (self $model) {
|
||||
self::manageFields($model);
|
||||
|
|
@ -122,6 +128,7 @@ class DynamicPage extends Model implements TranslatableModel
|
|||
]);
|
||||
}
|
||||
$model->status = PageStatusEnum::draft;
|
||||
$model->isRoot = false;
|
||||
});
|
||||
static::forceDeleted(function (self $model) {
|
||||
// TODO: update this after recursive deleting images.
|
||||
|
|
@ -223,14 +230,33 @@ class DynamicPage extends Model implements TranslatableModel
|
|||
private static function manageFields(self $model): void
|
||||
{
|
||||
// Check unique fields.
|
||||
$slug = $model->slug ?? Str::slug($model->title);
|
||||
TranslationHelper::assertTranslationFieldIsUnique($model, $model->title, 'title');
|
||||
TranslationHelper::assertTranslationFieldIsUnique($model, $slug, 'slug');
|
||||
$model->setAttribute('slug', $slug);
|
||||
if($model->isRoot) {
|
||||
self::assertRootIsUnique($model);
|
||||
} else {
|
||||
$slug = $model->slug ?? Str::slug($model->title);
|
||||
TranslationHelper::assertTranslationFieldIsUnique($model, $model->title, 'title');
|
||||
TranslationHelper::assertTranslationFieldIsUnique($model, $slug, 'slug');
|
||||
$model->setAttribute('slug', $slug);
|
||||
}
|
||||
// Check translations.
|
||||
self::validateFallbackTranslations($model);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert there is only one root page.
|
||||
*
|
||||
* @param self $model
|
||||
* @return void
|
||||
*/
|
||||
public static function assertRootIsUnique(self $model): void
|
||||
{
|
||||
$oldDynamicPageRoot = self::getModelsCached()->where('isRoot', true)->first();
|
||||
if ($oldDynamicPageRoot) {
|
||||
$oldDynamicPageRoot->isRoot = false;
|
||||
$oldDynamicPageRoot->saveQuietly();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert fallback locale translation is present.
|
||||
*
|
||||
|
|
@ -278,16 +304,16 @@ class DynamicPage extends Model implements TranslatableModel
|
|||
* Get the url to access a specific resource.
|
||||
*
|
||||
* @param integer $id Id field of the target model.
|
||||
* @return string
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getAccessModel(int $id): string
|
||||
public static function getAccessModel(int $id): string|null
|
||||
{
|
||||
$targetModel = self::getModelsCached()->firstWhere('id', $id);
|
||||
if (!$targetModel) {
|
||||
return null;
|
||||
}
|
||||
$url = RouteHelper::routeNameChecker("front.dynamic-pages.{$targetModel->id_key}");
|
||||
return parse_url($url, PHP_URL_PATH);
|
||||
return parse_url($url, PHP_URL_PATH) ?? "/";
|
||||
}
|
||||
|
||||
// * RELATIONSHIPS
|
||||
|
|
|
|||
|
|
@ -48,12 +48,22 @@ class News extends Model implements TranslatableModel, LocalizedUrlRoutable
|
|||
HasUwilImages::inertiaFill as traitInertiaFill;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the route key for the model.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return request()->routeIs('back.*') ? 'id' : 'slug';
|
||||
}
|
||||
|
||||
public function getLocalizedRouteKey($locale)
|
||||
/**
|
||||
* Get the value of the model's localized route key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocalizedRouteKey($locale): string
|
||||
{
|
||||
return $this->getTranslation(
|
||||
$this->getRouteKeyName(),
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class DynamicPageRouteServiceProvider extends ServiceProvider
|
|||
$slug = $dynamicPageModel->getTranslation('slug', $locale);
|
||||
|
||||
// If no slug for the locale → skip.
|
||||
if (!$slug) continue;
|
||||
if (!empty($slug) && !$slug) continue;
|
||||
|
||||
// Retrieves the parent segments for this locale.
|
||||
$segments = DynamicPageHelper::getAllDynamicPageSegments(
|
||||
|
|
|
|||
|
|
@ -33,10 +33,6 @@ return Application::configure(basePath: dirname(__DIR__))
|
|||
'auth' => \Uwil\LaravelBackend\Middlewares\Authenticate::class,
|
||||
'guest' => \Uwil\LaravelBackend\Middlewares\RedirectIfAuthenticated::class,
|
||||
'lang' => \Uwil\LaravelBackend\Middlewares\Lang::class,
|
||||
'localeSessionRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class,
|
||||
'localeCookieRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleCookieRedirect::class,
|
||||
'localizationRedirect' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class,
|
||||
'localeViewPath' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationViewPath::class,
|
||||
]);
|
||||
})
|
||||
->withExceptions(function (Exceptions $exceptions) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('dynamic_pages', function (Blueprint $table) {
|
||||
$table->boolean('isRoot')->default(false)->comment('Page root status.')->after('isLocked');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('dynamic_pages', function (Blueprint $table) {
|
||||
$table->dropColumn('isRoot');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
// Delete old key.
|
||||
Schema::table('dynamic_pages', function (Blueprint $table) {
|
||||
$table->dropUnique('dynamic_pages_id_key_unique');
|
||||
});
|
||||
// Set new unique key with delete_at date.
|
||||
Schema::table('dynamic_pages', function (Blueprint $table) {
|
||||
$table->unique(['id_key', 'deleted_at'], 'dynamic_pages_id_key_deleted_at_unique');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
// Delete old key.
|
||||
Schema::table('dynamic_pages', function (Blueprint $table) {
|
||||
$table->dropUnique('dynamic_pages_id_key_deleted_at_unique');
|
||||
});
|
||||
// Set new unique key.
|
||||
Schema::table('dynamic_pages', function (Blueprint $table) {
|
||||
$table->unique('id_key', 'dynamic_pages_id_key_unique');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -86,6 +86,8 @@ return [
|
|||
"form_subtitle_visibility" => "Manage account display.",
|
||||
"form_title_isLocked" => "Restriction",
|
||||
"form_subtitle_isLocked" => "Manage page locking.",
|
||||
"form_title_page_accessibility" => "Accessibility",
|
||||
"form_subtitle_page_accessibility" => "Manage access the dynamic page of the site.",
|
||||
"form_associate_to" => ":attribute associated to this model|:attribute associated to this model",
|
||||
"form_associate_to_plural" => ":attribute associated to this model|:attribute associated to this model",
|
||||
"form_title_config" => "Setup",
|
||||
|
|
@ -124,6 +126,7 @@ return [
|
|||
"list_children_needed" => "Children are required for this type :enumLabel",
|
||||
"empty_warning" => "No data recorded",
|
||||
"page_locked" => "This page is currently locked",
|
||||
"page_root" => "This page is currently home",
|
||||
"unsupported_type" => "Unsupported type:",
|
||||
"missing_translations" => "The translation of the :field for the language :locales is missing.|The translation
|
||||
of the :field for :locales languages are missing.",
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ return [
|
|||
"multiple_choice" => 'multiple choice',
|
||||
"required_field" => 'compulsory fields',
|
||||
"go_to_the_back_end" => "access the back-office",
|
||||
"back_to_homepage" => "Back to the homepage",
|
||||
"homepage" => "LDC",
|
||||
"nos-engagements" => [
|
||||
'key' => "Presentation of our commitments",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'contact' => 'contact-us/{slug}',
|
||||
'contact' => 'contact-us/{slug}',
|
||||
'contact_index' => 'contact-us',
|
||||
'news' => 'news/{news}'
|
||||
'news' => 'news/{news}'
|
||||
];
|
||||
|
|
|
|||
|
|
@ -240,6 +240,7 @@ return [
|
|||
"validation" => "validation",
|
||||
"reference" => "reference",
|
||||
"locked" => "locked",
|
||||
"root" => "root",
|
||||
"field" => "field",
|
||||
"key" => "unique key",
|
||||
"slug" => "slug",
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ return [
|
|||
"form_subtitle_visibility" => "Gérer l'affichage du compte.",
|
||||
"form_title_isLocked" => "Restriction",
|
||||
"form_subtitle_isLocked" => "Gérer le vérouillage de la page.",
|
||||
"form_title_page_accessibility" => "Accessibilité",
|
||||
"form_subtitle_page_accessibility" => "Gérer l’accès à la page dynamique du site.",
|
||||
"form_associate_to" => ":attribute associé au modèle|:attribute associée au modèle",
|
||||
"form_associate_to_plural" => ":attribute associés au modèle|:attribute associées au modèle",
|
||||
"form_title_config" => "Réglage",
|
||||
|
|
@ -124,6 +126,7 @@ return [
|
|||
"list_children_needed" => "Des enfants sont nécessaires pour ce type :enumLabel",
|
||||
"empty_warning" => "Aucune donnée enregistrée",
|
||||
"page_locked" => "Cette page est actuellement vérouillée",
|
||||
"page_root" => "Cette page est actuellement l'accueil",
|
||||
"unsupported_type" => "Type non supporté:",
|
||||
"missing_translations" => "La traduction du champs :field pour la langue :locales est manquante.|La traduction
|
||||
du champs :field pour l es langues :locales sont manquantes.",
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ return [
|
|||
"multiple_choice" => 'choix multiple',
|
||||
"required_field" => 'champs obligatoires',
|
||||
"go_to_the_back_end" => "accéder au back-office",
|
||||
"back_to_homepage" => "Revenir à la page d'accueil",
|
||||
"homepage" => "LDC",
|
||||
"nos-engagements" => "nos engagements",
|
||||
"nos-engagements" => [
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'contact' => 'nous-contacter/{slug}',
|
||||
'contact' => 'nous-contacter/{slug}',
|
||||
'contact_index' => 'nous-contacter',
|
||||
'news' => 'actualites/{news}'
|
||||
'news' => 'actualites/{news}'
|
||||
];
|
||||
|
|
|
|||
|
|
@ -240,6 +240,7 @@ return [
|
|||
"validation" => "validation",
|
||||
"reference" => "référence",
|
||||
"locked" => "vérouillé",
|
||||
"root" => "page racine (accueil)",
|
||||
"field" => "champs",
|
||||
"key" => "clé",
|
||||
"slug" => "chemin d'accès",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
@use '/node_modules/flag-icons/css/flag-icons.min.css';
|
||||
@use './fonts';
|
||||
@use './inputs/wysiwyg';
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
|
@ -117,30 +119,7 @@ html {
|
|||
}
|
||||
}
|
||||
|
||||
.richtext-outline,
|
||||
.richtext-outline-1,
|
||||
.richtext-shadow {
|
||||
all: unset !important;
|
||||
}
|
||||
|
||||
// Wysiwyg classes.
|
||||
.reactjs-tiptap-editor {
|
||||
@apply rounded-md border border-input bg-background;
|
||||
}
|
||||
|
||||
.wysiwyg-error .reactjs-tiptap-editor {
|
||||
@apply border-destructive/50;
|
||||
}
|
||||
|
||||
.tiptap .link {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* stylelint-disable-next-line selector-class-pattern */
|
||||
.ProseMirror-focused {
|
||||
@apply rounded-b ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2;
|
||||
}
|
||||
|
||||
// Multiselect input.
|
||||
.multiselect-singleline-scroll {
|
||||
scrollbar-color: hsl(var(--border) / 40%) transparent;
|
||||
scrollbar-width: thin;
|
||||
|
|
|
|||
26
resources/sass/back/inputs/_wysiwyg.scss
Normal file
26
resources/sass/back/inputs/_wysiwyg.scss
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
.richtext-outline,
|
||||
.richtext-outline-1,
|
||||
.richtext-shadow {
|
||||
all: unset !important;
|
||||
}
|
||||
|
||||
.reactjs-tiptap-editor {
|
||||
@apply rounded-md border border-input bg-background;
|
||||
}
|
||||
|
||||
.wysiwyg-error .reactjs-tiptap-editor {
|
||||
@apply border-destructive/50;
|
||||
}
|
||||
|
||||
.tiptap .link {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#tippy-4 {
|
||||
z-index: 1 !important;
|
||||
}
|
||||
|
||||
/* stylelint-disable-next-line selector-class-pattern */
|
||||
.ProseMirror-focused {
|
||||
@apply rounded-b ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2;
|
||||
}
|
||||
|
|
@ -75,7 +75,7 @@ export default function GoToFrontView({
|
|||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<p>{definitivePath}</p>
|
||||
<p className="flex-1">{definitivePath}</p>
|
||||
<ExternalLinkIcon size={12} />
|
||||
</a>
|
||||
</TooltipTrigger>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// * Packages
|
||||
import { usePage } from "@inertiajs/react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import axios from "axios";
|
||||
import { CheckIcon, ChevronLeftIcon, ChevronRightIcon, ChevronsUpDownIcon, LoaderCircleIcon, SearchIcon, XIcon } from "lucide-react";
|
||||
import { route } from "ziggy-js";
|
||||
|
|
@ -76,6 +76,9 @@ export default function ModelSelect({
|
|||
// String research in models collection.
|
||||
const [search, setSearch] = useState<string>("");
|
||||
|
||||
// Search identification.
|
||||
const requestIdRef = useRef(0);
|
||||
|
||||
// Field value of the selected model.
|
||||
const [selectedValue, setSelectedValue] = useState<string|null>(null);
|
||||
|
||||
|
|
@ -88,6 +91,9 @@ export default function ModelSelect({
|
|||
const [pageSize] = useState<number>(5);
|
||||
const [lastPage, setLastPage] = useState<number>(1);
|
||||
|
||||
// Hack to block closing popover when changing pages.
|
||||
const [blockingClosePopover, setBlockingClosePopover] = useState<boolean>(false);
|
||||
|
||||
/**
|
||||
* Get the identification field of specific option.
|
||||
* @param option Model
|
||||
|
|
@ -190,6 +196,8 @@ export default function ModelSelect({
|
|||
* @return void
|
||||
*/
|
||||
const getData = async (pageNumber = 1) => {
|
||||
// Increment search id.
|
||||
const requestId = ++requestIdRef.current;
|
||||
setLoading(true);
|
||||
try {
|
||||
const data = await fetchOptions(pageNumber) as {
|
||||
|
|
@ -197,6 +205,8 @@ export default function ModelSelect({
|
|||
field: string,
|
||||
model: DynamicPageModel,
|
||||
};
|
||||
// Ignore obsolete answers.
|
||||
if (requestId !== requestIdRef.current) return;
|
||||
if (data.model) {
|
||||
const value = extractLocalized(data.model, data.field, locale);
|
||||
setSelectedValue(value);
|
||||
|
|
@ -208,11 +218,17 @@ export default function ModelSelect({
|
|||
setPage(data.items.current_page);
|
||||
setLastPage(data.items.last_page ?? 1);
|
||||
} catch (err) {
|
||||
// Ignore obsolete errors.
|
||||
if (requestId !== requestIdRef.current) return;
|
||||
console.error(err);
|
||||
setOptions([]);
|
||||
setLastPage(1);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
// Only the last call can stop the loading.
|
||||
if (requestId === requestIdRef.current) {
|
||||
setLoading(false);
|
||||
setTimeout(() => setBlockingClosePopover(false), 100)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -223,12 +239,15 @@ export default function ModelSelect({
|
|||
*/
|
||||
const goToPage = async (pageNumber: number) => {
|
||||
if (pageNumber < 1 || pageNumber > lastPage) return;
|
||||
getData(pageNumber);
|
||||
setBlockingClosePopover(true);
|
||||
await getData(pageNumber);
|
||||
};
|
||||
|
||||
// Fetch with debounce.
|
||||
useEffect(() => {
|
||||
setDynamicField(field ?? null);
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset options list if empty search or null
|
||||
if (targetModel && search.length === 0) {
|
||||
|
|
@ -238,12 +257,22 @@ export default function ModelSelect({
|
|||
|
||||
// Nothing to do if search is below 3 caracters.
|
||||
if (search.length < 3) return;
|
||||
|
||||
|
||||
// Get updated options list with search.
|
||||
const handler = setTimeout(() => getData(), 300);
|
||||
return () => clearTimeout(handler);
|
||||
}, [search, targetModel, field]);
|
||||
|
||||
// Update when selected is updated.
|
||||
useEffect(() => {
|
||||
if (selected !== null) {
|
||||
handleSelect(selected);
|
||||
} else {
|
||||
setSelectedId(null);
|
||||
setSelectedValue(null);
|
||||
}
|
||||
}, [selected]);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col w-full gap-1.5">
|
||||
<Label htmlFor={name}>
|
||||
|
|
@ -264,13 +293,21 @@ export default function ModelSelect({
|
|||
)}
|
||||
>
|
||||
{selectedValue ?? placeholder}
|
||||
<ChevronsUpDownIcon className="opacity-50" />
|
||||
{loading ? <LoaderCircleIcon className="animate-spin opacity-50 w-4 h-4" /> : <ChevronsUpDownIcon className="opacity-50 w-4 h-4" />}
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-[var(--radix-popover-trigger-width)] p-0">
|
||||
<PopoverContent
|
||||
className="w-[var(--radix-popover-trigger-width)] p-0"
|
||||
onInteractOutside={(e) => {
|
||||
if (blockingClosePopover) {
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className="relative">
|
||||
<div className="absolute top-1/2 left-2 transform -translate-y-1/2 text-muted-foreground">
|
||||
{loading ? <LoaderCircleIcon className="animate-spin w-4 h-4" /> : <SearchIcon className="w-4 h-4" />}
|
||||
<SearchIcon className="w-4 h-4" />
|
||||
</div>
|
||||
<Input
|
||||
type="text"
|
||||
|
|
|
|||
|
|
@ -9,9 +9,10 @@ interface Props {
|
|||
value: string
|
||||
targetValue: string
|
||||
wordCounter?: boolean;
|
||||
disabled?: boolean,
|
||||
}
|
||||
const Slugifycator = (props: Props) => {
|
||||
const {value, targetValue, setData, wordCounter = false} = props;
|
||||
const {value, targetValue, setData, wordCounter = false, disabled = false} = props;
|
||||
return (
|
||||
<div className="flex items-end gap-1">
|
||||
<SimpleString
|
||||
|
|
@ -28,6 +29,7 @@ const Slugifycator = (props: Props) => {
|
|||
wordCounter={wordCounter}
|
||||
value={value}
|
||||
setData={setData}
|
||||
disabled={disabled}
|
||||
/>
|
||||
<BtnOptionnalLinkWithTooltip
|
||||
content={<GavelIcon className="w-4 h-4 m-auto" />}
|
||||
|
|
@ -35,6 +37,7 @@ const Slugifycator = (props: Props) => {
|
|||
type="button"
|
||||
variant="secondary"
|
||||
onClick={() => setData("slug", str(targetValue).slug().value())}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -488,7 +488,7 @@ export default function LinkButton({ editor, tooltip } : LinkProps) {
|
|||
placeholder="ex: John Doe"
|
||||
selected={selectedModelId}
|
||||
required={true}
|
||||
disabled={loading}
|
||||
disabled={selectedEnumValue === null || loading}
|
||||
setData={(_, value) => handleSelectEntry(value)}
|
||||
parentErrors={errors}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -33,139 +33,140 @@ import useTrans from "@/hooks/use-translations";
|
|||
import { cn } from "@/lib/utils";
|
||||
|
||||
type SimpleWysiwygProps = {
|
||||
className?: string;
|
||||
name: string;
|
||||
model: string;
|
||||
label: string;
|
||||
value?: string;
|
||||
id?: string;
|
||||
placeholder?: string;
|
||||
wordCounter?: boolean;
|
||||
required?: boolean;
|
||||
disabled?: boolean;
|
||||
parentErrors?: Record<string, string> | null,
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
setData: (name: string, value: string) => void;
|
||||
className?: string;
|
||||
name: string;
|
||||
model: string;
|
||||
label: string;
|
||||
value?: string;
|
||||
id?: string;
|
||||
placeholder?: string;
|
||||
wordCounter?: boolean;
|
||||
required?: boolean;
|
||||
disabled?: boolean;
|
||||
parentErrors?: Record<string, string> | null,
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
setData: (name: string, value: string) => void;
|
||||
};
|
||||
|
||||
export default function SimpleWysiwyg({
|
||||
className,
|
||||
value = "",
|
||||
model,
|
||||
name,
|
||||
label,
|
||||
id = name as string,
|
||||
placeholder = "back.enter_text_here",
|
||||
wordCounter = true,
|
||||
required = true,
|
||||
disabled = false,
|
||||
parentErrors = null,
|
||||
setData,
|
||||
className,
|
||||
value = "",
|
||||
model,
|
||||
name,
|
||||
label,
|
||||
id = name as string,
|
||||
placeholder = "back.enter_text_here",
|
||||
wordCounter = true,
|
||||
required = true,
|
||||
disabled = false,
|
||||
parentErrors = null,
|
||||
setData,
|
||||
}: SimpleWysiwygProps) {
|
||||
const { errors } = usePage().props;
|
||||
const localErrors = parentErrors ?? errors;
|
||||
const { errors } = usePage().props;
|
||||
const localErrors = parentErrors ?? errors;
|
||||
|
||||
const extensions = [
|
||||
BaseKit.configure({
|
||||
placeholder: {
|
||||
showOnlyCurrent: true,
|
||||
placeholder: useTrans(placeholder),
|
||||
},
|
||||
characterCount: false,
|
||||
}),
|
||||
Heading,
|
||||
SearchAndReplace,
|
||||
Bold,
|
||||
Italic,
|
||||
TextUnderline,
|
||||
Strike,
|
||||
BulletList,
|
||||
OrderedList,
|
||||
Indent,
|
||||
TextAlign,
|
||||
History,
|
||||
Blockquote,
|
||||
FontSize,
|
||||
HorizontalRule,
|
||||
Clear,
|
||||
Color,
|
||||
Image.configure({
|
||||
upload: async (file: File): Promise<string> => {
|
||||
// Prepare the form data.
|
||||
const data = new FormData();
|
||||
data.append("upload", file);
|
||||
data.append("folder", model);
|
||||
const extensions = [
|
||||
BaseKit.configure({
|
||||
placeholder: {
|
||||
showOnlyCurrent: true,
|
||||
placeholder: useTrans(placeholder),
|
||||
},
|
||||
characterCount: false,
|
||||
}),
|
||||
History,
|
||||
SearchAndReplace,
|
||||
Clear,
|
||||
Heading,
|
||||
Bold,
|
||||
Italic,
|
||||
TextUnderline,
|
||||
Strike,
|
||||
Color,
|
||||
FontSize,
|
||||
BulletList,
|
||||
OrderedList,
|
||||
Indent,
|
||||
TextAlign,
|
||||
Blockquote,
|
||||
HorizontalRule,
|
||||
Image.configure({
|
||||
upload: async (file: File): Promise<string> => {
|
||||
// Prepare the form data.
|
||||
const data = new FormData();
|
||||
data.append("upload", file);
|
||||
data.append("folder", model);
|
||||
|
||||
const uploadRoute = route("back.wysiwyg.upload");
|
||||
const uploadRoute = route("back.wysiwyg.upload");
|
||||
|
||||
const header = {
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await axios.post(uploadRoute, data, header);
|
||||
return response.data.url;
|
||||
} catch (error: Error | unknown) {
|
||||
throw new Error(`Erreur upload: ${(error as Error).message}`);
|
||||
}
|
||||
},
|
||||
}),
|
||||
// Custom plugins.
|
||||
Link,
|
||||
];
|
||||
|
||||
const [content, setContent] = useState(value);
|
||||
const [version, setVersion] = useState(1);
|
||||
|
||||
function stripHtmlTags(html: string) {
|
||||
const temp = document.createElement('div');
|
||||
temp.innerHTML = html;
|
||||
const text = temp.textContent || temp.innerText || '';
|
||||
return text.trim() === '' ? null : text;
|
||||
}
|
||||
const onChangeContent = (changedValue: string) => {
|
||||
const value = stripHtmlTags(changedValue) ? changedValue : '';
|
||||
setContent(value);
|
||||
setData(name, value);
|
||||
};
|
||||
|
||||
const customOptions: UseEditorOptions = {
|
||||
editorProps: {
|
||||
attributes: {
|
||||
required: String(required),
|
||||
id,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (content !== value) {
|
||||
setContent(value);
|
||||
setVersion(version + 1);
|
||||
try {
|
||||
const response = await axios.post(
|
||||
uploadRoute,
|
||||
data,
|
||||
{ headers: { "Content-Type": "multipart/form-data" } }
|
||||
);
|
||||
return response.data.url;
|
||||
} catch (error: Error | unknown) {
|
||||
throw new Error(`Erreur upload: ${(error as Error).message}`);
|
||||
}
|
||||
}, [value]);
|
||||
},
|
||||
}),
|
||||
Link,
|
||||
];
|
||||
|
||||
return (
|
||||
<div className={cn("col-span-2", { "wysiwyg-error": localErrors[name] }, className)}>
|
||||
<Label htmlFor={name}>{label + (required ? " *" : "")}</Label>
|
||||
{wordCounter && <WordCounter value={content.replace(/<[^>]*>/g, "")} />}
|
||||
<div className={cn("mt-1.5", { "mb-1.5": localErrors[name] })}>
|
||||
<RichTextEditor
|
||||
// Force re-render.
|
||||
key={version}
|
||||
output="html"
|
||||
content={content}
|
||||
onChangeContent={onChangeContent}
|
||||
// @ts-ignore
|
||||
extensions={extensions}
|
||||
disabled={disabled}
|
||||
useEditorOptions={customOptions}
|
||||
dark={false}
|
||||
/>
|
||||
</div>
|
||||
<InputError message={localErrors[name]} />
|
||||
</div>
|
||||
);
|
||||
const [content, setContent] = useState(value);
|
||||
const [version, setVersion] = useState(1);
|
||||
|
||||
function stripHtmlTags(html: string) {
|
||||
const temp = document.createElement('div');
|
||||
temp.innerHTML = html;
|
||||
const text = temp.textContent || temp.innerText || '';
|
||||
return text.trim() === '' ? null : text;
|
||||
}
|
||||
|
||||
const onChangeContent = (changedValue: string) => {
|
||||
const value = stripHtmlTags(changedValue) ? changedValue : "";
|
||||
setContent(value);
|
||||
setData(name, value);
|
||||
};
|
||||
|
||||
const customOptions: UseEditorOptions = {
|
||||
editorProps: {
|
||||
attributes: {
|
||||
required: String(required),
|
||||
id,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (content !== value) {
|
||||
setContent(value);
|
||||
setVersion(version + 1);
|
||||
}
|
||||
}, [value]);
|
||||
|
||||
return (
|
||||
<div className={cn("col-span-2", { "wysiwyg-error": localErrors[name] }, className)}>
|
||||
<Label htmlFor={name}>
|
||||
{label + (required ? " *" : "")}
|
||||
</Label>
|
||||
{wordCounter && (
|
||||
<WordCounter value={content.replace(/<[^>]*>/g, "")} />
|
||||
)}
|
||||
<div className={cn("mt-1.5", { "mb-1.5": localErrors[name] })}>
|
||||
<RichTextEditor
|
||||
// Force re-render.
|
||||
key={version}
|
||||
output="html"
|
||||
content={content}
|
||||
onChangeContent={onChangeContent}
|
||||
extensions={extensions}
|
||||
disabled={disabled}
|
||||
useEditorOptions={customOptions}
|
||||
dark={false}
|
||||
/>
|
||||
</div>
|
||||
<InputError message={localErrors[name]} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,8 +102,10 @@ export default function AppSidebar() {
|
|||
},
|
||||
{
|
||||
title: useTrans("back.your_website"),
|
||||
link: route("front.homepage"),
|
||||
show: true,
|
||||
link: route().has("front.dynamic-pages.accueil." + appEnv.locale)
|
||||
? route("front.dynamic-pages.accueil." + appEnv.locale)
|
||||
: "",
|
||||
show: route().has("front.dynamic-pages.accueil." + appEnv.locale),
|
||||
icon: SquareArrowOutUpRightIcon,
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// * Packages
|
||||
import { useForm, usePage } from "@inertiajs/react";
|
||||
import { BookTextIcon, CogIcon, EyeIcon, GavelIcon, ShieldAlertIcon } from "lucide-react";
|
||||
import { LinkIcon, BookTextIcon, CogIcon, EyeIcon, ShieldAlertIcon } from "lucide-react";
|
||||
import { route } from "ziggy-js";
|
||||
import { useEffect, useState } from "react";
|
||||
// * Components shadcn
|
||||
|
|
@ -125,6 +125,7 @@ export default function Form({
|
|||
config_id: model?.config_id ?? configOptions[defaultConfigId].id,
|
||||
status: model?.status ?? enumDynamicPageStatus.draft.value,
|
||||
isLocked: model?.isLocked ?? false,
|
||||
isRoot: model?.isRoot ?? false,
|
||||
});
|
||||
|
||||
const submit = useCrudSubmit({
|
||||
|
|
@ -227,6 +228,27 @@ export default function Form({
|
|||
selected={data.status}
|
||||
setData={setData}
|
||||
/>
|
||||
</FieldsetWrapper>
|
||||
<FieldsetWrapper
|
||||
title={useTrans("back.form_title_page_accessibility")}
|
||||
icon={<LinkIcon className="mr-1" />}
|
||||
description={useTrans("back.form_subtitle_page_accessibility")}
|
||||
className="sm:grid-cols-2 gap-4"
|
||||
>
|
||||
<div className="col-span-2">
|
||||
<SimpleSwitch
|
||||
label={str(useTrans("validation.custom.root")).ucFirst().value()}
|
||||
name="isRoot"
|
||||
checked={data.isRoot}
|
||||
setData={(name, value) => {
|
||||
setSelectedGroup(null);
|
||||
setData("page_id", null);
|
||||
setData("slug", "");
|
||||
// @ts-ignore
|
||||
setData(name, value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<ModelSelect
|
||||
name="page_id"
|
||||
targetModel="dynamic_pages"
|
||||
|
|
@ -242,21 +264,23 @@ export default function Form({
|
|||
.ucFirst()
|
||||
.value()}
|
||||
placeholder="ex: "
|
||||
selected={data.page_id}
|
||||
selected={!data.isRoot ? data.page_id : null}
|
||||
exclude={model?.id}
|
||||
required={false}
|
||||
setData={setData}
|
||||
onSelectValue={(value) => setSelectedGroup((value as DynamicPageModel).title[locale])}
|
||||
onSelectValue={(value) => setSelectedGroup((value !== null) ? (value as DynamicPageModel).title[locale] : null)}
|
||||
disabled={data.isRoot}
|
||||
/>
|
||||
<Slugifycator
|
||||
value={data.slug}
|
||||
value={!data.isRoot ? data.slug : ""}
|
||||
targetValue={data.title}
|
||||
setData={setData}
|
||||
disabled={data.isRoot}
|
||||
/>
|
||||
<div className="col-span-1 md:col-span-2">
|
||||
<GoToFrontView
|
||||
modelName={useTrans(`models.classes.${modelName}`, { choice: 1 })}
|
||||
pathField={data.slug}
|
||||
pathField={!data.isRoot ? data.slug : ""}
|
||||
additionalGroupPath={getFullSlugPath(dynamicPageModels, selectedGroup, locale) ?? undefined}
|
||||
isAvailable={model?.status === enumDynamicPageStatus.published.value}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import {
|
|||
ArchiveIcon,
|
||||
ArrowLeftIcon,
|
||||
CogIcon,
|
||||
HouseIcon,
|
||||
LockIcon,
|
||||
PlusIcon,
|
||||
StickyNoteIcon,
|
||||
|
|
@ -41,7 +42,6 @@ import {
|
|||
import str from "@/hooks/use-string";
|
||||
import useTrans from "@/hooks/use-translations";
|
||||
import DynamicStatusBadge from "@/back/Components/DynamicPages/DynamicStatusBadge";
|
||||
import { ReactNode } from "react";
|
||||
import { renderTranslationCell } from "@/lib/translationCellFallback";
|
||||
|
||||
export default function Index({
|
||||
|
|
@ -80,12 +80,21 @@ export default function Index({
|
|||
field={column.id}
|
||||
/>
|
||||
),
|
||||
cell: ({ row }: { row: Row<DynamicPageModel> }) => {
|
||||
return renderTranslationCell(
|
||||
row.getValue("title") as TranslationField
|
||||
);
|
||||
}
|
||||
|
||||
cell: ({ row }: { row: Row<DynamicPageModel> }) => (
|
||||
<div className="flex justify-center items-center">
|
||||
{renderTranslationCell(row.getValue("title") as TranslationField)}
|
||||
{row.original.isRoot && (
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<HouseIcon size={15} className="ms-1" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
{useTrans("back.page_root")}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "parent_page",
|
||||
|
|
|
|||
|
|
@ -136,6 +136,19 @@ export default function Show({ data, modelName }: { data: SingleResource, modelN
|
|||
</Badge>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "isRoot",
|
||||
header: str(useTrans("validation.custom.root")).ucFirst().value(),
|
||||
cell: ({ value }: { value: boolean }) => (
|
||||
<Badge
|
||||
variant="outline"
|
||||
className={`border-0 ${value ? "bg-green-200 dark:bg-green-900" : "bg-red-200 dark:bg-red-900"}`}
|
||||
>
|
||||
{value ? <CheckIcon size={15} className="mr-1" /> : <XIcon size={15} className="mr-1" />}
|
||||
{str(useTrans(value ? "back.yes" : "back.no")).ucFirst().value()}
|
||||
</Badge>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessorKey: "created_at",
|
||||
header: str(useTrans("validation.attributes.created_at")).ucFirst().value(),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// * Packages
|
||||
import { route } from "ziggy-js";
|
||||
import { Head, Link } from "@inertiajs/react";
|
||||
import { Head, Link, usePage } from "@inertiajs/react";
|
||||
// * Components shadcn
|
||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
|
@ -9,8 +9,10 @@ import { ThemeProvider } from "@/back/providers/ThemeProvider";
|
|||
import AppFooter from "@/back/Components/Layout/AppFooter";
|
||||
import ApplicationLogo from "@/back/Components/ApplicationLogo";
|
||||
import useTrans from "@/hooks/use-translations";
|
||||
import { AppEnv } from "@/back/types/global";
|
||||
|
||||
export default function Default({ status }: { status: number }) {
|
||||
const { locale } = usePage().props.appEnv as AppEnv;
|
||||
return (
|
||||
<ThemeProvider defaultTheme="light" storageKey="vite-ui-theme">
|
||||
<TooltipProvider>
|
||||
|
|
@ -31,7 +33,7 @@ export default function Default({ status }: { status: number }) {
|
|||
</Link>
|
||||
</Button>
|
||||
<Button variant="outline" asChild>
|
||||
<a href={route("front.homepage")}>
|
||||
<a href={route("front.dynamic-pages.accueil." + locale)}>
|
||||
{useTrans("back.your_website")}
|
||||
</a>
|
||||
</Button>
|
||||
|
|
|
|||
2
resources/ts/back/types/global.d.ts
vendored
2
resources/ts/back/types/global.d.ts
vendored
|
|
@ -55,6 +55,7 @@ type ActivityLogModel = {
|
|||
type DynamicPageModel = {
|
||||
policies: ModelPolicy;
|
||||
id: number;
|
||||
id_key: string;
|
||||
title: TranslationField;
|
||||
slug: TranslationField;
|
||||
content: TranslationField<string | boolean | number> | null;
|
||||
|
|
@ -62,6 +63,7 @@ type DynamicPageModel = {
|
|||
config_id: number;
|
||||
status: number;
|
||||
isLocked: boolean;
|
||||
isRoot: boolean;
|
||||
created_at: Date;
|
||||
updated_at: Date;
|
||||
deleted_at: Date;
|
||||
|
|
|
|||
|
|
@ -41,10 +41,10 @@
|
|||
<div class="{{ $wrapperClasses }}">
|
||||
<div class="{{ $containerClasses }}">
|
||||
<div class="swiper-wrapper">
|
||||
@foreach ($brands as $b)
|
||||
@foreach ($brands as $brand)
|
||||
<div class="swiper-slide">
|
||||
<a class="brands-list__item" href="{{ isset($b['link']) ? $b['link'] : '' }}"
|
||||
title="Nos marques"><img src="{{ $b['image']['url'] }}" alt="Nos marques" /></a>
|
||||
<a class="brands-list__item" href="{{ isset($brand['link']) ? $brand['link'] : '' }}"
|
||||
title="Nos marques"><img src="{{ $brand['image']['url'] }}" alt="Nos marques" /></a>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@
|
|||
{{-- # FIXME --}}
|
||||
<span>Pour toute information complémentaire concernant vos données personnelles et vos
|
||||
droits, merci de consulter notre <a class="cn-link"
|
||||
href="{{ route('front.politique-de-confidentialite') }}">Charte de
|
||||
href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamique-pages.politique-de-confidentialite') }}">Charte de
|
||||
confidentialité</a>.</span>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
@if ($breadcrumbs->isNotEmpty() && request()->route()->getName() !== 'front.homepage')
|
||||
@if ($breadcrumbs->isNotEmpty() && request()->route()->getName() !== 'front.dynamic-pages.accueil.' . app()->getLocale())
|
||||
<div class="breadcrumbs fw">
|
||||
<div class="breadcrumbs__wrapper wrapper">
|
||||
@foreach ($breadcrumbs as $breadcrumb)
|
||||
|
|
|
|||
|
|
@ -83,7 +83,8 @@
|
|||
<div class="footer__copyright copyright wrapper">
|
||||
<a class="copyright__item" href="/mentions-legales/" title="Mentions légales">Mentions légales et CGU</a>
|
||||
<span class="copyright__item">-</span>
|
||||
<a class="copyright__item" href="{{ route('front.politique-de-confidentialite') }}" title="Politique de confidentialité">Politique de confidentialité</a>
|
||||
<a class="copyright__item" href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamique-pages.politique-de-confidentialite') }}"
|
||||
title="Politique de confidentialité">Politique de confidentialité</a>
|
||||
<span class="copyright__item">-</span>
|
||||
<a class="copyright__item cn-cookie-link" href="#" title="Gestion des cookies">Gestion des cookies</a>
|
||||
<span class="copyright__item">-</span>
|
||||
|
|
|
|||
|
|
@ -14,8 +14,18 @@
|
|||
</form>
|
||||
</div>
|
||||
<div class="top-menu__item top-menu__item_lang langs">
|
||||
{{-- FIXME: Ici, le lien vers l'autre langue dispo est affiché. Si on est en fr, c'est EN et inversement --}}
|
||||
<a class="langs__item" href="/en/">EN</a>
|
||||
@foreach (LaravelLocalization::getSupportedLocales() as $localeCode => $properties)
|
||||
@if (!$loop->first)
|
||||
<span class="langs__separator"> / </span>
|
||||
@endif
|
||||
@php
|
||||
$url = \App\Helpers\RouteHelper::getLocalizedUrl($localeCode);
|
||||
@endphp
|
||||
<a rel="alternate" hreflang="{{ $localeCode }}" href="{{ $url }}"
|
||||
class="langs__item {{ app()->getLocale() === $localeCode ? 'active' : '' }}">
|
||||
{{ strtoupper($localeCode) }}
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -222,8 +232,9 @@
|
|||
<div class="mobile-menu__block mobile-menu__block_sub" data-menu="submenu-2951">
|
||||
<div class="mobile-menu__block-title">
|
||||
<div class="mobile-menu__block-close"></div>
|
||||
<a
|
||||
href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.nous-rejoindre') }}">{{ $pageNousRejoindre->title }}</a>
|
||||
<a href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.nous-rejoindre') }}">
|
||||
{{ $pageNousRejoindre->title }}
|
||||
</a>
|
||||
</div>
|
||||
<ul class="mobile-menu__level">
|
||||
<div class="offer__block offer__block_main offer-main">
|
||||
|
|
@ -248,108 +259,112 @@
|
|||
<a class="offer-link"
|
||||
href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.nos-metiers') }}"
|
||||
title="Découvrez nos métiers">
|
||||
<span class="offer-link__text"><b>{{ $pageNosMetiers->title }}</b><br>Découvrez nos
|
||||
métiers</span>
|
||||
<span class="offer-link__text">
|
||||
<b>{{ $pageNosMetiers->title }}</b>
|
||||
<br>Découvrez nos métiers
|
||||
</span>
|
||||
<i class="icon__arrow-right icon__arrow-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="offer-form-wrap">
|
||||
<div class="offer-form">
|
||||
<form class="form form_small" method="POST" id="dr-form">
|
||||
<div class="form__container">
|
||||
<div class="form__text">Activez les alertes pour recevoir par email les nouvelles offres
|
||||
correspondant à vos critères</div>
|
||||
<div class="form__field">
|
||||
<div class="form__field-title">Métier</div>
|
||||
<select id="dr-metiers" name="metiers" class="form__input" required="">
|
||||
<option value="all">Tous les métiers</option>
|
||||
<option value="35565">Achats - Approvisionnement</option>
|
||||
<option value="35571">Administratif - Secrétariat</option>
|
||||
<option value="35568">Commerce</option>
|
||||
<option value="35574">Gestion - Finance - Juridique</option>
|
||||
<option value="35577">Industriel</option>
|
||||
<option value="35580">Informatique</option>
|
||||
<option value="35583">Logistique</option>
|
||||
<option value="35586">Maintenance - Technique</option>
|
||||
<option value="35562">Marketing</option>
|
||||
<option value="35589">Planification Ordonnancement</option>
|
||||
<option value="35592">Production</option>
|
||||
<option value="127925">Production Animale Amont</option>
|
||||
<option value="35595">Qualité - Sécurité - Environnement</option>
|
||||
<option value="35598">R&D</option>
|
||||
<option value="35601">Ressources Humaines</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form__field">
|
||||
<div class="form__field-title">Type de contrat</div>
|
||||
<select id="dr-contrats" name="contrats"
|
||||
class="wpcf7-form-control wpcf7-select form__input" required="">
|
||||
<option value="all">Tous les types de contrats</option>
|
||||
<option value="2">CDD</option>
|
||||
<option value="1">CDI</option>
|
||||
<option value="9">Contrat d'alternance (pro, apprentissage)</option>
|
||||
<option value="4">Interim</option>
|
||||
<option value="3">Stage</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form__field">
|
||||
<div class="form__field-title">Temps de travail</div>
|
||||
<select id="dr-temps" name="temps"
|
||||
class="wpcf7-form-control wpcf7-select form__input" required="">
|
||||
<option value="all">Tous les temps de travail</option>
|
||||
<option value="2">Temps partiel</option>
|
||||
<option value="1">Temps plein</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form__field">
|
||||
<div class="form__field-title">Email*</div>
|
||||
<input id="dr-email" type="email" name="Email" size="40"
|
||||
class="form__input" required="">
|
||||
</div>
|
||||
<div class="form__field">
|
||||
<div class="form__field-label">
|
||||
<label class="form__field-pseudolabel">
|
||||
<input id="dr-agree" type="checkbox" name="agree" required="">
|
||||
<span class="form__field-pseudosquare"></span>
|
||||
<span class="form__field-label-text">J’ai lu et accepté la politique de
|
||||
confidentialité du site LDC, les conditions d’utilisation et son utilisation
|
||||
des cookies.<br>Lire <a
|
||||
href="{{ route('front.politique-de-confidentialite') }}"
|
||||
target="_blank" rel="noreferer noopener">la politique de
|
||||
confidentialité</a></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="offer__block offer-anchors">
|
||||
<a class="anchor-scroll"
|
||||
href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.nous-rejoindre') }}#rejoin_0">Plus
|
||||
de 130 métiers diversifiés</a>
|
||||
<a class="anchor-scroll"
|
||||
href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.nous-rejoindre') }}#rejoin_1">Votre
|
||||
parcours chez LDC</a>
|
||||
<a class="anchor-scroll"
|
||||
href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.nous-rejoindre') }}#rejoin_2">Notre
|
||||
politique Ressources Humaines</a>
|
||||
<a class="anchor-scroll"
|
||||
href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.nous-rejoindre') }}#rejoin_3">Votre
|
||||
bien-être, notre préoccupation</a>
|
||||
<a class="anchor-scroll"
|
||||
href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.nous-rejoindre') }}#rejoin_4">Nos
|
||||
évènements forum et job dating</a>
|
||||
<a class="anchor-scroll"
|
||||
href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.nous-rejoindre') }}#rejoin_5">Ecoles,
|
||||
visitez-nous</a>
|
||||
<a class="anchor-scroll"
|
||||
href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.nous-rejoindre') }}#rejoin_6">Eleveurs,
|
||||
rejoignez-nous</a>
|
||||
</div>
|
||||
<div class="offer-form-wrap">
|
||||
<div class="offer-form">
|
||||
<form class="form form_small" method="POST" id="dr-form">
|
||||
<div class="form__container">
|
||||
<div class="form__text">Activez les alertes pour recevoir par email les nouvelles offres
|
||||
correspondant à vos critères</div>
|
||||
<div class="form__field">
|
||||
<div class="form__field-title">Métier</div>
|
||||
<select id="dr-metiers" name="metiers" class="form__input" required="">
|
||||
<option value="all">Tous les métiers</option>
|
||||
<option value="35565">Achats - Approvisionnement</option>
|
||||
<option value="35571">Administratif - Secrétariat</option>
|
||||
<option value="35568">Commerce</option>
|
||||
<option value="35574">Gestion - Finance - Juridique</option>
|
||||
<option value="35577">Industriel</option>
|
||||
<option value="35580">Informatique</option>
|
||||
<option value="35583">Logistique</option>
|
||||
<option value="35586">Maintenance - Technique</option>
|
||||
<option value="35562">Marketing</option>
|
||||
<option value="35589">Planification Ordonnancement</option>
|
||||
<option value="35592">Production</option>
|
||||
<option value="127925">Production Animale Amont</option>
|
||||
<option value="35595">Qualité - Sécurité - Environnement</option>
|
||||
<option value="35598">R&D</option>
|
||||
<option value="35601">Ressources Humaines</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form__field">
|
||||
<div class="form__field-title">Type de contrat</div>
|
||||
<select id="dr-contrats" name="contrats"
|
||||
class="wpcf7-form-control wpcf7-select form__input" required="">
|
||||
<option value="all">Tous les types de contrats</option>
|
||||
<option value="2">CDD</option>
|
||||
<option value="1">CDI</option>
|
||||
<option value="9">Contrat d'alternance (pro, apprentissage)</option>
|
||||
<option value="4">Interim</option>
|
||||
<option value="3">Stage</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form__field">
|
||||
<div class="form__field-title">Temps de travail</div>
|
||||
<select id="dr-temps" name="temps"
|
||||
class="wpcf7-form-control wpcf7-select form__input" required="">
|
||||
<option value="all">Tous les temps de travail</option>
|
||||
<option value="2">Temps partiel</option>
|
||||
<option value="1">Temps plein</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form__field">
|
||||
<div class="form__field-title">Email*</div>
|
||||
<input id="dr-email" type="email" name="Email" size="40"
|
||||
class="form__input" required="">
|
||||
</div>
|
||||
<div class="form__field">
|
||||
<div class="form__field-label">
|
||||
<label class="form__field-pseudolabel">
|
||||
<input id="dr-agree" type="checkbox" name="agree" required="">
|
||||
<span class="form__field-pseudosquare"></span>
|
||||
<span class="form__field-label-text">J’ai lu et accepté la politique de
|
||||
confidentialité du site LDC, les conditions d’utilisation et son utilisation
|
||||
des cookies.<br>Lire <a
|
||||
href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamique-pages.politique-de-confidentialite') }}"
|
||||
target="_blank" rel="noreferer noopener">
|
||||
la politique de confidentialité
|
||||
</a>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="offer__block offer-anchors">
|
||||
<a class="anchor-scroll"
|
||||
href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.nous-rejoindre') }}#rejoin_0">Plus
|
||||
de 130 métiers diversifiés</a>
|
||||
<a class="anchor-scroll"
|
||||
href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.nous-rejoindre') }}#rejoin_1">Votre
|
||||
parcours chez LDC</a>
|
||||
<a class="anchor-scroll"
|
||||
href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.nous-rejoindre') }}#rejoin_2">Notre
|
||||
politique Ressources Humaines</a>
|
||||
<a class="anchor-scroll"
|
||||
href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.nous-rejoindre') }}#rejoin_3">Votre
|
||||
bien-être, notre préoccupation</a>
|
||||
<a class="anchor-scroll"
|
||||
href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.nous-rejoindre') }}#rejoin_4">Nos
|
||||
évènements forum et job dating</a>
|
||||
<a class="anchor-scroll"
|
||||
href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.nous-rejoindre') }}#rejoin_5">Ecoles,
|
||||
visitez-nous</a>
|
||||
<a class="anchor-scroll"
|
||||
href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.nous-rejoindre') }}#rejoin_6">Eleveurs,
|
||||
rejoignez-nous</a>
|
||||
</div>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@if (isset($pageFinance))
|
||||
<div class="mobile-menu__block mobile-menu__block_sub" data-menu="submenu-2943">
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
@section('content')
|
||||
<h1>{{ sprintf("%s - %s", $status, trans("errors.$status.title")) }}</h1>
|
||||
<p>{{ trans("errors.$status.description") }}</p>
|
||||
<a href="{{ route('front.homepage') }}">
|
||||
Revenir à la page d'accueil
|
||||
<a href="{{ \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.accueil') }}">
|
||||
{{ trans("front.back_to_homepage") }}
|
||||
</a>
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -1,674 +1,130 @@
|
|||
@extends('front.layouts.layout')
|
||||
|
||||
@section('title', 'Accueil - LDC Le Groupe LDC, groupe agroalimentaire responsable')
|
||||
@section('description', 'LDC, un groupe responsable parmi les leaders européens de la volaille et du traiteur,
|
||||
ancré dans les territoires et reconnu pour la qualité de ses produits.')
|
||||
@section('title', data_get($dynamicPageModel, 'content.list_seo_fields.0.string_seo_title'))
|
||||
@section('description', data_get($dynamicPageModel, 'content.list_seo_fields.0.textarea_seo_description'))
|
||||
|
||||
@section('content')
|
||||
|
||||
@php
|
||||
global $mob;
|
||||
$mob = false;
|
||||
|
||||
$hero = [
|
||||
[
|
||||
'title' => 'BIENVENUE CHEZ LDC',
|
||||
'subtitle' => 'LDC, un Groupe familial parmi les leaders européens de la volaille et du traiteur',
|
||||
'text' => '',
|
||||
'button' => '',
|
||||
'video_?' => true,
|
||||
'video_file' => '/assets/uploads/2023/06/Publicité-marque-LDC.mp4',
|
||||
'image' => '/assets/uploads/2020/02/homepage_hero.jpg',
|
||||
'image_borders' => [
|
||||
'desktop' => [
|
||||
'left' => true,
|
||||
'right' => true,
|
||||
'top' => true,
|
||||
'bottom' => true,
|
||||
], 'mobile' => [
|
||||
'left' => false,
|
||||
'right' => false,
|
||||
'top' => false,
|
||||
'bottom' => true,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
@endphp
|
||||
<x-front.hero :hero="$hero" />
|
||||
|
||||
<?php
|
||||
|
||||
// FIXME: Pas de données en PROD, on garde ou ça dégage ?
|
||||
|
||||
// $add_block = get_field('additional_video_text');
|
||||
// if (!empty($add_block) && $add_block['text_block'] !== NULL) {
|
||||
// set_query_var('text_block', $add_block['text_block']);
|
||||
// set_query_var('addclass', 'no-bottom-padding');
|
||||
// get_template_part('partials/text-block');
|
||||
// }
|
||||
?>
|
||||
|
||||
{{-- VIDEO --}}
|
||||
@php
|
||||
$video = [
|
||||
'show_block' => true,
|
||||
'title' => 'Présentation',
|
||||
'subtitle' => [
|
||||
'text' => 'Du Groupe LDC',
|
||||
'cursive' => true,
|
||||
],
|
||||
'video' => 't6w2stRvDH8',
|
||||
'type_video' => 'youtube',
|
||||
'texte' => ''
|
||||
];
|
||||
@endphp
|
||||
<x-front.videobloc :video="$video" />
|
||||
@if (isset($dynamicPageModel->content['list_section_presentation']))
|
||||
@php
|
||||
$video = [
|
||||
'show_block' => true,
|
||||
'title' => $dynamicPageModel->content['list_section_presentation'][0]['string_title'],
|
||||
'subtitle' => [
|
||||
'text' => $dynamicPageModel->content['list_section_presentation'][0]['string_subtitle'],
|
||||
'cursive' => true,
|
||||
],
|
||||
'video' => isset($dynamicPageModel->content['list_section_presentation'][0]['youtubeid_video'])
|
||||
? $dynamicPageModel->content['list_section_presentation'][0]['youtubeid_video']
|
||||
: $dynamicPageModel->content['list_section_presentation'][0]['vimeoid_video'],
|
||||
'type_video' => isset($dynamicPageModel->content['list_section_presentation'][0]['youtubeid_video']) ? 'youtube' : 'vimeo',
|
||||
'texte' => ''
|
||||
];
|
||||
@endphp
|
||||
<x-front.videobloc :video="$video" />
|
||||
@endif
|
||||
|
||||
{{-- ENGAGEMENTS --}}
|
||||
@php
|
||||
$engagements = [
|
||||
'title' => 'Nos engagements',
|
||||
'subtitle' => '', 'text' => 'Ancré dans les territoires, soucieux de préserver les filières locales et de
|
||||
valoriser l’origine nationale, LDC s’organise pour répondre avec pragmatisme aux enjeux de demain via 4 engagements
|
||||
prioritaires : Élever Durablement, Mieux Vivre Ensemble, Respecter la Terre, Bien Nourrir.',
|
||||
'button' => [
|
||||
'title' => 'Nos engagements',
|
||||
'url' => \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.nos-engagements'),
|
||||
'target' => '',
|
||||
],
|
||||
];
|
||||
@endphp
|
||||
<x-front.commitments.wrapper :engagements="$engagements" />
|
||||
@if(isset($pageNosEngagements))
|
||||
@php
|
||||
$engagements = [
|
||||
'title' => $pageNosEngagements->title,
|
||||
'subtitle' => '',
|
||||
'text' => $dynamicPageModel->content['list_section_our_commitments'][0]['wysiwyg_content'],
|
||||
'button' => [
|
||||
'title' => $pageNosEngagements->title,
|
||||
'url' => \App\Helpers\RouteHelper::routeNameChecker("front.dynamic-pages.$pageNosEngagements->id_key"),
|
||||
'target' => '',
|
||||
],
|
||||
];
|
||||
@endphp
|
||||
<x-front.commitments.wrapper :engagements="$engagements" />
|
||||
@endif
|
||||
|
||||
{{-- KEY FIGURES --}}
|
||||
<x-front.key-figures :keyFigures="[]" />
|
||||
@if(isset($pageNousConnaitre))
|
||||
<x-front.key-figures :keyFigures="$pageNousConnaitre->content['list_section_key_figures'][0]" />
|
||||
@endif
|
||||
|
||||
{{-- VALUES --}}
|
||||
<x-front.values title="" :list="[]" />
|
||||
@if(isset($pageNousConnaitre))
|
||||
<x-front.values :title="$pageNousConnaitre->content['list_section_our_values'][0]['string_title']"
|
||||
:list="$pageNousConnaitre->content['list_section_our_values'][0]['list_values']" />
|
||||
@endif
|
||||
|
||||
{{-- TEXT BLOCK --}}
|
||||
@php
|
||||
$text_block = [
|
||||
$blocks = [
|
||||
'hide_block' => false,
|
||||
'title' => 'Ensemble',
|
||||
'title' => $dynamicPageModel->content['list_section_together'][0]['string_title'],
|
||||
'subtitle' => [
|
||||
'text' => 'Cultivons notre avenir',
|
||||
'text' => $dynamicPageModel->content['list_section_together'][0]['string_subtitle'],
|
||||
'cursive' => true,
|
||||
],
|
||||
'bg' => true,
|
||||
'list' => [
|
||||
[
|
||||
'swap_position' => true,
|
||||
'in_row' => false,
|
||||
'floated' => false,
|
||||
'align_center' => false,
|
||||
'quote' => false,
|
||||
'quote_author' => '',
|
||||
'title' => 'Vous souhaitez exercer vos talents ? Rejoignez-nous !',
|
||||
'text' => 'Vous avez le goût de l’initiative et souhaitez intégrer une entreprise qui vous
|
||||
fasse confiance ?
|
||||
Vous recherchez une entreprise conviviale, engagée et innovante qui vous encourage à exprimer vos
|
||||
idées et à partager ce qui vous anime ?
|
||||
Rejoignez-nous !',
|
||||
'button' => [
|
||||
'title' => 'Nous rejoindre',
|
||||
'url' => 'https://recrutement.ldc.fr/fr/annonces',
|
||||
'target' => '_blank',
|
||||
],
|
||||
'button_icon' => 'btn__icon_arrow-right',
|
||||
'image' => [
|
||||
[
|
||||
'ID' => 14287,
|
||||
'id' => 14287,
|
||||
'title' => 'REJOIGNEZ-NOUS_2025',
|
||||
'filename' => 'REJOIGNEZ-NOUS_2025.jpg',
|
||||
'filesize' => 0,
|
||||
'url' => '/assets/uploads/2025/01/REJOIGNEZ-NOUS_2025.jpg',
|
||||
'link' => '/rejoignez-nous_2025/',
|
||||
'alt' => 'Rejoignez-nous : nous recrutons !',
|
||||
'author' => '8',
|
||||
'description' => 'Rejoignez-nous : nous recrutons !',
|
||||
'caption' => 'Rejoignez-nous : nous recrutons !',
|
||||
'name' => 'rejoignez-nous_2025',
|
||||
'status' => 'inherit',
|
||||
'uploaded_to' => 0,
|
||||
'date' => '2025-01-07 14:27:24',
|
||||
'modified' => '2025-01-07 14:28:13',
|
||||
'menu_order' => 0,
|
||||
'mime_type' => 'image/jpeg',
|
||||
'type' => 'image',
|
||||
'subtype' => 'jpeg',
|
||||
'icon' => '/wp/wp-includes/images/media/default.png',
|
||||
'width' => 600,
|
||||
'height' => 400,
|
||||
'sizes' => [
|
||||
'thumbnail' => '/assets/uploads/2025/01/REJOIGNEZ-NOUS_2025-150x150.jpg',
|
||||
'thumbnail-width' => 150,
|
||||
'thumbnail-height' => 150,
|
||||
'medium' => '/assets/uploads/2025/01/REJOIGNEZ-NOUS_2025-300x200.jpg',
|
||||
'medium-width' => 300,
|
||||
'medium-height' => 200,
|
||||
'medium_large' => '/assets/uploads/2025/01/REJOIGNEZ-NOUS_2025.jpg',
|
||||
'medium_large-width' => 600,
|
||||
'medium_large-height' => 400,
|
||||
'large' => '/assets/uploads/2025/01/REJOIGNEZ-NOUS_2025.jpg',
|
||||
'large-width' => 600,
|
||||
'large-height' => 400,
|
||||
'1536x1536' => '/assets/uploads/2025/01/REJOIGNEZ-NOUS_2025.jpg',
|
||||
'1536x1536-width' => 600,
|
||||
'1536x1536-height' => 400,
|
||||
'2048x2048' => '/assets/uploads/2025/01/REJOIGNEZ-NOUS_2025.jpg',
|
||||
'2048x2048-width' => 600,
|
||||
'2048x2048-height' => 400,
|
||||
'post-thumbnail' => '/assets/uploads/2025/01/REJOIGNEZ-NOUS_2025-360x240.jpg',
|
||||
'post-thumbnail-width' => 360,
|
||||
'post-thumbnail-height' => 240,
|
||||
'alm-thumbnail' => '/assets/uploads/2025/01/REJOIGNEZ-NOUS_2025-150x150.jpg',
|
||||
'alm-thumbnail-width' => 150,
|
||||
'alm-thumbnail-height' => 150,
|
||||
],
|
||||
],
|
||||
],
|
||||
'image_description' => '',
|
||||
'video' => NULL,
|
||||
'borders_desktop' => [
|
||||
'left' => true,
|
||||
'right' => true,
|
||||
'top' => true,
|
||||
'bottom' => true,
|
||||
],
|
||||
'borders_mobile' => [
|
||||
'left' => true,
|
||||
'right' => true,
|
||||
'top' => true,
|
||||
'bottom' => true,
|
||||
],
|
||||
],
|
||||
[
|
||||
'swap_position' => false,
|
||||
'in_row' => false,
|
||||
'floated' => false,
|
||||
'align_center' => false,
|
||||
'quote' => false,
|
||||
'quote_author' => '',
|
||||
'title' => 'Éleveurs, rejoignez-nous !',
|
||||
'text' => 'Nos éleveurs sont des femmes et des hommes responsables et passionnés par leur travail et
|
||||
leurs animaux, avec lesquels le Groupe LDC entretient une relation de confiance depuis près de 50 ans.
|
||||
Nos éleveurs respectent les différents cahiers des charges et leurs engagements (respect des animaux
|
||||
et de l’environnement, transparence, contrôles par des organismes tiers…], et le Groupe protège leur
|
||||
revenu via la contractualisation (fixation des prix, sécurisation des approvisionnements et débouchés)
|
||||
et l’accompagnement technique (conseil par des spécialistes de l’élevage, formations, audits qualité…).
|
||||
Pour développer durablement l’élevage, le Groupe s’appuie historiquement sur les démarches sous signes
|
||||
officiels de qualité (Label Rouge, Appellation d’origine contrôlée, Agriculture Biologique) pour les
|
||||
volailles élevées en plein-air, sur la Certification Conformité Produit, et depuis 2017 sur notre
|
||||
démarche éthique « Nature d’Eleveurs » pour les volailles certifiées et les volailles du quotidien.',
|
||||
'button' => [
|
||||
'title' => 'Nous rejoindre en tant qu\'éleveur',
|
||||
'url' => 'https://www.ldc.fr/nous-contacter/nous-rejoindre-en-tant-queleveur/',
|
||||
'target' => '_blank',
|
||||
],
|
||||
'button_icon' => 'btn__icon_arrow-right',
|
||||
'image' => [
|
||||
[
|
||||
'ID' => 6779,
|
||||
'id' => 6779,
|
||||
'title' => 'ELEVEURS-REJOIGNEZ-NOUS2',
|
||||
'filename' => 'ELEVEURS-REJOIGNEZ-NOUS2.jpg',
|
||||
'filesize' => 0,
|
||||
'url' => '/assets/uploads/2020/10/ELEVEURS-REJOIGNEZ-NOUS2.jpg',
|
||||
'link' => '/accueil/eleveurs-rejoignez-nous2/',
|
||||
'alt' => 'Une éleveuse et sa volaille dans son jardin.',
|
||||
'author' => '8',
|
||||
'description' => 'Une éleveuse et sa volaille dans son jardin.',
|
||||
'caption' => 'ELEVEURS-REJOIGNEZ-NOUS2',
|
||||
'name' => 'eleveurs-rejoignez-nous2',
|
||||
'status' => 'inherit',
|
||||
'uploaded_to' => 339,
|
||||
'date' => '2020-10-21 13:04:12',
|
||||
'modified' => '2020-10-21 13:05:07',
|
||||
'menu_order' => 0,
|
||||
'mime_type' => 'image/jpeg',
|
||||
'type' => 'image',
|
||||
'subtype' => 'jpeg',
|
||||
'icon' => '/wp/wp-includes/images/media/default.png',
|
||||
'width' => 500,
|
||||
'height' => 281,
|
||||
'sizes' => [
|
||||
'thumbnail' => '/assets/uploads/2020/10/ELEVEURS-REJOIGNEZ-NOUS2-150x150.jpg',
|
||||
'thumbnail-width' => 150,
|
||||
'thumbnail-height' => 150,
|
||||
'medium' => '/assets/uploads/2020/10/ELEVEURS-REJOIGNEZ-NOUS2-300x169.jpg',
|
||||
'medium-width' => 300,
|
||||
'medium-height' => 169,
|
||||
'medium_large' => '/assets/uploads/2020/10/ELEVEURS-REJOIGNEZ-NOUS2.jpg',
|
||||
'medium_large-width' => 500,
|
||||
'medium_large-height' => 281,
|
||||
'large' => '/assets/uploads/2020/10/ELEVEURS-REJOIGNEZ-NOUS2.jpg',
|
||||
'large-width' => 500,
|
||||
'large-height' => 281,
|
||||
'1536x1536' => '/assets/uploads/2020/10/ELEVEURS-REJOIGNEZ-NOUS2.jpg',
|
||||
'1536x1536-width' => 500,
|
||||
'1536x1536-height' => 281,
|
||||
'2048x2048' => '/assets/uploads/2020/10/ELEVEURS-REJOIGNEZ-NOUS2.jpg',
|
||||
'2048x2048-width' => 500,
|
||||
'2048x2048-height' => 281,
|
||||
'post-thumbnail' => '/assets/uploads/2020/10/ELEVEURS-REJOIGNEZ-NOUS2-412x232.jpg',
|
||||
'post-thumbnail-width' => 412,
|
||||
'post-thumbnail-height' => 232,
|
||||
'alm-thumbnail' => '/assets/uploads/2020/10/ELEVEURS-REJOIGNEZ-NOUS2-150x150.jpg',
|
||||
'alm-thumbnail-width' => 150,
|
||||
'alm-thumbnail-height' => 150,
|
||||
],
|
||||
],
|
||||
],
|
||||
'image_description' => '',
|
||||
'video' => NULL,
|
||||
'borders_desktop' => [
|
||||
'left' => true,
|
||||
'right' => true,
|
||||
'top' => true,
|
||||
'bottom' => true,
|
||||
],
|
||||
'borders_mobile' => [
|
||||
'left' => true,
|
||||
'right' => true,
|
||||
'top' => true,
|
||||
'bottom' => true,
|
||||
],
|
||||
],
|
||||
],
|
||||
'list' => [],
|
||||
];
|
||||
|
||||
foreach($dynamicPageModel->content['list_section_together'][0]['list_content_block'] as $keyContent => $content) {
|
||||
$positionMedium = intval($content['list_medium'][0]['position_medium']);
|
||||
array_push($blocks['list'], [
|
||||
'title' => $content['string_title'] ?? null,
|
||||
'text' => $content['wysiwyg_description'],
|
||||
'quote' => 0,
|
||||
'swap_position' => $positionMedium === \App\Enums\ElementPositionEnum::showbottom->value()
|
||||
? true
|
||||
: $positionMedium === \App\Enums\ElementPositionEnum::showright->value(),
|
||||
'in_row' => $positionMedium === \App\Enums\ElementPositionEnum::showbottom->value(),
|
||||
'floated' => 0,
|
||||
'align_center' => 1,
|
||||
'borders_desktop' => [
|
||||
'left' => true,
|
||||
'right' => true,
|
||||
'top' => true,
|
||||
'bottom' => true,
|
||||
],
|
||||
'borders_mobile' => [
|
||||
'left' => true,
|
||||
'right' => true,
|
||||
'top' => true,
|
||||
'bottom' => true,
|
||||
],
|
||||
'image' => [
|
||||
[
|
||||
'url' => $content['list_medium'][0]['image_picture'],
|
||||
'alt' => $content['list_medium'][0]['string_alt'],
|
||||
],
|
||||
],
|
||||
'button' => [
|
||||
'title' => $content['list_button'][0]['string_label'],
|
||||
'url' => $content['list_button'][0]['url_link'],
|
||||
'target' => '_blank',
|
||||
],
|
||||
'button_icon' => 'btn__icon_arrow-right',
|
||||
]);
|
||||
}
|
||||
@endphp
|
||||
|
||||
<x-front.text-block :textBlock="$text_block" />
|
||||
<x-front.text-block :textBlock="$blocks" />
|
||||
|
||||
{{-- BRANDS --}}
|
||||
@php
|
||||
$brands = [
|
||||
[
|
||||
'image' => [
|
||||
'ID' => 10154,
|
||||
'id' => 10154,
|
||||
'title' => 'Lg-site-web-ldc-255x255',
|
||||
'filename' => 'Lg-site-web-ldc-255x255-1.png',
|
||||
'filesize' => 0,
|
||||
'url' => '/assets/uploads/2021/05/Lg-site-web-ldc-255x255-1.png',
|
||||
'link' => '/lg-site-web-ldc-255x255/',
|
||||
'alt' => '',
|
||||
'author' => '8',
|
||||
'description' => '',
|
||||
'caption' => '',
|
||||
'name' => 'lg-site-web-ldc-255x255',
|
||||
'status' => 'inherit',
|
||||
'uploaded_to' => 0,
|
||||
'date' => '2021-05-10 12:27:55',
|
||||
'modified' => '2021-05-10 12:27:55',
|
||||
'menu_order' => 0,
|
||||
'mime_type' => 'image/png',
|
||||
'type' => 'image',
|
||||
'subtype' => 'png',
|
||||
'icon' => '/wp/wp-includes/images/media/default.png',
|
||||
'width' => 255,
|
||||
'height' => 255,
|
||||
'sizes' => [
|
||||
'thumbnail' => '/assets/uploads/2021/05/Lg-site-web-ldc-255x255-1-150x150.png',
|
||||
'thumbnail-width' => 150,
|
||||
'thumbnail-height' => 150,
|
||||
'medium' => '/assets/uploads/2021/05/Lg-site-web-ldc-255x255-1.png',
|
||||
'medium-width' => 255,
|
||||
'medium-height' => 255,
|
||||
'medium_large' => '/assets/uploads/2021/05/Lg-site-web-ldc-255x255-1.png',
|
||||
'medium_large-width' => 255,
|
||||
'medium_large-height' => 255,
|
||||
'large' => '/assets/uploads/2021/05/Lg-site-web-ldc-255x255-1.png',
|
||||
'large-width' => 255,
|
||||
'large-height' => 255,
|
||||
'1536x1536' => '/assets/uploads/2021/05/Lg-site-web-ldc-255x255-1.png',
|
||||
'1536x1536-width' => 255,
|
||||
'1536x1536-height' => 255,
|
||||
'2048x2048' => '/assets/uploads/2021/05/Lg-site-web-ldc-255x255-1.png',
|
||||
'2048x2048-width' => 255,
|
||||
'2048x2048-height' => 255,
|
||||
'post-thumbnail' => '/assets/uploads/2021/05/Lg-site-web-ldc-255x255-1-240x240.png',
|
||||
'post-thumbnail-width' => 240,
|
||||
'post-thumbnail-height' => 240,
|
||||
'alm-thumbnail' => '/assets/uploads/2021/05/Lg-site-web-ldc-255x255-1-150x150.png',
|
||||
'alm-thumbnail-width' => 150,
|
||||
'alm-thumbnail-height' => 150,
|
||||
$brands = [];
|
||||
if (
|
||||
isset($pageNosMarques)
|
||||
&& isset($pageNosMarques->content['list_our_big_brands'])
|
||||
&& isset($pageNosMarques->content['list_our_big_brands'][0]['list_brands'])
|
||||
) {
|
||||
foreach ($pageNosMarques->content['list_our_big_brands'][0]['list_brands'] as $key => $logo) {
|
||||
array_push($brands, [
|
||||
'image' => [
|
||||
'url' => asset($logo['list_logo'][0]['image_brand_logo']),
|
||||
],
|
||||
],
|
||||
'link' => '/nos-marques/#brand_1_1',
|
||||
],
|
||||
[
|
||||
'image' => [
|
||||
'ID' => 5507,
|
||||
'id' => 5507,
|
||||
'title' => 'LOUE-2020',
|
||||
'filename' => 'LOUE-2020.png',
|
||||
'filesize' => 0,
|
||||
'url' => '/assets/uploads/2020/06/LOUE-2020.png',
|
||||
'link' => '/loue-2020/',
|
||||
'alt' => '',
|
||||
'author' => '7',
|
||||
'description' => '',
|
||||
'caption' => '',
|
||||
'name' => 'loue-2020',
|
||||
'status' => 'inherit',
|
||||
'uploaded_to' => 0,
|
||||
'date' => '2020-06-25 12:15:31',
|
||||
'modified' => '2020-06-25 12:15:31',
|
||||
'menu_order' => 0,
|
||||
'mime_type' => 'image/png',
|
||||
'type' => 'image',
|
||||
'subtype' => 'png',
|
||||
'icon' => '/wp/wp-includes/images/media/default.png',
|
||||
'width' => 255,
|
||||
'height' => 255,
|
||||
'sizes' => [
|
||||
'thumbnail' => '/assets/uploads/2020/06/LOUE-2020-150x150.png',
|
||||
'thumbnail-width' => 150,
|
||||
'thumbnail-height' => 150,
|
||||
'medium' => '/assets/uploads/2020/06/LOUE-2020.png',
|
||||
'medium-width' => 255,
|
||||
'medium-height' => 255,
|
||||
'medium_large' => '/assets/uploads/2020/06/LOUE-2020.png',
|
||||
'medium_large-width' => 255,
|
||||
'medium_large-height' => 255,
|
||||
'large' => '/assets/uploads/2020/06/LOUE-2020.png',
|
||||
'large-width' => 255,
|
||||
'large-height' => 255,
|
||||
'1536x1536' => '/assets/uploads/2020/06/LOUE-2020.png',
|
||||
'1536x1536-width' => 255,
|
||||
'1536x1536-height' => 255,
|
||||
'2048x2048' => '/assets/uploads/2020/06/LOUE-2020.png',
|
||||
'2048x2048-width' => 255,
|
||||
'2048x2048-height' => 255,
|
||||
'post-thumbnail' => '/assets/uploads/2020/06/LOUE-2020-240x240.png',
|
||||
'post-thumbnail-width' => 240,
|
||||
'post-thumbnail-height' => 240,
|
||||
'alm-thumbnail' => '/assets/uploads/2020/06/LOUE-2020-150x150.png',
|
||||
'alm-thumbnail-width' => 150,
|
||||
'alm-thumbnail-height' => 150,
|
||||
],
|
||||
],
|
||||
'link' => '/nos-marques/#brand_1_2',
|
||||
],
|
||||
[
|
||||
'image' => [
|
||||
'ID' => 505,
|
||||
'id' => 505,
|
||||
'title' => 'brand-3',
|
||||
'filename' => 'brand-3-2.png',
|
||||
'filesize' => 0,
|
||||
'url' => '/assets/uploads/2020/02/brand-3-2.png',
|
||||
'link' => '/nos-marques/brand-3-3/',
|
||||
'alt' => '',
|
||||
'author' => '20',
|
||||
'description' => '',
|
||||
'caption' => '',
|
||||
'name' => 'brand-3-3',
|
||||
'status' => 'inherit',
|
||||
'uploaded_to' => 175,
|
||||
'date' => '2020-02-20 11:55:52',
|
||||
'modified' => '2020-02-20 11:55:52',
|
||||
'menu_order' => 0,
|
||||
'mime_type' => 'image/png',
|
||||
'type' => 'image',
|
||||
'subtype' => 'png',
|
||||
'icon' => '/wp/wp-includes/images/media/default.png',
|
||||
'width' => 255,
|
||||
'height' => 255,
|
||||
'sizes' => [
|
||||
'thumbnail' => '/assets/uploads/2020/02/brand-3-2-150x150.png',
|
||||
'thumbnail-width' => 150,
|
||||
'thumbnail-height' => 150,
|
||||
'medium' => '/assets/uploads/2020/02/brand-3-2.png',
|
||||
'medium-width' => 255,
|
||||
'medium-height' => 255,
|
||||
'medium_large' => '/assets/uploads/2020/02/brand-3-2.png',
|
||||
'medium_large-width' => 255,
|
||||
'medium_large-height' => 255,
|
||||
'large' => '/assets/uploads/2020/02/brand-3-2.png',
|
||||
'large-width' => 255,
|
||||
'large-height' => 255,
|
||||
'1536x1536' => '/assets/uploads/2020/02/brand-3-2.png',
|
||||
'1536x1536-width' => 255,
|
||||
'1536x1536-height' => 255,
|
||||
'2048x2048' => '/assets/uploads/2020/02/brand-3-2.png',
|
||||
'2048x2048-width' => 255,
|
||||
'2048x2048-height' => 255,
|
||||
'post-thumbnail' => '/assets/uploads/2020/02/brand-3-2-240x240.png',
|
||||
'post-thumbnail-width' => 240,
|
||||
'post-thumbnail-height' => 240,
|
||||
'alm-thumbnail' => '/assets/uploads/2020/02/brand-3-2-150x150.png',
|
||||
'alm-thumbnail-width' => 150,
|
||||
'alm-thumbnail-height' => 150,
|
||||
],
|
||||
],
|
||||
'link' => '/nos-marques/#brand_1_3',
|
||||
],
|
||||
[
|
||||
'image' => [
|
||||
'ID' => 506,
|
||||
'id' => 506,
|
||||
'title' => 'brand-4',
|
||||
'filename' => 'brand-4-2.png',
|
||||
'filesize' => 0,
|
||||
'url' => '/assets/uploads/2020/02/brand-4-2.png',
|
||||
'link' => '/nos-marques/brand-4-3/',
|
||||
'alt' => '',
|
||||
'author' => '20',
|
||||
'description' => '',
|
||||
'caption' => '',
|
||||
'name' => 'brand-4-3',
|
||||
'status' => 'inherit',
|
||||
'uploaded_to' => 175,
|
||||
'date' => '2020-02-20 11:55:52',
|
||||
'modified' => '2020-02-20 11:55:52',
|
||||
'menu_order' => 0,
|
||||
'mime_type' => 'image/png',
|
||||
'type' => 'image',
|
||||
'subtype' => 'png',
|
||||
'icon' => '/wp/wp-includes/images/media/default.png',
|
||||
'width' => 255,
|
||||
'height' => 255,
|
||||
'sizes' => [
|
||||
'thumbnail' => '/assets/uploads/2020/02/brand-4-2-150x150.png',
|
||||
'thumbnail-width' => 150,
|
||||
'thumbnail-height' => 150,
|
||||
'medium' => '/assets/uploads/2020/02/brand-4-2.png',
|
||||
'medium-width' => 255,
|
||||
'medium-height' => 255,
|
||||
'medium_large' => '/assets/uploads/2020/02/brand-4-2.png',
|
||||
'medium_large-width' => 255,
|
||||
'medium_large-height' => 255,
|
||||
'large' => '/assets/uploads/2020/02/brand-4-2.png',
|
||||
'large-width' => 255,
|
||||
'large-height' => 255,
|
||||
'1536x1536' => '/assets/uploads/2020/02/brand-4-2.png',
|
||||
'1536x1536-width' => 255,
|
||||
'1536x1536-height' => 255,
|
||||
'2048x2048' => '/assets/uploads/2020/02/brand-4-2.png',
|
||||
'2048x2048-width' => 255,
|
||||
'2048x2048-height' => 255,
|
||||
'post-thumbnail' => '/assets/uploads/2020/02/brand-4-2-240x240.png',
|
||||
'post-thumbnail-width' => 240,
|
||||
'post-thumbnail-height' => 240,
|
||||
'alm-thumbnail' => '/assets/uploads/2020/02/brand-4-2-150x150.png',
|
||||
'alm-thumbnail-width' => 150,
|
||||
'alm-thumbnail-height' => 150,
|
||||
],
|
||||
],
|
||||
'link' => '/nos-marques/#brand_1_4',
|
||||
],
|
||||
[
|
||||
'image' => [
|
||||
'ID' => 5503,
|
||||
'id' => 5503,
|
||||
'title' => 'MAITRE_COQ_255x255',
|
||||
'filename' => 'MAITRE_COQ_255x255.png',
|
||||
'filesize' => 0,
|
||||
'url' => '/assets/uploads/2020/06/MAITRE_COQ_255x255.png',
|
||||
'link' => '/type/arrive-plateforme-logistique-les-essarts/maitre_coq_255x255/',
|
||||
'alt' => '',
|
||||
'author' => '7',
|
||||
'description' => '',
|
||||
'caption' => '',
|
||||
'name' => 'maitre_coq_255x255',
|
||||
'status' => 'inherit',
|
||||
'uploaded_to' => 1373,
|
||||
'date' => '2020-06-25 12:15:30',
|
||||
'modified' => '2021-03-04 13:36:10',
|
||||
'menu_order' => 0,
|
||||
'mime_type' => 'image/png',
|
||||
'type' => 'image',
|
||||
'subtype' => 'png',
|
||||
'icon' => '/wp/wp-includes/images/media/default.png',
|
||||
'width' => 255,
|
||||
'height' => 255,
|
||||
'sizes' => [
|
||||
'thumbnail' => '/assets/uploads/2020/06/MAITRE_COQ_255x255-150x150.png',
|
||||
'thumbnail-width' => 150,
|
||||
'thumbnail-height' => 150,
|
||||
'medium' => '/assets/uploads/2020/06/MAITRE_COQ_255x255.png',
|
||||
'medium-width' => 255,
|
||||
'medium-height' => 255,
|
||||
'medium_large' => '/assets/uploads/2020/06/MAITRE_COQ_255x255.png',
|
||||
'medium_large-width' => 255,
|
||||
'medium_large-height' => 255,
|
||||
'large' => '/assets/uploads/2020/06/MAITRE_COQ_255x255.png',
|
||||
'large-width' => 255,
|
||||
'large-height' => 255,
|
||||
'1536x1536' => '/assets/uploads/2020/06/MAITRE_COQ_255x255.png',
|
||||
'1536x1536-width' => 255,
|
||||
'1536x1536-height' => 255,
|
||||
'2048x2048' => '/assets/uploads/2020/06/MAITRE_COQ_255x255.png',
|
||||
'2048x2048-width' => 255,
|
||||
'2048x2048-height' => 255,
|
||||
'post-thumbnail' => '/assets/uploads/2020/06/MAITRE_COQ_255x255-240x240.png',
|
||||
'post-thumbnail-width' => 240,
|
||||
'post-thumbnail-height' => 240,
|
||||
'alm-thumbnail' => '/assets/uploads/2020/06/MAITRE_COQ_255x255-150x150.png',
|
||||
'alm-thumbnail-width' => 150,
|
||||
'alm-thumbnail-height' => 150,
|
||||
],
|
||||
],
|
||||
'link' => '/nos-marques/#brand_1_5',
|
||||
],
|
||||
[
|
||||
'image' => [
|
||||
'ID' => 508,
|
||||
'id' => 508,
|
||||
'title' => 'brand-6',
|
||||
'filename' => 'brand-6-2.png',
|
||||
'filesize' => 0,
|
||||
'url' => '/assets/uploads/2020/02/brand-6-2.png',
|
||||
'link' => '/nos-marques/brand-6-3/',
|
||||
'alt' => '',
|
||||
'author' => '20',
|
||||
'description' => '',
|
||||
'caption' => '',
|
||||
'name' => 'brand-6-3',
|
||||
'status' => 'inherit',
|
||||
'uploaded_to' => 175,
|
||||
'date' => '2020-02-20 11:55:53',
|
||||
'modified' => '2020-02-20 11:55:53',
|
||||
'menu_order' => 0,
|
||||
'mime_type' => 'image/png',
|
||||
'type' => 'image',
|
||||
'subtype' => 'png',
|
||||
'icon' => '/wp/wp-includes/images/media/default.png',
|
||||
'width' => 255,
|
||||
'height' => 255,
|
||||
'sizes' => [
|
||||
'thumbnail' => '/assets/uploads/2020/02/brand-6-2-150x150.png',
|
||||
'thumbnail-width' => 150,
|
||||
'thumbnail-height' => 150,
|
||||
'medium' => '/assets/uploads/2020/02/brand-6-2.png',
|
||||
'medium-width' => 255,
|
||||
'medium-height' => 255,
|
||||
'medium_large' => '/assets/uploads/2020/02/brand-6-2.png',
|
||||
'medium_large-width' => 255,
|
||||
'medium_large-height' => 255,
|
||||
'large' => '/assets/uploads/2020/02/brand-6-2.png',
|
||||
'large-width' => 255,
|
||||
'large-height' => 255,
|
||||
'1536x1536' => '/assets/uploads/2020/02/brand-6-2.png',
|
||||
'1536x1536-width' => 255,
|
||||
'1536x1536-height' => 255,
|
||||
'2048x2048' => '/assets/uploads/2020/02/brand-6-2.png',
|
||||
'2048x2048-width' => 255,
|
||||
'2048x2048-height' => 255,
|
||||
'post-thumbnail' => '/assets/uploads/2020/02/brand-6-2-240x240.png',
|
||||
'post-thumbnail-width' => 240,
|
||||
'post-thumbnail-height' => 240,
|
||||
'alm-thumbnail' => '/assets/uploads/2020/02/brand-6-2-150x150.png',
|
||||
'alm-thumbnail-width' => 150,
|
||||
'alm-thumbnail-height' => 150,
|
||||
],
|
||||
],
|
||||
'link' => '/nos-marques/#brand_2_1',
|
||||
],
|
||||
[
|
||||
'image' => [
|
||||
'ID' => 12529,
|
||||
'id' => 12529,
|
||||
'title' => 'logo-matines-255x255',
|
||||
'filename' => 'logo-matines-255x255-1.gif',
|
||||
'filesize' => 0,
|
||||
'url' => '/assets/uploads/2023/04/logo-matines-255x255-1.gif',
|
||||
'link' => '/logo-matines-255x255/',
|
||||
'alt' => 'Logo de la marque Matines',
|
||||
'author' => '8',
|
||||
'description' => 'Logo de la marque Matines',
|
||||
'caption' => 'Logo de la marque Matines',
|
||||
'name' => 'logo-matines-255x255',
|
||||
'status' => 'inherit',
|
||||
'uploaded_to' => 0,
|
||||
'date' => '2023-04-28 12:15:44',
|
||||
'modified' => '2023-04-28 12:15:59',
|
||||
'menu_order' => 0,
|
||||
'mime_type' => 'image/gif',
|
||||
'type' => 'image',
|
||||
'subtype' => 'gif',
|
||||
'icon' => '/wp/wp-includes/images/media/default.png',
|
||||
'width' => 255,
|
||||
'height' => 255,
|
||||
'sizes' => [
|
||||
'thumbnail' => '/assets/uploads/2023/04/logo-matines-255x255-1-150x150.gif',
|
||||
'thumbnail-width' => 150,
|
||||
'thumbnail-height' => 150,
|
||||
'medium' => '/assets/uploads/2023/04/logo-matines-255x255-1.gif',
|
||||
'medium-width' => 255,
|
||||
'medium-height' => 255,
|
||||
'medium_large' => '/assets/uploads/2023/04/logo-matines-255x255-1.gif',
|
||||
'medium_large-width' => 255,
|
||||
'medium_large-height' => 255,
|
||||
'large' => '/assets/uploads/2023/04/logo-matines-255x255-1.gif',
|
||||
'large-width' => 255,
|
||||
'large-height' => 255,
|
||||
'1536x1536' => '/assets/uploads/2023/04/logo-matines-255x255-1.gif',
|
||||
'1536x1536-width' => 255,
|
||||
'1536x1536-height' => 255,
|
||||
'2048x2048' => '/assets/uploads/2023/04/logo-matines-255x255-1.gif',
|
||||
'2048x2048-width' => 255,
|
||||
'2048x2048-height' => 255,
|
||||
'post-thumbnail' => '/assets/uploads/2023/04/logo-matines-255x255-1-240x240.gif',
|
||||
'post-thumbnail-width' => 240,
|
||||
'post-thumbnail-height' => 240,
|
||||
'alm-thumbnail' => '/assets/uploads/2023/04/logo-matines-255x255-1-150x150.gif',
|
||||
'alm-thumbnail-width' => 150,
|
||||
'alm-thumbnail-height' => 150,
|
||||
],
|
||||
],
|
||||
'link' => '',
|
||||
],
|
||||
];
|
||||
$includeBladeName = $mob ? 'front.brands-icons.brands-icons-mobile' : 'front.brands-icons.brands-icons';
|
||||
'link' => \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.nos-marques'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@endphp
|
||||
<x-dynamic-component :component="$includeBladeName" :brands="$brands" title="Nos marques" />
|
||||
|
||||
@if(isset($pageNosMarques) && !empty($brands))
|
||||
<x-front.brands-icons.brands-icons :brands="$brands" :title="$pageNosMarques->title" />
|
||||
@endif
|
||||
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@
|
|||
'image' => [
|
||||
'url' => asset($logo['list_logo'][0]['image_brand_logo']),
|
||||
],
|
||||
'link' => \App\Helpers\RouteHelper::routeNameChecker('front.dynamic-pages.nos-marques'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
@extends('front.layouts.layout')
|
||||
|
||||
@section('title', $page['seo_title'])
|
||||
@section('description', $page['seo_description'])
|
||||
|
||||
@section('content')
|
||||
<div class="single-page fw fw-container">
|
||||
<div class="single-page__wrapper wrapper">
|
||||
<h1 class="title">
|
||||
<span class="title-text">{{ $page['title'] }}</span>
|
||||
</h1>
|
||||
<div class="single-page__content description">
|
||||
{!! $page['content'] !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -10,26 +10,34 @@ use Diglactic\Breadcrumbs\Generator;
|
|||
use Illuminate\Support\Str;
|
||||
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
|
||||
|
||||
$currentLocale = app()->getLocale();
|
||||
$supportedLocales = LaravelLocalization::getSupportedLanguagesKeys();
|
||||
|
||||
// * HOMEPAGE.
|
||||
Breadcrumbs::for('front.homepage', function (Generator $trail) {
|
||||
$trail->push(
|
||||
Str::ucfirst(trans('front.homepage')),
|
||||
route('front.homepage')
|
||||
);
|
||||
});
|
||||
|
||||
$pageHome = DynamicPage::getModelsCached()
|
||||
->where('status', PageStatusEnum::published)
|
||||
->where('id_key', 'accueil')
|
||||
->first();
|
||||
if ($pageHome && !request()->routeIs("front.dynamic-pages.accueil.$currentLocale")) {
|
||||
foreach ($supportedLocales as $key => $locale) {
|
||||
Breadcrumbs::for("front.dynamic-pages.accueil.$locale", function (Generator $trail) use ($pageHome) {
|
||||
$trail->push($pageHome->title, RouteHelper::routeNameChecker('front.dynamic-pages.accueil'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// * CONTACT PAGE
|
||||
Breadcrumbs::for('front.contact.index', function (Generator $trail) {
|
||||
$trail->parent('front.homepage');
|
||||
Breadcrumbs::for('front.contact.index', function (Generator $trail) use ($pageHome, $currentLocale) {
|
||||
if ($pageHome) {
|
||||
$trail->parent("front.dynamic-pages.accueil.$currentLocale");
|
||||
}
|
||||
$trail->push(
|
||||
Str::of(trans('front.contact.index'))->ucfirst(),
|
||||
route('front.contact.index')
|
||||
);
|
||||
});
|
||||
|
||||
// * CONTACT PAGE
|
||||
Breadcrumbs::for('front.contact.show', function (Generator $trail) {
|
||||
$trail->parent('front.contact.index');
|
||||
$slug = \request()->route()->parameters['slug'];
|
||||
|
|
@ -45,8 +53,10 @@ Breadcrumbs::for('front.contact.show', function (Generator $trail) {
|
|||
});
|
||||
|
||||
// * SEARCH PAGE
|
||||
Breadcrumbs::for('front.search', function (Generator $trail) {
|
||||
$trail->parent('front.homepage');
|
||||
Breadcrumbs::for('front.search', function (Generator $trail) use ($pageHome, $currentLocale) {
|
||||
if ($pageHome) {
|
||||
$trail->parent("front.dynamic-pages.accueil.$currentLocale");
|
||||
}
|
||||
$trail->push(
|
||||
Str::of(trans('front.search'))->ucfirst(),
|
||||
route('front.search')
|
||||
|
|
@ -59,14 +69,15 @@ $pageEspacePresse = DynamicPage::getModelsCached()
|
|||
->where('id_key', 'espace-presse')
|
||||
->first();
|
||||
if ($pageEspacePresse) {
|
||||
Breadcrumbs::for('front.dynamic-pages.espace-presse.fr', function (Generator $trail) use ($pageEspacePresse) {
|
||||
$trail->parent('front.homepage');
|
||||
$trail->push($pageEspacePresse->title);
|
||||
});
|
||||
Breadcrumbs::for('front.dynamic-pages.espace-presse.en', function (Generator $trail) use ($pageEspacePresse) {
|
||||
$trail->parent('front.homepage');
|
||||
$trail->push($pageEspacePresse->title);
|
||||
});
|
||||
foreach ($supportedLocales as $key => $locale) {
|
||||
Breadcrumbs::for("front.dynamic-pages.espace-presse.$locale", function (Generator $trail) use ($pageEspacePresse, $pageHome, $locale) {
|
||||
if ($pageHome) {
|
||||
$trail->parent("front.dynamic-pages.accueil.$locale");
|
||||
}
|
||||
$trail->parent("front.dynamic-pages.accueil");
|
||||
$trail->push($pageEspacePresse->title);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// * ENGAGEMENTS PAGES.
|
||||
|
|
@ -76,8 +87,10 @@ $pageOurCommitments = DynamicPage::getModelsCached()
|
|||
->first();
|
||||
if ($pageOurCommitments) {
|
||||
foreach ($supportedLocales as $key => $locale) {
|
||||
Breadcrumbs::for("front.dynamic-pages.nos-engagements.$locale", function (Generator $trail) use ($pageOurCommitments) {
|
||||
$trail->parent('front.homepage');
|
||||
Breadcrumbs::for("front.dynamic-pages.nos-engagements.$locale", function (Generator $trail) use ($pageOurCommitments, $pageHome, $locale) {
|
||||
if ($pageHome) {
|
||||
$trail->parent("front.dynamic-pages.accueil.$locale");
|
||||
}
|
||||
$trail->push($pageOurCommitments->title, RouteHelper::routeNameChecker('front.dynamic-pages.nos-engagements'));
|
||||
});
|
||||
foreach ($pageOurCommitments->childPages as $key => $childPage) {
|
||||
|
|
@ -96,8 +109,10 @@ $pageKnowUs = DynamicPage::getModelsCached()
|
|||
->first();
|
||||
if ($pageKnowUs) {
|
||||
foreach ($supportedLocales as $key => $locale) {
|
||||
Breadcrumbs::for("front.dynamic-pages.nous-connaitre.$locale", function (Generator $trail) use ($pageKnowUs) {
|
||||
$trail->parent('front.homepage');
|
||||
Breadcrumbs::for("front.dynamic-pages.nous-connaitre.$locale", function (Generator $trail) use ($pageKnowUs, $pageHome, $locale) {
|
||||
if ($pageHome) {
|
||||
$trail->parent("front.dynamic-pages.accueil.$locale");
|
||||
}
|
||||
$trail->push($pageKnowUs->title);
|
||||
});
|
||||
}
|
||||
|
|
@ -109,14 +124,14 @@ $pageNosMarques = DynamicPage::getModelsCached()
|
|||
->where('id_key', 'nos-marques')
|
||||
->first();
|
||||
if ($pageNosMarques) {
|
||||
Breadcrumbs::for('front.dynamic-pages.nos-marques.fr', function (Generator $trail) use ($pageNosMarques) {
|
||||
$trail->parent('front.homepage');
|
||||
$trail->push($pageNosMarques->title);
|
||||
});
|
||||
Breadcrumbs::for('front.dynamic-pages.nos-marques.en', function (Generator $trail) use ($pageNosMarques) {
|
||||
$trail->parent('front.homepage');
|
||||
$trail->push($pageNosMarques->title);
|
||||
});
|
||||
foreach ($supportedLocales as $key => $locale) {
|
||||
Breadcrumbs::for("front.dynamic-pages.nos-marques.$locale", function (Generator $trail) use ($pageNosMarques, $pageHome, $locale) {
|
||||
if ($pageHome) {
|
||||
$trail->parent("front.dynamic-pages.accueil.$locale");
|
||||
}
|
||||
$trail->push($pageNosMarques->title);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// * JOIN US.
|
||||
|
|
@ -125,14 +140,14 @@ $pageNousRejoindre = DynamicPage::getModelsCached()
|
|||
->where('id_key', 'nous-rejoindre')
|
||||
->first();
|
||||
if ($pageNousRejoindre) {
|
||||
Breadcrumbs::for('front.dynamic-pages.nous-rejoindre.fr', function (Generator $trail) use ($pageNousRejoindre) {
|
||||
$trail->parent('front.homepage');
|
||||
$trail->push($pageNousRejoindre->title);
|
||||
});
|
||||
Breadcrumbs::for('front.dynamic-pages.nous-rejoindre.en', function (Generator $trail) use ($pageNousRejoindre) {
|
||||
$trail->parent('front.homepage');
|
||||
$trail->push($pageNousRejoindre->title);
|
||||
});
|
||||
foreach ($supportedLocales as $key => $locale) {
|
||||
Breadcrumbs::for("front.dynamic-pages.nous-rejoindre.$locale", function (Generator $trail) use ($pageNousRejoindre, $pageHome, $locale) {
|
||||
if ($pageHome) {
|
||||
$trail->parent("front.dynamic-pages.accueil.$locale");
|
||||
}
|
||||
$trail->push($pageNousRejoindre->title);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// * OUR JOBS.
|
||||
|
|
@ -141,14 +156,14 @@ $pageNosMetiers = DynamicPage::getModelsCached()
|
|||
->where('id_key', 'nos-metiers')
|
||||
->first();
|
||||
if ($pageNosMetiers) {
|
||||
Breadcrumbs::for('front.dynamic-pages.nos-metiers.fr', function (Generator $trail) use ($pageNosMetiers) {
|
||||
$trail->parent('front.homepage');
|
||||
$trail->push($pageNosMetiers->title);
|
||||
});
|
||||
Breadcrumbs::for('front.dynamic-pages.nos-metiers.en', function (Generator $trail) use ($pageNosMetiers) {
|
||||
$trail->parent('front.homepage');
|
||||
$trail->push($pageNosMetiers->title);
|
||||
});
|
||||
foreach ($supportedLocales as $key => $locale) {
|
||||
Breadcrumbs::for("front.dynamic-pages.nos-metiers.$locale", function (Generator $trail) use ($pageNosMetiers, $pageHome, $locale) {
|
||||
if ($pageHome) {
|
||||
$trail->parent("front.dynamic-pages.accueil.$locale");
|
||||
}
|
||||
$trail->push($pageNosMetiers->title);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// * NEWS.
|
||||
|
|
@ -158,8 +173,10 @@ $pageNews = DynamicPage::getModelsCached()
|
|||
->first();
|
||||
if ($pageNews) {
|
||||
foreach ($supportedLocales as $key => $locale) {
|
||||
Breadcrumbs::for("front.dynamic-pages.actualites.$locale", function (Generator $trail) use ($pageNews) {
|
||||
$trail->parent('front.homepage');
|
||||
Breadcrumbs::for("front.dynamic-pages.actualites.$locale", function (Generator $trail) use ($pageNews, $pageHome, $currentLocale) {
|
||||
if ($pageHome) {
|
||||
$trail->parent("front.dynamic-pages.accueil.$currentLocale");
|
||||
}
|
||||
$trail->push($pageNews->title, RouteHelper::routeNameChecker('front.dynamic-pages.actualites'));
|
||||
});
|
||||
}
|
||||
|
|
@ -174,10 +191,11 @@ if ($pageNews) {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
// * FINANCE.
|
||||
Breadcrumbs::for('front.finance', function (Generator $trail) {
|
||||
$trail->parent('front.homepage');
|
||||
Breadcrumbs::for('front.finance', function (Generator $trail) use ($pageHome, $currentLocale) {
|
||||
if ($pageHome) {
|
||||
$trail->parent("front.dynamic-pages.accueil.$currentLocale");
|
||||
}
|
||||
$trail->push(
|
||||
Str::of(trans('front.finance'))->ucfirst(),
|
||||
route('front.finance')
|
||||
|
|
|
|||
|
|
@ -10,15 +10,8 @@ Route::group(
|
|||
[
|
||||
'prefix' => LaravelLocalization::setLocale(),
|
||||
'as' => 'front.',
|
||||
'middleware' => [
|
||||
'localeSessionRedirect',
|
||||
'localizationRedirect',
|
||||
'localeViewPath'
|
||||
]
|
||||
],
|
||||
function () {
|
||||
Route::get('/', [HomeController::class, 'homepage'])->name('homepage');
|
||||
|
||||
Route::name('contact.')->controller(ContactController::class)->group(function () {
|
||||
Route::get(LaravelLocalization::transRoute('routes.contact_index'), 'index')->name('index');
|
||||
Route::get(LaravelLocalization::transRoute('routes.contact'), 'show')->defaults('contactPage', 'contactPage')->name('show');
|
||||
|
|
@ -34,72 +27,6 @@ Route::group(
|
|||
return view('front.pages.search');
|
||||
})->name('search');
|
||||
|
||||
|
||||
Route::get(LaravelLocalization::transRoute('routes.news'), [NewsController::class, 'show'])->name('news.show');
|
||||
|
||||
|
||||
|
||||
Route::get('/politique-de-confidentialite', function () {
|
||||
$page = [
|
||||
'seo_title' => 'LDC Charte de confidentialité',
|
||||
'seo_description' => 'Politique de confidentialité, gestion de vos droits, cookies, confidentialité',
|
||||
'title' => 'Charte de confidentialité',
|
||||
'content' => "
|
||||
<h2 class='wp-block-heading'><strong>INTRODUCTION</strong></h2>
|
||||
<p><strong>INTRODUCTION</strong></p>
|
||||
<p>La société LDC est particulièrement attentif à la protection de vos données personnelles. Concernant les données personnelles que vous nous confiez nous vous informons de manière transparente sur notre politique en matière de protection des données personnelles.<strong></strong></p>
|
||||
<p>La société LDC s'engage à traiter vos données à caractère personnel conformément aux dispositions du Règlement Général sur la Protection des Données 2016/679 du Parlement européen et du Conseil du 27 avril 2016 (RGPD) et la loi n°78-17 du 6 janvier 1978 modifiée relative à l'informatique, aux fichiers et aux libertés (loi « Informatique et Libertés »), qui définissent les conditions dans lesquelles des traitements de données à caractère personnel peuvent être mis en œuvre.</p>
|
||||
<p>Toute information recueillie au travers du site internet et permettant de vous identifier, de manière directe ou indirecte, est considérée comme une donnée à caractère personnel et sera traitée conformément à cette politique.</p>
|
||||
<p><strong>Nous vous invitons à consulter régulièrement cette rubrique car </strong><strong>la société LDC </strong><strong>peut être amenée à la modifier à tout moment.</strong></p>
|
||||
<p>La présente Charte de confidentialité a été mise à jour le 30 novembre 2023.</p>
|
||||
<p><strong>RESPONSABLE DE TRAITEMENT ET DELEGUE A LA PROTECTION DES DONNEES</strong></p>
|
||||
<p>Le responsable de traitement des données collectées et traitées sur notre site internet est la société LDC, située ZI Saint-Laurent, 72300 Sablé-sur-Sarthe (ci-après désigné le « <strong>Responsable de Traitement</strong> »).</p>
|
||||
<p>Le Responsable de Traitement a désigné un délégué à la protection des données ou « DPO » que vous pouvez contacter à l'adresse suivante : <a href='mailto:dpo@ldc.fr'>dpo@ldc.fr</a> .</p>
|
||||
<p><strong>DONNEES PERSONNELLES</strong></p>
|
||||
<p>Au sens du Règlement RGPD, une donnée à caractère personnel désigne toute information relative à une personne physique identifiée ou identifiable.</p>
|
||||
<p>Les données personnelles collectées varient en fonction du but de la collecte et du service dont vous souhaitez bénéficier.</p>
|
||||
<p>Vous vous engagez à fournir des données personnelles actualisées et valides et garantissez ne faire aucune fausse déclaration et ne donner aucune information erronée.</p>
|
||||
<p><strong>FINALITES DE TRAITEMENT, BASES JURIDIQUES ET DUREES DE CONSERVATION</strong></p>
|
||||
<p><strong>Finalité du traitement : Gestion de l'inscription à la newsletter</strong></p>
|
||||
<p>Base juridique : Consentement (BtoC) / Intérêt légitime (BtoB) (Diffusion d'informations avec la newsletter)</p>
|
||||
<p>Durée de conservation : Le temps de l'inscription de la personne concernée à la newsletter</p>
|
||||
<p><strong>Finalité du traitement : Gérer les candidatures au travers de l'espace dédié sur le site</strong></p>
|
||||
<p>Base juridique : Consentement</p>
|
||||
<p>Durée de conservation : 2 ans à compter du dernier contact avec le candidat</p>
|
||||
<p><strong>Finalité du traitement</strong><strong> </strong><strong>: Gérer les demandes qui nous parviennent au travers du formulaire de contact</strong></p>
|
||||
<p>Base juridique : Intérêt légitime (Répondre aux demandes de contacts)</p>
|
||||
<p>Durée de conservation : Pour les clients : 3 ans à compter de la fin de la relation commerciale / Pour les prospects : 3 ans à compter de la collecte des données personnelles ou à compter du dernier contact émanant du prospect</p>
|
||||
<p><strong>Finalité du traitement</strong><strong> </strong><strong>: Gestion des cookies</strong></p>
|
||||
<p>Base juridique : Consentement</p>
|
||||
<p>Durée de conservation : 13 mois</p>
|
||||
<p><strong>VOS DROITS</strong></p>
|
||||
<p>Conformément aux dispositions du RGPD, vous pouvez exercer vos droits suivants :</p>
|
||||
<ul class='wp-block-list'><li>Un droit d'accès : le droit d'obtenir la confirmation que vos données personnelles font ou ne font pas l'objet d'un traitement, et d'en obtenir la communication </li><li>Un droit de rectification : le droit d'obtenir la rectification de données personnelles inexactes ou de pouvoir compléter des données incomplètes </li><li>Un droit d'effacement : le droit d'obtenir la suppression de vos données personnelles quand cela est possible </li><li>Un droit d'opposition : le droit de s'opposer à tout moment au traitement de vos données personnelles, quand celui-ci est fondé sur notre intérêt légitime </li><li>Un droit au retrait de votre consentement : lorsque le traitement de vos données est fondé sur votre consentement. Vous pouvez exercer ce droit à tout moment sans avoir à en justifier la raison </li><li>Un droit à la limitation : le droit de demander le gel des données du traitement pour une période donnée </li><li>Un droit à la portabilité : le droit de recevoir les données personnelles que vous avez fournies dans un format structuré, couramment lisible par machine, et de les communiquer à un tiers </li><li>Un droit à réclamation : le droit d'adresser à la CNIL une réclamation si vous estimez que vos droits ne sont pas respectés</li></ul>
|
||||
<p><strong>Vous pouvez exercer ces droits <u>à tout moment</u> en nous contactant via le formulaire suivant</strong><strong> </strong><strong>:</strong></p>
|
||||
<p><a href='/rgpd/professionnels/'>/professionnels/</a></p>
|
||||
<p><a href='/rgpd/consommateurs/'>/rgpd/consommateurs/</a></p>
|
||||
<p><a href='/rgpd/salaries/'>/rgpd/salaries/</a></p>
|
||||
<p><strong>Droit de porter réclamation auprès de la CNIL</strong></p>
|
||||
<p>Si vous estimez, après nous avoir contactés, que vos droits « Informatique et Libertés » ne sont pas respectés, vous pouvez adresser une réclamation à la CNIL : <a href='https://www.cnil.fr/fr/plaintes'>https://www.cnil.fr/fr/plaintes</a>.</p>
|
||||
<p><strong>PROTECTION DE VOS DONNEES PERSONNELLES</strong></p>
|
||||
<p>Afin d'assurer la sécurité de vos données personnelles nous avons mis en place des mesures de sécurité, notamment des contrôles d'accès, des pare-feux, des serveurs sécurisés.</p>
|
||||
<p>Ces mesures visent à protéger vos données personnelles contre toute perte, détournement, mauvaise utilisation, divulgation, modification, interférence, dommage, accès non autorisé des données.</p>
|
||||
<p><strong>ACCES A VOS DONNEES PERSONNELLES</strong><strong> </strong><strong></strong></p>
|
||||
<p>Vos données personnelles sont destinées au personnel du Responsable de Traitement habilité à les traiter, notamment le service marketing, développement durable, informatique, commercial, qualité et administratif.</p>
|
||||
<p><strong>PARTAGE DE VOS DONNÉES PERSONNELLES</strong></p>
|
||||
<p>Conformément à la réglementation, quand nous sommes amenés à partager vos données personnelles avec des sous-traitants pour certaines finalités décrites dans la présente Charte, nous nous assurons que leur dispositif en matière de sécurité des données et de leur stockage est au moins aussi important que celui de notre organisation. Nous veillons également à ce qu'ils respectent les lois relatives à la protection des données personnelles dans des conditions au moins équivalentes à celles que nous respectons.</p>
|
||||
<p>Par ailleurs, les sous-traitants étant amenés à traiter de vos données personnelles pour notre compte et sur nos instructions, nous nous engageons à ce que vos données personnelles ne soient pas partagées ou divulguées pour des finalités autres que celles décrites dans la présente Charte. Nous pouvons cependant être amenés à transmettre vos données, pour des finalités autres que celles prévues dans la Charte, dans les cas où leur communication est requise par la loi et les autorités gouvernementales.</p>
|
||||
<p><strong>TRANSFERT DE VOS DONNÉES EN DEHORS DE L'ESPACE ECONOMIQUE EUROPEEN</strong></p>
|
||||
<p>En principe, nous veillons à conserver vos données personnelles dans l'Union européenne. Il est toutefois possible que vos données soient ponctuellement transférées à des sous-traitants ou partenaires commerciaux situés dans d'autres pays sous réserve qu'ils offrent un niveau de protection adéquat reconnu par la Commission européenne. En cas de transfert de vos données vers un pays dont le niveau de protection n'a pas été reconnu comme adéquat, nous mettons en place des Clauses contractuelles types approuvées par la Commission européenne qui permettent de garantir un niveau de protection suffisant de la vie privée et des droits fondamentaux des personnes.</p>
|
||||
<p><strong>SITES INTERNET DE TIERS</strong></p>
|
||||
<p>Le site internet du Responsable de Traitement peut être associé à des sites internet tiers. Les sites hébergés par des tiers sont hors de notre contrôle. Lorsque vous renseignez des données personnelles sur un site internet tiers, le traitement de ces données n'est pas effectué sur notre site internet, mais sur le site internet tiers concerné. Toute donnée personnelle que vous fournissez sera collectée et traitée conformément à la politique relative à la confidentialité des données du tiers concerné.</p>
|
||||
<p>Par conséquent, nous n'assumons aucune responsabilité concernant les pratiques exercées par lesdits tiers en matière de protection des données.</p>
|
||||
<p><strong>DROIT APPLICABLE</strong></p>
|
||||
<p>La présente Charte de confidentialité est régie et sera interprétée conformément au droit français.</p>
|
||||
",
|
||||
];
|
||||
|
||||
return view('front.pages.static-pages.template', ['page' => $page]);
|
||||
})->name('politique-de-confidentialite');
|
||||
}
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue